Support for Signal calls.

Merge in RedPhone

// FREEBIE
This commit is contained in:
Moxie Marlinspike
2015-09-09 13:54:29 -07:00
parent 3d4ae60d81
commit d83a3d71bc
2585 changed files with 803492 additions and 45 deletions

View File

@@ -0,0 +1,211 @@
Notes: 2001-09-24
-----------------
This "description" (if one chooses to call it that) needed some major updating
so here goes. This update addresses a change being made at the same time to
OpenSSL, and it pretty much completely restructures the underlying mechanics of
the "ENGINE" code. So it serves a double purpose of being a "ENGINE internals
for masochists" document *and* a rather extensive commit log message. (I'd get
lynched for sticking all this in CHANGES or the commit mails :-).
ENGINE_TABLE underlies this restructuring, as described in the internal header
"eng_int.h", implemented in eng_table.c, and used in each of the "class" files;
tb_rsa.c, tb_dsa.c, etc.
However, "EVP_CIPHER" underlies the motivation and design of ENGINE_TABLE so
I'll mention a bit about that first. EVP_CIPHER (and most of this applies
equally to EVP_MD for digests) is both a "method" and a algorithm/mode
identifier that, in the current API, "lingers". These cipher description +
implementation structures can be defined or obtained directly by applications,
or can be loaded "en masse" into EVP storage so that they can be catalogued and
searched in various ways, ie. two ways of encrypting with the "des_cbc"
algorithm/mode pair are;
(i) directly;
const EVP_CIPHER *cipher = EVP_des_cbc();
EVP_EncryptInit(&ctx, cipher, key, iv);
[ ... use EVP_EncryptUpdate() and EVP_EncryptFinal() ...]
(ii) indirectly;
OpenSSL_add_all_ciphers();
cipher = EVP_get_cipherbyname("des_cbc");
EVP_EncryptInit(&ctx, cipher, key, iv);
[ ... etc ... ]
The latter is more generally used because it also allows ciphers/digests to be
looked up based on other identifiers which can be useful for automatic cipher
selection, eg. in SSL/TLS, or by user-controllable configuration.
The important point about this is that EVP_CIPHER definitions and structures are
passed around with impunity and there is no safe way, without requiring massive
rewrites of many applications, to assume that EVP_CIPHERs can be reference
counted. One an EVP_CIPHER is exposed to the caller, neither it nor anything it
comes from can "safely" be destroyed. Unless of course the way of getting to
such ciphers is via entirely distinct API calls that didn't exist before.
However existing API usage cannot be made to understand when an EVP_CIPHER
pointer, that has been passed to the caller, is no longer being used.
The other problem with the existing API w.r.t. to hooking EVP_CIPHER support
into ENGINE is storage - the OBJ_NAME-based storage used by EVP to register
ciphers simultaneously registers cipher *types* and cipher *implementations* -
they are effectively the same thing, an "EVP_CIPHER" pointer. The problem with
hooking in ENGINEs is that multiple ENGINEs may implement the same ciphers. The
solution is necessarily that ENGINE-provided ciphers simply are not registered,
stored, or exposed to the caller in the same manner as existing ciphers. This is
especially necessary considering the fact ENGINE uses reference counts to allow
for cleanup, modularity, and DSO support - yet EVP_CIPHERs, as exposed to
callers in the current API, support no such controls.
Another sticking point for integrating cipher support into ENGINE is linkage.
Already there is a problem with the way ENGINE supports RSA, DSA, etc whereby
they are available *because* they're part of a giant ENGINE called "openssl".
Ie. all implementations *have* to come from an ENGINE, but we get round that by
having a giant ENGINE with all the software support encapsulated. This creates
linker hassles if nothing else - linking a 1-line application that calls 2 basic
RSA functions (eg. "RSA_free(RSA_new());") will result in large quantities of
ENGINE code being linked in *and* because of that DSA, DH, and RAND also. If we
continue with this approach for EVP_CIPHER support (even if it *was* possible)
we would lose our ability to link selectively by selectively loading certain
implementations of certain functionality. Touching any part of any kind of
crypto would result in massive static linkage of everything else. So the
solution is to change the way ENGINE feeds existing "classes", ie. how the
hooking to ENGINE works from RSA, DSA, DH, RAND, as well as adding new hooking
for EVP_CIPHER, and EVP_MD.
The way this is now being done is by mostly reverting back to how things used to
work prior to ENGINE :-). Ie. RSA now has a "RSA_METHOD" pointer again - this
was previously replaced by an "ENGINE" pointer and all RSA code that required
the RSA_METHOD would call ENGINE_get_RSA() each time on its ENGINE handle to
temporarily get and use the ENGINE's RSA implementation. Apart from being more
efficient, switching back to each RSA having an RSA_METHOD pointer also allows
us to conceivably operate with *no* ENGINE. As we'll see, this removes any need
for a fallback ENGINE that encapsulates default implementations - we can simply
have our RSA structure pointing its RSA_METHOD pointer to the software
implementation and have its ENGINE pointer set to NULL.
A look at the EVP_CIPHER hooking is most explanatory, the RSA, DSA (etc) cases
turn out to be degenerate forms of the same thing. The EVP storage of ciphers,
and the existing EVP API functions that return "software" implementations and
descriptions remain untouched. However, the storage takes more meaning in terms
of "cipher description" and less meaning in terms of "implementation". When an
EVP_CIPHER_CTX is actually initialised with an EVP_CIPHER method and is about to
begin en/decryption, the hooking to ENGINE comes into play. What happens is that
cipher-specific ENGINE code is asked for an ENGINE pointer (a functional
reference) for any ENGINE that is registered to perform the algo/mode that the
provided EVP_CIPHER structure represents. Under normal circumstances, that
ENGINE code will return NULL because no ENGINEs will have had any cipher
implementations *registered*. As such, a NULL ENGINE pointer is stored in the
EVP_CIPHER_CTX context, and the EVP_CIPHER structure is left hooked into the
context and so is used as the implementation. Pretty much how things work now
except we'd have a redundant ENGINE pointer set to NULL and doing nothing.
Conversely, if an ENGINE *has* been registered to perform the algorithm/mode
combination represented by the provided EVP_CIPHER, then a functional reference
to that ENGINE will be returned to the EVP_CIPHER_CTX during initialisation.
That functional reference will be stored in the context (and released on
cleanup) - and having that reference provides a *safe* way to use an EVP_CIPHER
definition that is private to the ENGINE. Ie. the EVP_CIPHER provided by the
application will actually be replaced by an EVP_CIPHER from the registered
ENGINE - it will support the same algorithm/mode as the original but will be a
completely different implementation. Because this EVP_CIPHER isn't stored in the
EVP storage, nor is it returned to applications from traditional API functions,
there is no associated problem with it not having reference counts. And of
course, when one of these "private" cipher implementations is hooked into
EVP_CIPHER_CTX, it is done whilst the EVP_CIPHER_CTX holds a functional
reference to the ENGINE that owns it, thus the use of the ENGINE's EVP_CIPHER is
safe.
The "cipher-specific ENGINE code" I mentioned is implemented in tb_cipher.c but
in essence it is simply an instantiation of "ENGINE_TABLE" code for use by
EVP_CIPHER code. tb_digest.c is virtually identical but, of course, it is for
use by EVP_MD code. Ditto for tb_rsa.c, tb_dsa.c, etc. These instantiations of
ENGINE_TABLE essentially provide linker-separation of the classes so that even
if ENGINEs implement *all* possible algorithms, an application using only
EVP_CIPHER code will link at most code relating to EVP_CIPHER, tb_cipher.c, core
ENGINE code that is independant of class, and of course the ENGINE
implementation that the application loaded. It will *not* however link any
class-specific ENGINE code for digests, RSA, etc nor will it bleed over into
other APIs, such as the RSA/DSA/etc library code.
ENGINE_TABLE is a little more complicated than may seem necessary but this is
mostly to avoid a lot of "init()"-thrashing on ENGINEs (that may have to load
DSOs, and other expensive setup that shouldn't be thrashed unnecessarily) *and*
to duplicate "default" behaviour. Basically an ENGINE_TABLE instantiation, for
example tb_cipher.c, implements a hash-table keyed by integer "nid" values.
These nids provide the uniquenness of an algorithm/mode - and each nid will hash
to a potentially NULL "ENGINE_PILE". An ENGINE_PILE is essentially a list of
pointers to ENGINEs that implement that particular 'nid'. Each "pile" uses some
caching tricks such that requests on that 'nid' will be cached and all future
requests will return immediately (well, at least with minimal operation) unless
a change is made to the pile, eg. perhaps an ENGINE was unloaded. The reason is
that an application could have support for 10 ENGINEs statically linked
in, and the machine in question may not have any of the hardware those 10
ENGINEs support. If each of those ENGINEs has a "des_cbc" implementation, we
want to avoid every EVP_CIPHER_CTX setup from trying (and failing) to initialise
each of those 10 ENGINEs. Instead, the first such request will try to do that
and will either return (and cache) a NULL ENGINE pointer or will return a
functional reference to the first that successfully initialised. In the latter
case it will also cache an extra functional reference to the ENGINE as a
"default" for that 'nid'. The caching is acknowledged by a 'uptodate' variable
that is unset only if un/registration takes place on that pile. Ie. if
implementations of "des_cbc" are added or removed. This behaviour can be
tweaked; the ENGINE_TABLE_FLAG_NOINIT value can be passed to
ENGINE_set_table_flags(), in which case the only ENGINEs that tb_cipher.c will
try to initialise from the "pile" will be those that are already initialised
(ie. it's simply an increment of the functional reference count, and no real
"initialisation" will take place).
RSA, DSA, DH, and RAND all have their own ENGINE_TABLE code as well, and the
difference is that they all use an implicit 'nid' of 1. Whereas EVP_CIPHERs are
actually qualitatively different depending on 'nid' (the "des_cbc" EVP_CIPHER is
not an interoperable implementation of "aes_256_cbc"), RSA_METHODs are
necessarily interoperable and don't have different flavours, only different
implementations. In other words, the ENGINE_TABLE for RSA will either be empty,
or will have a single ENGING_PILE hashed to by the 'nid' 1 and that pile
represents ENGINEs that implement the single "type" of RSA there is.
Cleanup - the registration and unregistration may pose questions about how
cleanup works with the ENGINE_PILE doing all this caching nonsense (ie. when the
application or EVP_CIPHER code releases its last reference to an ENGINE, the
ENGINE_PILE code may still have references and thus those ENGINEs will stay
hooked in forever). The way this is handled is via "unregistration". With these
new ENGINE changes, an abstract ENGINE can be loaded and initialised, but that
is an algorithm-agnostic process. Even if initialised, it will not have
registered any of its implementations (to do so would link all class "table"
code despite the fact the application may use only ciphers, for example). This
is deliberately a distinct step. Moreover, registration and unregistration has
nothing to do with whether an ENGINE is *functional* or not (ie. you can even
register an ENGINE and its implementations without it being operational, you may
not even have the drivers to make it operate). What actually happens with
respect to cleanup is managed inside eng_lib.c with the "engine_cleanup_***"
functions. These functions are internal-only and each part of ENGINE code that
could require cleanup will, upon performing its first allocation, register a
callback with the "engine_cleanup" code. The other part of this that makes it
tick is that the ENGINE_TABLE instantiations (tb_***.c) use NULL as their
initialised state. So if RSA code asks for an ENGINE and no ENGINE has
registered an implementation, the code will simply return NULL and the tb_rsa.c
state will be unchanged. Thus, no cleanup is required unless registration takes
place. ENGINE_cleanup() will simply iterate across a list of registered cleanup
callbacks calling each in turn, and will then internally delete its own storage
(a STACK). When a cleanup callback is next registered (eg. if the cleanup() is
part of a gracefull restart and the application wants to cleanup all state then
start again), the internal STACK storage will be freshly allocated. This is much
the same as the situation in the ENGINE_TABLE instantiations ... NULL is the
initialised state, so only modification operations (not queries) will cause that
code to have to register a cleanup.
What else? The bignum callbacks and associated ENGINE functions have been
removed for two obvious reasons; (i) there was no way to generalise them to the
mechanism now used by RSA/DSA/..., because there's no such thing as a BIGNUM
method, and (ii) because of (i), there was no meaningful way for library or
application code to automatically hook and use ENGINE supplied bignum functions
anyway. Also, ENGINE_cpy() has been removed (although an internal-only version
exists) - the idea of providing an ENGINE_cpy() function probably wasn't a good
one and now certainly doesn't make sense in any generalised way. Some of the
RSA, DSA, DH, and RAND functions that were fiddled during the original ENGINE
changes have now, as a consequence, been reverted back. This is because the
hooking of ENGINE is now automatic (and passive, it can interally use a NULL
ENGINE pointer to simply ignore ENGINE from then on).
Hell, that should be enough for now ... comments welcome: geoff@openssl.org

View File

@@ -0,0 +1,135 @@
/* crypto/engine/eng_all.c -*- mode: C; c-file-style: "eay" -*- */
/* Written by Richard Levitte <richard@levitte.org> for the OpenSSL
* project 2000.
*/
/* ====================================================================
* Copyright (c) 2000-2001 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include "cryptlib.h"
#include "eng_int.h"
void ENGINE_load_builtin_engines(void)
{
/* Some ENGINEs need this */
OPENSSL_cpuid_setup();
#if 0
/* There's no longer any need for an "openssl" ENGINE unless, one day,
* it is the *only* way for standard builtin implementations to be be
* accessed (ie. it would be possible to statically link binaries with
* *no* builtin implementations). */
ENGINE_load_openssl();
#endif
#if !defined(OPENSSL_NO_HW) && (defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV))
ENGINE_load_cryptodev();
#endif
#ifndef OPENSSL_NO_RSAX
ENGINE_load_rsax();
#endif
#ifndef OPENSSL_NO_RDRAND
ENGINE_load_rdrand();
#endif
ENGINE_load_dynamic();
#ifndef OPENSSL_NO_STATIC_ENGINE
#ifndef OPENSSL_NO_HW
#ifndef OPENSSL_NO_HW_4758_CCA
ENGINE_load_4758cca();
#endif
#ifndef OPENSSL_NO_HW_AEP
ENGINE_load_aep();
#endif
#ifndef OPENSSL_NO_HW_ATALLA
ENGINE_load_atalla();
#endif
#ifndef OPENSSL_NO_HW_CSWIFT
ENGINE_load_cswift();
#endif
#ifndef OPENSSL_NO_HW_NCIPHER
ENGINE_load_chil();
#endif
#ifndef OPENSSL_NO_HW_NURON
ENGINE_load_nuron();
#endif
#ifndef OPENSSL_NO_HW_SUREWARE
ENGINE_load_sureware();
#endif
#ifndef OPENSSL_NO_HW_UBSEC
ENGINE_load_ubsec();
#endif
#ifndef OPENSSL_NO_HW_PADLOCK
ENGINE_load_padlock();
#endif
#endif
#ifndef OPENSSL_NO_GOST
ENGINE_load_gost();
#endif
#ifndef OPENSSL_NO_GMP
ENGINE_load_gmp();
#endif
#if defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_NO_CAPIENG)
ENGINE_load_capi();
#endif
#endif
ENGINE_register_all_complete();
}
#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV)
void ENGINE_setup_bsd_cryptodev(void) {
static int bsd_cryptodev_default_loaded = 0;
if (!bsd_cryptodev_default_loaded) {
ENGINE_load_cryptodev();
ENGINE_register_all_complete();
}
bsd_cryptodev_default_loaded=1;
}
#endif

View File

@@ -0,0 +1,259 @@
/* eng_cnf.c */
/* Written by Stephen Henson (steve@openssl.org) for the OpenSSL
* project 2001.
*/
/* ====================================================================
* Copyright (c) 2001 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include "eng_int.h"
#include <openssl/conf.h>
/* #define ENGINE_CONF_DEBUG */
/* ENGINE config module */
static char *skip_dot(char *name)
{
char *p;
p = strchr(name, '.');
if (p)
return p + 1;
return name;
}
static STACK_OF(ENGINE) *initialized_engines = NULL;
static int int_engine_init(ENGINE *e)
{
if (!ENGINE_init(e))
return 0;
if (!initialized_engines)
initialized_engines = sk_ENGINE_new_null();
if (!initialized_engines || !sk_ENGINE_push(initialized_engines, e))
{
ENGINE_finish(e);
return 0;
}
return 1;
}
static int int_engine_configure(char *name, char *value, const CONF *cnf)
{
int i;
int ret = 0;
long do_init = -1;
STACK_OF(CONF_VALUE) *ecmds;
CONF_VALUE *ecmd = NULL;
char *ctrlname, *ctrlvalue;
ENGINE *e = NULL;
int soft = 0;
name = skip_dot(name);
#ifdef ENGINE_CONF_DEBUG
fprintf(stderr, "Configuring engine %s\n", name);
#endif
/* Value is a section containing ENGINE commands */
ecmds = NCONF_get_section(cnf, value);
if (!ecmds)
{
ENGINEerr(ENGINE_F_INT_ENGINE_CONFIGURE, ENGINE_R_ENGINE_SECTION_ERROR);
return 0;
}
for (i = 0; i < sk_CONF_VALUE_num(ecmds); i++)
{
ecmd = sk_CONF_VALUE_value(ecmds, i);
ctrlname = skip_dot(ecmd->name);
ctrlvalue = ecmd->value;
#ifdef ENGINE_CONF_DEBUG
fprintf(stderr, "ENGINE conf: doing ctrl(%s,%s)\n", ctrlname, ctrlvalue);
#endif
/* First handle some special pseudo ctrls */
/* Override engine name to use */
if (!strcmp(ctrlname, "engine_id"))
name = ctrlvalue;
else if (!strcmp(ctrlname, "soft_load"))
soft = 1;
/* Load a dynamic ENGINE */
else if (!strcmp(ctrlname, "dynamic_path"))
{
e = ENGINE_by_id("dynamic");
if (!e)
goto err;
if (!ENGINE_ctrl_cmd_string(e, "SO_PATH", ctrlvalue, 0))
goto err;
if (!ENGINE_ctrl_cmd_string(e, "LIST_ADD", "2", 0))
goto err;
if (!ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0))
goto err;
}
/* ... add other pseudos here ... */
else
{
/* At this point we need an ENGINE structural reference
* if we don't already have one.
*/
if (!e)
{
e = ENGINE_by_id(name);
if (!e && soft)
{
ERR_clear_error();
return 1;
}
if (!e)
goto err;
}
/* Allow "EMPTY" to mean no value: this allows a valid
* "value" to be passed to ctrls of type NO_INPUT
*/
if (!strcmp(ctrlvalue, "EMPTY"))
ctrlvalue = NULL;
if (!strcmp(ctrlname, "init"))
{
if (!NCONF_get_number_e(cnf, value, "init", &do_init))
goto err;
if (do_init == 1)
{
if (!int_engine_init(e))
goto err;
}
else if (do_init != 0)
{
ENGINEerr(ENGINE_F_INT_ENGINE_CONFIGURE, ENGINE_R_INVALID_INIT_VALUE);
goto err;
}
}
else if (!strcmp(ctrlname, "default_algorithms"))
{
if (!ENGINE_set_default_string(e, ctrlvalue))
goto err;
}
else if (!ENGINE_ctrl_cmd_string(e,
ctrlname, ctrlvalue, 0))
goto err;
}
}
if (e && (do_init == -1) && !int_engine_init(e))
{
ecmd = NULL;
goto err;
}
ret = 1;
err:
if (ret != 1)
{
ENGINEerr(ENGINE_F_INT_ENGINE_CONFIGURE, ENGINE_R_ENGINE_CONFIGURATION_ERROR);
if (ecmd)
ERR_add_error_data(6, "section=", ecmd->section,
", name=", ecmd->name,
", value=", ecmd->value);
}
if (e)
ENGINE_free(e);
return ret;
}
static int int_engine_module_init(CONF_IMODULE *md, const CONF *cnf)
{
STACK_OF(CONF_VALUE) *elist;
CONF_VALUE *cval;
int i;
#ifdef ENGINE_CONF_DEBUG
fprintf(stderr, "Called engine module: name %s, value %s\n",
CONF_imodule_get_name(md), CONF_imodule_get_value(md));
#endif
/* Value is a section containing ENGINEs to configure */
elist = NCONF_get_section(cnf, CONF_imodule_get_value(md));
if (!elist)
{
ENGINEerr(ENGINE_F_INT_ENGINE_MODULE_INIT, ENGINE_R_ENGINES_SECTION_ERROR);
return 0;
}
for (i = 0; i < sk_CONF_VALUE_num(elist); i++)
{
cval = sk_CONF_VALUE_value(elist, i);
if (!int_engine_configure(cval->name, cval->value, cnf))
return 0;
}
return 1;
}
static void int_engine_module_finish(CONF_IMODULE *md)
{
ENGINE *e;
while ((e = sk_ENGINE_pop(initialized_engines)))
ENGINE_finish(e);
sk_ENGINE_free(initialized_engines);
initialized_engines = NULL;
}
void ENGINE_add_conf_module(void)
{
CONF_module_add("engines",
int_engine_module_init,
int_engine_module_finish);
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,389 @@
/* crypto/engine/eng_ctrl.c */
/* ====================================================================
* Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include "eng_int.h"
/* When querying a ENGINE-specific control command's 'description', this string
* is used if the ENGINE_CMD_DEFN has cmd_desc set to NULL. */
static const char *int_no_description = "";
/* These internal functions handle 'CMD'-related control commands when the
* ENGINE in question has asked us to take care of it (ie. the ENGINE did not
* set the ENGINE_FLAGS_MANUAL_CMD_CTRL flag. */
static int int_ctrl_cmd_is_null(const ENGINE_CMD_DEFN *defn)
{
if((defn->cmd_num == 0) || (defn->cmd_name == NULL))
return 1;
return 0;
}
static int int_ctrl_cmd_by_name(const ENGINE_CMD_DEFN *defn, const char *s)
{
int idx = 0;
while(!int_ctrl_cmd_is_null(defn) && (strcmp(defn->cmd_name, s) != 0))
{
idx++;
defn++;
}
if(int_ctrl_cmd_is_null(defn))
/* The given name wasn't found */
return -1;
return idx;
}
static int int_ctrl_cmd_by_num(const ENGINE_CMD_DEFN *defn, unsigned int num)
{
int idx = 0;
/* NB: It is stipulated that 'cmd_defn' lists are ordered by cmd_num. So
* our searches don't need to take any longer than necessary. */
while(!int_ctrl_cmd_is_null(defn) && (defn->cmd_num < num))
{
idx++;
defn++;
}
if(defn->cmd_num == num)
return idx;
/* The given cmd_num wasn't found */
return -1;
}
static int int_ctrl_helper(ENGINE *e, int cmd, long i, void *p,
void (*f)(void))
{
int idx;
char *s = (char *)p;
/* Take care of the easy one first (eg. it requires no searches) */
if(cmd == ENGINE_CTRL_GET_FIRST_CMD_TYPE)
{
if((e->cmd_defns == NULL) || int_ctrl_cmd_is_null(e->cmd_defns))
return 0;
return e->cmd_defns->cmd_num;
}
/* One or two commands require that "p" be a valid string buffer */
if((cmd == ENGINE_CTRL_GET_CMD_FROM_NAME) ||
(cmd == ENGINE_CTRL_GET_NAME_FROM_CMD) ||
(cmd == ENGINE_CTRL_GET_DESC_FROM_CMD))
{
if(s == NULL)
{
ENGINEerr(ENGINE_F_INT_CTRL_HELPER,
ERR_R_PASSED_NULL_PARAMETER);
return -1;
}
}
/* Now handle cmd_name -> cmd_num conversion */
if(cmd == ENGINE_CTRL_GET_CMD_FROM_NAME)
{
if((e->cmd_defns == NULL) || ((idx = int_ctrl_cmd_by_name(
e->cmd_defns, s)) < 0))
{
ENGINEerr(ENGINE_F_INT_CTRL_HELPER,
ENGINE_R_INVALID_CMD_NAME);
return -1;
}
return e->cmd_defns[idx].cmd_num;
}
/* For the rest of the commands, the 'long' argument must specify a
* valie command number - so we need to conduct a search. */
if((e->cmd_defns == NULL) || ((idx = int_ctrl_cmd_by_num(e->cmd_defns,
(unsigned int)i)) < 0))
{
ENGINEerr(ENGINE_F_INT_CTRL_HELPER,
ENGINE_R_INVALID_CMD_NUMBER);
return -1;
}
/* Now the logic splits depending on command type */
switch(cmd)
{
case ENGINE_CTRL_GET_NEXT_CMD_TYPE:
idx++;
if(int_ctrl_cmd_is_null(e->cmd_defns + idx))
/* end-of-list */
return 0;
else
return e->cmd_defns[idx].cmd_num;
case ENGINE_CTRL_GET_NAME_LEN_FROM_CMD:
return strlen(e->cmd_defns[idx].cmd_name);
case ENGINE_CTRL_GET_NAME_FROM_CMD:
return BIO_snprintf(s,strlen(e->cmd_defns[idx].cmd_name) + 1,
"%s", e->cmd_defns[idx].cmd_name);
case ENGINE_CTRL_GET_DESC_LEN_FROM_CMD:
if(e->cmd_defns[idx].cmd_desc)
return strlen(e->cmd_defns[idx].cmd_desc);
return strlen(int_no_description);
case ENGINE_CTRL_GET_DESC_FROM_CMD:
if(e->cmd_defns[idx].cmd_desc)
return BIO_snprintf(s,
strlen(e->cmd_defns[idx].cmd_desc) + 1,
"%s", e->cmd_defns[idx].cmd_desc);
return BIO_snprintf(s, strlen(int_no_description) + 1,"%s",
int_no_description);
case ENGINE_CTRL_GET_CMD_FLAGS:
return e->cmd_defns[idx].cmd_flags;
}
/* Shouldn't really be here ... */
ENGINEerr(ENGINE_F_INT_CTRL_HELPER,ENGINE_R_INTERNAL_LIST_ERROR);
return -1;
}
int ENGINE_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
{
int ctrl_exists, ref_exists;
if(e == NULL)
{
ENGINEerr(ENGINE_F_ENGINE_CTRL,ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
ref_exists = ((e->struct_ref > 0) ? 1 : 0);
CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
ctrl_exists = ((e->ctrl == NULL) ? 0 : 1);
if(!ref_exists)
{
ENGINEerr(ENGINE_F_ENGINE_CTRL,ENGINE_R_NO_REFERENCE);
return 0;
}
/* Intercept any "root-level" commands before trying to hand them on to
* ctrl() handlers. */
switch(cmd)
{
case ENGINE_CTRL_HAS_CTRL_FUNCTION:
return ctrl_exists;
case ENGINE_CTRL_GET_FIRST_CMD_TYPE:
case ENGINE_CTRL_GET_NEXT_CMD_TYPE:
case ENGINE_CTRL_GET_CMD_FROM_NAME:
case ENGINE_CTRL_GET_NAME_LEN_FROM_CMD:
case ENGINE_CTRL_GET_NAME_FROM_CMD:
case ENGINE_CTRL_GET_DESC_LEN_FROM_CMD:
case ENGINE_CTRL_GET_DESC_FROM_CMD:
case ENGINE_CTRL_GET_CMD_FLAGS:
if(ctrl_exists && !(e->flags & ENGINE_FLAGS_MANUAL_CMD_CTRL))
return int_ctrl_helper(e,cmd,i,p,f);
if(!ctrl_exists)
{
ENGINEerr(ENGINE_F_ENGINE_CTRL,ENGINE_R_NO_CONTROL_FUNCTION);
/* For these cmd-related functions, failure is indicated
* by a -1 return value (because 0 is used as a valid
* return in some places). */
return -1;
}
default:
break;
}
/* Anything else requires a ctrl() handler to exist. */
if(!ctrl_exists)
{
ENGINEerr(ENGINE_F_ENGINE_CTRL,ENGINE_R_NO_CONTROL_FUNCTION);
return 0;
}
return e->ctrl(e, cmd, i, p, f);
}
int ENGINE_cmd_is_executable(ENGINE *e, int cmd)
{
int flags;
if((flags = ENGINE_ctrl(e, ENGINE_CTRL_GET_CMD_FLAGS, cmd, NULL, NULL)) < 0)
{
ENGINEerr(ENGINE_F_ENGINE_CMD_IS_EXECUTABLE,
ENGINE_R_INVALID_CMD_NUMBER);
return 0;
}
if(!(flags & ENGINE_CMD_FLAG_NO_INPUT) &&
!(flags & ENGINE_CMD_FLAG_NUMERIC) &&
!(flags & ENGINE_CMD_FLAG_STRING))
return 0;
return 1;
}
int ENGINE_ctrl_cmd(ENGINE *e, const char *cmd_name,
long i, void *p, void (*f)(void), int cmd_optional)
{
int num;
if((e == NULL) || (cmd_name == NULL))
{
ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD,
ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
if((e->ctrl == NULL) || ((num = ENGINE_ctrl(e,
ENGINE_CTRL_GET_CMD_FROM_NAME,
0, (void *)cmd_name, NULL)) <= 0))
{
/* If the command didn't *have* to be supported, we fake
* success. This allows certain settings to be specified for
* multiple ENGINEs and only require a change of ENGINE id
* (without having to selectively apply settings). Eg. changing
* from a hardware device back to the regular software ENGINE
* without editing the config file, etc. */
if(cmd_optional)
{
ERR_clear_error();
return 1;
}
ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD,
ENGINE_R_INVALID_CMD_NAME);
return 0;
}
/* Force the result of the control command to 0 or 1, for the reasons
* mentioned before. */
if (ENGINE_ctrl(e, num, i, p, f) > 0)
return 1;
return 0;
}
int ENGINE_ctrl_cmd_string(ENGINE *e, const char *cmd_name, const char *arg,
int cmd_optional)
{
int num, flags;
long l;
char *ptr;
if((e == NULL) || (cmd_name == NULL))
{
ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
if((e->ctrl == NULL) || ((num = ENGINE_ctrl(e,
ENGINE_CTRL_GET_CMD_FROM_NAME,
0, (void *)cmd_name, NULL)) <= 0))
{
/* If the command didn't *have* to be supported, we fake
* success. This allows certain settings to be specified for
* multiple ENGINEs and only require a change of ENGINE id
* (without having to selectively apply settings). Eg. changing
* from a hardware device back to the regular software ENGINE
* without editing the config file, etc. */
if(cmd_optional)
{
ERR_clear_error();
return 1;
}
ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
ENGINE_R_INVALID_CMD_NAME);
return 0;
}
if(!ENGINE_cmd_is_executable(e, num))
{
ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
ENGINE_R_CMD_NOT_EXECUTABLE);
return 0;
}
if((flags = ENGINE_ctrl(e, ENGINE_CTRL_GET_CMD_FLAGS, num, NULL, NULL)) < 0)
{
/* Shouldn't happen, given that ENGINE_cmd_is_executable()
* returned success. */
ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
ENGINE_R_INTERNAL_LIST_ERROR);
return 0;
}
/* If the command takes no input, there must be no input. And vice
* versa. */
if(flags & ENGINE_CMD_FLAG_NO_INPUT)
{
if(arg != NULL)
{
ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
ENGINE_R_COMMAND_TAKES_NO_INPUT);
return 0;
}
/* We deliberately force the result of ENGINE_ctrl() to 0 or 1
* rather than returning it as "return data". This is to ensure
* usage of these commands is consistent across applications and
* that certain applications don't understand it one way, and
* others another. */
if(ENGINE_ctrl(e, num, 0, (void *)arg, NULL) > 0)
return 1;
return 0;
}
/* So, we require input */
if(arg == NULL)
{
ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
ENGINE_R_COMMAND_TAKES_INPUT);
return 0;
}
/* If it takes string input, that's easy */
if(flags & ENGINE_CMD_FLAG_STRING)
{
/* Same explanation as above */
if(ENGINE_ctrl(e, num, 0, (void *)arg, NULL) > 0)
return 1;
return 0;
}
/* If it doesn't take numeric either, then it is unsupported for use in
* a config-setting situation, which is what this function is for. This
* should never happen though, because ENGINE_cmd_is_executable() was
* used. */
if(!(flags & ENGINE_CMD_FLAG_NUMERIC))
{
ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
ENGINE_R_INTERNAL_LIST_ERROR);
return 0;
}
l = strtol(arg, &ptr, 10);
if((arg == ptr) || (*ptr != '\0'))
{
ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER);
return 0;
}
/* Force the result of the control command to 0 or 1, for the reasons
* mentioned before. */
if(ENGINE_ctrl(e, num, l, NULL, NULL) > 0)
return 1;
return 0;
}

View File

@@ -0,0 +1,551 @@
/* crypto/engine/eng_dyn.c */
/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
* project 2001.
*/
/* ====================================================================
* Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include "eng_int.h"
#include <openssl/dso.h>
/* Shared libraries implementing ENGINEs for use by the "dynamic" ENGINE loader
* should implement the hook-up functions with the following prototypes. */
/* Our ENGINE handlers */
static int dynamic_init(ENGINE *e);
static int dynamic_finish(ENGINE *e);
static int dynamic_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void));
/* Predeclare our context type */
typedef struct st_dynamic_data_ctx dynamic_data_ctx;
/* The implementation for the important control command */
static int dynamic_load(ENGINE *e, dynamic_data_ctx *ctx);
#define DYNAMIC_CMD_SO_PATH ENGINE_CMD_BASE
#define DYNAMIC_CMD_NO_VCHECK (ENGINE_CMD_BASE + 1)
#define DYNAMIC_CMD_ID (ENGINE_CMD_BASE + 2)
#define DYNAMIC_CMD_LIST_ADD (ENGINE_CMD_BASE + 3)
#define DYNAMIC_CMD_DIR_LOAD (ENGINE_CMD_BASE + 4)
#define DYNAMIC_CMD_DIR_ADD (ENGINE_CMD_BASE + 5)
#define DYNAMIC_CMD_LOAD (ENGINE_CMD_BASE + 6)
/* The constants used when creating the ENGINE */
static const char *engine_dynamic_id = "dynamic";
static const char *engine_dynamic_name = "Dynamic engine loading support";
static const ENGINE_CMD_DEFN dynamic_cmd_defns[] = {
{DYNAMIC_CMD_SO_PATH,
"SO_PATH",
"Specifies the path to the new ENGINE shared library",
ENGINE_CMD_FLAG_STRING},
{DYNAMIC_CMD_NO_VCHECK,
"NO_VCHECK",
"Specifies to continue even if version checking fails (boolean)",
ENGINE_CMD_FLAG_NUMERIC},
{DYNAMIC_CMD_ID,
"ID",
"Specifies an ENGINE id name for loading",
ENGINE_CMD_FLAG_STRING},
{DYNAMIC_CMD_LIST_ADD,
"LIST_ADD",
"Whether to add a loaded ENGINE to the internal list (0=no,1=yes,2=mandatory)",
ENGINE_CMD_FLAG_NUMERIC},
{DYNAMIC_CMD_DIR_LOAD,
"DIR_LOAD",
"Specifies whether to load from 'DIR_ADD' directories (0=no,1=yes,2=mandatory)",
ENGINE_CMD_FLAG_NUMERIC},
{DYNAMIC_CMD_DIR_ADD,
"DIR_ADD",
"Adds a directory from which ENGINEs can be loaded",
ENGINE_CMD_FLAG_STRING},
{DYNAMIC_CMD_LOAD,
"LOAD",
"Load up the ENGINE specified by other settings",
ENGINE_CMD_FLAG_NO_INPUT},
{0, NULL, NULL, 0}
};
static const ENGINE_CMD_DEFN dynamic_cmd_defns_empty[] = {
{0, NULL, NULL, 0}
};
/* Loading code stores state inside the ENGINE structure via the "ex_data"
* element. We load all our state into a single structure and use that as a
* single context in the "ex_data" stack. */
struct st_dynamic_data_ctx
{
/* The DSO object we load that supplies the ENGINE code */
DSO *dynamic_dso;
/* The function pointer to the version checking shared library function */
dynamic_v_check_fn v_check;
/* The function pointer to the engine-binding shared library function */
dynamic_bind_engine bind_engine;
/* The default name/path for loading the shared library */
const char *DYNAMIC_LIBNAME;
/* Whether to continue loading on a version check failure */
int no_vcheck;
/* If non-NULL, stipulates the 'id' of the ENGINE to be loaded */
const char *engine_id;
/* If non-zero, a successfully loaded ENGINE should be added to the internal
* ENGINE list. If 2, the add must succeed or the entire load should fail. */
int list_add_value;
/* The symbol name for the version checking function */
const char *DYNAMIC_F1;
/* The symbol name for the "initialise ENGINE structure" function */
const char *DYNAMIC_F2;
/* Whether to never use 'dirs', use 'dirs' as a fallback, or only use
* 'dirs' for loading. Default is to use 'dirs' as a fallback. */
int dir_load;
/* A stack of directories from which ENGINEs could be loaded */
STACK_OF(OPENSSL_STRING) *dirs;
};
/* This is the "ex_data" index we obtain and reserve for use with our context
* structure. */
static int dynamic_ex_data_idx = -1;
static void int_free_str(char *s) { OPENSSL_free(s); }
/* Because our ex_data element may or may not get allocated depending on whether
* a "first-use" occurs before the ENGINE is freed, we have a memory leak
* problem to solve. We can't declare a "new" handler for the ex_data as we
* don't want a dynamic_data_ctx in *all* ENGINE structures of all types (this
* is a bug in the design of CRYPTO_EX_DATA). As such, we just declare a "free"
* handler and that will get called if an ENGINE is being destroyed and there
* was an ex_data element corresponding to our context type. */
static void dynamic_data_ctx_free_func(void *parent, void *ptr,
CRYPTO_EX_DATA *ad, int idx, long argl, void *argp)
{
if(ptr)
{
dynamic_data_ctx *ctx = (dynamic_data_ctx *)ptr;
if(ctx->dynamic_dso)
DSO_free(ctx->dynamic_dso);
if(ctx->DYNAMIC_LIBNAME)
OPENSSL_free((void*)ctx->DYNAMIC_LIBNAME);
if(ctx->engine_id)
OPENSSL_free((void*)ctx->engine_id);
if(ctx->dirs)
sk_OPENSSL_STRING_pop_free(ctx->dirs, int_free_str);
OPENSSL_free(ctx);
}
}
/* Construct the per-ENGINE context. We create it blindly and then use a lock to
* check for a race - if so, all but one of the threads "racing" will have
* wasted their time. The alternative involves creating everything inside the
* lock which is far worse. */
static int dynamic_set_data_ctx(ENGINE *e, dynamic_data_ctx **ctx)
{
dynamic_data_ctx *c;
c = OPENSSL_malloc(sizeof(dynamic_data_ctx));
if(!c)
{
ENGINEerr(ENGINE_F_DYNAMIC_SET_DATA_CTX,ERR_R_MALLOC_FAILURE);
return 0;
}
memset(c, 0, sizeof(dynamic_data_ctx));
c->dynamic_dso = NULL;
c->v_check = NULL;
c->bind_engine = NULL;
c->DYNAMIC_LIBNAME = NULL;
c->no_vcheck = 0;
c->engine_id = NULL;
c->list_add_value = 0;
c->DYNAMIC_F1 = "v_check";
c->DYNAMIC_F2 = "bind_engine";
c->dir_load = 1;
c->dirs = sk_OPENSSL_STRING_new_null();
if(!c->dirs)
{
ENGINEerr(ENGINE_F_DYNAMIC_SET_DATA_CTX,ERR_R_MALLOC_FAILURE);
OPENSSL_free(c);
return 0;
}
CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
if((*ctx = (dynamic_data_ctx *)ENGINE_get_ex_data(e,
dynamic_ex_data_idx)) == NULL)
{
/* Good, we're the first */
ENGINE_set_ex_data(e, dynamic_ex_data_idx, c);
*ctx = c;
c = NULL;
}
CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
/* If we lost the race to set the context, c is non-NULL and *ctx is the
* context of the thread that won. */
if(c)
OPENSSL_free(c);
return 1;
}
/* This function retrieves the context structure from an ENGINE's "ex_data", or
* if it doesn't exist yet, sets it up. */
static dynamic_data_ctx *dynamic_get_data_ctx(ENGINE *e)
{
dynamic_data_ctx *ctx;
if(dynamic_ex_data_idx < 0)
{
/* Create and register the ENGINE ex_data, and associate our
* "free" function with it to ensure any allocated contexts get
* freed when an ENGINE goes underground. */
int new_idx = ENGINE_get_ex_new_index(0, NULL, NULL, NULL,
dynamic_data_ctx_free_func);
if(new_idx == -1)
{
ENGINEerr(ENGINE_F_DYNAMIC_GET_DATA_CTX,ENGINE_R_NO_INDEX);
return NULL;
}
CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
/* Avoid a race by checking again inside this lock */
if(dynamic_ex_data_idx < 0)
{
/* Good, someone didn't beat us to it */
dynamic_ex_data_idx = new_idx;
new_idx = -1;
}
CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
/* In theory we could "give back" the index here if
* (new_idx>-1), but it's not possible and wouldn't gain us much
* if it were. */
}
ctx = (dynamic_data_ctx *)ENGINE_get_ex_data(e, dynamic_ex_data_idx);
/* Check if the context needs to be created */
if((ctx == NULL) && !dynamic_set_data_ctx(e, &ctx))
/* "set_data" will set errors if necessary */
return NULL;
return ctx;
}
static ENGINE *engine_dynamic(void)
{
ENGINE *ret = ENGINE_new();
if(!ret)
return NULL;
if(!ENGINE_set_id(ret, engine_dynamic_id) ||
!ENGINE_set_name(ret, engine_dynamic_name) ||
!ENGINE_set_init_function(ret, dynamic_init) ||
!ENGINE_set_finish_function(ret, dynamic_finish) ||
!ENGINE_set_ctrl_function(ret, dynamic_ctrl) ||
!ENGINE_set_flags(ret, ENGINE_FLAGS_BY_ID_COPY) ||
!ENGINE_set_cmd_defns(ret, dynamic_cmd_defns))
{
ENGINE_free(ret);
return NULL;
}
return ret;
}
void ENGINE_load_dynamic(void)
{
ENGINE *toadd = engine_dynamic();
if(!toadd) return;
ENGINE_add(toadd);
/* If the "add" worked, it gets a structural reference. So either way,
* we release our just-created reference. */
ENGINE_free(toadd);
/* If the "add" didn't work, it was probably a conflict because it was
* already added (eg. someone calling ENGINE_load_blah then calling
* ENGINE_load_builtin_engines() perhaps). */
ERR_clear_error();
}
static int dynamic_init(ENGINE *e)
{
/* We always return failure - the "dyanamic" engine itself can't be used
* for anything. */
return 0;
}
static int dynamic_finish(ENGINE *e)
{
/* This should never be called on account of "dynamic_init" always
* failing. */
return 0;
}
static int dynamic_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
{
dynamic_data_ctx *ctx = dynamic_get_data_ctx(e);
int initialised;
if(!ctx)
{
ENGINEerr(ENGINE_F_DYNAMIC_CTRL,ENGINE_R_NOT_LOADED);
return 0;
}
initialised = ((ctx->dynamic_dso == NULL) ? 0 : 1);
/* All our control commands require the ENGINE to be uninitialised */
if(initialised)
{
ENGINEerr(ENGINE_F_DYNAMIC_CTRL,
ENGINE_R_ALREADY_LOADED);
return 0;
}
switch(cmd)
{
case DYNAMIC_CMD_SO_PATH:
/* a NULL 'p' or a string of zero-length is the same thing */
if(p && (strlen((const char *)p) < 1))
p = NULL;
if(ctx->DYNAMIC_LIBNAME)
OPENSSL_free((void*)ctx->DYNAMIC_LIBNAME);
if(p)
ctx->DYNAMIC_LIBNAME = BUF_strdup(p);
else
ctx->DYNAMIC_LIBNAME = NULL;
return (ctx->DYNAMIC_LIBNAME ? 1 : 0);
case DYNAMIC_CMD_NO_VCHECK:
ctx->no_vcheck = ((i == 0) ? 0 : 1);
return 1;
case DYNAMIC_CMD_ID:
/* a NULL 'p' or a string of zero-length is the same thing */
if(p && (strlen((const char *)p) < 1))
p = NULL;
if(ctx->engine_id)
OPENSSL_free((void*)ctx->engine_id);
if(p)
ctx->engine_id = BUF_strdup(p);
else
ctx->engine_id = NULL;
return (ctx->engine_id ? 1 : 0);
case DYNAMIC_CMD_LIST_ADD:
if((i < 0) || (i > 2))
{
ENGINEerr(ENGINE_F_DYNAMIC_CTRL,
ENGINE_R_INVALID_ARGUMENT);
return 0;
}
ctx->list_add_value = (int)i;
return 1;
case DYNAMIC_CMD_LOAD:
return dynamic_load(e, ctx);
case DYNAMIC_CMD_DIR_LOAD:
if((i < 0) || (i > 2))
{
ENGINEerr(ENGINE_F_DYNAMIC_CTRL,
ENGINE_R_INVALID_ARGUMENT);
return 0;
}
ctx->dir_load = (int)i;
return 1;
case DYNAMIC_CMD_DIR_ADD:
/* a NULL 'p' or a string of zero-length is the same thing */
if(!p || (strlen((const char *)p) < 1))
{
ENGINEerr(ENGINE_F_DYNAMIC_CTRL,
ENGINE_R_INVALID_ARGUMENT);
return 0;
}
{
char *tmp_str = BUF_strdup(p);
if(!tmp_str)
{
ENGINEerr(ENGINE_F_DYNAMIC_CTRL,
ERR_R_MALLOC_FAILURE);
return 0;
}
sk_OPENSSL_STRING_insert(ctx->dirs, tmp_str, -1);
}
return 1;
default:
break;
}
ENGINEerr(ENGINE_F_DYNAMIC_CTRL,ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED);
return 0;
}
static int int_load(dynamic_data_ctx *ctx)
{
int num, loop;
/* Unless told not to, try a direct load */
if((ctx->dir_load != 2) && (DSO_load(ctx->dynamic_dso,
ctx->DYNAMIC_LIBNAME, NULL, 0) != NULL))
return 1;
/* If we're not allowed to use 'dirs' or we have none, fail */
if(!ctx->dir_load || (num = sk_OPENSSL_STRING_num(ctx->dirs)) < 1)
return 0;
for(loop = 0; loop < num; loop++)
{
const char *s = sk_OPENSSL_STRING_value(ctx->dirs, loop);
char *merge = DSO_merge(ctx->dynamic_dso, ctx->DYNAMIC_LIBNAME, s);
if(!merge)
return 0;
if(DSO_load(ctx->dynamic_dso, merge, NULL, 0))
{
/* Found what we're looking for */
OPENSSL_free(merge);
/* Previous failed loop iterations, if any, will have resulted in
* errors. Clear them out before returning success. */
ERR_clear_error();
return 1;
}
OPENSSL_free(merge);
}
return 0;
}
static int dynamic_load(ENGINE *e, dynamic_data_ctx *ctx)
{
ENGINE cpy;
dynamic_fns fns;
if(!ctx->dynamic_dso)
ctx->dynamic_dso = DSO_new();
if(!ctx->DYNAMIC_LIBNAME)
{
if(!ctx->engine_id)
return 0;
ctx->DYNAMIC_LIBNAME =
DSO_convert_filename(ctx->dynamic_dso, ctx->engine_id);
}
if(!int_load(ctx))
{
ENGINEerr(ENGINE_F_DYNAMIC_LOAD,
ENGINE_R_DSO_NOT_FOUND);
DSO_free(ctx->dynamic_dso);
ctx->dynamic_dso = NULL;
return 0;
}
/* We have to find a bind function otherwise it'll always end badly */
if(!(ctx->bind_engine = (dynamic_bind_engine)DSO_bind_func(
ctx->dynamic_dso, ctx->DYNAMIC_F2)))
{
ctx->bind_engine = NULL;
DSO_free(ctx->dynamic_dso);
ctx->dynamic_dso = NULL;
ENGINEerr(ENGINE_F_DYNAMIC_LOAD,
ENGINE_R_DSO_FAILURE);
return 0;
}
/* Do we perform version checking? */
if(!ctx->no_vcheck)
{
unsigned long vcheck_res = 0;
/* Now we try to find a version checking function and decide how
* to cope with failure if/when it fails. */
ctx->v_check = (dynamic_v_check_fn)DSO_bind_func(
ctx->dynamic_dso, ctx->DYNAMIC_F1);
if(ctx->v_check)
vcheck_res = ctx->v_check(OSSL_DYNAMIC_VERSION);
/* We fail if the version checker veto'd the load *or* if it is
* deferring to us (by returning its version) and we think it is
* too old. */
if(vcheck_res < OSSL_DYNAMIC_OLDEST)
{
/* Fail */
ctx->bind_engine = NULL;
ctx->v_check = NULL;
DSO_free(ctx->dynamic_dso);
ctx->dynamic_dso = NULL;
ENGINEerr(ENGINE_F_DYNAMIC_LOAD,
ENGINE_R_VERSION_INCOMPATIBILITY);
return 0;
}
}
/* First binary copy the ENGINE structure so that we can roll back if
* the hand-over fails */
memcpy(&cpy, e, sizeof(ENGINE));
/* Provide the ERR, "ex_data", memory, and locking callbacks so the
* loaded library uses our state rather than its own. FIXME: As noted in
* engine.h, much of this would be simplified if each area of code
* provided its own "summary" structure of all related callbacks. It
* would also increase opaqueness. */
fns.static_state = ENGINE_get_static_state();
fns.err_fns = ERR_get_implementation();
fns.ex_data_fns = CRYPTO_get_ex_data_implementation();
CRYPTO_get_mem_functions(&fns.mem_fns.malloc_cb,
&fns.mem_fns.realloc_cb,
&fns.mem_fns.free_cb);
fns.lock_fns.lock_locking_cb = CRYPTO_get_locking_callback();
fns.lock_fns.lock_add_lock_cb = CRYPTO_get_add_lock_callback();
fns.lock_fns.dynlock_create_cb = CRYPTO_get_dynlock_create_callback();
fns.lock_fns.dynlock_lock_cb = CRYPTO_get_dynlock_lock_callback();
fns.lock_fns.dynlock_destroy_cb = CRYPTO_get_dynlock_destroy_callback();
/* Now that we've loaded the dynamic engine, make sure no "dynamic"
* ENGINE elements will show through. */
engine_set_all_null(e);
/* Try to bind the ENGINE onto our own ENGINE structure */
if(!ctx->bind_engine(e, ctx->engine_id, &fns))
{
ctx->bind_engine = NULL;
ctx->v_check = NULL;
DSO_free(ctx->dynamic_dso);
ctx->dynamic_dso = NULL;
ENGINEerr(ENGINE_F_DYNAMIC_LOAD,ENGINE_R_INIT_FAILED);
/* Copy the original ENGINE structure back */
memcpy(e, &cpy, sizeof(ENGINE));
return 0;
}
/* Do we try to add this ENGINE to the internal list too? */
if(ctx->list_add_value > 0)
{
if(!ENGINE_add(e))
{
/* Do we tolerate this or fail? */
if(ctx->list_add_value > 1)
{
/* Fail - NB: By this time, it's too late to
* rollback, and trying to do so allows the
* bind_engine() code to have created leaks. We
* just have to fail where we are, after the
* ENGINE has changed. */
ENGINEerr(ENGINE_F_DYNAMIC_LOAD,
ENGINE_R_CONFLICTING_ENGINE_ID);
return 0;
}
/* Tolerate */
ERR_clear_error();
}
}
return 1;
}

View File

@@ -0,0 +1,173 @@
/* crypto/engine/eng_err.c */
/* ====================================================================
* Copyright (c) 1999-2010 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
/* NOTE: this file was auto generated by the mkerr.pl script: any changes
* made to it will be overwritten when the script next updates this file,
* only reason strings will be preserved.
*/
#include <stdio.h>
#include <openssl/err.h>
#include <openssl/engine.h>
/* BEGIN ERROR CODES */
#ifndef OPENSSL_NO_ERR
#define ERR_FUNC(func) ERR_PACK(ERR_LIB_ENGINE,func,0)
#define ERR_REASON(reason) ERR_PACK(ERR_LIB_ENGINE,0,reason)
static ERR_STRING_DATA ENGINE_str_functs[]=
{
{ERR_FUNC(ENGINE_F_DYNAMIC_CTRL), "DYNAMIC_CTRL"},
{ERR_FUNC(ENGINE_F_DYNAMIC_GET_DATA_CTX), "DYNAMIC_GET_DATA_CTX"},
{ERR_FUNC(ENGINE_F_DYNAMIC_LOAD), "DYNAMIC_LOAD"},
{ERR_FUNC(ENGINE_F_DYNAMIC_SET_DATA_CTX), "DYNAMIC_SET_DATA_CTX"},
{ERR_FUNC(ENGINE_F_ENGINE_ADD), "ENGINE_add"},
{ERR_FUNC(ENGINE_F_ENGINE_BY_ID), "ENGINE_by_id"},
{ERR_FUNC(ENGINE_F_ENGINE_CMD_IS_EXECUTABLE), "ENGINE_cmd_is_executable"},
{ERR_FUNC(ENGINE_F_ENGINE_CTRL), "ENGINE_ctrl"},
{ERR_FUNC(ENGINE_F_ENGINE_CTRL_CMD), "ENGINE_ctrl_cmd"},
{ERR_FUNC(ENGINE_F_ENGINE_CTRL_CMD_STRING), "ENGINE_ctrl_cmd_string"},
{ERR_FUNC(ENGINE_F_ENGINE_FINISH), "ENGINE_finish"},
{ERR_FUNC(ENGINE_F_ENGINE_FREE_UTIL), "ENGINE_FREE_UTIL"},
{ERR_FUNC(ENGINE_F_ENGINE_GET_CIPHER), "ENGINE_get_cipher"},
{ERR_FUNC(ENGINE_F_ENGINE_GET_DEFAULT_TYPE), "ENGINE_GET_DEFAULT_TYPE"},
{ERR_FUNC(ENGINE_F_ENGINE_GET_DIGEST), "ENGINE_get_digest"},
{ERR_FUNC(ENGINE_F_ENGINE_GET_NEXT), "ENGINE_get_next"},
{ERR_FUNC(ENGINE_F_ENGINE_GET_PKEY_ASN1_METH), "ENGINE_get_pkey_asn1_meth"},
{ERR_FUNC(ENGINE_F_ENGINE_GET_PKEY_METH), "ENGINE_get_pkey_meth"},
{ERR_FUNC(ENGINE_F_ENGINE_GET_PREV), "ENGINE_get_prev"},
{ERR_FUNC(ENGINE_F_ENGINE_INIT), "ENGINE_init"},
{ERR_FUNC(ENGINE_F_ENGINE_LIST_ADD), "ENGINE_LIST_ADD"},
{ERR_FUNC(ENGINE_F_ENGINE_LIST_REMOVE), "ENGINE_LIST_REMOVE"},
{ERR_FUNC(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY), "ENGINE_load_private_key"},
{ERR_FUNC(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY), "ENGINE_load_public_key"},
{ERR_FUNC(ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT), "ENGINE_load_ssl_client_cert"},
{ERR_FUNC(ENGINE_F_ENGINE_NEW), "ENGINE_new"},
{ERR_FUNC(ENGINE_F_ENGINE_REMOVE), "ENGINE_remove"},
{ERR_FUNC(ENGINE_F_ENGINE_SET_DEFAULT_STRING), "ENGINE_set_default_string"},
{ERR_FUNC(ENGINE_F_ENGINE_SET_DEFAULT_TYPE), "ENGINE_SET_DEFAULT_TYPE"},
{ERR_FUNC(ENGINE_F_ENGINE_SET_ID), "ENGINE_set_id"},
{ERR_FUNC(ENGINE_F_ENGINE_SET_NAME), "ENGINE_set_name"},
{ERR_FUNC(ENGINE_F_ENGINE_TABLE_REGISTER), "ENGINE_TABLE_REGISTER"},
{ERR_FUNC(ENGINE_F_ENGINE_UNLOAD_KEY), "ENGINE_UNLOAD_KEY"},
{ERR_FUNC(ENGINE_F_ENGINE_UNLOCKED_FINISH), "ENGINE_UNLOCKED_FINISH"},
{ERR_FUNC(ENGINE_F_ENGINE_UP_REF), "ENGINE_up_ref"},
{ERR_FUNC(ENGINE_F_INT_CTRL_HELPER), "INT_CTRL_HELPER"},
{ERR_FUNC(ENGINE_F_INT_ENGINE_CONFIGURE), "INT_ENGINE_CONFIGURE"},
{ERR_FUNC(ENGINE_F_INT_ENGINE_MODULE_INIT), "INT_ENGINE_MODULE_INIT"},
{ERR_FUNC(ENGINE_F_LOG_MESSAGE), "LOG_MESSAGE"},
{0,NULL}
};
static ERR_STRING_DATA ENGINE_str_reasons[]=
{
{ERR_REASON(ENGINE_R_ALREADY_LOADED) ,"already loaded"},
{ERR_REASON(ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER),"argument is not a number"},
{ERR_REASON(ENGINE_R_CMD_NOT_EXECUTABLE) ,"cmd not executable"},
{ERR_REASON(ENGINE_R_COMMAND_TAKES_INPUT),"command takes input"},
{ERR_REASON(ENGINE_R_COMMAND_TAKES_NO_INPUT),"command takes no input"},
{ERR_REASON(ENGINE_R_CONFLICTING_ENGINE_ID),"conflicting engine id"},
{ERR_REASON(ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED),"ctrl command not implemented"},
{ERR_REASON(ENGINE_R_DH_NOT_IMPLEMENTED) ,"dh not implemented"},
{ERR_REASON(ENGINE_R_DSA_NOT_IMPLEMENTED),"dsa not implemented"},
{ERR_REASON(ENGINE_R_DSO_FAILURE) ,"DSO failure"},
{ERR_REASON(ENGINE_R_DSO_NOT_FOUND) ,"dso not found"},
{ERR_REASON(ENGINE_R_ENGINES_SECTION_ERROR),"engines section error"},
{ERR_REASON(ENGINE_R_ENGINE_CONFIGURATION_ERROR),"engine configuration error"},
{ERR_REASON(ENGINE_R_ENGINE_IS_NOT_IN_LIST),"engine is not in the list"},
{ERR_REASON(ENGINE_R_ENGINE_SECTION_ERROR),"engine section error"},
{ERR_REASON(ENGINE_R_FAILED_LOADING_PRIVATE_KEY),"failed loading private key"},
{ERR_REASON(ENGINE_R_FAILED_LOADING_PUBLIC_KEY),"failed loading public key"},
{ERR_REASON(ENGINE_R_FINISH_FAILED) ,"finish failed"},
{ERR_REASON(ENGINE_R_GET_HANDLE_FAILED) ,"could not obtain hardware handle"},
{ERR_REASON(ENGINE_R_ID_OR_NAME_MISSING) ,"'id' or 'name' missing"},
{ERR_REASON(ENGINE_R_INIT_FAILED) ,"init failed"},
{ERR_REASON(ENGINE_R_INTERNAL_LIST_ERROR),"internal list error"},
{ERR_REASON(ENGINE_R_INVALID_ARGUMENT) ,"invalid argument"},
{ERR_REASON(ENGINE_R_INVALID_CMD_NAME) ,"invalid cmd name"},
{ERR_REASON(ENGINE_R_INVALID_CMD_NUMBER) ,"invalid cmd number"},
{ERR_REASON(ENGINE_R_INVALID_INIT_VALUE) ,"invalid init value"},
{ERR_REASON(ENGINE_R_INVALID_STRING) ,"invalid string"},
{ERR_REASON(ENGINE_R_NOT_INITIALISED) ,"not initialised"},
{ERR_REASON(ENGINE_R_NOT_LOADED) ,"not loaded"},
{ERR_REASON(ENGINE_R_NO_CONTROL_FUNCTION),"no control function"},
{ERR_REASON(ENGINE_R_NO_INDEX) ,"no index"},
{ERR_REASON(ENGINE_R_NO_LOAD_FUNCTION) ,"no load function"},
{ERR_REASON(ENGINE_R_NO_REFERENCE) ,"no reference"},
{ERR_REASON(ENGINE_R_NO_SUCH_ENGINE) ,"no such engine"},
{ERR_REASON(ENGINE_R_NO_UNLOAD_FUNCTION) ,"no unload function"},
{ERR_REASON(ENGINE_R_PROVIDE_PARAMETERS) ,"provide parameters"},
{ERR_REASON(ENGINE_R_RSA_NOT_IMPLEMENTED),"rsa not implemented"},
{ERR_REASON(ENGINE_R_UNIMPLEMENTED_CIPHER),"unimplemented cipher"},
{ERR_REASON(ENGINE_R_UNIMPLEMENTED_DIGEST),"unimplemented digest"},
{ERR_REASON(ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD),"unimplemented public key method"},
{ERR_REASON(ENGINE_R_VERSION_INCOMPATIBILITY),"version incompatibility"},
{0,NULL}
};
#endif
void ERR_load_ENGINE_strings(void)
{
#ifndef OPENSSL_NO_ERR
if (ERR_func_error_string(ENGINE_str_functs[0].error) == NULL)
{
ERR_load_strings(0,ENGINE_str_functs);
ERR_load_strings(0,ENGINE_str_reasons);
}
#endif
}

View File

@@ -0,0 +1,182 @@
/* crypto/engine/eng_fat.c */
/* ====================================================================
* Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
/* ====================================================================
* Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
* ECDH support in OpenSSL originally developed by
* SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
*/
#include "eng_int.h"
#include <openssl/conf.h>
int ENGINE_set_default(ENGINE *e, unsigned int flags)
{
if((flags & ENGINE_METHOD_CIPHERS) && !ENGINE_set_default_ciphers(e))
return 0;
if((flags & ENGINE_METHOD_DIGESTS) && !ENGINE_set_default_digests(e))
return 0;
#ifndef OPENSSL_NO_RSA
if((flags & ENGINE_METHOD_RSA) && !ENGINE_set_default_RSA(e))
return 0;
#endif
#ifndef OPENSSL_NO_DSA
if((flags & ENGINE_METHOD_DSA) && !ENGINE_set_default_DSA(e))
return 0;
#endif
#ifndef OPENSSL_NO_DH
if((flags & ENGINE_METHOD_DH) && !ENGINE_set_default_DH(e))
return 0;
#endif
#ifndef OPENSSL_NO_ECDH
if((flags & ENGINE_METHOD_ECDH) && !ENGINE_set_default_ECDH(e))
return 0;
#endif
#ifndef OPENSSL_NO_ECDSA
if((flags & ENGINE_METHOD_ECDSA) && !ENGINE_set_default_ECDSA(e))
return 0;
#endif
if((flags & ENGINE_METHOD_RAND) && !ENGINE_set_default_RAND(e))
return 0;
if((flags & ENGINE_METHOD_PKEY_METHS)
&& !ENGINE_set_default_pkey_meths(e))
return 0;
if((flags & ENGINE_METHOD_PKEY_ASN1_METHS)
&& !ENGINE_set_default_pkey_asn1_meths(e))
return 0;
return 1;
}
/* Set default algorithms using a string */
static int int_def_cb(const char *alg, int len, void *arg)
{
unsigned int *pflags = arg;
if (!strncmp(alg, "ALL", len))
*pflags |= ENGINE_METHOD_ALL;
else if (!strncmp(alg, "RSA", len))
*pflags |= ENGINE_METHOD_RSA;
else if (!strncmp(alg, "DSA", len))
*pflags |= ENGINE_METHOD_DSA;
else if (!strncmp(alg, "ECDH", len))
*pflags |= ENGINE_METHOD_ECDH;
else if (!strncmp(alg, "ECDSA", len))
*pflags |= ENGINE_METHOD_ECDSA;
else if (!strncmp(alg, "DH", len))
*pflags |= ENGINE_METHOD_DH;
else if (!strncmp(alg, "RAND", len))
*pflags |= ENGINE_METHOD_RAND;
else if (!strncmp(alg, "CIPHERS", len))
*pflags |= ENGINE_METHOD_CIPHERS;
else if (!strncmp(alg, "DIGESTS", len))
*pflags |= ENGINE_METHOD_DIGESTS;
else if (!strncmp(alg, "PKEY", len))
*pflags |=
ENGINE_METHOD_PKEY_METHS|ENGINE_METHOD_PKEY_ASN1_METHS;
else if (!strncmp(alg, "PKEY_CRYPTO", len))
*pflags |= ENGINE_METHOD_PKEY_METHS;
else if (!strncmp(alg, "PKEY_ASN1", len))
*pflags |= ENGINE_METHOD_PKEY_ASN1_METHS;
else
return 0;
return 1;
}
int ENGINE_set_default_string(ENGINE *e, const char *def_list)
{
unsigned int flags = 0;
if (!CONF_parse_list(def_list, ',', 1, int_def_cb, &flags))
{
ENGINEerr(ENGINE_F_ENGINE_SET_DEFAULT_STRING,
ENGINE_R_INVALID_STRING);
ERR_add_error_data(2, "str=",def_list);
return 0;
}
return ENGINE_set_default(e, flags);
}
int ENGINE_register_complete(ENGINE *e)
{
ENGINE_register_ciphers(e);
ENGINE_register_digests(e);
#ifndef OPENSSL_NO_RSA
ENGINE_register_RSA(e);
#endif
#ifndef OPENSSL_NO_DSA
ENGINE_register_DSA(e);
#endif
#ifndef OPENSSL_NO_DH
ENGINE_register_DH(e);
#endif
#ifndef OPENSSL_NO_ECDH
ENGINE_register_ECDH(e);
#endif
#ifndef OPENSSL_NO_ECDSA
ENGINE_register_ECDSA(e);
#endif
ENGINE_register_RAND(e);
ENGINE_register_pkey_meths(e);
return 1;
}
int ENGINE_register_all_complete(void)
{
ENGINE *e;
for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
if (!(e->flags & ENGINE_FLAGS_NO_REGISTER_ALL))
ENGINE_register_complete(e);
return 1;
}

View File

@@ -0,0 +1,154 @@
/* crypto/engine/eng_init.c */
/* ====================================================================
* Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include "eng_int.h"
/* Initialise a engine type for use (or up its functional reference count
* if it's already in use). This version is only used internally. */
int engine_unlocked_init(ENGINE *e)
{
int to_return = 1;
if((e->funct_ref == 0) && e->init)
/* This is the first functional reference and the engine
* requires initialisation so we do it now. */
to_return = e->init(e);
if(to_return)
{
/* OK, we return a functional reference which is also a
* structural reference. */
e->struct_ref++;
e->funct_ref++;
engine_ref_debug(e, 0, 1)
engine_ref_debug(e, 1, 1)
}
return to_return;
}
/* Free a functional reference to a engine type. This version is only used
* internally. */
int engine_unlocked_finish(ENGINE *e, int unlock_for_handlers)
{
int to_return = 1;
/* Reduce the functional reference count here so if it's the terminating
* case, we can release the lock safely and call the finish() handler
* without risk of a race. We get a race if we leave the count until
* after and something else is calling "finish" at the same time -
* there's a chance that both threads will together take the count from
* 2 to 0 without either calling finish(). */
e->funct_ref--;
engine_ref_debug(e, 1, -1);
if((e->funct_ref == 0) && e->finish)
{
if(unlock_for_handlers)
CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
to_return = e->finish(e);
if(unlock_for_handlers)
CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
if(!to_return)
return 0;
}
#ifdef REF_CHECK
if(e->funct_ref < 0)
{
fprintf(stderr,"ENGINE_finish, bad functional reference count\n");
abort();
}
#endif
/* Release the structural reference too */
if(!engine_free_util(e, 0))
{
ENGINEerr(ENGINE_F_ENGINE_UNLOCKED_FINISH,ENGINE_R_FINISH_FAILED);
return 0;
}
return to_return;
}
/* The API (locked) version of "init" */
int ENGINE_init(ENGINE *e)
{
int ret;
if(e == NULL)
{
ENGINEerr(ENGINE_F_ENGINE_INIT,ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
ret = engine_unlocked_init(e);
CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
return ret;
}
/* The API (locked) version of "finish" */
int ENGINE_finish(ENGINE *e)
{
int to_return = 1;
if(e == NULL)
{
ENGINEerr(ENGINE_F_ENGINE_FINISH,ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
to_return = engine_unlocked_finish(e, 1);
CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
if(!to_return)
{
ENGINEerr(ENGINE_F_ENGINE_FINISH,ENGINE_R_FINISH_FAILED);
return 0;
}
return to_return;
}

View File

@@ -0,0 +1,206 @@
/* crypto/engine/eng_int.h */
/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
* project 2000.
*/
/* ====================================================================
* Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
/* ====================================================================
* Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
* ECDH support in OpenSSL originally developed by
* SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
*/
#ifndef HEADER_ENGINE_INT_H
#define HEADER_ENGINE_INT_H
#include "cryptlib.h"
/* Take public definitions from engine.h */
#include <openssl/engine.h>
#ifdef __cplusplus
extern "C" {
#endif
/* If we compile with this symbol defined, then both reference counts in the
* ENGINE structure will be monitored with a line of output on stderr for each
* change. This prints the engine's pointer address (truncated to unsigned int),
* "struct" or "funct" to indicate the reference type, the before and after
* reference count, and the file:line-number pair. The "engine_ref_debug"
* statements must come *after* the change. */
#ifdef ENGINE_REF_COUNT_DEBUG
#define engine_ref_debug(e, isfunct, diff) \
fprintf(stderr, "engine: %08x %s from %d to %d (%s:%d)\n", \
(unsigned int)(e), (isfunct ? "funct" : "struct"), \
((isfunct) ? ((e)->funct_ref - (diff)) : ((e)->struct_ref - (diff))), \
((isfunct) ? (e)->funct_ref : (e)->struct_ref), \
(__FILE__), (__LINE__));
#else
#define engine_ref_debug(e, isfunct, diff)
#endif
/* Any code that will need cleanup operations should use these functions to
* register callbacks. ENGINE_cleanup() will call all registered callbacks in
* order. NB: both the "add" functions assume CRYPTO_LOCK_ENGINE to already be
* held (in "write" mode). */
typedef void (ENGINE_CLEANUP_CB)(void);
typedef struct st_engine_cleanup_item
{
ENGINE_CLEANUP_CB *cb;
} ENGINE_CLEANUP_ITEM;
DECLARE_STACK_OF(ENGINE_CLEANUP_ITEM)
void engine_cleanup_add_first(ENGINE_CLEANUP_CB *cb);
void engine_cleanup_add_last(ENGINE_CLEANUP_CB *cb);
/* We need stacks of ENGINEs for use in eng_table.c */
DECLARE_STACK_OF(ENGINE)
/* If this symbol is defined then engine_table_select(), the function that is
* used by RSA, DSA (etc) code to select registered ENGINEs, cache defaults and
* functional references (etc), will display debugging summaries to stderr. */
/* #define ENGINE_TABLE_DEBUG */
/* This represents an implementation table. Dependent code should instantiate it
* as a (ENGINE_TABLE *) pointer value set initially to NULL. */
typedef struct st_engine_table ENGINE_TABLE;
int engine_table_register(ENGINE_TABLE **table, ENGINE_CLEANUP_CB *cleanup,
ENGINE *e, const int *nids, int num_nids, int setdefault);
void engine_table_unregister(ENGINE_TABLE **table, ENGINE *e);
void engine_table_cleanup(ENGINE_TABLE **table);
#ifndef ENGINE_TABLE_DEBUG
ENGINE *engine_table_select(ENGINE_TABLE **table, int nid);
#else
ENGINE *engine_table_select_tmp(ENGINE_TABLE **table, int nid, const char *f, int l);
#define engine_table_select(t,n) engine_table_select_tmp(t,n,__FILE__,__LINE__)
#endif
typedef void (engine_table_doall_cb)(int nid, STACK_OF(ENGINE) *sk, ENGINE *def, void *arg);
void engine_table_doall(ENGINE_TABLE *table, engine_table_doall_cb *cb, void *arg);
/* Internal versions of API functions that have control over locking. These are
* used between C files when functionality needs to be shared but the caller may
* already be controlling of the CRYPTO_LOCK_ENGINE lock. */
int engine_unlocked_init(ENGINE *e);
int engine_unlocked_finish(ENGINE *e, int unlock_for_handlers);
int engine_free_util(ENGINE *e, int locked);
/* This function will reset all "set"able values in an ENGINE to NULL. This
* won't touch reference counts or ex_data, but is equivalent to calling all the
* ENGINE_set_***() functions with a NULL value. */
void engine_set_all_null(ENGINE *e);
/* NB: Bitwise OR-able values for the "flags" variable in ENGINE are now exposed
* in engine.h. */
/* Free up dynamically allocated public key methods associated with ENGINE */
void engine_pkey_meths_free(ENGINE *e);
void engine_pkey_asn1_meths_free(ENGINE *e);
/* This is a structure for storing implementations of various crypto
* algorithms and functions. */
struct engine_st
{
const char *id;
const char *name;
const RSA_METHOD *rsa_meth;
const DSA_METHOD *dsa_meth;
const DH_METHOD *dh_meth;
const ECDH_METHOD *ecdh_meth;
const ECDSA_METHOD *ecdsa_meth;
const RAND_METHOD *rand_meth;
const STORE_METHOD *store_meth;
/* Cipher handling is via this callback */
ENGINE_CIPHERS_PTR ciphers;
/* Digest handling is via this callback */
ENGINE_DIGESTS_PTR digests;
/* Public key handling via this callback */
ENGINE_PKEY_METHS_PTR pkey_meths;
/* ASN1 public key handling via this callback */
ENGINE_PKEY_ASN1_METHS_PTR pkey_asn1_meths;
ENGINE_GEN_INT_FUNC_PTR destroy;
ENGINE_GEN_INT_FUNC_PTR init;
ENGINE_GEN_INT_FUNC_PTR finish;
ENGINE_CTRL_FUNC_PTR ctrl;
ENGINE_LOAD_KEY_PTR load_privkey;
ENGINE_LOAD_KEY_PTR load_pubkey;
ENGINE_SSL_CLIENT_CERT_PTR load_ssl_client_cert;
const ENGINE_CMD_DEFN *cmd_defns;
int flags;
/* reference count on the structure itself */
int struct_ref;
/* reference count on usability of the engine type. NB: This
* controls the loading and initialisation of any functionlity
* required by this engine, whereas the previous count is
* simply to cope with (de)allocation of this structure. Hence,
* running_ref <= struct_ref at all times. */
int funct_ref;
/* A place to store per-ENGINE data */
CRYPTO_EX_DATA ex_data;
/* Used to maintain the linked-list of engines. */
struct engine_st *prev;
struct engine_st *next;
};
#ifdef __cplusplus
}
#endif
#endif /* HEADER_ENGINE_INT_H */

View File

@@ -0,0 +1,332 @@
/* crypto/engine/eng_lib.c */
/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
* project 2000.
*/
/* ====================================================================
* Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include "eng_int.h"
#include <openssl/rand.h>
/* The "new"/"free" stuff first */
ENGINE *ENGINE_new(void)
{
ENGINE *ret;
ret = (ENGINE *)OPENSSL_malloc(sizeof(ENGINE));
if(ret == NULL)
{
ENGINEerr(ENGINE_F_ENGINE_NEW, ERR_R_MALLOC_FAILURE);
return NULL;
}
memset(ret, 0, sizeof(ENGINE));
ret->struct_ref = 1;
engine_ref_debug(ret, 0, 1)
CRYPTO_new_ex_data(CRYPTO_EX_INDEX_ENGINE, ret, &ret->ex_data);
return ret;
}
/* Placed here (close proximity to ENGINE_new) so that modifications to the
* elements of the ENGINE structure are more likely to be caught and changed
* here. */
void engine_set_all_null(ENGINE *e)
{
e->id = NULL;
e->name = NULL;
e->rsa_meth = NULL;
e->dsa_meth = NULL;
e->dh_meth = NULL;
e->rand_meth = NULL;
e->store_meth = NULL;
e->ciphers = NULL;
e->digests = NULL;
e->destroy = NULL;
e->init = NULL;
e->finish = NULL;
e->ctrl = NULL;
e->load_privkey = NULL;
e->load_pubkey = NULL;
e->cmd_defns = NULL;
e->flags = 0;
}
int engine_free_util(ENGINE *e, int locked)
{
int i;
if(e == NULL)
{
ENGINEerr(ENGINE_F_ENGINE_FREE_UTIL,
ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
if(locked)
i = CRYPTO_add(&e->struct_ref,-1,CRYPTO_LOCK_ENGINE);
else
i = --e->struct_ref;
engine_ref_debug(e, 0, -1)
if (i > 0) return 1;
#ifdef REF_CHECK
if (i < 0)
{
fprintf(stderr,"ENGINE_free, bad structural reference count\n");
abort();
}
#endif
/* Free up any dynamically allocated public key methods */
engine_pkey_meths_free(e);
engine_pkey_asn1_meths_free(e);
/* Give the ENGINE a chance to do any structural cleanup corresponding
* to allocation it did in its constructor (eg. unload error strings) */
if(e->destroy)
e->destroy(e);
CRYPTO_free_ex_data(CRYPTO_EX_INDEX_ENGINE, e, &e->ex_data);
OPENSSL_free(e);
return 1;
}
int ENGINE_free(ENGINE *e)
{
return engine_free_util(e, 1);
}
/* Cleanup stuff */
/* ENGINE_cleanup() is coded such that anything that does work that will need
* cleanup can register a "cleanup" callback here. That way we don't get linker
* bloat by referring to all *possible* cleanups, but any linker bloat into code
* "X" will cause X's cleanup function to end up here. */
static STACK_OF(ENGINE_CLEANUP_ITEM) *cleanup_stack = NULL;
static int int_cleanup_check(int create)
{
if(cleanup_stack) return 1;
if(!create) return 0;
cleanup_stack = sk_ENGINE_CLEANUP_ITEM_new_null();
return (cleanup_stack ? 1 : 0);
}
static ENGINE_CLEANUP_ITEM *int_cleanup_item(ENGINE_CLEANUP_CB *cb)
{
ENGINE_CLEANUP_ITEM *item = OPENSSL_malloc(sizeof(
ENGINE_CLEANUP_ITEM));
if(!item) return NULL;
item->cb = cb;
return item;
}
void engine_cleanup_add_first(ENGINE_CLEANUP_CB *cb)
{
ENGINE_CLEANUP_ITEM *item;
if(!int_cleanup_check(1)) return;
item = int_cleanup_item(cb);
if(item)
sk_ENGINE_CLEANUP_ITEM_insert(cleanup_stack, item, 0);
}
void engine_cleanup_add_last(ENGINE_CLEANUP_CB *cb)
{
ENGINE_CLEANUP_ITEM *item;
if(!int_cleanup_check(1)) return;
item = int_cleanup_item(cb);
if(item)
sk_ENGINE_CLEANUP_ITEM_push(cleanup_stack, item);
}
/* The API function that performs all cleanup */
static void engine_cleanup_cb_free(ENGINE_CLEANUP_ITEM *item)
{
(*(item->cb))();
OPENSSL_free(item);
}
void ENGINE_cleanup(void)
{
if(int_cleanup_check(0))
{
sk_ENGINE_CLEANUP_ITEM_pop_free(cleanup_stack,
engine_cleanup_cb_free);
cleanup_stack = NULL;
}
/* FIXME: This should be handled (somehow) through RAND, eg. by it
* registering a cleanup callback. */
RAND_set_rand_method(NULL);
}
/* Now the "ex_data" support */
int ENGINE_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
{
return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_ENGINE, argl, argp,
new_func, dup_func, free_func);
}
int ENGINE_set_ex_data(ENGINE *e, int idx, void *arg)
{
return(CRYPTO_set_ex_data(&e->ex_data, idx, arg));
}
void *ENGINE_get_ex_data(const ENGINE *e, int idx)
{
return(CRYPTO_get_ex_data(&e->ex_data, idx));
}
/* Functions to get/set an ENGINE's elements - mainly to avoid exposing the
* ENGINE structure itself. */
int ENGINE_set_id(ENGINE *e, const char *id)
{
if(id == NULL)
{
ENGINEerr(ENGINE_F_ENGINE_SET_ID,
ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
e->id = id;
return 1;
}
int ENGINE_set_name(ENGINE *e, const char *name)
{
if(name == NULL)
{
ENGINEerr(ENGINE_F_ENGINE_SET_NAME,
ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
e->name = name;
return 1;
}
int ENGINE_set_destroy_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR destroy_f)
{
e->destroy = destroy_f;
return 1;
}
int ENGINE_set_init_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR init_f)
{
e->init = init_f;
return 1;
}
int ENGINE_set_finish_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR finish_f)
{
e->finish = finish_f;
return 1;
}
int ENGINE_set_ctrl_function(ENGINE *e, ENGINE_CTRL_FUNC_PTR ctrl_f)
{
e->ctrl = ctrl_f;
return 1;
}
int ENGINE_set_flags(ENGINE *e, int flags)
{
e->flags = flags;
return 1;
}
int ENGINE_set_cmd_defns(ENGINE *e, const ENGINE_CMD_DEFN *defns)
{
e->cmd_defns = defns;
return 1;
}
const char *ENGINE_get_id(const ENGINE *e)
{
return e->id;
}
const char *ENGINE_get_name(const ENGINE *e)
{
return e->name;
}
ENGINE_GEN_INT_FUNC_PTR ENGINE_get_destroy_function(const ENGINE *e)
{
return e->destroy;
}
ENGINE_GEN_INT_FUNC_PTR ENGINE_get_init_function(const ENGINE *e)
{
return e->init;
}
ENGINE_GEN_INT_FUNC_PTR ENGINE_get_finish_function(const ENGINE *e)
{
return e->finish;
}
ENGINE_CTRL_FUNC_PTR ENGINE_get_ctrl_function(const ENGINE *e)
{
return e->ctrl;
}
int ENGINE_get_flags(const ENGINE *e)
{
return e->flags;
}
const ENGINE_CMD_DEFN *ENGINE_get_cmd_defns(const ENGINE *e)
{
return e->cmd_defns;
}
/* eng_lib.o is pretty much linked into anything that touches ENGINE already, so
* put the "static_state" hack here. */
static int internal_static_hack = 0;
void *ENGINE_get_static_state(void)
{
return &internal_static_hack;
}

View File

@@ -0,0 +1,434 @@
/* crypto/engine/eng_list.c */
/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
* project 2000.
*/
/* ====================================================================
* Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
/* ====================================================================
* Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
* ECDH support in OpenSSL originally developed by
* SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
*/
#include "eng_int.h"
/* The linked-list of pointers to engine types. engine_list_head
* incorporates an implicit structural reference but engine_list_tail
* does not - the latter is a computational niceity and only points
* to something that is already pointed to by its predecessor in the
* list (or engine_list_head itself). In the same way, the use of the
* "prev" pointer in each ENGINE is to save excessive list iteration,
* it doesn't correspond to an extra structural reference. Hence,
* engine_list_head, and each non-null "next" pointer account for
* the list itself assuming exactly 1 structural reference on each
* list member. */
static ENGINE *engine_list_head = NULL;
static ENGINE *engine_list_tail = NULL;
/* This cleanup function is only needed internally. If it should be called, we
* register it with the "ENGINE_cleanup()" stack to be called during cleanup. */
static void engine_list_cleanup(void)
{
ENGINE *iterator = engine_list_head;
while(iterator != NULL)
{
ENGINE_remove(iterator);
iterator = engine_list_head;
}
return;
}
/* These static functions starting with a lower case "engine_" always
* take place when CRYPTO_LOCK_ENGINE has been locked up. */
static int engine_list_add(ENGINE *e)
{
int conflict = 0;
ENGINE *iterator = NULL;
if(e == NULL)
{
ENGINEerr(ENGINE_F_ENGINE_LIST_ADD,
ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
iterator = engine_list_head;
while(iterator && !conflict)
{
conflict = (strcmp(iterator->id, e->id) == 0);
iterator = iterator->next;
}
if(conflict)
{
ENGINEerr(ENGINE_F_ENGINE_LIST_ADD,
ENGINE_R_CONFLICTING_ENGINE_ID);
return 0;
}
if(engine_list_head == NULL)
{
/* We are adding to an empty list. */
if(engine_list_tail)
{
ENGINEerr(ENGINE_F_ENGINE_LIST_ADD,
ENGINE_R_INTERNAL_LIST_ERROR);
return 0;
}
engine_list_head = e;
e->prev = NULL;
/* The first time the list allocates, we should register the
* cleanup. */
engine_cleanup_add_last(engine_list_cleanup);
}
else
{
/* We are adding to the tail of an existing list. */
if((engine_list_tail == NULL) ||
(engine_list_tail->next != NULL))
{
ENGINEerr(ENGINE_F_ENGINE_LIST_ADD,
ENGINE_R_INTERNAL_LIST_ERROR);
return 0;
}
engine_list_tail->next = e;
e->prev = engine_list_tail;
}
/* Having the engine in the list assumes a structural
* reference. */
e->struct_ref++;
engine_ref_debug(e, 0, 1)
/* However it came to be, e is the last item in the list. */
engine_list_tail = e;
e->next = NULL;
return 1;
}
static int engine_list_remove(ENGINE *e)
{
ENGINE *iterator;
if(e == NULL)
{
ENGINEerr(ENGINE_F_ENGINE_LIST_REMOVE,
ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
/* We need to check that e is in our linked list! */
iterator = engine_list_head;
while(iterator && (iterator != e))
iterator = iterator->next;
if(iterator == NULL)
{
ENGINEerr(ENGINE_F_ENGINE_LIST_REMOVE,
ENGINE_R_ENGINE_IS_NOT_IN_LIST);
return 0;
}
/* un-link e from the chain. */
if(e->next)
e->next->prev = e->prev;
if(e->prev)
e->prev->next = e->next;
/* Correct our head/tail if necessary. */
if(engine_list_head == e)
engine_list_head = e->next;
if(engine_list_tail == e)
engine_list_tail = e->prev;
engine_free_util(e, 0);
return 1;
}
/* Get the first/last "ENGINE" type available. */
ENGINE *ENGINE_get_first(void)
{
ENGINE *ret;
CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
ret = engine_list_head;
if(ret)
{
ret->struct_ref++;
engine_ref_debug(ret, 0, 1)
}
CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
return ret;
}
ENGINE *ENGINE_get_last(void)
{
ENGINE *ret;
CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
ret = engine_list_tail;
if(ret)
{
ret->struct_ref++;
engine_ref_debug(ret, 0, 1)
}
CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
return ret;
}
/* Iterate to the next/previous "ENGINE" type (NULL = end of the list). */
ENGINE *ENGINE_get_next(ENGINE *e)
{
ENGINE *ret = NULL;
if(e == NULL)
{
ENGINEerr(ENGINE_F_ENGINE_GET_NEXT,
ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
ret = e->next;
if(ret)
{
/* Return a valid structural refernce to the next ENGINE */
ret->struct_ref++;
engine_ref_debug(ret, 0, 1)
}
CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
/* Release the structural reference to the previous ENGINE */
ENGINE_free(e);
return ret;
}
ENGINE *ENGINE_get_prev(ENGINE *e)
{
ENGINE *ret = NULL;
if(e == NULL)
{
ENGINEerr(ENGINE_F_ENGINE_GET_PREV,
ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
ret = e->prev;
if(ret)
{
/* Return a valid structural reference to the next ENGINE */
ret->struct_ref++;
engine_ref_debug(ret, 0, 1)
}
CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
/* Release the structural reference to the previous ENGINE */
ENGINE_free(e);
return ret;
}
/* Add another "ENGINE" type into the list. */
int ENGINE_add(ENGINE *e)
{
int to_return = 1;
if(e == NULL)
{
ENGINEerr(ENGINE_F_ENGINE_ADD,
ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
if((e->id == NULL) || (e->name == NULL))
{
ENGINEerr(ENGINE_F_ENGINE_ADD,
ENGINE_R_ID_OR_NAME_MISSING);
}
CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
if(!engine_list_add(e))
{
ENGINEerr(ENGINE_F_ENGINE_ADD,
ENGINE_R_INTERNAL_LIST_ERROR);
to_return = 0;
}
CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
return to_return;
}
/* Remove an existing "ENGINE" type from the array. */
int ENGINE_remove(ENGINE *e)
{
int to_return = 1;
if(e == NULL)
{
ENGINEerr(ENGINE_F_ENGINE_REMOVE,
ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
if(!engine_list_remove(e))
{
ENGINEerr(ENGINE_F_ENGINE_REMOVE,
ENGINE_R_INTERNAL_LIST_ERROR);
to_return = 0;
}
CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
return to_return;
}
static void engine_cpy(ENGINE *dest, const ENGINE *src)
{
dest->id = src->id;
dest->name = src->name;
#ifndef OPENSSL_NO_RSA
dest->rsa_meth = src->rsa_meth;
#endif
#ifndef OPENSSL_NO_DSA
dest->dsa_meth = src->dsa_meth;
#endif
#ifndef OPENSSL_NO_DH
dest->dh_meth = src->dh_meth;
#endif
#ifndef OPENSSL_NO_ECDH
dest->ecdh_meth = src->ecdh_meth;
#endif
#ifndef OPENSSL_NO_ECDSA
dest->ecdsa_meth = src->ecdsa_meth;
#endif
dest->rand_meth = src->rand_meth;
dest->store_meth = src->store_meth;
dest->ciphers = src->ciphers;
dest->digests = src->digests;
dest->pkey_meths = src->pkey_meths;
dest->destroy = src->destroy;
dest->init = src->init;
dest->finish = src->finish;
dest->ctrl = src->ctrl;
dest->load_privkey = src->load_privkey;
dest->load_pubkey = src->load_pubkey;
dest->cmd_defns = src->cmd_defns;
dest->flags = src->flags;
}
ENGINE *ENGINE_by_id(const char *id)
{
ENGINE *iterator;
char *load_dir = NULL;
if(id == NULL)
{
ENGINEerr(ENGINE_F_ENGINE_BY_ID,
ERR_R_PASSED_NULL_PARAMETER);
return NULL;
}
CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
iterator = engine_list_head;
while(iterator && (strcmp(id, iterator->id) != 0))
iterator = iterator->next;
if(iterator)
{
/* We need to return a structural reference. If this is an
* ENGINE type that returns copies, make a duplicate - otherwise
* increment the existing ENGINE's reference count. */
if(iterator->flags & ENGINE_FLAGS_BY_ID_COPY)
{
ENGINE *cp = ENGINE_new();
if(!cp)
iterator = NULL;
else
{
engine_cpy(cp, iterator);
iterator = cp;
}
}
else
{
iterator->struct_ref++;
engine_ref_debug(iterator, 0, 1)
}
}
CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
#if 0
if(iterator == NULL)
{
ENGINEerr(ENGINE_F_ENGINE_BY_ID,
ENGINE_R_NO_SUCH_ENGINE);
ERR_add_error_data(2, "id=", id);
}
return iterator;
#else
/* EEK! Experimental code starts */
if(iterator) return iterator;
/* Prevent infinite recusrion if we're looking for the dynamic engine. */
if (strcmp(id, "dynamic"))
{
#ifdef OPENSSL_SYS_VMS
if((load_dir = getenv("OPENSSL_ENGINES")) == 0) load_dir = "SSLROOT:[ENGINES]";
#else
if((load_dir = getenv("OPENSSL_ENGINES")) == 0) load_dir = ENGINESDIR;
#endif
iterator = ENGINE_by_id("dynamic");
if(!iterator || !ENGINE_ctrl_cmd_string(iterator, "ID", id, 0) ||
!ENGINE_ctrl_cmd_string(iterator, "DIR_LOAD", "2", 0) ||
!ENGINE_ctrl_cmd_string(iterator, "DIR_ADD",
load_dir, 0) ||
!ENGINE_ctrl_cmd_string(iterator, "LIST_ADD", "1", 0) ||
!ENGINE_ctrl_cmd_string(iterator, "LOAD", NULL, 0))
goto notfound;
return iterator;
}
notfound:
ENGINE_free(iterator);
ENGINEerr(ENGINE_F_ENGINE_BY_ID,ENGINE_R_NO_SUCH_ENGINE);
ERR_add_error_data(2, "id=", id);
return NULL;
/* EEK! Experimental code ends */
#endif
}
int ENGINE_up_ref(ENGINE *e)
{
if (e == NULL)
{
ENGINEerr(ENGINE_F_ENGINE_UP_REF,ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
CRYPTO_add(&e->struct_ref,1,CRYPTO_LOCK_ENGINE);
return 1;
}

View File

@@ -0,0 +1,384 @@
/* crypto/engine/eng_openssl.c */
/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
* project 2000.
*/
/* ====================================================================
* Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
/* ====================================================================
* Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
* ECDH support in OpenSSL originally developed by
* SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
*/
#include <stdio.h>
#include <openssl/crypto.h>
#include "cryptlib.h"
#include <openssl/engine.h>
#include <openssl/dso.h>
#include <openssl/pem.h>
#include <openssl/evp.h>
#include <openssl/rand.h>
#ifndef OPENSSL_NO_RSA
#include <openssl/rsa.h>
#endif
#ifndef OPENSSL_NO_DSA
#include <openssl/dsa.h>
#endif
#ifndef OPENSSL_NO_DH
#include <openssl/dh.h>
#endif
/* This testing gunk is implemented (and explained) lower down. It also assumes
* the application explicitly calls "ENGINE_load_openssl()" because this is no
* longer automatic in ENGINE_load_builtin_engines(). */
#define TEST_ENG_OPENSSL_RC4
#define TEST_ENG_OPENSSL_PKEY
/* #define TEST_ENG_OPENSSL_RC4_OTHERS */
#define TEST_ENG_OPENSSL_RC4_P_INIT
/* #define TEST_ENG_OPENSSL_RC4_P_CIPHER */
#define TEST_ENG_OPENSSL_SHA
/* #define TEST_ENG_OPENSSL_SHA_OTHERS */
/* #define TEST_ENG_OPENSSL_SHA_P_INIT */
/* #define TEST_ENG_OPENSSL_SHA_P_UPDATE */
/* #define TEST_ENG_OPENSSL_SHA_P_FINAL */
/* Now check what of those algorithms are actually enabled */
#ifdef OPENSSL_NO_RC4
#undef TEST_ENG_OPENSSL_RC4
#undef TEST_ENG_OPENSSL_RC4_OTHERS
#undef TEST_ENG_OPENSSL_RC4_P_INIT
#undef TEST_ENG_OPENSSL_RC4_P_CIPHER
#endif
#if defined(OPENSSL_NO_SHA) || defined(OPENSSL_NO_SHA0) || defined(OPENSSL_NO_SHA1)
#undef TEST_ENG_OPENSSL_SHA
#undef TEST_ENG_OPENSSL_SHA_OTHERS
#undef TEST_ENG_OPENSSL_SHA_P_INIT
#undef TEST_ENG_OPENSSL_SHA_P_UPDATE
#undef TEST_ENG_OPENSSL_SHA_P_FINAL
#endif
#ifdef TEST_ENG_OPENSSL_RC4
static int openssl_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
const int **nids, int nid);
#endif
#ifdef TEST_ENG_OPENSSL_SHA
static int openssl_digests(ENGINE *e, const EVP_MD **digest,
const int **nids, int nid);
#endif
#ifdef TEST_ENG_OPENSSL_PKEY
static EVP_PKEY *openssl_load_privkey(ENGINE *eng, const char *key_id,
UI_METHOD *ui_method, void *callback_data);
#endif
/* The constants used when creating the ENGINE */
static const char *engine_openssl_id = "openssl";
static const char *engine_openssl_name = "Software engine support";
/* This internal function is used by ENGINE_openssl() and possibly by the
* "dynamic" ENGINE support too */
static int bind_helper(ENGINE *e)
{
if(!ENGINE_set_id(e, engine_openssl_id)
|| !ENGINE_set_name(e, engine_openssl_name)
#ifndef TEST_ENG_OPENSSL_NO_ALGORITHMS
#ifndef OPENSSL_NO_RSA
|| !ENGINE_set_RSA(e, RSA_get_default_method())
#endif
#ifndef OPENSSL_NO_DSA
|| !ENGINE_set_DSA(e, DSA_get_default_method())
#endif
#ifndef OPENSSL_NO_ECDH
|| !ENGINE_set_ECDH(e, ECDH_OpenSSL())
#endif
#ifndef OPENSSL_NO_ECDSA
|| !ENGINE_set_ECDSA(e, ECDSA_OpenSSL())
#endif
#ifndef OPENSSL_NO_DH
|| !ENGINE_set_DH(e, DH_get_default_method())
#endif
|| !ENGINE_set_RAND(e, RAND_SSLeay())
#ifdef TEST_ENG_OPENSSL_RC4
|| !ENGINE_set_ciphers(e, openssl_ciphers)
#endif
#ifdef TEST_ENG_OPENSSL_SHA
|| !ENGINE_set_digests(e, openssl_digests)
#endif
#endif
#ifdef TEST_ENG_OPENSSL_PKEY
|| !ENGINE_set_load_privkey_function(e, openssl_load_privkey)
#endif
)
return 0;
/* If we add errors to this ENGINE, ensure the error handling is setup here */
/* openssl_load_error_strings(); */
return 1;
}
static ENGINE *engine_openssl(void)
{
ENGINE *ret = ENGINE_new();
if(!ret)
return NULL;
if(!bind_helper(ret))
{
ENGINE_free(ret);
return NULL;
}
return ret;
}
void ENGINE_load_openssl(void)
{
ENGINE *toadd = engine_openssl();
if(!toadd) return;
ENGINE_add(toadd);
/* If the "add" worked, it gets a structural reference. So either way,
* we release our just-created reference. */
ENGINE_free(toadd);
ERR_clear_error();
}
/* This stuff is needed if this ENGINE is being compiled into a self-contained
* shared-library. */
#ifdef ENGINE_DYNAMIC_SUPPORT
static int bind_fn(ENGINE *e, const char *id)
{
if(id && (strcmp(id, engine_openssl_id) != 0))
return 0;
if(!bind_helper(e))
return 0;
return 1;
}
IMPLEMENT_DYNAMIC_CHECK_FN()
IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
#endif /* ENGINE_DYNAMIC_SUPPORT */
#ifdef TEST_ENG_OPENSSL_RC4
/* This section of code compiles an "alternative implementation" of two modes of
* RC4 into this ENGINE. The result is that EVP_CIPHER operation for "rc4"
* should under normal circumstances go via this support rather than the default
* EVP support. There are other symbols to tweak the testing;
* TEST_ENC_OPENSSL_RC4_OTHERS - print a one line message to stderr each time
* we're asked for a cipher we don't support (should not happen).
* TEST_ENG_OPENSSL_RC4_P_INIT - print a one line message to stderr each time
* the "init_key" handler is called.
* TEST_ENG_OPENSSL_RC4_P_CIPHER - ditto for the "cipher" handler.
*/
#include <openssl/rc4.h>
#define TEST_RC4_KEY_SIZE 16
static int test_cipher_nids[] = {NID_rc4,NID_rc4_40};
static int test_cipher_nids_number = 2;
typedef struct {
unsigned char key[TEST_RC4_KEY_SIZE];
RC4_KEY ks;
} TEST_RC4_KEY;
#define test(ctx) ((TEST_RC4_KEY *)(ctx)->cipher_data)
static int test_rc4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
const unsigned char *iv, int enc)
{
#ifdef TEST_ENG_OPENSSL_RC4_P_INIT
fprintf(stderr, "(TEST_ENG_OPENSSL_RC4) test_init_key() called\n");
#endif
memcpy(&test(ctx)->key[0],key,EVP_CIPHER_CTX_key_length(ctx));
RC4_set_key(&test(ctx)->ks,EVP_CIPHER_CTX_key_length(ctx),
test(ctx)->key);
return 1;
}
static int test_rc4_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
const unsigned char *in, size_t inl)
{
#ifdef TEST_ENG_OPENSSL_RC4_P_CIPHER
fprintf(stderr, "(TEST_ENG_OPENSSL_RC4) test_cipher() called\n");
#endif
RC4(&test(ctx)->ks,inl,in,out);
return 1;
}
static const EVP_CIPHER test_r4_cipher=
{
NID_rc4,
1,TEST_RC4_KEY_SIZE,0,
EVP_CIPH_VARIABLE_LENGTH,
test_rc4_init_key,
test_rc4_cipher,
NULL,
sizeof(TEST_RC4_KEY),
NULL,
NULL,
NULL,
NULL
};
static const EVP_CIPHER test_r4_40_cipher=
{
NID_rc4_40,
1,5 /* 40 bit */,0,
EVP_CIPH_VARIABLE_LENGTH,
test_rc4_init_key,
test_rc4_cipher,
NULL,
sizeof(TEST_RC4_KEY),
NULL,
NULL,
NULL,
NULL
};
static int openssl_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
const int **nids, int nid)
{
if(!cipher)
{
/* We are returning a list of supported nids */
*nids = test_cipher_nids;
return test_cipher_nids_number;
}
/* We are being asked for a specific cipher */
if(nid == NID_rc4)
*cipher = &test_r4_cipher;
else if(nid == NID_rc4_40)
*cipher = &test_r4_40_cipher;
else
{
#ifdef TEST_ENG_OPENSSL_RC4_OTHERS
fprintf(stderr, "(TEST_ENG_OPENSSL_RC4) returning NULL for "
"nid %d\n", nid);
#endif
*cipher = NULL;
return 0;
}
return 1;
}
#endif
#ifdef TEST_ENG_OPENSSL_SHA
/* Much the same sort of comment as for TEST_ENG_OPENSSL_RC4 */
#include <openssl/sha.h>
static int test_digest_nids[] = {NID_sha1};
static int test_digest_nids_number = 1;
static int test_sha1_init(EVP_MD_CTX *ctx)
{
#ifdef TEST_ENG_OPENSSL_SHA_P_INIT
fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) test_sha1_init() called\n");
#endif
return SHA1_Init(ctx->md_data);
}
static int test_sha1_update(EVP_MD_CTX *ctx,const void *data,size_t count)
{
#ifdef TEST_ENG_OPENSSL_SHA_P_UPDATE
fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) test_sha1_update() called\n");
#endif
return SHA1_Update(ctx->md_data,data,count);
}
static int test_sha1_final(EVP_MD_CTX *ctx,unsigned char *md)
{
#ifdef TEST_ENG_OPENSSL_SHA_P_FINAL
fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) test_sha1_final() called\n");
#endif
return SHA1_Final(md,ctx->md_data);
}
static const EVP_MD test_sha_md=
{
NID_sha1,
NID_sha1WithRSAEncryption,
SHA_DIGEST_LENGTH,
0,
test_sha1_init,
test_sha1_update,
test_sha1_final,
NULL,
NULL,
EVP_PKEY_RSA_method,
SHA_CBLOCK,
sizeof(EVP_MD *)+sizeof(SHA_CTX),
};
static int openssl_digests(ENGINE *e, const EVP_MD **digest,
const int **nids, int nid)
{
if(!digest)
{
/* We are returning a list of supported nids */
*nids = test_digest_nids;
return test_digest_nids_number;
}
/* We are being asked for a specific digest */
if(nid == NID_sha1)
*digest = &test_sha_md;
else
{
#ifdef TEST_ENG_OPENSSL_SHA_OTHERS
fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) returning NULL for "
"nid %d\n", nid);
#endif
*digest = NULL;
return 0;
}
return 1;
}
#endif
#ifdef TEST_ENG_OPENSSL_PKEY
static EVP_PKEY *openssl_load_privkey(ENGINE *eng, const char *key_id,
UI_METHOD *ui_method, void *callback_data)
{
BIO *in;
EVP_PKEY *key;
fprintf(stderr, "(TEST_ENG_OPENSSL_PKEY)Loading Private key %s\n", key_id);
in = BIO_new_file(key_id, "r");
if (!in)
return NULL;
key = PEM_read_bio_PrivateKey(in, NULL, 0, NULL);
BIO_free(in);
return key;
}
#endif

View File

@@ -0,0 +1,196 @@
/* crypto/engine/eng_pkey.c */
/* ====================================================================
* Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include "eng_int.h"
/* Basic get/set stuff */
int ENGINE_set_load_privkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpriv_f)
{
e->load_privkey = loadpriv_f;
return 1;
}
int ENGINE_set_load_pubkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpub_f)
{
e->load_pubkey = loadpub_f;
return 1;
}
int ENGINE_set_load_ssl_client_cert_function(ENGINE *e,
ENGINE_SSL_CLIENT_CERT_PTR loadssl_f)
{
e->load_ssl_client_cert = loadssl_f;
return 1;
}
ENGINE_LOAD_KEY_PTR ENGINE_get_load_privkey_function(const ENGINE *e)
{
return e->load_privkey;
}
ENGINE_LOAD_KEY_PTR ENGINE_get_load_pubkey_function(const ENGINE *e)
{
return e->load_pubkey;
}
ENGINE_SSL_CLIENT_CERT_PTR ENGINE_get_ssl_client_cert_function(const ENGINE *e)
{
return e->load_ssl_client_cert;
}
/* API functions to load public/private keys */
EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id,
UI_METHOD *ui_method, void *callback_data)
{
EVP_PKEY *pkey;
if(e == NULL)
{
ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY,
ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
if(e->funct_ref == 0)
{
CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY,
ENGINE_R_NOT_INITIALISED);
return 0;
}
CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
if (!e->load_privkey)
{
ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY,
ENGINE_R_NO_LOAD_FUNCTION);
return 0;
}
pkey = e->load_privkey(e, key_id, ui_method, callback_data);
if (!pkey)
{
ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY,
ENGINE_R_FAILED_LOADING_PRIVATE_KEY);
return 0;
}
return pkey;
}
EVP_PKEY *ENGINE_load_public_key(ENGINE *e, const char *key_id,
UI_METHOD *ui_method, void *callback_data)
{
EVP_PKEY *pkey;
if(e == NULL)
{
ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY,
ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
if(e->funct_ref == 0)
{
CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY,
ENGINE_R_NOT_INITIALISED);
return 0;
}
CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
if (!e->load_pubkey)
{
ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY,
ENGINE_R_NO_LOAD_FUNCTION);
return 0;
}
pkey = e->load_pubkey(e, key_id, ui_method, callback_data);
if (!pkey)
{
ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY,
ENGINE_R_FAILED_LOADING_PUBLIC_KEY);
return 0;
}
return pkey;
}
int ENGINE_load_ssl_client_cert(ENGINE *e, SSL *s,
STACK_OF(X509_NAME) *ca_dn, X509 **pcert, EVP_PKEY **ppkey,
STACK_OF(X509) **pother, UI_METHOD *ui_method, void *callback_data)
{
if(e == NULL)
{
ENGINEerr(ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT,
ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
if(e->funct_ref == 0)
{
CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
ENGINEerr(ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT,
ENGINE_R_NOT_INITIALISED);
return 0;
}
CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
if (!e->load_ssl_client_cert)
{
ENGINEerr(ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT,
ENGINE_R_NO_LOAD_FUNCTION);
return 0;
}
return e->load_ssl_client_cert(e, s, ca_dn, pcert, ppkey, pother,
ui_method, callback_data);
}

View File

@@ -0,0 +1,351 @@
/* ====================================================================
* Copyright (c) 2001 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include "cryptlib.h"
#include <openssl/evp.h>
#include <openssl/lhash.h>
#include "eng_int.h"
/* The type of the items in the table */
typedef struct st_engine_pile
{
/* The 'nid' of this algorithm/mode */
int nid;
/* ENGINEs that implement this algorithm/mode. */
STACK_OF(ENGINE) *sk;
/* The default ENGINE to perform this algorithm/mode. */
ENGINE *funct;
/* Zero if 'sk' is newer than the cached 'funct', non-zero otherwise */
int uptodate;
} ENGINE_PILE;
DECLARE_LHASH_OF(ENGINE_PILE);
/* The type exposed in eng_int.h */
struct st_engine_table
{
LHASH_OF(ENGINE_PILE) piles;
}; /* ENGINE_TABLE */
typedef struct st_engine_pile_doall
{
engine_table_doall_cb *cb;
void *arg;
} ENGINE_PILE_DOALL;
/* Global flags (ENGINE_TABLE_FLAG_***). */
static unsigned int table_flags = 0;
/* API function manipulating 'table_flags' */
unsigned int ENGINE_get_table_flags(void)
{
return table_flags;
}
void ENGINE_set_table_flags(unsigned int flags)
{
table_flags = flags;
}
/* Internal functions for the "piles" hash table */
static unsigned long engine_pile_hash(const ENGINE_PILE *c)
{
return c->nid;
}
static int engine_pile_cmp(const ENGINE_PILE *a, const ENGINE_PILE *b)
{
return a->nid - b->nid;
}
static IMPLEMENT_LHASH_HASH_FN(engine_pile, ENGINE_PILE)
static IMPLEMENT_LHASH_COMP_FN(engine_pile, ENGINE_PILE)
static int int_table_check(ENGINE_TABLE **t, int create)
{
LHASH_OF(ENGINE_PILE) *lh;
if(*t) return 1;
if(!create) return 0;
if((lh = lh_ENGINE_PILE_new()) == NULL)
return 0;
*t = (ENGINE_TABLE *)lh;
return 1;
}
/* Privately exposed (via eng_int.h) functions for adding and/or removing
* ENGINEs from the implementation table */
int engine_table_register(ENGINE_TABLE **table, ENGINE_CLEANUP_CB *cleanup,
ENGINE *e, const int *nids, int num_nids, int setdefault)
{
int ret = 0, added = 0;
ENGINE_PILE tmplate, *fnd;
CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
if(!(*table))
added = 1;
if(!int_table_check(table, 1))
goto end;
if(added)
/* The cleanup callback needs to be added */
engine_cleanup_add_first(cleanup);
while(num_nids--)
{
tmplate.nid = *nids;
fnd = lh_ENGINE_PILE_retrieve(&(*table)->piles, &tmplate);
if(!fnd)
{
fnd = OPENSSL_malloc(sizeof(ENGINE_PILE));
if(!fnd) goto end;
fnd->uptodate = 1;
fnd->nid = *nids;
fnd->sk = sk_ENGINE_new_null();
if(!fnd->sk)
{
OPENSSL_free(fnd);
goto end;
}
fnd->funct = NULL;
(void)lh_ENGINE_PILE_insert(&(*table)->piles, fnd);
}
/* A registration shouldn't add duplciate entries */
(void)sk_ENGINE_delete_ptr(fnd->sk, e);
/* if 'setdefault', this ENGINE goes to the head of the list */
if(!sk_ENGINE_push(fnd->sk, e))
goto end;
/* "touch" this ENGINE_PILE */
fnd->uptodate = 0;
if(setdefault)
{
if(!engine_unlocked_init(e))
{
ENGINEerr(ENGINE_F_ENGINE_TABLE_REGISTER,
ENGINE_R_INIT_FAILED);
goto end;
}
if(fnd->funct)
engine_unlocked_finish(fnd->funct, 0);
fnd->funct = e;
fnd->uptodate = 1;
}
nids++;
}
ret = 1;
end:
CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
return ret;
}
static void int_unregister_cb_doall_arg(ENGINE_PILE *pile, ENGINE *e)
{
int n;
/* Iterate the 'c->sk' stack removing any occurance of 'e' */
while((n = sk_ENGINE_find(pile->sk, e)) >= 0)
{
(void)sk_ENGINE_delete(pile->sk, n);
pile->uptodate = 0;
}
if(pile->funct == e)
{
engine_unlocked_finish(e, 0);
pile->funct = NULL;
}
}
static IMPLEMENT_LHASH_DOALL_ARG_FN(int_unregister_cb, ENGINE_PILE, ENGINE)
void engine_table_unregister(ENGINE_TABLE **table, ENGINE *e)
{
CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
if(int_table_check(table, 0))
lh_ENGINE_PILE_doall_arg(&(*table)->piles,
LHASH_DOALL_ARG_FN(int_unregister_cb),
ENGINE, e);
CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
}
static void int_cleanup_cb_doall(ENGINE_PILE *p)
{
sk_ENGINE_free(p->sk);
if(p->funct)
engine_unlocked_finish(p->funct, 0);
OPENSSL_free(p);
}
static IMPLEMENT_LHASH_DOALL_FN(int_cleanup_cb, ENGINE_PILE)
void engine_table_cleanup(ENGINE_TABLE **table)
{
CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
if(*table)
{
lh_ENGINE_PILE_doall(&(*table)->piles,
LHASH_DOALL_FN(int_cleanup_cb));
lh_ENGINE_PILE_free(&(*table)->piles);
*table = NULL;
}
CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
}
/* return a functional reference for a given 'nid' */
#ifndef ENGINE_TABLE_DEBUG
ENGINE *engine_table_select(ENGINE_TABLE **table, int nid)
#else
ENGINE *engine_table_select_tmp(ENGINE_TABLE **table, int nid, const char *f, int l)
#endif
{
ENGINE *ret = NULL;
ENGINE_PILE tmplate, *fnd=NULL;
int initres, loop = 0;
if(!(*table))
{
#ifdef ENGINE_TABLE_DEBUG
fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, nothing "
"registered!\n", f, l, nid);
#endif
return NULL;
}
ERR_set_mark();
CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
/* Check again inside the lock otherwise we could race against cleanup
* operations. But don't worry about a fprintf(stderr). */
if(!int_table_check(table, 0)) goto end;
tmplate.nid = nid;
fnd = lh_ENGINE_PILE_retrieve(&(*table)->piles, &tmplate);
if(!fnd) goto end;
if(fnd->funct && engine_unlocked_init(fnd->funct))
{
#ifdef ENGINE_TABLE_DEBUG
fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, using "
"ENGINE '%s' cached\n", f, l, nid, fnd->funct->id);
#endif
ret = fnd->funct;
goto end;
}
if(fnd->uptodate)
{
ret = fnd->funct;
goto end;
}
trynext:
ret = sk_ENGINE_value(fnd->sk, loop++);
if(!ret)
{
#ifdef ENGINE_TABLE_DEBUG
fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, no "
"registered implementations would initialise\n",
f, l, nid);
#endif
goto end;
}
/* Try to initialise the ENGINE? */
if((ret->funct_ref > 0) || !(table_flags & ENGINE_TABLE_FLAG_NOINIT))
initres = engine_unlocked_init(ret);
else
initres = 0;
if(initres)
{
/* Update 'funct' */
if((fnd->funct != ret) && engine_unlocked_init(ret))
{
/* If there was a previous default we release it. */
if(fnd->funct)
engine_unlocked_finish(fnd->funct, 0);
fnd->funct = ret;
#ifdef ENGINE_TABLE_DEBUG
fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, "
"setting default to '%s'\n", f, l, nid, ret->id);
#endif
}
#ifdef ENGINE_TABLE_DEBUG
fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, using "
"newly initialised '%s'\n", f, l, nid, ret->id);
#endif
goto end;
}
goto trynext;
end:
/* If it failed, it is unlikely to succeed again until some future
* registrations have taken place. In all cases, we cache. */
if(fnd) fnd->uptodate = 1;
#ifdef ENGINE_TABLE_DEBUG
if(ret)
fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, caching "
"ENGINE '%s'\n", f, l, nid, ret->id);
else
fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, caching "
"'no matching ENGINE'\n", f, l, nid);
#endif
CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
/* Whatever happened, any failed init()s are not failures in this
* context, so clear our error state. */
ERR_pop_to_mark();
return ret;
}
/* Table enumeration */
static void int_cb_doall_arg(ENGINE_PILE *pile, ENGINE_PILE_DOALL *dall)
{
dall->cb(pile->nid, pile->sk, pile->funct, dall->arg);
}
static IMPLEMENT_LHASH_DOALL_ARG_FN(int_cb, ENGINE_PILE,ENGINE_PILE_DOALL)
void engine_table_doall(ENGINE_TABLE *table, engine_table_doall_cb *cb,
void *arg)
{
ENGINE_PILE_DOALL dall;
dall.cb = cb;
dall.arg = arg;
lh_ENGINE_PILE_doall_arg(&table->piles, LHASH_DOALL_ARG_FN(int_cb),
ENGINE_PILE_DOALL, &dall);
}

View File

@@ -0,0 +1,842 @@
/* openssl/engine.h */
/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
* project 2000.
*/
/* ====================================================================
* Copyright (c) 1999-2004 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
/* ====================================================================
* Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
* ECDH support in OpenSSL originally developed by
* SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
*/
#ifndef HEADER_ENGINE_H
#define HEADER_ENGINE_H
#include <openssl/opensslconf.h>
#ifdef OPENSSL_NO_ENGINE
#error ENGINE is disabled.
#endif
#ifndef OPENSSL_NO_DEPRECATED
#include <openssl/bn.h>
#ifndef OPENSSL_NO_RSA
#include <openssl/rsa.h>
#endif
#ifndef OPENSSL_NO_DSA
#include <openssl/dsa.h>
#endif
#ifndef OPENSSL_NO_DH
#include <openssl/dh.h>
#endif
#ifndef OPENSSL_NO_ECDH
#include <openssl/ecdh.h>
#endif
#ifndef OPENSSL_NO_ECDSA
#include <openssl/ecdsa.h>
#endif
#include <openssl/rand.h>
#include <openssl/ui.h>
#include <openssl/err.h>
#endif
#include <openssl/ossl_typ.h>
#include <openssl/symhacks.h>
#include <openssl/x509.h>
#ifdef __cplusplus
extern "C" {
#endif
/* These flags are used to control combinations of algorithm (methods)
* by bitwise "OR"ing. */
#define ENGINE_METHOD_RSA (unsigned int)0x0001
#define ENGINE_METHOD_DSA (unsigned int)0x0002
#define ENGINE_METHOD_DH (unsigned int)0x0004
#define ENGINE_METHOD_RAND (unsigned int)0x0008
#define ENGINE_METHOD_ECDH (unsigned int)0x0010
#define ENGINE_METHOD_ECDSA (unsigned int)0x0020
#define ENGINE_METHOD_CIPHERS (unsigned int)0x0040
#define ENGINE_METHOD_DIGESTS (unsigned int)0x0080
#define ENGINE_METHOD_STORE (unsigned int)0x0100
#define ENGINE_METHOD_PKEY_METHS (unsigned int)0x0200
#define ENGINE_METHOD_PKEY_ASN1_METHS (unsigned int)0x0400
/* Obvious all-or-nothing cases. */
#define ENGINE_METHOD_ALL (unsigned int)0xFFFF
#define ENGINE_METHOD_NONE (unsigned int)0x0000
/* This(ese) flag(s) controls behaviour of the ENGINE_TABLE mechanism used
* internally to control registration of ENGINE implementations, and can be set
* by ENGINE_set_table_flags(). The "NOINIT" flag prevents attempts to
* initialise registered ENGINEs if they are not already initialised. */
#define ENGINE_TABLE_FLAG_NOINIT (unsigned int)0x0001
/* ENGINE flags that can be set by ENGINE_set_flags(). */
/* #define ENGINE_FLAGS_MALLOCED 0x0001 */ /* Not used */
/* This flag is for ENGINEs that wish to handle the various 'CMD'-related
* control commands on their own. Without this flag, ENGINE_ctrl() handles these
* control commands on behalf of the ENGINE using their "cmd_defns" data. */
#define ENGINE_FLAGS_MANUAL_CMD_CTRL (int)0x0002
/* This flag is for ENGINEs who return new duplicate structures when found via
* "ENGINE_by_id()". When an ENGINE must store state (eg. if ENGINE_ctrl()
* commands are called in sequence as part of some stateful process like
* key-generation setup and execution), it can set this flag - then each attempt
* to obtain the ENGINE will result in it being copied into a new structure.
* Normally, ENGINEs don't declare this flag so ENGINE_by_id() just increments
* the existing ENGINE's structural reference count. */
#define ENGINE_FLAGS_BY_ID_COPY (int)0x0004
/* This flag if for an ENGINE that does not want its methods registered as
* part of ENGINE_register_all_complete() for example if the methods are
* not usable as default methods.
*/
#define ENGINE_FLAGS_NO_REGISTER_ALL (int)0x0008
/* ENGINEs can support their own command types, and these flags are used in
* ENGINE_CTRL_GET_CMD_FLAGS to indicate to the caller what kind of input each
* command expects. Currently only numeric and string input is supported. If a
* control command supports none of the _NUMERIC, _STRING, or _NO_INPUT options,
* then it is regarded as an "internal" control command - and not for use in
* config setting situations. As such, they're not available to the
* ENGINE_ctrl_cmd_string() function, only raw ENGINE_ctrl() access. Changes to
* this list of 'command types' should be reflected carefully in
* ENGINE_cmd_is_executable() and ENGINE_ctrl_cmd_string(). */
/* accepts a 'long' input value (3rd parameter to ENGINE_ctrl) */
#define ENGINE_CMD_FLAG_NUMERIC (unsigned int)0x0001
/* accepts string input (cast from 'void*' to 'const char *', 4th parameter to
* ENGINE_ctrl) */
#define ENGINE_CMD_FLAG_STRING (unsigned int)0x0002
/* Indicates that the control command takes *no* input. Ie. the control command
* is unparameterised. */
#define ENGINE_CMD_FLAG_NO_INPUT (unsigned int)0x0004
/* Indicates that the control command is internal. This control command won't
* be shown in any output, and is only usable through the ENGINE_ctrl_cmd()
* function. */
#define ENGINE_CMD_FLAG_INTERNAL (unsigned int)0x0008
/* NB: These 3 control commands are deprecated and should not be used. ENGINEs
* relying on these commands should compile conditional support for
* compatibility (eg. if these symbols are defined) but should also migrate the
* same functionality to their own ENGINE-specific control functions that can be
* "discovered" by calling applications. The fact these control commands
* wouldn't be "executable" (ie. usable by text-based config) doesn't change the
* fact that application code can find and use them without requiring per-ENGINE
* hacking. */
/* These flags are used to tell the ctrl function what should be done.
* All command numbers are shared between all engines, even if some don't
* make sense to some engines. In such a case, they do nothing but return
* the error ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED. */
#define ENGINE_CTRL_SET_LOGSTREAM 1
#define ENGINE_CTRL_SET_PASSWORD_CALLBACK 2
#define ENGINE_CTRL_HUP 3 /* Close and reinitialise any
handles/connections etc. */
#define ENGINE_CTRL_SET_USER_INTERFACE 4 /* Alternative to callback */
#define ENGINE_CTRL_SET_CALLBACK_DATA 5 /* User-specific data, used
when calling the password
callback and the user
interface */
#define ENGINE_CTRL_LOAD_CONFIGURATION 6 /* Load a configuration, given
a string that represents a
file name or so */
#define ENGINE_CTRL_LOAD_SECTION 7 /* Load data from a given
section in the already loaded
configuration */
/* These control commands allow an application to deal with an arbitrary engine
* in a dynamic way. Warn: Negative return values indicate errors FOR THESE
* COMMANDS because zero is used to indicate 'end-of-list'. Other commands,
* including ENGINE-specific command types, return zero for an error.
*
* An ENGINE can choose to implement these ctrl functions, and can internally
* manage things however it chooses - it does so by setting the
* ENGINE_FLAGS_MANUAL_CMD_CTRL flag (using ENGINE_set_flags()). Otherwise the
* ENGINE_ctrl() code handles this on the ENGINE's behalf using the cmd_defns
* data (set using ENGINE_set_cmd_defns()). This means an ENGINE's ctrl()
* handler need only implement its own commands - the above "meta" commands will
* be taken care of. */
/* Returns non-zero if the supplied ENGINE has a ctrl() handler. If "not", then
* all the remaining control commands will return failure, so it is worth
* checking this first if the caller is trying to "discover" the engine's
* capabilities and doesn't want errors generated unnecessarily. */
#define ENGINE_CTRL_HAS_CTRL_FUNCTION 10
/* Returns a positive command number for the first command supported by the
* engine. Returns zero if no ctrl commands are supported. */
#define ENGINE_CTRL_GET_FIRST_CMD_TYPE 11
/* The 'long' argument specifies a command implemented by the engine, and the
* return value is the next command supported, or zero if there are no more. */
#define ENGINE_CTRL_GET_NEXT_CMD_TYPE 12
/* The 'void*' argument is a command name (cast from 'const char *'), and the
* return value is the command that corresponds to it. */
#define ENGINE_CTRL_GET_CMD_FROM_NAME 13
/* The next two allow a command to be converted into its corresponding string
* form. In each case, the 'long' argument supplies the command. In the NAME_LEN
* case, the return value is the length of the command name (not counting a
* trailing EOL). In the NAME case, the 'void*' argument must be a string buffer
* large enough, and it will be populated with the name of the command (WITH a
* trailing EOL). */
#define ENGINE_CTRL_GET_NAME_LEN_FROM_CMD 14
#define ENGINE_CTRL_GET_NAME_FROM_CMD 15
/* The next two are similar but give a "short description" of a command. */
#define ENGINE_CTRL_GET_DESC_LEN_FROM_CMD 16
#define ENGINE_CTRL_GET_DESC_FROM_CMD 17
/* With this command, the return value is the OR'd combination of
* ENGINE_CMD_FLAG_*** values that indicate what kind of input a given
* engine-specific ctrl command expects. */
#define ENGINE_CTRL_GET_CMD_FLAGS 18
/* ENGINE implementations should start the numbering of their own control
* commands from this value. (ie. ENGINE_CMD_BASE, ENGINE_CMD_BASE + 1, etc). */
#define ENGINE_CMD_BASE 200
/* NB: These 2 nCipher "chil" control commands are deprecated, and their
* functionality is now available through ENGINE-specific control commands
* (exposed through the above-mentioned 'CMD'-handling). Code using these 2
* commands should be migrated to the more general command handling before these
* are removed. */
/* Flags specific to the nCipher "chil" engine */
#define ENGINE_CTRL_CHIL_SET_FORKCHECK 100
/* Depending on the value of the (long)i argument, this sets or
* unsets the SimpleForkCheck flag in the CHIL API to enable or
* disable checking and workarounds for applications that fork().
*/
#define ENGINE_CTRL_CHIL_NO_LOCKING 101
/* This prevents the initialisation function from providing mutex
* callbacks to the nCipher library. */
/* If an ENGINE supports its own specific control commands and wishes the
* framework to handle the above 'ENGINE_CMD_***'-manipulation commands on its
* behalf, it should supply a null-terminated array of ENGINE_CMD_DEFN entries
* to ENGINE_set_cmd_defns(). It should also implement a ctrl() handler that
* supports the stated commands (ie. the "cmd_num" entries as described by the
* array). NB: The array must be ordered in increasing order of cmd_num.
* "null-terminated" means that the last ENGINE_CMD_DEFN element has cmd_num set
* to zero and/or cmd_name set to NULL. */
typedef struct ENGINE_CMD_DEFN_st
{
unsigned int cmd_num; /* The command number */
const char *cmd_name; /* The command name itself */
const char *cmd_desc; /* A short description of the command */
unsigned int cmd_flags; /* The input the command expects */
} ENGINE_CMD_DEFN;
/* Generic function pointer */
typedef int (*ENGINE_GEN_FUNC_PTR)(void);
/* Generic function pointer taking no arguments */
typedef int (*ENGINE_GEN_INT_FUNC_PTR)(ENGINE *);
/* Specific control function pointer */
typedef int (*ENGINE_CTRL_FUNC_PTR)(ENGINE *, int, long, void *, void (*f)(void));
/* Generic load_key function pointer */
typedef EVP_PKEY * (*ENGINE_LOAD_KEY_PTR)(ENGINE *, const char *,
UI_METHOD *ui_method, void *callback_data);
typedef int (*ENGINE_SSL_CLIENT_CERT_PTR)(ENGINE *, SSL *ssl,
STACK_OF(X509_NAME) *ca_dn, X509 **pcert, EVP_PKEY **pkey,
STACK_OF(X509) **pother, UI_METHOD *ui_method, void *callback_data);
/* These callback types are for an ENGINE's handler for cipher and digest logic.
* These handlers have these prototypes;
* int foo(ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid);
* int foo(ENGINE *e, const EVP_MD **digest, const int **nids, int nid);
* Looking at how to implement these handlers in the case of cipher support, if
* the framework wants the EVP_CIPHER for 'nid', it will call;
* foo(e, &p_evp_cipher, NULL, nid); (return zero for failure)
* If the framework wants a list of supported 'nid's, it will call;
* foo(e, NULL, &p_nids, 0); (returns number of 'nids' or -1 for error)
*/
/* Returns to a pointer to the array of supported cipher 'nid's. If the second
* parameter is non-NULL it is set to the size of the returned array. */
typedef int (*ENGINE_CIPHERS_PTR)(ENGINE *, const EVP_CIPHER **, const int **, int);
typedef int (*ENGINE_DIGESTS_PTR)(ENGINE *, const EVP_MD **, const int **, int);
typedef int (*ENGINE_PKEY_METHS_PTR)(ENGINE *, EVP_PKEY_METHOD **, const int **, int);
typedef int (*ENGINE_PKEY_ASN1_METHS_PTR)(ENGINE *, EVP_PKEY_ASN1_METHOD **, const int **, int);
/* STRUCTURE functions ... all of these functions deal with pointers to ENGINE
* structures where the pointers have a "structural reference". This means that
* their reference is to allowed access to the structure but it does not imply
* that the structure is functional. To simply increment or decrement the
* structural reference count, use ENGINE_by_id and ENGINE_free. NB: This is not
* required when iterating using ENGINE_get_next as it will automatically
* decrement the structural reference count of the "current" ENGINE and
* increment the structural reference count of the ENGINE it returns (unless it
* is NULL). */
/* Get the first/last "ENGINE" type available. */
ENGINE *ENGINE_get_first(void);
ENGINE *ENGINE_get_last(void);
/* Iterate to the next/previous "ENGINE" type (NULL = end of the list). */
ENGINE *ENGINE_get_next(ENGINE *e);
ENGINE *ENGINE_get_prev(ENGINE *e);
/* Add another "ENGINE" type into the array. */
int ENGINE_add(ENGINE *e);
/* Remove an existing "ENGINE" type from the array. */
int ENGINE_remove(ENGINE *e);
/* Retrieve an engine from the list by its unique "id" value. */
ENGINE *ENGINE_by_id(const char *id);
/* Add all the built-in engines. */
void ENGINE_load_openssl(void);
void ENGINE_load_dynamic(void);
#ifndef OPENSSL_NO_STATIC_ENGINE
void ENGINE_load_4758cca(void);
void ENGINE_load_aep(void);
void ENGINE_load_atalla(void);
void ENGINE_load_chil(void);
void ENGINE_load_cswift(void);
void ENGINE_load_nuron(void);
void ENGINE_load_sureware(void);
void ENGINE_load_ubsec(void);
void ENGINE_load_padlock(void);
void ENGINE_load_capi(void);
#ifndef OPENSSL_NO_GMP
void ENGINE_load_gmp(void);
#endif
#ifndef OPENSSL_NO_GOST
void ENGINE_load_gost(void);
#endif
#endif
void ENGINE_load_cryptodev(void);
void ENGINE_load_rsax(void);
void ENGINE_load_rdrand(void);
void ENGINE_load_builtin_engines(void);
/* Get and set global flags (ENGINE_TABLE_FLAG_***) for the implementation
* "registry" handling. */
unsigned int ENGINE_get_table_flags(void);
void ENGINE_set_table_flags(unsigned int flags);
/* Manage registration of ENGINEs per "table". For each type, there are 3
* functions;
* ENGINE_register_***(e) - registers the implementation from 'e' (if it has one)
* ENGINE_unregister_***(e) - unregister the implementation from 'e'
* ENGINE_register_all_***() - call ENGINE_register_***() for each 'e' in the list
* Cleanup is automatically registered from each table when required, so
* ENGINE_cleanup() will reverse any "register" operations. */
int ENGINE_register_RSA(ENGINE *e);
void ENGINE_unregister_RSA(ENGINE *e);
void ENGINE_register_all_RSA(void);
int ENGINE_register_DSA(ENGINE *e);
void ENGINE_unregister_DSA(ENGINE *e);
void ENGINE_register_all_DSA(void);
int ENGINE_register_ECDH(ENGINE *e);
void ENGINE_unregister_ECDH(ENGINE *e);
void ENGINE_register_all_ECDH(void);
int ENGINE_register_ECDSA(ENGINE *e);
void ENGINE_unregister_ECDSA(ENGINE *e);
void ENGINE_register_all_ECDSA(void);
int ENGINE_register_DH(ENGINE *e);
void ENGINE_unregister_DH(ENGINE *e);
void ENGINE_register_all_DH(void);
int ENGINE_register_RAND(ENGINE *e);
void ENGINE_unregister_RAND(ENGINE *e);
void ENGINE_register_all_RAND(void);
int ENGINE_register_STORE(ENGINE *e);
void ENGINE_unregister_STORE(ENGINE *e);
void ENGINE_register_all_STORE(void);
int ENGINE_register_ciphers(ENGINE *e);
void ENGINE_unregister_ciphers(ENGINE *e);
void ENGINE_register_all_ciphers(void);
int ENGINE_register_digests(ENGINE *e);
void ENGINE_unregister_digests(ENGINE *e);
void ENGINE_register_all_digests(void);
int ENGINE_register_pkey_meths(ENGINE *e);
void ENGINE_unregister_pkey_meths(ENGINE *e);
void ENGINE_register_all_pkey_meths(void);
int ENGINE_register_pkey_asn1_meths(ENGINE *e);
void ENGINE_unregister_pkey_asn1_meths(ENGINE *e);
void ENGINE_register_all_pkey_asn1_meths(void);
/* These functions register all support from the above categories. Note, use of
* these functions can result in static linkage of code your application may not
* need. If you only need a subset of functionality, consider using more
* selective initialisation. */
int ENGINE_register_complete(ENGINE *e);
int ENGINE_register_all_complete(void);
/* Send parametrised control commands to the engine. The possibilities to send
* down an integer, a pointer to data or a function pointer are provided. Any of
* the parameters may or may not be NULL, depending on the command number. In
* actuality, this function only requires a structural (rather than functional)
* reference to an engine, but many control commands may require the engine be
* functional. The caller should be aware of trying commands that require an
* operational ENGINE, and only use functional references in such situations. */
int ENGINE_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void));
/* This function tests if an ENGINE-specific command is usable as a "setting".
* Eg. in an application's config file that gets processed through
* ENGINE_ctrl_cmd_string(). If this returns zero, it is not available to
* ENGINE_ctrl_cmd_string(), only ENGINE_ctrl(). */
int ENGINE_cmd_is_executable(ENGINE *e, int cmd);
/* This function works like ENGINE_ctrl() with the exception of taking a
* command name instead of a command number, and can handle optional commands.
* See the comment on ENGINE_ctrl_cmd_string() for an explanation on how to
* use the cmd_name and cmd_optional. */
int ENGINE_ctrl_cmd(ENGINE *e, const char *cmd_name,
long i, void *p, void (*f)(void), int cmd_optional);
/* This function passes a command-name and argument to an ENGINE. The cmd_name
* is converted to a command number and the control command is called using
* 'arg' as an argument (unless the ENGINE doesn't support such a command, in
* which case no control command is called). The command is checked for input
* flags, and if necessary the argument will be converted to a numeric value. If
* cmd_optional is non-zero, then if the ENGINE doesn't support the given
* cmd_name the return value will be success anyway. This function is intended
* for applications to use so that users (or config files) can supply
* engine-specific config data to the ENGINE at run-time to control behaviour of
* specific engines. As such, it shouldn't be used for calling ENGINE_ctrl()
* functions that return data, deal with binary data, or that are otherwise
* supposed to be used directly through ENGINE_ctrl() in application code. Any
* "return" data from an ENGINE_ctrl() operation in this function will be lost -
* the return value is interpreted as failure if the return value is zero,
* success otherwise, and this function returns a boolean value as a result. In
* other words, vendors of 'ENGINE'-enabled devices should write ENGINE
* implementations with parameterisations that work in this scheme, so that
* compliant ENGINE-based applications can work consistently with the same
* configuration for the same ENGINE-enabled devices, across applications. */
int ENGINE_ctrl_cmd_string(ENGINE *e, const char *cmd_name, const char *arg,
int cmd_optional);
/* These functions are useful for manufacturing new ENGINE structures. They
* don't address reference counting at all - one uses them to populate an ENGINE
* structure with personalised implementations of things prior to using it
* directly or adding it to the builtin ENGINE list in OpenSSL. These are also
* here so that the ENGINE structure doesn't have to be exposed and break binary
* compatibility! */
ENGINE *ENGINE_new(void);
int ENGINE_free(ENGINE *e);
int ENGINE_up_ref(ENGINE *e);
int ENGINE_set_id(ENGINE *e, const char *id);
int ENGINE_set_name(ENGINE *e, const char *name);
int ENGINE_set_RSA(ENGINE *e, const RSA_METHOD *rsa_meth);
int ENGINE_set_DSA(ENGINE *e, const DSA_METHOD *dsa_meth);
int ENGINE_set_ECDH(ENGINE *e, const ECDH_METHOD *ecdh_meth);
int ENGINE_set_ECDSA(ENGINE *e, const ECDSA_METHOD *ecdsa_meth);
int ENGINE_set_DH(ENGINE *e, const DH_METHOD *dh_meth);
int ENGINE_set_RAND(ENGINE *e, const RAND_METHOD *rand_meth);
int ENGINE_set_STORE(ENGINE *e, const STORE_METHOD *store_meth);
int ENGINE_set_destroy_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR destroy_f);
int ENGINE_set_init_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR init_f);
int ENGINE_set_finish_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR finish_f);
int ENGINE_set_ctrl_function(ENGINE *e, ENGINE_CTRL_FUNC_PTR ctrl_f);
int ENGINE_set_load_privkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpriv_f);
int ENGINE_set_load_pubkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpub_f);
int ENGINE_set_load_ssl_client_cert_function(ENGINE *e,
ENGINE_SSL_CLIENT_CERT_PTR loadssl_f);
int ENGINE_set_ciphers(ENGINE *e, ENGINE_CIPHERS_PTR f);
int ENGINE_set_digests(ENGINE *e, ENGINE_DIGESTS_PTR f);
int ENGINE_set_pkey_meths(ENGINE *e, ENGINE_PKEY_METHS_PTR f);
int ENGINE_set_pkey_asn1_meths(ENGINE *e, ENGINE_PKEY_ASN1_METHS_PTR f);
int ENGINE_set_flags(ENGINE *e, int flags);
int ENGINE_set_cmd_defns(ENGINE *e, const ENGINE_CMD_DEFN *defns);
/* These functions allow control over any per-structure ENGINE data. */
int ENGINE_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
int ENGINE_set_ex_data(ENGINE *e, int idx, void *arg);
void *ENGINE_get_ex_data(const ENGINE *e, int idx);
/* This function cleans up anything that needs it. Eg. the ENGINE_add() function
* automatically ensures the list cleanup function is registered to be called
* from ENGINE_cleanup(). Similarly, all ENGINE_register_*** functions ensure
* ENGINE_cleanup() will clean up after them. */
void ENGINE_cleanup(void);
/* These return values from within the ENGINE structure. These can be useful
* with functional references as well as structural references - it depends
* which you obtained. Using the result for functional purposes if you only
* obtained a structural reference may be problematic! */
const char *ENGINE_get_id(const ENGINE *e);
const char *ENGINE_get_name(const ENGINE *e);
const RSA_METHOD *ENGINE_get_RSA(const ENGINE *e);
const DSA_METHOD *ENGINE_get_DSA(const ENGINE *e);
const ECDH_METHOD *ENGINE_get_ECDH(const ENGINE *e);
const ECDSA_METHOD *ENGINE_get_ECDSA(const ENGINE *e);
const DH_METHOD *ENGINE_get_DH(const ENGINE *e);
const RAND_METHOD *ENGINE_get_RAND(const ENGINE *e);
const STORE_METHOD *ENGINE_get_STORE(const ENGINE *e);
ENGINE_GEN_INT_FUNC_PTR ENGINE_get_destroy_function(const ENGINE *e);
ENGINE_GEN_INT_FUNC_PTR ENGINE_get_init_function(const ENGINE *e);
ENGINE_GEN_INT_FUNC_PTR ENGINE_get_finish_function(const ENGINE *e);
ENGINE_CTRL_FUNC_PTR ENGINE_get_ctrl_function(const ENGINE *e);
ENGINE_LOAD_KEY_PTR ENGINE_get_load_privkey_function(const ENGINE *e);
ENGINE_LOAD_KEY_PTR ENGINE_get_load_pubkey_function(const ENGINE *e);
ENGINE_SSL_CLIENT_CERT_PTR ENGINE_get_ssl_client_cert_function(const ENGINE *e);
ENGINE_CIPHERS_PTR ENGINE_get_ciphers(const ENGINE *e);
ENGINE_DIGESTS_PTR ENGINE_get_digests(const ENGINE *e);
ENGINE_PKEY_METHS_PTR ENGINE_get_pkey_meths(const ENGINE *e);
ENGINE_PKEY_ASN1_METHS_PTR ENGINE_get_pkey_asn1_meths(const ENGINE *e);
const EVP_CIPHER *ENGINE_get_cipher(ENGINE *e, int nid);
const EVP_MD *ENGINE_get_digest(ENGINE *e, int nid);
const EVP_PKEY_METHOD *ENGINE_get_pkey_meth(ENGINE *e, int nid);
const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth(ENGINE *e, int nid);
const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth_str(ENGINE *e,
const char *str, int len);
const EVP_PKEY_ASN1_METHOD *ENGINE_pkey_asn1_find_str(ENGINE **pe,
const char *str, int len);
const ENGINE_CMD_DEFN *ENGINE_get_cmd_defns(const ENGINE *e);
int ENGINE_get_flags(const ENGINE *e);
/* FUNCTIONAL functions. These functions deal with ENGINE structures
* that have (or will) be initialised for use. Broadly speaking, the
* structural functions are useful for iterating the list of available
* engine types, creating new engine types, and other "list" operations.
* These functions actually deal with ENGINEs that are to be used. As
* such these functions can fail (if applicable) when particular
* engines are unavailable - eg. if a hardware accelerator is not
* attached or not functioning correctly. Each ENGINE has 2 reference
* counts; structural and functional. Every time a functional reference
* is obtained or released, a corresponding structural reference is
* automatically obtained or released too. */
/* Initialise a engine type for use (or up its reference count if it's
* already in use). This will fail if the engine is not currently
* operational and cannot initialise. */
int ENGINE_init(ENGINE *e);
/* Free a functional reference to a engine type. This does not require
* a corresponding call to ENGINE_free as it also releases a structural
* reference. */
int ENGINE_finish(ENGINE *e);
/* The following functions handle keys that are stored in some secondary
* location, handled by the engine. The storage may be on a card or
* whatever. */
EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id,
UI_METHOD *ui_method, void *callback_data);
EVP_PKEY *ENGINE_load_public_key(ENGINE *e, const char *key_id,
UI_METHOD *ui_method, void *callback_data);
int ENGINE_load_ssl_client_cert(ENGINE *e, SSL *s,
STACK_OF(X509_NAME) *ca_dn, X509 **pcert, EVP_PKEY **ppkey,
STACK_OF(X509) **pother,
UI_METHOD *ui_method, void *callback_data);
/* This returns a pointer for the current ENGINE structure that
* is (by default) performing any RSA operations. The value returned
* is an incremented reference, so it should be free'd (ENGINE_finish)
* before it is discarded. */
ENGINE *ENGINE_get_default_RSA(void);
/* Same for the other "methods" */
ENGINE *ENGINE_get_default_DSA(void);
ENGINE *ENGINE_get_default_ECDH(void);
ENGINE *ENGINE_get_default_ECDSA(void);
ENGINE *ENGINE_get_default_DH(void);
ENGINE *ENGINE_get_default_RAND(void);
/* These functions can be used to get a functional reference to perform
* ciphering or digesting corresponding to "nid". */
ENGINE *ENGINE_get_cipher_engine(int nid);
ENGINE *ENGINE_get_digest_engine(int nid);
ENGINE *ENGINE_get_pkey_meth_engine(int nid);
ENGINE *ENGINE_get_pkey_asn1_meth_engine(int nid);
/* This sets a new default ENGINE structure for performing RSA
* operations. If the result is non-zero (success) then the ENGINE
* structure will have had its reference count up'd so the caller
* should still free their own reference 'e'. */
int ENGINE_set_default_RSA(ENGINE *e);
int ENGINE_set_default_string(ENGINE *e, const char *def_list);
/* Same for the other "methods" */
int ENGINE_set_default_DSA(ENGINE *e);
int ENGINE_set_default_ECDH(ENGINE *e);
int ENGINE_set_default_ECDSA(ENGINE *e);
int ENGINE_set_default_DH(ENGINE *e);
int ENGINE_set_default_RAND(ENGINE *e);
int ENGINE_set_default_ciphers(ENGINE *e);
int ENGINE_set_default_digests(ENGINE *e);
int ENGINE_set_default_pkey_meths(ENGINE *e);
int ENGINE_set_default_pkey_asn1_meths(ENGINE *e);
/* The combination "set" - the flags are bitwise "OR"d from the
* ENGINE_METHOD_*** defines above. As with the "ENGINE_register_complete()"
* function, this function can result in unnecessary static linkage. If your
* application requires only specific functionality, consider using more
* selective functions. */
int ENGINE_set_default(ENGINE *e, unsigned int flags);
void ENGINE_add_conf_module(void);
/* Deprecated functions ... */
/* int ENGINE_clear_defaults(void); */
/**************************/
/* DYNAMIC ENGINE SUPPORT */
/**************************/
/* Binary/behaviour compatibility levels */
#define OSSL_DYNAMIC_VERSION (unsigned long)0x00020000
/* Binary versions older than this are too old for us (whether we're a loader or
* a loadee) */
#define OSSL_DYNAMIC_OLDEST (unsigned long)0x00020000
/* When compiling an ENGINE entirely as an external shared library, loadable by
* the "dynamic" ENGINE, these types are needed. The 'dynamic_fns' structure
* type provides the calling application's (or library's) error functionality
* and memory management function pointers to the loaded library. These should
* be used/set in the loaded library code so that the loading application's
* 'state' will be used/changed in all operations. The 'static_state' pointer
* allows the loaded library to know if it shares the same static data as the
* calling application (or library), and thus whether these callbacks need to be
* set or not. */
typedef void *(*dyn_MEM_malloc_cb)(size_t);
typedef void *(*dyn_MEM_realloc_cb)(void *, size_t);
typedef void (*dyn_MEM_free_cb)(void *);
typedef struct st_dynamic_MEM_fns {
dyn_MEM_malloc_cb malloc_cb;
dyn_MEM_realloc_cb realloc_cb;
dyn_MEM_free_cb free_cb;
} dynamic_MEM_fns;
/* FIXME: Perhaps the memory and locking code (crypto.h) should declare and use
* these types so we (and any other dependant code) can simplify a bit?? */
typedef void (*dyn_lock_locking_cb)(int,int,const char *,int);
typedef int (*dyn_lock_add_lock_cb)(int*,int,int,const char *,int);
typedef struct CRYPTO_dynlock_value *(*dyn_dynlock_create_cb)(
const char *,int);
typedef void (*dyn_dynlock_lock_cb)(int,struct CRYPTO_dynlock_value *,
const char *,int);
typedef void (*dyn_dynlock_destroy_cb)(struct CRYPTO_dynlock_value *,
const char *,int);
typedef struct st_dynamic_LOCK_fns {
dyn_lock_locking_cb lock_locking_cb;
dyn_lock_add_lock_cb lock_add_lock_cb;
dyn_dynlock_create_cb dynlock_create_cb;
dyn_dynlock_lock_cb dynlock_lock_cb;
dyn_dynlock_destroy_cb dynlock_destroy_cb;
} dynamic_LOCK_fns;
/* The top-level structure */
typedef struct st_dynamic_fns {
void *static_state;
const ERR_FNS *err_fns;
const CRYPTO_EX_DATA_IMPL *ex_data_fns;
dynamic_MEM_fns mem_fns;
dynamic_LOCK_fns lock_fns;
} dynamic_fns;
/* The version checking function should be of this prototype. NB: The
* ossl_version value passed in is the OSSL_DYNAMIC_VERSION of the loading code.
* If this function returns zero, it indicates a (potential) version
* incompatibility and the loaded library doesn't believe it can proceed.
* Otherwise, the returned value is the (latest) version supported by the
* loading library. The loader may still decide that the loaded code's version
* is unsatisfactory and could veto the load. The function is expected to
* be implemented with the symbol name "v_check", and a default implementation
* can be fully instantiated with IMPLEMENT_DYNAMIC_CHECK_FN(). */
typedef unsigned long (*dynamic_v_check_fn)(unsigned long ossl_version);
#define IMPLEMENT_DYNAMIC_CHECK_FN() \
OPENSSL_EXPORT unsigned long v_check(unsigned long v); \
OPENSSL_EXPORT unsigned long v_check(unsigned long v) { \
if(v >= OSSL_DYNAMIC_OLDEST) return OSSL_DYNAMIC_VERSION; \
return 0; }
/* This function is passed the ENGINE structure to initialise with its own
* function and command settings. It should not adjust the structural or
* functional reference counts. If this function returns zero, (a) the load will
* be aborted, (b) the previous ENGINE state will be memcpy'd back onto the
* structure, and (c) the shared library will be unloaded. So implementations
* should do their own internal cleanup in failure circumstances otherwise they
* could leak. The 'id' parameter, if non-NULL, represents the ENGINE id that
* the loader is looking for. If this is NULL, the shared library can choose to
* return failure or to initialise a 'default' ENGINE. If non-NULL, the shared
* library must initialise only an ENGINE matching the passed 'id'. The function
* is expected to be implemented with the symbol name "bind_engine". A standard
* implementation can be instantiated with IMPLEMENT_DYNAMIC_BIND_FN(fn) where
* the parameter 'fn' is a callback function that populates the ENGINE structure
* and returns an int value (zero for failure). 'fn' should have prototype;
* [static] int fn(ENGINE *e, const char *id); */
typedef int (*dynamic_bind_engine)(ENGINE *e, const char *id,
const dynamic_fns *fns);
#define IMPLEMENT_DYNAMIC_BIND_FN(fn) \
OPENSSL_EXPORT \
int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns); \
OPENSSL_EXPORT \
int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns) { \
if(ENGINE_get_static_state() == fns->static_state) goto skip_cbs; \
if(!CRYPTO_set_mem_functions(fns->mem_fns.malloc_cb, \
fns->mem_fns.realloc_cb, fns->mem_fns.free_cb)) \
return 0; \
CRYPTO_set_locking_callback(fns->lock_fns.lock_locking_cb); \
CRYPTO_set_add_lock_callback(fns->lock_fns.lock_add_lock_cb); \
CRYPTO_set_dynlock_create_callback(fns->lock_fns.dynlock_create_cb); \
CRYPTO_set_dynlock_lock_callback(fns->lock_fns.dynlock_lock_cb); \
CRYPTO_set_dynlock_destroy_callback(fns->lock_fns.dynlock_destroy_cb); \
if(!CRYPTO_set_ex_data_implementation(fns->ex_data_fns)) \
return 0; \
if(!ERR_set_implementation(fns->err_fns)) return 0; \
skip_cbs: \
if(!fn(e,id)) return 0; \
return 1; }
/* If the loading application (or library) and the loaded ENGINE library share
* the same static data (eg. they're both dynamically linked to the same
* libcrypto.so) we need a way to avoid trying to set system callbacks - this
* would fail, and for the same reason that it's unnecessary to try. If the
* loaded ENGINE has (or gets from through the loader) its own copy of the
* libcrypto static data, we will need to set the callbacks. The easiest way to
* detect this is to have a function that returns a pointer to some static data
* and let the loading application and loaded ENGINE compare their respective
* values. */
void *ENGINE_get_static_state(void);
#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV)
void ENGINE_setup_bsd_cryptodev(void);
#endif
/* BEGIN ERROR CODES */
/* The following lines are auto generated by the script mkerr.pl. Any changes
* made after this point may be overwritten when the script is next run.
*/
void ERR_load_ENGINE_strings(void);
/* Error codes for the ENGINE functions. */
/* Function codes. */
#define ENGINE_F_DYNAMIC_CTRL 180
#define ENGINE_F_DYNAMIC_GET_DATA_CTX 181
#define ENGINE_F_DYNAMIC_LOAD 182
#define ENGINE_F_DYNAMIC_SET_DATA_CTX 183
#define ENGINE_F_ENGINE_ADD 105
#define ENGINE_F_ENGINE_BY_ID 106
#define ENGINE_F_ENGINE_CMD_IS_EXECUTABLE 170
#define ENGINE_F_ENGINE_CTRL 142
#define ENGINE_F_ENGINE_CTRL_CMD 178
#define ENGINE_F_ENGINE_CTRL_CMD_STRING 171
#define ENGINE_F_ENGINE_FINISH 107
#define ENGINE_F_ENGINE_FREE_UTIL 108
#define ENGINE_F_ENGINE_GET_CIPHER 185
#define ENGINE_F_ENGINE_GET_DEFAULT_TYPE 177
#define ENGINE_F_ENGINE_GET_DIGEST 186
#define ENGINE_F_ENGINE_GET_NEXT 115
#define ENGINE_F_ENGINE_GET_PKEY_ASN1_METH 193
#define ENGINE_F_ENGINE_GET_PKEY_METH 192
#define ENGINE_F_ENGINE_GET_PREV 116
#define ENGINE_F_ENGINE_INIT 119
#define ENGINE_F_ENGINE_LIST_ADD 120
#define ENGINE_F_ENGINE_LIST_REMOVE 121
#define ENGINE_F_ENGINE_LOAD_PRIVATE_KEY 150
#define ENGINE_F_ENGINE_LOAD_PUBLIC_KEY 151
#define ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT 194
#define ENGINE_F_ENGINE_NEW 122
#define ENGINE_F_ENGINE_REMOVE 123
#define ENGINE_F_ENGINE_SET_DEFAULT_STRING 189
#define ENGINE_F_ENGINE_SET_DEFAULT_TYPE 126
#define ENGINE_F_ENGINE_SET_ID 129
#define ENGINE_F_ENGINE_SET_NAME 130
#define ENGINE_F_ENGINE_TABLE_REGISTER 184
#define ENGINE_F_ENGINE_UNLOAD_KEY 152
#define ENGINE_F_ENGINE_UNLOCKED_FINISH 191
#define ENGINE_F_ENGINE_UP_REF 190
#define ENGINE_F_INT_CTRL_HELPER 172
#define ENGINE_F_INT_ENGINE_CONFIGURE 188
#define ENGINE_F_INT_ENGINE_MODULE_INIT 187
#define ENGINE_F_LOG_MESSAGE 141
/* Reason codes. */
#define ENGINE_R_ALREADY_LOADED 100
#define ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER 133
#define ENGINE_R_CMD_NOT_EXECUTABLE 134
#define ENGINE_R_COMMAND_TAKES_INPUT 135
#define ENGINE_R_COMMAND_TAKES_NO_INPUT 136
#define ENGINE_R_CONFLICTING_ENGINE_ID 103
#define ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED 119
#define ENGINE_R_DH_NOT_IMPLEMENTED 139
#define ENGINE_R_DSA_NOT_IMPLEMENTED 140
#define ENGINE_R_DSO_FAILURE 104
#define ENGINE_R_DSO_NOT_FOUND 132
#define ENGINE_R_ENGINES_SECTION_ERROR 148
#define ENGINE_R_ENGINE_CONFIGURATION_ERROR 102
#define ENGINE_R_ENGINE_IS_NOT_IN_LIST 105
#define ENGINE_R_ENGINE_SECTION_ERROR 149
#define ENGINE_R_FAILED_LOADING_PRIVATE_KEY 128
#define ENGINE_R_FAILED_LOADING_PUBLIC_KEY 129
#define ENGINE_R_FINISH_FAILED 106
#define ENGINE_R_GET_HANDLE_FAILED 107
#define ENGINE_R_ID_OR_NAME_MISSING 108
#define ENGINE_R_INIT_FAILED 109
#define ENGINE_R_INTERNAL_LIST_ERROR 110
#define ENGINE_R_INVALID_ARGUMENT 143
#define ENGINE_R_INVALID_CMD_NAME 137
#define ENGINE_R_INVALID_CMD_NUMBER 138
#define ENGINE_R_INVALID_INIT_VALUE 151
#define ENGINE_R_INVALID_STRING 150
#define ENGINE_R_NOT_INITIALISED 117
#define ENGINE_R_NOT_LOADED 112
#define ENGINE_R_NO_CONTROL_FUNCTION 120
#define ENGINE_R_NO_INDEX 144
#define ENGINE_R_NO_LOAD_FUNCTION 125
#define ENGINE_R_NO_REFERENCE 130
#define ENGINE_R_NO_SUCH_ENGINE 116
#define ENGINE_R_NO_UNLOAD_FUNCTION 126
#define ENGINE_R_PROVIDE_PARAMETERS 113
#define ENGINE_R_RSA_NOT_IMPLEMENTED 141
#define ENGINE_R_UNIMPLEMENTED_CIPHER 146
#define ENGINE_R_UNIMPLEMENTED_DIGEST 147
#define ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD 101
#define ENGINE_R_VERSION_INCOMPATIBILITY 145
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,283 @@
/* crypto/engine/enginetest.c */
/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
* project 2000.
*/
/* ====================================================================
* Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include <stdio.h>
#include <string.h>
#include <openssl/e_os2.h>
#ifdef OPENSSL_NO_ENGINE
int main(int argc, char *argv[])
{
printf("No ENGINE support\n");
return(0);
}
#else
#include <openssl/buffer.h>
#include <openssl/crypto.h>
#include <openssl/engine.h>
#include <openssl/err.h>
static void display_engine_list(void)
{
ENGINE *h;
int loop;
h = ENGINE_get_first();
loop = 0;
printf("listing available engine types\n");
while(h)
{
printf("engine %i, id = \"%s\", name = \"%s\"\n",
loop++, ENGINE_get_id(h), ENGINE_get_name(h));
h = ENGINE_get_next(h);
}
printf("end of list\n");
/* ENGINE_get_first() increases the struct_ref counter, so we
must call ENGINE_free() to decrease it again */
ENGINE_free(h);
}
int main(int argc, char *argv[])
{
ENGINE *block[512];
char buf[256];
const char *id, *name;
ENGINE *ptr;
int loop;
int to_return = 1;
ENGINE *new_h1 = NULL;
ENGINE *new_h2 = NULL;
ENGINE *new_h3 = NULL;
ENGINE *new_h4 = NULL;
/* enable memory leak checking unless explicitly disabled */
if (!((getenv("OPENSSL_DEBUG_MEMORY") != NULL) && (0 == strcmp(getenv("OPENSSL_DEBUG_MEMORY"), "off"))))
{
CRYPTO_malloc_debug_init();
CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL);
}
else
{
/* OPENSSL_DEBUG_MEMORY=off */
CRYPTO_set_mem_debug_functions(0, 0, 0, 0, 0);
}
CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
ERR_load_crypto_strings();
memset(block, 0, 512 * sizeof(ENGINE *));
if(((new_h1 = ENGINE_new()) == NULL) ||
!ENGINE_set_id(new_h1, "test_id0") ||
!ENGINE_set_name(new_h1, "First test item") ||
((new_h2 = ENGINE_new()) == NULL) ||
!ENGINE_set_id(new_h2, "test_id1") ||
!ENGINE_set_name(new_h2, "Second test item") ||
((new_h3 = ENGINE_new()) == NULL) ||
!ENGINE_set_id(new_h3, "test_id2") ||
!ENGINE_set_name(new_h3, "Third test item") ||
((new_h4 = ENGINE_new()) == NULL) ||
!ENGINE_set_id(new_h4, "test_id3") ||
!ENGINE_set_name(new_h4, "Fourth test item"))
{
printf("Couldn't set up test ENGINE structures\n");
goto end;
}
printf("\nenginetest beginning\n\n");
display_engine_list();
if(!ENGINE_add(new_h1))
{
printf("Add failed!\n");
goto end;
}
display_engine_list();
ptr = ENGINE_get_first();
if(!ENGINE_remove(ptr))
{
printf("Remove failed!\n");
goto end;
}
if (ptr)
ENGINE_free(ptr);
display_engine_list();
if(!ENGINE_add(new_h3) || !ENGINE_add(new_h2))
{
printf("Add failed!\n");
goto end;
}
display_engine_list();
if(!ENGINE_remove(new_h2))
{
printf("Remove failed!\n");
goto end;
}
display_engine_list();
if(!ENGINE_add(new_h4))
{
printf("Add failed!\n");
goto end;
}
display_engine_list();
if(ENGINE_add(new_h3))
{
printf("Add *should* have failed but didn't!\n");
goto end;
}
else
printf("Add that should fail did.\n");
ERR_clear_error();
if(ENGINE_remove(new_h2))
{
printf("Remove *should* have failed but didn't!\n");
goto end;
}
else
printf("Remove that should fail did.\n");
ERR_clear_error();
if(!ENGINE_remove(new_h3))
{
printf("Remove failed!\n");
goto end;
}
display_engine_list();
if(!ENGINE_remove(new_h4))
{
printf("Remove failed!\n");
goto end;
}
display_engine_list();
/* Depending on whether there's any hardware support compiled
* in, this remove may be destined to fail. */
ptr = ENGINE_get_first();
if(ptr)
if(!ENGINE_remove(ptr))
printf("Remove failed!i - probably no hardware "
"support present.\n");
if (ptr)
ENGINE_free(ptr);
display_engine_list();
if(!ENGINE_add(new_h1) || !ENGINE_remove(new_h1))
{
printf("Couldn't add and remove to an empty list!\n");
goto end;
}
else
printf("Successfully added and removed to an empty list!\n");
printf("About to beef up the engine-type list\n");
for(loop = 0; loop < 512; loop++)
{
sprintf(buf, "id%i", loop);
id = BUF_strdup(buf);
sprintf(buf, "Fake engine type %i", loop);
name = BUF_strdup(buf);
if(((block[loop] = ENGINE_new()) == NULL) ||
!ENGINE_set_id(block[loop], id) ||
!ENGINE_set_name(block[loop], name))
{
printf("Couldn't create block of ENGINE structures.\n"
"I'll probably also core-dump now, damn.\n");
goto end;
}
}
for(loop = 0; loop < 512; loop++)
{
if(!ENGINE_add(block[loop]))
{
printf("\nAdding stopped at %i, (%s,%s)\n",
loop, ENGINE_get_id(block[loop]),
ENGINE_get_name(block[loop]));
goto cleanup_loop;
}
else
printf("."); fflush(stdout);
}
cleanup_loop:
printf("\nAbout to empty the engine-type list\n");
while((ptr = ENGINE_get_first()) != NULL)
{
if(!ENGINE_remove(ptr))
{
printf("\nRemove failed!\n");
goto end;
}
ENGINE_free(ptr);
printf("."); fflush(stdout);
}
for(loop = 0; loop < 512; loop++)
{
OPENSSL_free((void *)ENGINE_get_id(block[loop]));
OPENSSL_free((void *)ENGINE_get_name(block[loop]));
}
printf("\nTests completed happily\n");
to_return = 0;
end:
if(to_return)
ERR_print_errors_fp(stderr);
if(new_h1) ENGINE_free(new_h1);
if(new_h2) ENGINE_free(new_h2);
if(new_h3) ENGINE_free(new_h3);
if(new_h4) ENGINE_free(new_h4);
for(loop = 0; loop < 512; loop++)
if(block[loop])
ENGINE_free(block[loop]);
ENGINE_cleanup();
CRYPTO_cleanup_all_ex_data();
ERR_free_strings();
ERR_remove_thread_state(NULL);
CRYPTO_mem_leaks_fp(stderr);
return to_return;
}
#endif

View File

@@ -0,0 +1,246 @@
/* ====================================================================
* Copyright (c) 2006 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include "eng_int.h"
#include "asn1_locl.h"
#include <openssl/evp.h>
/* If this symbol is defined then ENGINE_get_pkey_asn1_meth_engine(), the
* function that is used by EVP to hook in pkey_asn1_meth code and cache
* defaults (etc), will display brief debugging summaries to stderr with the
* 'nid'. */
/* #define ENGINE_PKEY_ASN1_METH_DEBUG */
static ENGINE_TABLE *pkey_asn1_meth_table = NULL;
void ENGINE_unregister_pkey_asn1_meths(ENGINE *e)
{
engine_table_unregister(&pkey_asn1_meth_table, e);
}
static void engine_unregister_all_pkey_asn1_meths(void)
{
engine_table_cleanup(&pkey_asn1_meth_table);
}
int ENGINE_register_pkey_asn1_meths(ENGINE *e)
{
if(e->pkey_asn1_meths)
{
const int *nids;
int num_nids = e->pkey_asn1_meths(e, NULL, &nids, 0);
if(num_nids > 0)
return engine_table_register(&pkey_asn1_meth_table,
engine_unregister_all_pkey_asn1_meths, e, nids,
num_nids, 0);
}
return 1;
}
void ENGINE_register_all_pkey_asn1_meths(void)
{
ENGINE *e;
for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
ENGINE_register_pkey_asn1_meths(e);
}
int ENGINE_set_default_pkey_asn1_meths(ENGINE *e)
{
if(e->pkey_asn1_meths)
{
const int *nids;
int num_nids = e->pkey_asn1_meths(e, NULL, &nids, 0);
if(num_nids > 0)
return engine_table_register(&pkey_asn1_meth_table,
engine_unregister_all_pkey_asn1_meths, e, nids,
num_nids, 1);
}
return 1;
}
/* Exposed API function to get a functional reference from the implementation
* table (ie. try to get a functional reference from the tabled structural
* references) for a given pkey_asn1_meth 'nid' */
ENGINE *ENGINE_get_pkey_asn1_meth_engine(int nid)
{
return engine_table_select(&pkey_asn1_meth_table, nid);
}
/* Obtains a pkey_asn1_meth implementation from an ENGINE functional reference */
const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth(ENGINE *e, int nid)
{
EVP_PKEY_ASN1_METHOD *ret;
ENGINE_PKEY_ASN1_METHS_PTR fn = ENGINE_get_pkey_asn1_meths(e);
if(!fn || !fn(e, &ret, NULL, nid))
{
ENGINEerr(ENGINE_F_ENGINE_GET_PKEY_ASN1_METH,
ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD);
return NULL;
}
return ret;
}
/* Gets the pkey_asn1_meth callback from an ENGINE structure */
ENGINE_PKEY_ASN1_METHS_PTR ENGINE_get_pkey_asn1_meths(const ENGINE *e)
{
return e->pkey_asn1_meths;
}
/* Sets the pkey_asn1_meth callback in an ENGINE structure */
int ENGINE_set_pkey_asn1_meths(ENGINE *e, ENGINE_PKEY_ASN1_METHS_PTR f)
{
e->pkey_asn1_meths = f;
return 1;
}
/* Internal function to free up EVP_PKEY_ASN1_METHOD structures before an
* ENGINE is destroyed
*/
void engine_pkey_asn1_meths_free(ENGINE *e)
{
int i;
EVP_PKEY_ASN1_METHOD *pkm;
if (e->pkey_asn1_meths)
{
const int *pknids;
int npknids;
npknids = e->pkey_asn1_meths(e, NULL, &pknids, 0);
for (i = 0; i < npknids; i++)
{
if (e->pkey_asn1_meths(e, &pkm, NULL, pknids[i]))
{
EVP_PKEY_asn1_free(pkm);
}
}
}
}
/* Find a method based on a string. This does a linear search through
* all implemented algorithms. This is OK in practice because only
* a small number of algorithms are likely to be implemented in an engine
* and it is not used for speed critical operations.
*/
const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth_str(ENGINE *e,
const char *str, int len)
{
int i, nidcount;
const int *nids;
EVP_PKEY_ASN1_METHOD *ameth;
if (!e->pkey_asn1_meths)
return NULL;
if (len == -1)
len = strlen(str);
nidcount = e->pkey_asn1_meths(e, NULL, &nids, 0);
for (i = 0; i < nidcount; i++)
{
e->pkey_asn1_meths(e, &ameth, NULL, nids[i]);
if (((int)strlen(ameth->pem_str) == len) &&
!strncasecmp(ameth->pem_str, str, len))
return ameth;
}
return NULL;
}
typedef struct
{
ENGINE *e;
const EVP_PKEY_ASN1_METHOD *ameth;
const char *str;
int len;
} ENGINE_FIND_STR;
static void look_str_cb(int nid, STACK_OF(ENGINE) *sk, ENGINE *def, void *arg)
{
ENGINE_FIND_STR *lk = arg;
int i;
if (lk->ameth)
return;
for (i = 0; i < sk_ENGINE_num(sk); i++)
{
ENGINE *e = sk_ENGINE_value(sk, i);
EVP_PKEY_ASN1_METHOD *ameth;
e->pkey_asn1_meths(e, &ameth, NULL, nid);
if (((int)strlen(ameth->pem_str) == lk->len) &&
!strncasecmp(ameth->pem_str, lk->str, lk->len))
{
lk->e = e;
lk->ameth = ameth;
return;
}
}
}
const EVP_PKEY_ASN1_METHOD *ENGINE_pkey_asn1_find_str(ENGINE **pe,
const char *str, int len)
{
ENGINE_FIND_STR fstr;
fstr.e = NULL;
fstr.ameth = NULL;
fstr.str = str;
fstr.len = len;
CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
engine_table_doall(pkey_asn1_meth_table, look_str_cb, &fstr);
/* If found obtain a structural reference to engine */
if (fstr.e)
{
fstr.e->struct_ref++;
engine_ref_debug(fstr.e, 0, 1)
}
*pe = fstr.e;
CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
return fstr.ameth;
}

View File

@@ -0,0 +1,143 @@
/* ====================================================================
* Copyright (c) 2000 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include "eng_int.h"
/* If this symbol is defined then ENGINE_get_cipher_engine(), the function that
* is used by EVP to hook in cipher code and cache defaults (etc), will display
* brief debugging summaries to stderr with the 'nid'. */
/* #define ENGINE_CIPHER_DEBUG */
static ENGINE_TABLE *cipher_table = NULL;
void ENGINE_unregister_ciphers(ENGINE *e)
{
engine_table_unregister(&cipher_table, e);
}
static void engine_unregister_all_ciphers(void)
{
engine_table_cleanup(&cipher_table);
}
int ENGINE_register_ciphers(ENGINE *e)
{
if(e->ciphers)
{
const int *nids;
int num_nids = e->ciphers(e, NULL, &nids, 0);
if(num_nids > 0)
return engine_table_register(&cipher_table,
engine_unregister_all_ciphers, e, nids,
num_nids, 0);
}
return 1;
}
void ENGINE_register_all_ciphers()
{
ENGINE *e;
for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
ENGINE_register_ciphers(e);
}
int ENGINE_set_default_ciphers(ENGINE *e)
{
if(e->ciphers)
{
const int *nids;
int num_nids = e->ciphers(e, NULL, &nids, 0);
if(num_nids > 0)
return engine_table_register(&cipher_table,
engine_unregister_all_ciphers, e, nids,
num_nids, 1);
}
return 1;
}
/* Exposed API function to get a functional reference from the implementation
* table (ie. try to get a functional reference from the tabled structural
* references) for a given cipher 'nid' */
ENGINE *ENGINE_get_cipher_engine(int nid)
{
return engine_table_select(&cipher_table, nid);
}
/* Obtains a cipher implementation from an ENGINE functional reference */
const EVP_CIPHER *ENGINE_get_cipher(ENGINE *e, int nid)
{
const EVP_CIPHER *ret;
ENGINE_CIPHERS_PTR fn = ENGINE_get_ciphers(e);
if(!fn || !fn(e, &ret, NULL, nid))
{
ENGINEerr(ENGINE_F_ENGINE_GET_CIPHER,
ENGINE_R_UNIMPLEMENTED_CIPHER);
return NULL;
}
return ret;
}
/* Gets the cipher callback from an ENGINE structure */
ENGINE_CIPHERS_PTR ENGINE_get_ciphers(const ENGINE *e)
{
return e->ciphers;
}
/* Sets the cipher callback in an ENGINE structure */
int ENGINE_set_ciphers(ENGINE *e, ENGINE_CIPHERS_PTR f)
{
e->ciphers = f;
return 1;
}

View File

@@ -0,0 +1,118 @@
/* ====================================================================
* Copyright (c) 2000 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include "eng_int.h"
/* If this symbol is defined then ENGINE_get_default_DH(), the function that is
* used by DH to hook in implementation code and cache defaults (etc), will
* display brief debugging summaries to stderr with the 'nid'. */
/* #define ENGINE_DH_DEBUG */
static ENGINE_TABLE *dh_table = NULL;
static const int dummy_nid = 1;
void ENGINE_unregister_DH(ENGINE *e)
{
engine_table_unregister(&dh_table, e);
}
static void engine_unregister_all_DH(void)
{
engine_table_cleanup(&dh_table);
}
int ENGINE_register_DH(ENGINE *e)
{
if(e->dh_meth)
return engine_table_register(&dh_table,
engine_unregister_all_DH, e, &dummy_nid, 1, 0);
return 1;
}
void ENGINE_register_all_DH()
{
ENGINE *e;
for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
ENGINE_register_DH(e);
}
int ENGINE_set_default_DH(ENGINE *e)
{
if(e->dh_meth)
return engine_table_register(&dh_table,
engine_unregister_all_DH, e, &dummy_nid, 1, 1);
return 1;
}
/* Exposed API function to get a functional reference from the implementation
* table (ie. try to get a functional reference from the tabled structural
* references). */
ENGINE *ENGINE_get_default_DH(void)
{
return engine_table_select(&dh_table, dummy_nid);
}
/* Obtains an DH implementation from an ENGINE functional reference */
const DH_METHOD *ENGINE_get_DH(const ENGINE *e)
{
return e->dh_meth;
}
/* Sets an DH implementation in an ENGINE structure */
int ENGINE_set_DH(ENGINE *e, const DH_METHOD *dh_meth)
{
e->dh_meth = dh_meth;
return 1;
}

View File

@@ -0,0 +1,143 @@
/* ====================================================================
* Copyright (c) 2000 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include "eng_int.h"
/* If this symbol is defined then ENGINE_get_digest_engine(), the function that
* is used by EVP to hook in digest code and cache defaults (etc), will display
* brief debugging summaries to stderr with the 'nid'. */
/* #define ENGINE_DIGEST_DEBUG */
static ENGINE_TABLE *digest_table = NULL;
void ENGINE_unregister_digests(ENGINE *e)
{
engine_table_unregister(&digest_table, e);
}
static void engine_unregister_all_digests(void)
{
engine_table_cleanup(&digest_table);
}
int ENGINE_register_digests(ENGINE *e)
{
if(e->digests)
{
const int *nids;
int num_nids = e->digests(e, NULL, &nids, 0);
if(num_nids > 0)
return engine_table_register(&digest_table,
engine_unregister_all_digests, e, nids,
num_nids, 0);
}
return 1;
}
void ENGINE_register_all_digests()
{
ENGINE *e;
for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
ENGINE_register_digests(e);
}
int ENGINE_set_default_digests(ENGINE *e)
{
if(e->digests)
{
const int *nids;
int num_nids = e->digests(e, NULL, &nids, 0);
if(num_nids > 0)
return engine_table_register(&digest_table,
engine_unregister_all_digests, e, nids,
num_nids, 1);
}
return 1;
}
/* Exposed API function to get a functional reference from the implementation
* table (ie. try to get a functional reference from the tabled structural
* references) for a given digest 'nid' */
ENGINE *ENGINE_get_digest_engine(int nid)
{
return engine_table_select(&digest_table, nid);
}
/* Obtains a digest implementation from an ENGINE functional reference */
const EVP_MD *ENGINE_get_digest(ENGINE *e, int nid)
{
const EVP_MD *ret;
ENGINE_DIGESTS_PTR fn = ENGINE_get_digests(e);
if(!fn || !fn(e, &ret, NULL, nid))
{
ENGINEerr(ENGINE_F_ENGINE_GET_DIGEST,
ENGINE_R_UNIMPLEMENTED_DIGEST);
return NULL;
}
return ret;
}
/* Gets the digest callback from an ENGINE structure */
ENGINE_DIGESTS_PTR ENGINE_get_digests(const ENGINE *e)
{
return e->digests;
}
/* Sets the digest callback in an ENGINE structure */
int ENGINE_set_digests(ENGINE *e, ENGINE_DIGESTS_PTR f)
{
e->digests = f;
return 1;
}

View File

@@ -0,0 +1,118 @@
/* ====================================================================
* Copyright (c) 2000 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include "eng_int.h"
/* If this symbol is defined then ENGINE_get_default_DSA(), the function that is
* used by DSA to hook in implementation code and cache defaults (etc), will
* display brief debugging summaries to stderr with the 'nid'. */
/* #define ENGINE_DSA_DEBUG */
static ENGINE_TABLE *dsa_table = NULL;
static const int dummy_nid = 1;
void ENGINE_unregister_DSA(ENGINE *e)
{
engine_table_unregister(&dsa_table, e);
}
static void engine_unregister_all_DSA(void)
{
engine_table_cleanup(&dsa_table);
}
int ENGINE_register_DSA(ENGINE *e)
{
if(e->dsa_meth)
return engine_table_register(&dsa_table,
engine_unregister_all_DSA, e, &dummy_nid, 1, 0);
return 1;
}
void ENGINE_register_all_DSA()
{
ENGINE *e;
for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
ENGINE_register_DSA(e);
}
int ENGINE_set_default_DSA(ENGINE *e)
{
if(e->dsa_meth)
return engine_table_register(&dsa_table,
engine_unregister_all_DSA, e, &dummy_nid, 1, 1);
return 1;
}
/* Exposed API function to get a functional reference from the implementation
* table (ie. try to get a functional reference from the tabled structural
* references). */
ENGINE *ENGINE_get_default_DSA(void)
{
return engine_table_select(&dsa_table, dummy_nid);
}
/* Obtains an DSA implementation from an ENGINE functional reference */
const DSA_METHOD *ENGINE_get_DSA(const ENGINE *e)
{
return e->dsa_meth;
}
/* Sets an DSA implementation in an ENGINE structure */
int ENGINE_set_DSA(ENGINE *e, const DSA_METHOD *dsa_meth)
{
e->dsa_meth = dsa_meth;
return 1;
}

View File

@@ -0,0 +1,133 @@
/* crypto/engine/tb_ecdh.c */
/* ====================================================================
* Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
*
* The Elliptic Curve Public-Key Crypto Library (ECC Code) included
* herein is developed by SUN MICROSYSTEMS, INC., and is contributed
* to the OpenSSL project.
*
* The ECC Code is licensed pursuant to the OpenSSL open source
* license provided below.
*
* The ECDH engine software is originally written by Nils Gura and
* Douglas Stebila of Sun Microsystems Laboratories.
*
*/
/* ====================================================================
* Copyright (c) 2000-2002 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include "eng_int.h"
/* If this symbol is defined then ENGINE_get_default_ECDH(), the function that is
* used by ECDH to hook in implementation code and cache defaults (etc), will
* display brief debugging summaries to stderr with the 'nid'. */
/* #define ENGINE_ECDH_DEBUG */
static ENGINE_TABLE *ecdh_table = NULL;
static const int dummy_nid = 1;
void ENGINE_unregister_ECDH(ENGINE *e)
{
engine_table_unregister(&ecdh_table, e);
}
static void engine_unregister_all_ECDH(void)
{
engine_table_cleanup(&ecdh_table);
}
int ENGINE_register_ECDH(ENGINE *e)
{
if(e->ecdh_meth)
return engine_table_register(&ecdh_table,
engine_unregister_all_ECDH, e, &dummy_nid, 1, 0);
return 1;
}
void ENGINE_register_all_ECDH()
{
ENGINE *e;
for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
ENGINE_register_ECDH(e);
}
int ENGINE_set_default_ECDH(ENGINE *e)
{
if(e->ecdh_meth)
return engine_table_register(&ecdh_table,
engine_unregister_all_ECDH, e, &dummy_nid, 1, 1);
return 1;
}
/* Exposed API function to get a functional reference from the implementation
* table (ie. try to get a functional reference from the tabled structural
* references). */
ENGINE *ENGINE_get_default_ECDH(void)
{
return engine_table_select(&ecdh_table, dummy_nid);
}
/* Obtains an ECDH implementation from an ENGINE functional reference */
const ECDH_METHOD *ENGINE_get_ECDH(const ENGINE *e)
{
return e->ecdh_meth;
}
/* Sets an ECDH implementation in an ENGINE structure */
int ENGINE_set_ECDH(ENGINE *e, const ECDH_METHOD *ecdh_meth)
{
e->ecdh_meth = ecdh_meth;
return 1;
}

View File

@@ -0,0 +1,118 @@
/* ====================================================================
* Copyright (c) 2000-2002 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include "eng_int.h"
/* If this symbol is defined then ENGINE_get_default_ECDSA(), the function that is
* used by ECDSA to hook in implementation code and cache defaults (etc), will
* display brief debugging summaries to stderr with the 'nid'. */
/* #define ENGINE_ECDSA_DEBUG */
static ENGINE_TABLE *ecdsa_table = NULL;
static const int dummy_nid = 1;
void ENGINE_unregister_ECDSA(ENGINE *e)
{
engine_table_unregister(&ecdsa_table, e);
}
static void engine_unregister_all_ECDSA(void)
{
engine_table_cleanup(&ecdsa_table);
}
int ENGINE_register_ECDSA(ENGINE *e)
{
if(e->ecdsa_meth)
return engine_table_register(&ecdsa_table,
engine_unregister_all_ECDSA, e, &dummy_nid, 1, 0);
return 1;
}
void ENGINE_register_all_ECDSA()
{
ENGINE *e;
for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
ENGINE_register_ECDSA(e);
}
int ENGINE_set_default_ECDSA(ENGINE *e)
{
if(e->ecdsa_meth)
return engine_table_register(&ecdsa_table,
engine_unregister_all_ECDSA, e, &dummy_nid, 1, 1);
return 1;
}
/* Exposed API function to get a functional reference from the implementation
* table (ie. try to get a functional reference from the tabled structural
* references). */
ENGINE *ENGINE_get_default_ECDSA(void)
{
return engine_table_select(&ecdsa_table, dummy_nid);
}
/* Obtains an ECDSA implementation from an ENGINE functional reference */
const ECDSA_METHOD *ENGINE_get_ECDSA(const ENGINE *e)
{
return e->ecdsa_meth;
}
/* Sets an ECDSA implementation in an ENGINE structure */
int ENGINE_set_ECDSA(ENGINE *e, const ECDSA_METHOD *ecdsa_meth)
{
e->ecdsa_meth = ecdsa_meth;
return 1;
}

View File

@@ -0,0 +1,167 @@
/* ====================================================================
* Copyright (c) 2006 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include "eng_int.h"
#include <openssl/evp.h>
/* If this symbol is defined then ENGINE_get_pkey_meth_engine(), the function
* that is used by EVP to hook in pkey_meth code and cache defaults (etc), will
* display brief debugging summaries to stderr with the 'nid'. */
/* #define ENGINE_PKEY_METH_DEBUG */
static ENGINE_TABLE *pkey_meth_table = NULL;
void ENGINE_unregister_pkey_meths(ENGINE *e)
{
engine_table_unregister(&pkey_meth_table, e);
}
static void engine_unregister_all_pkey_meths(void)
{
engine_table_cleanup(&pkey_meth_table);
}
int ENGINE_register_pkey_meths(ENGINE *e)
{
if(e->pkey_meths)
{
const int *nids;
int num_nids = e->pkey_meths(e, NULL, &nids, 0);
if(num_nids > 0)
return engine_table_register(&pkey_meth_table,
engine_unregister_all_pkey_meths, e, nids,
num_nids, 0);
}
return 1;
}
void ENGINE_register_all_pkey_meths()
{
ENGINE *e;
for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
ENGINE_register_pkey_meths(e);
}
int ENGINE_set_default_pkey_meths(ENGINE *e)
{
if(e->pkey_meths)
{
const int *nids;
int num_nids = e->pkey_meths(e, NULL, &nids, 0);
if(num_nids > 0)
return engine_table_register(&pkey_meth_table,
engine_unregister_all_pkey_meths, e, nids,
num_nids, 1);
}
return 1;
}
/* Exposed API function to get a functional reference from the implementation
* table (ie. try to get a functional reference from the tabled structural
* references) for a given pkey_meth 'nid' */
ENGINE *ENGINE_get_pkey_meth_engine(int nid)
{
return engine_table_select(&pkey_meth_table, nid);
}
/* Obtains a pkey_meth implementation from an ENGINE functional reference */
const EVP_PKEY_METHOD *ENGINE_get_pkey_meth(ENGINE *e, int nid)
{
EVP_PKEY_METHOD *ret;
ENGINE_PKEY_METHS_PTR fn = ENGINE_get_pkey_meths(e);
if(!fn || !fn(e, &ret, NULL, nid))
{
ENGINEerr(ENGINE_F_ENGINE_GET_PKEY_METH,
ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD);
return NULL;
}
return ret;
}
/* Gets the pkey_meth callback from an ENGINE structure */
ENGINE_PKEY_METHS_PTR ENGINE_get_pkey_meths(const ENGINE *e)
{
return e->pkey_meths;
}
/* Sets the pkey_meth callback in an ENGINE structure */
int ENGINE_set_pkey_meths(ENGINE *e, ENGINE_PKEY_METHS_PTR f)
{
e->pkey_meths = f;
return 1;
}
/* Internal function to free up EVP_PKEY_METHOD structures before an
* ENGINE is destroyed
*/
void engine_pkey_meths_free(ENGINE *e)
{
int i;
EVP_PKEY_METHOD *pkm;
if (e->pkey_meths)
{
const int *pknids;
int npknids;
npknids = e->pkey_meths(e, NULL, &pknids, 0);
for (i = 0; i < npknids; i++)
{
if (e->pkey_meths(e, &pkm, NULL, pknids[i]))
{
EVP_PKEY_meth_free(pkm);
}
}
}
}

View File

@@ -0,0 +1,118 @@
/* ====================================================================
* Copyright (c) 2000 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include "eng_int.h"
/* If this symbol is defined then ENGINE_get_default_RAND(), the function that is
* used by RAND to hook in implementation code and cache defaults (etc), will
* display brief debugging summaries to stderr with the 'nid'. */
/* #define ENGINE_RAND_DEBUG */
static ENGINE_TABLE *rand_table = NULL;
static const int dummy_nid = 1;
void ENGINE_unregister_RAND(ENGINE *e)
{
engine_table_unregister(&rand_table, e);
}
static void engine_unregister_all_RAND(void)
{
engine_table_cleanup(&rand_table);
}
int ENGINE_register_RAND(ENGINE *e)
{
if(e->rand_meth)
return engine_table_register(&rand_table,
engine_unregister_all_RAND, e, &dummy_nid, 1, 0);
return 1;
}
void ENGINE_register_all_RAND()
{
ENGINE *e;
for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
ENGINE_register_RAND(e);
}
int ENGINE_set_default_RAND(ENGINE *e)
{
if(e->rand_meth)
return engine_table_register(&rand_table,
engine_unregister_all_RAND, e, &dummy_nid, 1, 1);
return 1;
}
/* Exposed API function to get a functional reference from the implementation
* table (ie. try to get a functional reference from the tabled structural
* references). */
ENGINE *ENGINE_get_default_RAND(void)
{
return engine_table_select(&rand_table, dummy_nid);
}
/* Obtains an RAND implementation from an ENGINE functional reference */
const RAND_METHOD *ENGINE_get_RAND(const ENGINE *e)
{
return e->rand_meth;
}
/* Sets an RAND implementation in an ENGINE structure */
int ENGINE_set_RAND(ENGINE *e, const RAND_METHOD *rand_meth)
{
e->rand_meth = rand_meth;
return 1;
}

View File

@@ -0,0 +1,118 @@
/* ====================================================================
* Copyright (c) 2000 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include "eng_int.h"
/* If this symbol is defined then ENGINE_get_default_RSA(), the function that is
* used by RSA to hook in implementation code and cache defaults (etc), will
* display brief debugging summaries to stderr with the 'nid'. */
/* #define ENGINE_RSA_DEBUG */
static ENGINE_TABLE *rsa_table = NULL;
static const int dummy_nid = 1;
void ENGINE_unregister_RSA(ENGINE *e)
{
engine_table_unregister(&rsa_table, e);
}
static void engine_unregister_all_RSA(void)
{
engine_table_cleanup(&rsa_table);
}
int ENGINE_register_RSA(ENGINE *e)
{
if(e->rsa_meth)
return engine_table_register(&rsa_table,
engine_unregister_all_RSA, e, &dummy_nid, 1, 0);
return 1;
}
void ENGINE_register_all_RSA()
{
ENGINE *e;
for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
ENGINE_register_RSA(e);
}
int ENGINE_set_default_RSA(ENGINE *e)
{
if(e->rsa_meth)
return engine_table_register(&rsa_table,
engine_unregister_all_RSA, e, &dummy_nid, 1, 1);
return 1;
}
/* Exposed API function to get a functional reference from the implementation
* table (ie. try to get a functional reference from the tabled structural
* references). */
ENGINE *ENGINE_get_default_RSA(void)
{
return engine_table_select(&rsa_table, dummy_nid);
}
/* Obtains an RSA implementation from an ENGINE functional reference */
const RSA_METHOD *ENGINE_get_RSA(const ENGINE *e)
{
return e->rsa_meth;
}
/* Sets an RSA implementation in an ENGINE structure */
int ENGINE_set_RSA(ENGINE *e, const RSA_METHOD *rsa_meth)
{
e->rsa_meth = rsa_meth;
return 1;
}

View File

@@ -0,0 +1,123 @@
/* ====================================================================
* Copyright (c) 2003 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include "eng_int.h"
/* If this symbol is defined then ENGINE_get_default_STORE(), the function that is
* used by STORE to hook in implementation code and cache defaults (etc), will
* display brief debugging summaries to stderr with the 'nid'. */
/* #define ENGINE_STORE_DEBUG */
static ENGINE_TABLE *store_table = NULL;
static const int dummy_nid = 1;
void ENGINE_unregister_STORE(ENGINE *e)
{
engine_table_unregister(&store_table, e);
}
static void engine_unregister_all_STORE(void)
{
engine_table_cleanup(&store_table);
}
int ENGINE_register_STORE(ENGINE *e)
{
if(e->store_meth)
return engine_table_register(&store_table,
engine_unregister_all_STORE, e, &dummy_nid, 1, 0);
return 1;
}
void ENGINE_register_all_STORE()
{
ENGINE *e;
for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
ENGINE_register_STORE(e);
}
/* The following two functions are removed because they're useless. */
#if 0
int ENGINE_set_default_STORE(ENGINE *e)
{
if(e->store_meth)
return engine_table_register(&store_table,
engine_unregister_all_STORE, e, &dummy_nid, 1, 1);
return 1;
}
#endif
#if 0
/* Exposed API function to get a functional reference from the implementation
* table (ie. try to get a functional reference from the tabled structural
* references). */
ENGINE *ENGINE_get_default_STORE(void)
{
return engine_table_select(&store_table, dummy_nid);
}
#endif
/* Obtains an STORE implementation from an ENGINE functional reference */
const STORE_METHOD *ENGINE_get_STORE(const ENGINE *e)
{
return e->store_meth;
}
/* Sets an STORE implementation in an ENGINE structure */
int ENGINE_set_STORE(ENGINE *e, const STORE_METHOD *store_meth)
{
e->store_meth = store_meth;
return 1;
}