summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/engine
diff options
context:
space:
mode:
authorcvs2svn <admin@example.com>2002-05-15 02:29:24 +0000
committercvs2svn <admin@example.com>2002-05-15 02:29:24 +0000
commit027351f729b9e837200dae6e1520cda6577ab930 (patch)
treee25a717057aa4529e433fc3b1fac8d4df8db3a5c /src/lib/libcrypto/engine
parentaeeae06a79815dc190061534d47236cec09f9e32 (diff)
downloadopenbsd-027351f729b9e837200dae6e1520cda6577ab930.tar.gz
openbsd-027351f729b9e837200dae6e1520cda6577ab930.tar.bz2
openbsd-027351f729b9e837200dae6e1520cda6577ab930.zip
This commit was manufactured by cvs2git to create branch 'unlabeled-1.1.1'.
Diffstat (limited to 'src/lib/libcrypto/engine')
-rw-r--r--src/lib/libcrypto/engine/README278
-rw-r--r--src/lib/libcrypto/engine/eng_all.c118
-rw-r--r--src/lib/libcrypto/engine/eng_cnf.c242
-rw-r--r--src/lib/libcrypto/engine/eng_ctrl.c387
-rw-r--r--src/lib/libcrypto/engine/eng_dyn.c446
-rw-r--r--src/lib/libcrypto/engine/eng_err.c165
-rw-r--r--src/lib/libcrypto/engine/eng_fat.c148
-rw-r--r--src/lib/libcrypto/engine/eng_init.c158
-rw-r--r--src/lib/libcrypto/engine/eng_int.h185
-rw-r--r--src/lib/libcrypto/engine/eng_lib.c321
-rw-r--r--src/lib/libcrypto/engine/eng_list.c383
-rw-r--r--src/lib/libcrypto/engine/eng_openssl.c347
-rw-r--r--src/lib/libcrypto/engine/eng_pkey.c157
-rw-r--r--src/lib/libcrypto/engine/eng_table.c361
-rw-r--r--src/lib/libcrypto/engine/engine.h398
-rw-r--r--src/lib/libcrypto/engine/tb_cipher.c145
-rw-r--r--src/lib/libcrypto/engine/tb_dh.c120
-rw-r--r--src/lib/libcrypto/engine/tb_digest.c145
-rw-r--r--src/lib/libcrypto/engine/tb_dsa.c120
-rw-r--r--src/lib/libcrypto/engine/tb_rand.c120
-rw-r--r--src/lib/libcrypto/engine/tb_rsa.c120
21 files changed, 4864 insertions, 0 deletions
diff --git a/src/lib/libcrypto/engine/README b/src/lib/libcrypto/engine/README
new file mode 100644
index 0000000000..96595e6f35
--- /dev/null
+++ b/src/lib/libcrypto/engine/README
@@ -0,0 +1,278 @@
1NOTES, THOUGHTS, and EVERYTHING
2-------------------------------
3
4(1) Concurrency and locking ... I made a change to the ENGINE_free code
5 because I spotted a potential hold-up in proceedings (doing too
6 much inside a lock including calling a callback), there may be
7 other bits like this. What do the speed/optimisation freaks think
8 of this aspect of the code and design? There's lots of locking for
9 manipulation functions and I need that to keep things nice and
10 solid, but this manipulation is mostly (de)initialisation, I would
11 think that most run-time locking is purely in the ENGINE_init and
12 ENGINE_finish calls that might be made when getting handles for
13 RSA (and friends') structures. These would be mostly reference
14 count operations as the functional references should always be 1
15 or greater at run-time to prevent init/deinit thrashing.
16
17(2) nCipher support, via the HWCryptoHook API, is now in the code.
18 Apparently this hasn't been tested too much yet, but it looks
19 good. :-) Atalla support has been added too, but shares a lot in
20 common with Ben's original hooks in bn_exp.c (although it has been
21 ENGINE-ified, and error handling wrapped around it) and it's also
22 had some low-volume testing, so it should be usable.
23
24(3) Of more concern, we need to work out (a) how to put together usable
25 RAND_METHODs for units that just have one "get n or less random
26 bytes" function, (b) we also need to determine how to hook the code
27 in crypto/rand/ to use the ENGINE defaults in a way similar to what
28 has been done in crypto/rsa/, crypto/dsa/, etc.
29
30(4) ENGINE should really grow to encompass more than 3 public key
31 algorithms and randomness gathering. The structure/data level of
32 the engine code is hidden from code outside the crypto/engine/
33 directory so change shouldn't be too viral. More important though
34 is how things should evolve ... this needs thought and discussion.
35
36
37-----------------------------------==*==-----------------------------------
38
39More notes 2000-08-01
40---------------------
41
42Geoff Thorpe, who designed the engine part, wrote a pretty good description
43of the thoughts he had when he built it, good enough to include verbatim here
44(with his permission) -- Richard Levitte
45
46
47Date: Tue, 1 Aug 2000 16:54:08 +0100 (BST)
48From: Geoff Thorpe
49Subject: Re: The thoughts to merge BRANCH_engine into the main trunk are
50 emerging
51
52Hi there,
53
54I'm going to try and do some justice to this, but I'm a little short on
55time and the there is an endless amount that could be discussed on this
56subject. sigh ... please bear with me :-)
57
58> The changes in BRANCH_engine dig deep into the core of OpenSSL, for example
59> into the RSA and RAND routines, adding a level of indirection which is needed
60> to keep the abstraction, as far as I understand. It would be a good thing if
61> those who do play with those things took a look at the changes that have been
62> done in the branch and say out loud how much (or hopefully little) we've made
63> fools of ourselves.
64
65The point here is that the code that has emerged in the BRANCH_engine
66branch was based on some initial requirements of mine that I went in and
67addressed, and Richard has picked up the ball and run with it too. It
68would be really useful to get some review of the approach we've taken, but
69first I think I need to describe as best I can the reasons behind what has
70been done so far, in particular what issues we have tried to address when
71doing this, and what issues we have intentionally (or necessarily) tried
72to avoid.
73
74methods, engines, and evps
75--------------------------
76
77There has been some dicussion, particularly with Steve, about where this
78ENGINE stuff might fit into the conceptual picture as/when we start to
79abstract algorithms a little bit to make the library more extensible. In
80particular, it would desirable to have algorithms (symmetric, hash, pkc,
81etc) abstracted in some way that allows them to be just objects sitting in
82a list (or database) ... it'll just happen that the "DSA" object doesn't
83support encryption whereas the "RSA" object does. This requires a lot of
84consideration to begin to know how to tackle it; in particular how
85encapsulated should these things be? If the objects also understand their
86own ASN1 encodings and what-not, then it would for example be possible to
87add support for elliptic-curve DSA in as a new algorithm and automatically
88have ECC-DSA certificates supported in SSL applications. Possible, but not
89easy. :-)
90
91Whatever, it seems that the way to go (if I've grok'd Steve's comments on
92this in the past) is to amalgamate these things in EVP as is already done
93(I think) for ciphers or hashes (Steve, please correct/elaborate). I
94certainly think something should be done in this direction because right
95now we have different source directories, types, functions, and methods
96for each algorithm - even when conceptually they are very much different
97feathers of the same bird. (This is certainly all true for the public-key
98stuff, and may be partially true for the other parts.)
99
100ENGINE was *not* conceived as a way of solving this, far from it. Nor was
101it conceived as a way of replacing the various "***_METHOD"s. It was
102conceived as an abstraction of a sort of "virtual crypto device". If we
103lived in a world where "EVP_ALGO"s (or something like them) encapsulated
104particular algorithms like RSA,DSA,MD5,RC4,etc, and "***_METHOD"s
105encapsulated interfaces to algorithms (eg. some algo's might support a
106PKC_METHOD, a HASH_METHOD, or a CIPHER_METHOD, who knows?), then I would
107think that ENGINE would encapsulate an implementation of arbitrarily many
108of those algorithms - perhaps as alternatives to existing algorithms
109and/or perhaps as new previously unimplemented algorithms. An ENGINE could
110be used to contain an alternative software implementation, a wrapper for a
111hardware acceleration and/or key-management unit, a comms-wrapper for
112distributing cryptographic operations to remote machines, or any other
113"devices" your imagination can dream up.
114
115However, what has been done in the ENGINE branch so far is nothing more
116than starting to get our toes wet. I had a couple of self-imposed
117requirements when putting the initial abstraction together, and I may have
118already posed these in one form or another on the list, but briefly;
119
120 (i) only bother with public key algorithms for now, and maybe RAND too
121 (motivated by the need to get hardware support going and the fact
122 this was a comparitively easy subset to address to begin with).
123
124 (ii) don't change (if at all possible) the existing crypto code, ie. the
125 implementations, the way the ***_METHODs work, etc.
126
127 (iii) ensure that if no function from the ENGINE code is ever called then
128 things work the way they always did, and there is no memory
129 allocation (otherwise the failure to cleanup would be a problem -
130 this is part of the reason no STACKs were used, the other part of
131 the reason being I found them inappropriate).
132
133 (iv) ensure that all the built-in crypto was encapsulated by one of
134 these "ENGINE"s and that this engine was automatically selected as
135 the default.
136
137 (v) provide the minimum hooking possible in the existing crypto code
138 so that global functions (eg. RSA_public_encrypt) do not need any
139 extra parameter, yet will use whatever the current default ENGINE
140 for that RSA key is, and that the default can be set "per-key"
141 and globally (new keys will assume the global default, and keys
142 without their own default will be operated on using the global
143 default). NB: Try and make (v) conflict as little as possible with
144 (ii). :-)
145
146 (vi) wrap the ENGINE code up in duct tape so you can't even see the
147 corners. Ie. expose no structures at all, just black-box pointers.
148
149 (v) maintain internally a list of ENGINEs on which a calling
150 application can iterate, interrogate, etc. Allow a calling
151 application to hook in new ENGINEs, remove ENGINEs from the list,
152 and enforce uniqueness within the global list of each ENGINE's
153 "unique id".
154
155 (vi) keep reference counts for everything - eg. this includes storing a
156 reference inside each RSA structure to the ENGINE that it uses.
157 This is freed when the RSA structure is destroyed, or has its
158 ENGINE explicitly changed. The net effect needs to be that at any
159 time, it is deterministic to know whether an ENGINE is in use or
160 can be safely removed (or unloaded in the case of the other type
161 of reference) without invalidating function pointers that may or
162 may not be used indavertently in the future. This was actually
163 one of the biggest problems to overcome in the existing OpenSSL
164 code - implementations had always been assumed to be ever-present,
165 so there was no trivial way to get round this.
166
167 (vii) distinguish between structural references and functional
168 references.
169
170A *little* detail
171-----------------
172
173While my mind is on it; I'll illustrate the bit in item (vii). This idea
174turned out to be very handy - the ENGINEs themselves need to be operated
175on and manipulated simply as objects without necessarily trying to
176"enable" them for use. Eg. most host machines will not have the necessary
177hardware or software to support all the engines one might compile into
178OpenSSL, yet it needs to be possible to iterate across the ENGINEs,
179querying their names, properties, etc - all happening in a thread-safe
180manner that uses reference counts (if you imagine two threads iterating
181through a list and one thread removing the ENGINE the other is currently
182looking at - you can see the gotcha waiting to happen). For all of this,
183*structural references* are used and operate much like the other reference
184counts in OpenSSL.
185
186The other kind of reference count is for *functional* references - these
187indicate a reference on which the caller can actually assume the
188particular ENGINE to be initialised and usable to perform the operations
189it implements. Any increment or decrement of the functional reference
190count automatically invokes a corresponding change in the structural
191reference count, as it is fairly obvious that a functional reference is a
192restricted case of a structural reference. So struct_ref >= funct_ref at
193all times. NB: functional references are usually obtained by a call to
194ENGINE_init(), but can also be created implicitly by calls that require a
195new functional reference to be created, eg. ENGINE_set_default(). Either
196way the only time the underlying ENGINE's "init" function is really called
197is when the (functional) reference count increases to 1, similarly the
198underlying "finish" handler is only called as the count goes down to 0.
199The effect of this, for example, is that if you set the default ENGINE for
200RSA operations to be "cswift", then its functional reference count will
201already be at least 1 so the CryptoSwift shared-library and the card will
202stay loaded and initialised until such time as all RSA keys using the
203cswift ENGINE are changed or destroyed and the default ENGINE for RSA
204operations has been changed. This prevents repeated thrashing of init and
205finish handling if the count keeps getting down as far as zero.
206
207Otherwise, the way the ENGINE code has been put together I think pretty
208much reflects the above points. The reason for the ENGINE structure having
209individual RSA_METHOD, DSA_METHOD, etc pointers is simply that it was the
210easiest way to go about things for now, to hook it all into the raw
211RSA,DSA,etc code, and I was trying to the keep the structure invisible
212anyway so that the way this is internally managed could be easily changed
213later on when we start to work out what's to be done about these other
214abstractions.
215
216Down the line, if some EVP-based technique emerges for adequately
217encapsulating algorithms and all their various bits and pieces, then I can
218imagine that "ENGINE" would turn into a reference-counting database of
219these EVP things, of which the default "openssl" ENGINE would be the
220library's own object database of pre-built software implemented algorithms
221(and such). It would also be cool to see the idea of "METHOD"s detached
222from the algorithms themselves ... so RSA, DSA, ElGamal, etc can all
223expose essentially the same METHOD (aka interface), which would include
224any querying/flagging stuff to identify what the algorithm can/can't do,
225its name, and other stuff like max/min block sizes, key sizes, etc. This
226would result in ENGINE similarly detaching its internal database of
227algorithm implementations from the function definitions that return
228interfaces to them. I think ...
229
230As for DSOs etc. Well the DSO code is pretty handy (but could be made much
231more so) for loading vendor's driver-libraries and talking to them in some
232generic way, but right now there's still big problems associated with
233actually putting OpenSSL code (ie. new ENGINEs, or anything else for that
234matter) in dynamically loadable libraries. These problems won't go away in
235a hurry so I don't think we should expect to have any kind of
236shared-library extensions any time soon - but solving the problems is a
237good thing to aim for, and would as a side-effect probably help make
238OpenSSL more usable as a shared-library itself (looking at the things
239needed to do this will show you why).
240
241One of the problems is that if you look at any of the ENGINE
242implementations, eg. hw_cswift.c or hw_ncipher.c, you'll see how it needs
243a variety of functionality and definitions from various areas of OpenSSL,
244including crypto/bn/, crypto/err/, crypto/ itself (locking for example),
245crypto/dso/, crypto/engine/, crypto/rsa, etc etc etc. So if similar code
246were to be suctioned off into shared libraries, the shared libraries would
247either have to duplicate all the definitions and code and avoid loader
248conflicts, or OpenSSL would have to somehow expose all that functionality
249to the shared-library. If this isn't a big enough problem, the issue of
250binary compatibility will be - anyone writing Apache modules can tell you
251that (Ralf? Ben? :-). However, I don't think OpenSSL would need to be
252quite so forgiving as Apache should be, so OpenSSL could simply tell its
253version to the DSO and leave the DSO with the problem of deciding whether
254to proceed or bail out for fear of binary incompatibilities.
255
256Certainly one thing that would go a long way to addressing this is to
257embark on a bit of an opaqueness mission. I've set the ENGINE code up with
258this in mind - it's so draconian that even to declare your own ENGINE, you
259have to get the engine code to create the underlying ENGINE structure, and
260then feed in the new ENGINE's function/method pointers through various
261"set" functions. The more of the code that takes on such a black-box
262approach, the more of the code that will be (a) easy to expose to shared
263libraries that need it, and (b) easy to expose to applications wanting to
264use OpenSSL itself as a shared-library. From my own explorations in
265OpenSSL, the biggest leviathan I've seen that is a problem in this respect
266is the BIGNUM code. Trying to "expose" the bignum code through any kind of
267organised "METHODs", let alone do all the necessary bignum operations
268solely through functions rather than direct access to the structures and
269macros, will be a massive pain in the "r"s.
270
271Anyway, I'm done for now - hope it was readable. Thoughts?
272
273Cheers,
274Geoff
275
276
277-----------------------------------==*==-----------------------------------
278
diff --git a/src/lib/libcrypto/engine/eng_all.c b/src/lib/libcrypto/engine/eng_all.c
new file mode 100644
index 0000000000..a35b3db9e8
--- /dev/null
+++ b/src/lib/libcrypto/engine/eng_all.c
@@ -0,0 +1,118 @@
1/* crypto/engine/eng_all.c -*- mode: C; c-file-style: "eay" -*- */
2/* Written by Richard Levitte <richard@levitte.org> for the OpenSSL
3 * project 2000.
4 */
5/* ====================================================================
6 * Copyright (c) 2000-2001 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59#include <openssl/err.h>
60#include <openssl/engine.h>
61#include "eng_int.h"
62
63#ifdef __OpenBSD__
64static int openbsd_default_loaded = 0;
65#endif
66
67void ENGINE_load_builtin_engines(void)
68 {
69 /* There's no longer any need for an "openssl" ENGINE unless, one day,
70 * it is the *only* way for standard builtin implementations to be be
71 * accessed (ie. it would be possible to statically link binaries with
72 * *no* builtin implementations). */
73#if 0
74 ENGINE_load_openssl();
75#endif
76 ENGINE_load_dynamic();
77#ifndef OPENSSL_NO_HW
78#ifndef OPENSSL_NO_HW_CSWIFT
79 ENGINE_load_cswift();
80#endif
81#ifndef OPENSSL_NO_HW_NCIPHER
82 ENGINE_load_chil();
83#endif
84#ifndef OPENSSL_NO_HW_ATALLA
85 ENGINE_load_atalla();
86#endif
87#ifndef OPENSSL_NO_HW_NURON
88 ENGINE_load_nuron();
89#endif
90#ifndef OPENSSL_NO_HW_UBSEC
91 ENGINE_load_ubsec();
92#endif
93#ifndef OPENSSL_NO_HW_AEP
94 ENGINE_load_aep();
95#endif
96#ifndef OPENSSL_NO_HW_SUREWARE
97 ENGINE_load_sureware();
98#endif
99#ifdef OPENSSL_OPENBSD_DEV_CRYPTO
100 ENGINE_load_openbsd_dev_crypto();
101#endif
102#ifdef __OpenBSD__
103 ENGINE_load_cryptodev();
104#endif
105#endif
106 }
107
108#ifdef __OpenBSD__
109void ENGINE_setup_openbsd(void) {
110 if (!openbsd_default_loaded) {
111 ENGINE_load_cryptodev();
112 ENGINE_register_all_complete();
113 }
114 openbsd_default_loaded=1;
115}
116#endif
117
118
diff --git a/src/lib/libcrypto/engine/eng_cnf.c b/src/lib/libcrypto/engine/eng_cnf.c
new file mode 100644
index 0000000000..8c0ae8a1ad
--- /dev/null
+++ b/src/lib/libcrypto/engine/eng_cnf.c
@@ -0,0 +1,242 @@
1/* eng_cnf.c */
2/* Written by Stephen Henson (shenson@bigfoot.com) for the OpenSSL
3 * project 2001.
4 */
5/* ====================================================================
6 * Copyright (c) 2001 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59#include <stdio.h>
60#include <openssl/crypto.h>
61#include "cryptlib.h"
62#include <openssl/conf.h>
63#include <openssl/engine.h>
64
65/* #define ENGINE_CONF_DEBUG */
66
67/* ENGINE config module */
68
69static char *skip_dot(char *name)
70 {
71 char *p;
72 p = strchr(name, '.');
73 if (p)
74 return p + 1;
75 return name;
76 }
77
78static STACK_OF(ENGINE) *initialized_engines = NULL;
79
80static int int_engine_init(ENGINE *e)
81 {
82 if (!ENGINE_init(e))
83 return 0;
84 if (!initialized_engines)
85 initialized_engines = sk_ENGINE_new_null();
86 if (!initialized_engines || !sk_ENGINE_push(initialized_engines, e))
87 {
88 ENGINE_finish(e);
89 return 0;
90 }
91 return 1;
92 }
93
94
95int int_engine_configure(char *name, char *value, const CONF *cnf)
96 {
97 int i;
98 int ret = 0;
99 long do_init = -1;
100 STACK_OF(CONF_VALUE) *ecmds;
101 CONF_VALUE *ecmd;
102 char *ctrlname, *ctrlvalue;
103 ENGINE *e = NULL;
104 name = skip_dot(name);
105#ifdef ENGINE_CONF_DEBUG
106 fprintf(stderr, "Configuring engine %s\n", name);
107#endif
108 /* Value is a section containing ENGINE commands */
109 ecmds = NCONF_get_section(cnf, value);
110
111 if (!ecmds)
112 {
113 ENGINEerr(ENGINE_F_INT_ENGINE_CONFIGURE, ENGINE_R_ENGINE_SECTION_ERROR);
114 return 0;
115 }
116
117 for (i = 0; i < sk_CONF_VALUE_num(ecmds); i++)
118 {
119 ecmd = sk_CONF_VALUE_value(ecmds, i);
120 ctrlname = skip_dot(ecmd->name);
121 ctrlvalue = ecmd->value;
122#ifdef ENGINE_CONF_DEBUG
123 fprintf(stderr, "ENGINE conf: doing ctrl(%s,%s)\n", ctrlname, ctrlvalue);
124#endif
125
126 /* First handle some special pseudo ctrls */
127
128 /* Override engine name to use */
129 if (!strcmp(ctrlname, "engine_id"))
130 name = ctrlvalue;
131 /* Load a dynamic ENGINE */
132 else if (!strcmp(ctrlname, "dynamic_path"))
133 {
134 e = ENGINE_by_id("dynamic");
135 if (!e)
136 goto err;
137 if (!ENGINE_ctrl_cmd_string(e, "SO_PATH", ctrlvalue, 0))
138 goto err;
139 if (!ENGINE_ctrl_cmd_string(e, "LIST_ADD", "2", 0))
140 goto err;
141 if (!ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0))
142 goto err;
143 }
144 /* ... add other pseudos here ... */
145 else
146 {
147 /* At this point we need an ENGINE structural reference
148 * if we don't already have one.
149 */
150 if (!e)
151 {
152 e = ENGINE_by_id(name);
153 if (!e)
154 return 0;
155 }
156 /* Allow "EMPTY" to mean no value: this allows a valid
157 * "value" to be passed to ctrls of type NO_INPUT
158 */
159 if (!strcmp(ctrlvalue, "EMPTY"))
160 ctrlvalue = NULL;
161 else if (!strcmp(ctrlname, "init"))
162 {
163 if (!NCONF_get_number_e(cnf, value, "init", &do_init))
164 goto err;
165 if (do_init == 1)
166 {
167 if (!int_engine_init(e))
168 goto err;
169 }
170 else if (do_init != 0)
171 {
172 ENGINEerr(ENGINE_F_INT_ENGINE_CONFIGURE, ENGINE_R_INVALID_INIT_VALUE);
173 goto err;
174 }
175 }
176 else if (!strcmp(ctrlname, "default_algorithms"))
177 {
178 if (!ENGINE_set_default_string(e, ctrlvalue))
179 goto err;
180 }
181 else if (!ENGINE_ctrl_cmd_string(e,
182 ctrlname, ctrlvalue, 0))
183 return 0;
184 }
185
186
187
188 }
189 if (e && (do_init == -1) && !int_engine_init(e))
190 goto err;
191 ret = 1;
192 err:
193 if (e)
194 ENGINE_free(e);
195 return ret;
196 }
197
198
199static int int_engine_module_init(CONF_IMODULE *md, const CONF *cnf)
200 {
201 STACK_OF(CONF_VALUE) *elist;
202 CONF_VALUE *cval;
203 int i;
204#ifdef ENGINE_CONF_DEBUG
205 fprintf(stderr, "Called engine module: name %s, value %s\n",
206 CONF_imodule_get_name(md), CONF_imodule_get_value(md));
207#endif
208 /* Value is a section containing ENGINEs to configure */
209 elist = NCONF_get_section(cnf, CONF_imodule_get_value(md));
210
211 if (!elist)
212 {
213 ENGINEerr(ENGINE_F_ENGINE_MODULE_INIT, ENGINE_R_ENGINES_SECTION_ERROR);
214 return 0;
215 }
216
217 for (i = 0; i < sk_CONF_VALUE_num(elist); i++)
218 {
219 cval = sk_CONF_VALUE_value(elist, i);
220 if (!int_engine_configure(cval->name, cval->value, cnf))
221 return 0;
222 }
223
224 return 1;
225 }
226
227static void int_engine_module_finish(CONF_IMODULE *md)
228 {
229 ENGINE *e;
230 while ((e = sk_ENGINE_pop(initialized_engines)))
231 ENGINE_finish(e);
232 sk_ENGINE_free(initialized_engines);
233 initialized_engines = NULL;
234 }
235
236
237void ENGINE_add_conf_module(void)
238 {
239 CONF_module_add("engines",
240 int_engine_module_init,
241 int_engine_module_finish);
242 }
diff --git a/src/lib/libcrypto/engine/eng_ctrl.c b/src/lib/libcrypto/engine/eng_ctrl.c
new file mode 100644
index 0000000000..ad3858395b
--- /dev/null
+++ b/src/lib/libcrypto/engine/eng_ctrl.c
@@ -0,0 +1,387 @@
1/* crypto/engine/eng_ctrl.c */
2/* ====================================================================
3 * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
16 *
17 * 3. All advertising materials mentioning features or use of this
18 * software must display the following acknowledgment:
19 * "This product includes software developed by the OpenSSL Project
20 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
21 *
22 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
23 * endorse or promote products derived from this software without
24 * prior written permission. For written permission, please contact
25 * licensing@OpenSSL.org.
26 *
27 * 5. Products derived from this software may not be called "OpenSSL"
28 * nor may "OpenSSL" appear in their names without prior written
29 * permission of the OpenSSL Project.
30 *
31 * 6. Redistributions of any form whatsoever must retain the following
32 * acknowledgment:
33 * "This product includes software developed by the OpenSSL Project
34 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
35 *
36 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
37 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
39 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
40 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
42 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
45 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
47 * OF THE POSSIBILITY OF SUCH DAMAGE.
48 * ====================================================================
49 *
50 * This product includes cryptographic software written by Eric Young
51 * (eay@cryptsoft.com). This product includes software written by Tim
52 * Hudson (tjh@cryptsoft.com).
53 *
54 */
55
56#include <openssl/crypto.h>
57#include "cryptlib.h"
58#include "eng_int.h"
59#include <openssl/engine.h>
60
61/* When querying a ENGINE-specific control command's 'description', this string
62 * is used if the ENGINE_CMD_DEFN has cmd_desc set to NULL. */
63static const char *int_no_description = "";
64
65/* These internal functions handle 'CMD'-related control commands when the
66 * ENGINE in question has asked us to take care of it (ie. the ENGINE did not
67 * set the ENGINE_FLAGS_MANUAL_CMD_CTRL flag. */
68
69static int int_ctrl_cmd_is_null(const ENGINE_CMD_DEFN *defn)
70 {
71 if((defn->cmd_num == 0) || (defn->cmd_name == NULL))
72 return 1;
73 return 0;
74 }
75
76static int int_ctrl_cmd_by_name(const ENGINE_CMD_DEFN *defn, const char *s)
77 {
78 int idx = 0;
79 while(!int_ctrl_cmd_is_null(defn) && (strcmp(defn->cmd_name, s) != 0))
80 {
81 idx++;
82 defn++;
83 }
84 if(int_ctrl_cmd_is_null(defn))
85 /* The given name wasn't found */
86 return -1;
87 return idx;
88 }
89
90static int int_ctrl_cmd_by_num(const ENGINE_CMD_DEFN *defn, unsigned int num)
91 {
92 int idx = 0;
93 /* NB: It is stipulated that 'cmd_defn' lists are ordered by cmd_num. So
94 * our searches don't need to take any longer than necessary. */
95 while(!int_ctrl_cmd_is_null(defn) && (defn->cmd_num < num))
96 {
97 idx++;
98 defn++;
99 }
100 if(defn->cmd_num == num)
101 return idx;
102 /* The given cmd_num wasn't found */
103 return -1;
104 }
105
106static int int_ctrl_helper(ENGINE *e, int cmd, long i, void *p, void (*f)())
107 {
108 int idx;
109 char *s = (char *)p;
110 /* Take care of the easy one first (eg. it requires no searches) */
111 if(cmd == ENGINE_CTRL_GET_FIRST_CMD_TYPE)
112 {
113 if((e->cmd_defns == NULL) || int_ctrl_cmd_is_null(e->cmd_defns))
114 return 0;
115 return e->cmd_defns->cmd_num;
116 }
117 /* One or two commands require that "p" be a valid string buffer */
118 if((cmd == ENGINE_CTRL_GET_CMD_FROM_NAME) ||
119 (cmd == ENGINE_CTRL_GET_NAME_FROM_CMD) ||
120 (cmd == ENGINE_CTRL_GET_DESC_FROM_CMD))
121 {
122 if(s == NULL)
123 {
124 ENGINEerr(ENGINE_F_INT_CTRL_HELPER,
125 ERR_R_PASSED_NULL_PARAMETER);
126 return -1;
127 }
128 }
129 /* Now handle cmd_name -> cmd_num conversion */
130 if(cmd == ENGINE_CTRL_GET_CMD_FROM_NAME)
131 {
132 if((e->cmd_defns == NULL) || ((idx = int_ctrl_cmd_by_name(
133 e->cmd_defns, s)) < 0))
134 {
135 ENGINEerr(ENGINE_F_INT_CTRL_HELPER,
136 ENGINE_R_INVALID_CMD_NAME);
137 return -1;
138 }
139 return e->cmd_defns[idx].cmd_num;
140 }
141 /* For the rest of the commands, the 'long' argument must specify a
142 * valie command number - so we need to conduct a search. */
143 if((e->cmd_defns == NULL) || ((idx = int_ctrl_cmd_by_num(e->cmd_defns,
144 (unsigned int)i)) < 0))
145 {
146 ENGINEerr(ENGINE_F_INT_CTRL_HELPER,
147 ENGINE_R_INVALID_CMD_NUMBER);
148 return -1;
149 }
150 /* Now the logic splits depending on command type */
151 switch(cmd)
152 {
153 case ENGINE_CTRL_GET_NEXT_CMD_TYPE:
154 idx++;
155 if(int_ctrl_cmd_is_null(e->cmd_defns + idx))
156 /* end-of-list */
157 return 0;
158 else
159 return e->cmd_defns[idx].cmd_num;
160 case ENGINE_CTRL_GET_NAME_LEN_FROM_CMD:
161 return strlen(e->cmd_defns[idx].cmd_name);
162 case ENGINE_CTRL_GET_NAME_FROM_CMD:
163 return sprintf(s, "%s", e->cmd_defns[idx].cmd_name);
164 case ENGINE_CTRL_GET_DESC_LEN_FROM_CMD:
165 if(e->cmd_defns[idx].cmd_desc)
166 return strlen(e->cmd_defns[idx].cmd_desc);
167 return strlen(int_no_description);
168 case ENGINE_CTRL_GET_DESC_FROM_CMD:
169 if(e->cmd_defns[idx].cmd_desc)
170 return sprintf(s, "%s", e->cmd_defns[idx].cmd_desc);
171 return sprintf(s, "%s", int_no_description);
172 case ENGINE_CTRL_GET_CMD_FLAGS:
173 return e->cmd_defns[idx].cmd_flags;
174 }
175 /* Shouldn't really be here ... */
176 ENGINEerr(ENGINE_F_INT_CTRL_HELPER,ENGINE_R_INTERNAL_LIST_ERROR);
177 return -1;
178 }
179
180int ENGINE_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)())
181 {
182 int ctrl_exists, ref_exists;
183 if(e == NULL)
184 {
185 ENGINEerr(ENGINE_F_ENGINE_CTRL,ERR_R_PASSED_NULL_PARAMETER);
186 return 0;
187 }
188 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
189 ref_exists = ((e->struct_ref > 0) ? 1 : 0);
190 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
191 ctrl_exists = ((e->ctrl == NULL) ? 0 : 1);
192 if(!ref_exists)
193 {
194 ENGINEerr(ENGINE_F_ENGINE_CTRL,ENGINE_R_NO_REFERENCE);
195 return 0;
196 }
197 /* Intercept any "root-level" commands before trying to hand them on to
198 * ctrl() handlers. */
199 switch(cmd)
200 {
201 case ENGINE_CTRL_HAS_CTRL_FUNCTION:
202 return ctrl_exists;
203 case ENGINE_CTRL_GET_FIRST_CMD_TYPE:
204 case ENGINE_CTRL_GET_NEXT_CMD_TYPE:
205 case ENGINE_CTRL_GET_CMD_FROM_NAME:
206 case ENGINE_CTRL_GET_NAME_LEN_FROM_CMD:
207 case ENGINE_CTRL_GET_NAME_FROM_CMD:
208 case ENGINE_CTRL_GET_DESC_LEN_FROM_CMD:
209 case ENGINE_CTRL_GET_DESC_FROM_CMD:
210 case ENGINE_CTRL_GET_CMD_FLAGS:
211 if(ctrl_exists && !(e->flags & ENGINE_FLAGS_MANUAL_CMD_CTRL))
212 return int_ctrl_helper(e,cmd,i,p,f);
213 if(!ctrl_exists)
214 {
215 ENGINEerr(ENGINE_F_ENGINE_CTRL,ENGINE_R_NO_CONTROL_FUNCTION);
216 /* For these cmd-related functions, failure is indicated
217 * by a -1 return value (because 0 is used as a valid
218 * return in some places). */
219 return -1;
220 }
221 default:
222 break;
223 }
224 /* Anything else requires a ctrl() handler to exist. */
225 if(!ctrl_exists)
226 {
227 ENGINEerr(ENGINE_F_ENGINE_CTRL,ENGINE_R_NO_CONTROL_FUNCTION);
228 return 0;
229 }
230 return e->ctrl(e, cmd, i, p, f);
231 }
232
233int ENGINE_cmd_is_executable(ENGINE *e, int cmd)
234 {
235 int flags;
236 if((flags = ENGINE_ctrl(e, ENGINE_CTRL_GET_CMD_FLAGS, cmd, NULL, NULL)) < 0)
237 {
238 ENGINEerr(ENGINE_F_ENGINE_CMD_IS_EXECUTABLE,
239 ENGINE_R_INVALID_CMD_NUMBER);
240 return 0;
241 }
242 if(!(flags & ENGINE_CMD_FLAG_NO_INPUT) &&
243 !(flags & ENGINE_CMD_FLAG_NUMERIC) &&
244 !(flags & ENGINE_CMD_FLAG_STRING))
245 return 0;
246 return 1;
247 }
248
249int ENGINE_ctrl_cmd(ENGINE *e, const char *cmd_name,
250 long i, void *p, void (*f)(), int cmd_optional)
251 {
252 int num;
253
254 if((e == NULL) || (cmd_name == NULL))
255 {
256 ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
257 ERR_R_PASSED_NULL_PARAMETER);
258 return 0;
259 }
260 if((e->ctrl == NULL) || ((num = ENGINE_ctrl(e,
261 ENGINE_CTRL_GET_CMD_FROM_NAME,
262 0, (void *)cmd_name, NULL)) <= 0))
263 {
264 /* If the command didn't *have* to be supported, we fake
265 * success. This allows certain settings to be specified for
266 * multiple ENGINEs and only require a change of ENGINE id
267 * (without having to selectively apply settings). Eg. changing
268 * from a hardware device back to the regular software ENGINE
269 * without editing the config file, etc. */
270 if(cmd_optional)
271 {
272 ERR_clear_error();
273 return 1;
274 }
275 ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD,
276 ENGINE_R_INVALID_CMD_NAME);
277 return 0;
278 }
279 /* Force the result of the control command to 0 or 1, for the reasons
280 * mentioned before. */
281 if (ENGINE_ctrl(e, num, i, p, f))
282 return 1;
283 return 0;
284 }
285
286int ENGINE_ctrl_cmd_string(ENGINE *e, const char *cmd_name, const char *arg,
287 int cmd_optional)
288 {
289 int num, flags;
290 long l;
291 char *ptr;
292 if((e == NULL) || (cmd_name == NULL))
293 {
294 ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
295 ERR_R_PASSED_NULL_PARAMETER);
296 return 0;
297 }
298 if((e->ctrl == NULL) || ((num = ENGINE_ctrl(e,
299 ENGINE_CTRL_GET_CMD_FROM_NAME,
300 0, (void *)cmd_name, NULL)) <= 0))
301 {
302 /* If the command didn't *have* to be supported, we fake
303 * success. This allows certain settings to be specified for
304 * multiple ENGINEs and only require a change of ENGINE id
305 * (without having to selectively apply settings). Eg. changing
306 * from a hardware device back to the regular software ENGINE
307 * without editing the config file, etc. */
308 if(cmd_optional)
309 {
310 ERR_clear_error();
311 return 1;
312 }
313 ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
314 ENGINE_R_INVALID_CMD_NAME);
315 return 0;
316 }
317 if(!ENGINE_cmd_is_executable(e, num))
318 {
319 ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
320 ENGINE_R_CMD_NOT_EXECUTABLE);
321 return 0;
322 }
323 if((flags = ENGINE_ctrl(e, ENGINE_CTRL_GET_CMD_FLAGS, num, NULL, NULL)) < 0)
324 {
325 /* Shouldn't happen, given that ENGINE_cmd_is_executable()
326 * returned success. */
327 ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
328 ENGINE_R_INTERNAL_LIST_ERROR);
329 return 0;
330 }
331 /* If the command takes no input, there must be no input. And vice
332 * versa. */
333 if(flags & ENGINE_CMD_FLAG_NO_INPUT)
334 {
335 if(arg != NULL)
336 {
337 ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
338 ENGINE_R_COMMAND_TAKES_NO_INPUT);
339 return 0;
340 }
341 /* We deliberately force the result of ENGINE_ctrl() to 0 or 1
342 * rather than returning it as "return data". This is to ensure
343 * usage of these commands is consistent across applications and
344 * that certain applications don't understand it one way, and
345 * others another. */
346 if(ENGINE_ctrl(e, num, 0, (void *)arg, NULL))
347 return 1;
348 return 0;
349 }
350 /* So, we require input */
351 if(arg == NULL)
352 {
353 ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
354 ENGINE_R_COMMAND_TAKES_INPUT);
355 return 0;
356 }
357 /* If it takes string input, that's easy */
358 if(flags & ENGINE_CMD_FLAG_STRING)
359 {
360 /* Same explanation as above */
361 if(ENGINE_ctrl(e, num, 0, (void *)arg, NULL))
362 return 1;
363 return 0;
364 }
365 /* If it doesn't take numeric either, then it is unsupported for use in
366 * a config-setting situation, which is what this function is for. This
367 * should never happen though, because ENGINE_cmd_is_executable() was
368 * used. */
369 if(!(flags & ENGINE_CMD_FLAG_NUMERIC))
370 {
371 ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
372 ENGINE_R_INTERNAL_LIST_ERROR);
373 return 0;
374 }
375 l = strtol(arg, &ptr, 10);
376 if((arg == ptr) || (*ptr != '\0'))
377 {
378 ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
379 ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER);
380 return 0;
381 }
382 /* Force the result of the control command to 0 or 1, for the reasons
383 * mentioned before. */
384 if(ENGINE_ctrl(e, num, l, NULL, NULL))
385 return 1;
386 return 0;
387 }
diff --git a/src/lib/libcrypto/engine/eng_dyn.c b/src/lib/libcrypto/engine/eng_dyn.c
new file mode 100644
index 0000000000..4fefcc0cae
--- /dev/null
+++ b/src/lib/libcrypto/engine/eng_dyn.c
@@ -0,0 +1,446 @@
1/* crypto/engine/eng_dyn.c */
2/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
3 * project 2001.
4 */
5/* ====================================================================
6 * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59
60#include <stdio.h>
61#include <openssl/crypto.h>
62#include "cryptlib.h"
63#include "eng_int.h"
64#include <openssl/engine.h>
65#include <openssl/dso.h>
66
67/* Shared libraries implementing ENGINEs for use by the "dynamic" ENGINE loader
68 * should implement the hook-up functions with the following prototypes. */
69
70/* Our ENGINE handlers */
71static int dynamic_init(ENGINE *e);
72static int dynamic_finish(ENGINE *e);
73static int dynamic_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)());
74/* Predeclare our context type */
75typedef struct st_dynamic_data_ctx dynamic_data_ctx;
76/* The implementation for the important control command */
77static int dynamic_load(ENGINE *e, dynamic_data_ctx *ctx);
78
79#define DYNAMIC_CMD_SO_PATH ENGINE_CMD_BASE
80#define DYNAMIC_CMD_NO_VCHECK (ENGINE_CMD_BASE + 1)
81#define DYNAMIC_CMD_ID (ENGINE_CMD_BASE + 2)
82#define DYNAMIC_CMD_LIST_ADD (ENGINE_CMD_BASE + 3)
83#define DYNAMIC_CMD_LOAD (ENGINE_CMD_BASE + 4)
84
85/* The constants used when creating the ENGINE */
86static const char *engine_dynamic_id = "dynamic";
87static const char *engine_dynamic_name = "Dynamic engine loading support";
88static const ENGINE_CMD_DEFN dynamic_cmd_defns[] = {
89 {DYNAMIC_CMD_SO_PATH,
90 "SO_PATH",
91 "Specifies the path to the new ENGINE shared library",
92 ENGINE_CMD_FLAG_STRING},
93 {DYNAMIC_CMD_NO_VCHECK,
94 "NO_VCHECK",
95 "Specifies to continue even if version checking fails (boolean)",
96 ENGINE_CMD_FLAG_NUMERIC},
97 {DYNAMIC_CMD_ID,
98 "ID",
99 "Specifies an ENGINE id name for loading",
100 ENGINE_CMD_FLAG_STRING},
101 {DYNAMIC_CMD_LIST_ADD,
102 "LIST_ADD",
103 "Whether to add a loaded ENGINE to the internal list (0=no,1=yes,2=mandatory)",
104 ENGINE_CMD_FLAG_NUMERIC},
105 {DYNAMIC_CMD_LOAD,
106 "LOAD",
107 "Load up the ENGINE specified by other settings",
108 ENGINE_CMD_FLAG_NO_INPUT},
109 {0, NULL, NULL, 0}
110 };
111static const ENGINE_CMD_DEFN dynamic_cmd_defns_empty[] = {
112 {0, NULL, NULL, 0}
113 };
114
115/* Loading code stores state inside the ENGINE structure via the "ex_data"
116 * element. We load all our state into a single structure and use that as a
117 * single context in the "ex_data" stack. */
118struct st_dynamic_data_ctx
119 {
120 /* The DSO object we load that supplies the ENGINE code */
121 DSO *dynamic_dso;
122 /* The function pointer to the version checking shared library function */
123 dynamic_v_check_fn v_check;
124 /* The function pointer to the engine-binding shared library function */
125 dynamic_bind_engine bind_engine;
126 /* The default name/path for loading the shared library */
127 const char *DYNAMIC_LIBNAME;
128 /* Whether to continue loading on a version check failure */
129 int no_vcheck;
130 /* If non-NULL, stipulates the 'id' of the ENGINE to be loaded */
131 const char *engine_id;
132 /* If non-zero, a successfully loaded ENGINE should be added to the internal
133 * ENGINE list. If 2, the add must succeed or the entire load should fail. */
134 int list_add_value;
135 /* The symbol name for the version checking function */
136 const char *DYNAMIC_F1;
137 /* The symbol name for the "initialise ENGINE structure" function */
138 const char *DYNAMIC_F2;
139 };
140
141/* This is the "ex_data" index we obtain and reserve for use with our context
142 * structure. */
143static int dynamic_ex_data_idx = -1;
144
145/* Because our ex_data element may or may not get allocated depending on whether
146 * a "first-use" occurs before the ENGINE is freed, we have a memory leak
147 * problem to solve. We can't declare a "new" handler for the ex_data as we
148 * don't want a dynamic_data_ctx in *all* ENGINE structures of all types (this
149 * is a bug in the design of CRYPTO_EX_DATA). As such, we just declare a "free"
150 * handler and that will get called if an ENGINE is being destroyed and there
151 * was an ex_data element corresponding to our context type. */
152static void dynamic_data_ctx_free_func(void *parent, void *ptr,
153 CRYPTO_EX_DATA *ad, int idx, long argl, void *argp)
154 {
155 if(ptr)
156 {
157 dynamic_data_ctx *ctx = (dynamic_data_ctx *)ptr;
158 if(ctx->dynamic_dso)
159 DSO_free(ctx->dynamic_dso);
160 OPENSSL_free(ctx);
161 }
162 }
163
164/* Construct the per-ENGINE context. We create it blindly and then use a lock to
165 * check for a race - if so, all but one of the threads "racing" will have
166 * wasted their time. The alternative involves creating everything inside the
167 * lock which is far worse. */
168static int dynamic_set_data_ctx(ENGINE *e, dynamic_data_ctx **ctx)
169 {
170 dynamic_data_ctx *c;
171 c = OPENSSL_malloc(sizeof(dynamic_data_ctx));
172 if(!ctx)
173 {
174 ENGINEerr(ENGINE_F_SET_DATA_CTX,ERR_R_MALLOC_FAILURE);
175 return 0;
176 }
177 memset(c, 0, sizeof(dynamic_data_ctx));
178 c->dynamic_dso = NULL;
179 c->v_check = NULL;
180 c->bind_engine = NULL;
181 c->DYNAMIC_LIBNAME = NULL;
182 c->no_vcheck = 0;
183 c->engine_id = NULL;
184 c->list_add_value = 0;
185 c->DYNAMIC_F1 = "v_check";
186 c->DYNAMIC_F2 = "bind_engine";
187 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
188 if((*ctx = (dynamic_data_ctx *)ENGINE_get_ex_data(e,
189 dynamic_ex_data_idx)) == NULL)
190 {
191 /* Good, we're the first */
192 ENGINE_set_ex_data(e, dynamic_ex_data_idx, c);
193 *ctx = c;
194 c = NULL;
195 }
196 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
197 /* If we lost the race to set the context, c is non-NULL and *ctx is the
198 * context of the thread that won. */
199 if(c)
200 OPENSSL_free(c);
201 return 1;
202 }
203
204/* This function retrieves the context structure from an ENGINE's "ex_data", or
205 * if it doesn't exist yet, sets it up. */
206static dynamic_data_ctx *dynamic_get_data_ctx(ENGINE *e)
207 {
208 dynamic_data_ctx *ctx;
209 if(dynamic_ex_data_idx < 0)
210 {
211 /* Create and register the ENGINE ex_data, and associate our
212 * "free" function with it to ensure any allocated contexts get
213 * freed when an ENGINE goes underground. */
214 int new_idx = ENGINE_get_ex_new_index(0, NULL, NULL, NULL,
215 dynamic_data_ctx_free_func);
216 if(new_idx == -1)
217 {
218 ENGINEerr(ENGINE_F_DYNAMIC_GET_DATA_CTX,ENGINE_R_NO_INDEX);
219 return NULL;
220 }
221 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
222 /* Avoid a race by checking again inside this lock */
223 if(dynamic_ex_data_idx < 0)
224 {
225 /* Good, someone didn't beat us to it */
226 dynamic_ex_data_idx = new_idx;
227 new_idx = -1;
228 }
229 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
230 /* In theory we could "give back" the index here if
231 * (new_idx>-1), but it's not possible and wouldn't gain us much
232 * if it were. */
233 }
234 ctx = (dynamic_data_ctx *)ENGINE_get_ex_data(e, dynamic_ex_data_idx);
235 /* Check if the context needs to be created */
236 if((ctx == NULL) && !dynamic_set_data_ctx(e, &ctx))
237 /* "set_data" will set errors if necessary */
238 return NULL;
239 return ctx;
240 }
241
242static ENGINE *engine_dynamic(void)
243 {
244 ENGINE *ret = ENGINE_new();
245 if(!ret)
246 return NULL;
247 if(!ENGINE_set_id(ret, engine_dynamic_id) ||
248 !ENGINE_set_name(ret, engine_dynamic_name) ||
249 !ENGINE_set_init_function(ret, dynamic_init) ||
250 !ENGINE_set_finish_function(ret, dynamic_finish) ||
251 !ENGINE_set_ctrl_function(ret, dynamic_ctrl) ||
252 !ENGINE_set_flags(ret, ENGINE_FLAGS_BY_ID_COPY) ||
253 !ENGINE_set_cmd_defns(ret, dynamic_cmd_defns))
254 {
255 ENGINE_free(ret);
256 return NULL;
257 }
258 return ret;
259 }
260
261void ENGINE_load_dynamic(void)
262 {
263 ENGINE *toadd = engine_dynamic();
264 if(!toadd) return;
265 ENGINE_add(toadd);
266 /* If the "add" worked, it gets a structural reference. So either way,
267 * we release our just-created reference. */
268 ENGINE_free(toadd);
269 /* If the "add" didn't work, it was probably a conflict because it was
270 * already added (eg. someone calling ENGINE_load_blah then calling
271 * ENGINE_load_builtin_engines() perhaps). */
272 ERR_clear_error();
273 }
274
275static int dynamic_init(ENGINE *e)
276 {
277 /* We always return failure - the "dyanamic" engine itself can't be used
278 * for anything. */
279 return 0;
280 }
281
282static int dynamic_finish(ENGINE *e)
283 {
284 /* This should never be called on account of "dynamic_init" always
285 * failing. */
286 return 0;
287 }
288
289static int dynamic_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)())
290 {
291 dynamic_data_ctx *ctx = dynamic_get_data_ctx(e);
292 int initialised;
293
294 if(!ctx)
295 {
296 ENGINEerr(ENGINE_F_DYNAMIC_CTRL,ENGINE_R_NOT_LOADED);
297 return 0;
298 }
299 initialised = ((ctx->dynamic_dso == NULL) ? 0 : 1);
300 /* All our control commands require the ENGINE to be uninitialised */
301 if(initialised)
302 {
303 ENGINEerr(ENGINE_F_DYNAMIC_CTRL,
304 ENGINE_R_ALREADY_LOADED);
305 return 0;
306 }
307 switch(cmd)
308 {
309 case DYNAMIC_CMD_SO_PATH:
310 /* a NULL 'p' or a string of zero-length is the same thing */
311 if(p && (strlen((const char *)p) < 1))
312 p = NULL;
313 ctx->DYNAMIC_LIBNAME = (const char *)p;
314 return 1;
315 case DYNAMIC_CMD_NO_VCHECK:
316 ctx->no_vcheck = ((i == 0) ? 0 : 1);
317 return 1;
318 case DYNAMIC_CMD_ID:
319 /* a NULL 'p' or a string of zero-length is the same thing */
320 if(p && (strlen((const char *)p) < 1))
321 p = NULL;
322 ctx->engine_id = (const char *)p;
323 return 1;
324 case DYNAMIC_CMD_LIST_ADD:
325 if((i < 0) || (i > 2))
326 {
327 ENGINEerr(ENGINE_F_DYNAMIC_CTRL,
328 ENGINE_R_INVALID_ARGUMENT);
329 return 0;
330 }
331 ctx->list_add_value = (int)i;
332 return 1;
333 case DYNAMIC_CMD_LOAD:
334 return dynamic_load(e, ctx);
335 default:
336 break;
337 }
338 ENGINEerr(ENGINE_F_DYNAMIC_CTRL,ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED);
339 return 0;
340 }
341
342static int dynamic_load(ENGINE *e, dynamic_data_ctx *ctx)
343 {
344 ENGINE cpy;
345 dynamic_fns fns;
346
347 if(!ctx->DYNAMIC_LIBNAME || ((ctx->dynamic_dso = DSO_load(NULL,
348 ctx->DYNAMIC_LIBNAME, NULL, 0)) == NULL))
349 {
350 ENGINEerr(ENGINE_F_DYNAMIC_LOAD,
351 ENGINE_R_DSO_NOT_FOUND);
352 return 0;
353 }
354 /* We have to find a bind function otherwise it'll always end badly */
355 if(!(ctx->bind_engine = (dynamic_bind_engine)DSO_bind_func(
356 ctx->dynamic_dso, ctx->DYNAMIC_F2)))
357 {
358 ctx->bind_engine = NULL;
359 DSO_free(ctx->dynamic_dso);
360 ctx->dynamic_dso = NULL;
361 ENGINEerr(ENGINE_F_DYNAMIC_LOAD,
362 ENGINE_R_DSO_FAILURE);
363 return 0;
364 }
365 /* Do we perform version checking? */
366 if(!ctx->no_vcheck)
367 {
368 unsigned long vcheck_res = 0;
369 /* Now we try to find a version checking function and decide how
370 * to cope with failure if/when it fails. */
371 ctx->v_check = (dynamic_v_check_fn)DSO_bind_func(
372 ctx->dynamic_dso, ctx->DYNAMIC_F1);
373 if(ctx->v_check)
374 vcheck_res = ctx->v_check(OSSL_DYNAMIC_VERSION);
375 /* We fail if the version checker veto'd the load *or* if it is
376 * deferring to us (by returning its version) and we think it is
377 * too old. */
378 if(vcheck_res < OSSL_DYNAMIC_OLDEST)
379 {
380 /* Fail */
381 ctx->bind_engine = NULL;
382 ctx->v_check = NULL;
383 DSO_free(ctx->dynamic_dso);
384 ctx->dynamic_dso = NULL;
385 ENGINEerr(ENGINE_F_DYNAMIC_LOAD,
386 ENGINE_R_VERSION_INCOMPATIBILITY);
387 return 0;
388 }
389 }
390 /* First binary copy the ENGINE structure so that we can roll back if
391 * the hand-over fails */
392 memcpy(&cpy, e, sizeof(ENGINE));
393 /* Provide the ERR, "ex_data", memory, and locking callbacks so the
394 * loaded library uses our state rather than its own. FIXME: As noted in
395 * engine.h, much of this would be simplified if each area of code
396 * provided its own "summary" structure of all related callbacks. It
397 * would also increase opaqueness. */
398 fns.err_fns = ERR_get_implementation();
399 fns.ex_data_fns = CRYPTO_get_ex_data_implementation();
400 CRYPTO_get_mem_functions(&fns.mem_fns.malloc_cb,
401 &fns.mem_fns.realloc_cb,
402 &fns.mem_fns.free_cb);
403 fns.lock_fns.lock_locking_cb = CRYPTO_get_locking_callback();
404 fns.lock_fns.lock_add_lock_cb = CRYPTO_get_add_lock_callback();
405 fns.lock_fns.dynlock_create_cb = CRYPTO_get_dynlock_create_callback();
406 fns.lock_fns.dynlock_lock_cb = CRYPTO_get_dynlock_lock_callback();
407 fns.lock_fns.dynlock_destroy_cb = CRYPTO_get_dynlock_destroy_callback();
408 /* Now that we've loaded the dynamic engine, make sure no "dynamic"
409 * ENGINE elements will show through. */
410 engine_set_all_null(e);
411
412 /* Try to bind the ENGINE onto our own ENGINE structure */
413 if(!ctx->bind_engine(e, ctx->engine_id, &fns))
414 {
415 ctx->bind_engine = NULL;
416 ctx->v_check = NULL;
417 DSO_free(ctx->dynamic_dso);
418 ctx->dynamic_dso = NULL;
419 ENGINEerr(ENGINE_F_DYNAMIC_LOAD,ENGINE_R_INIT_FAILED);
420 /* Copy the original ENGINE structure back */
421 memcpy(e, &cpy, sizeof(ENGINE));
422 return 0;
423 }
424 /* Do we try to add this ENGINE to the internal list too? */
425 if(ctx->list_add_value > 0)
426 {
427 if(!ENGINE_add(e))
428 {
429 /* Do we tolerate this or fail? */
430 if(ctx->list_add_value > 1)
431 {
432 /* Fail - NB: By this time, it's too late to
433 * rollback, and trying to do so allows the
434 * bind_engine() code to have created leaks. We
435 * just have to fail where we are, after the
436 * ENGINE has changed. */
437 ENGINEerr(ENGINE_F_DYNAMIC_LOAD,
438 ENGINE_R_CONFLICTING_ENGINE_ID);
439 return 0;
440 }
441 /* Tolerate */
442 ERR_clear_error();
443 }
444 }
445 return 1;
446 }
diff --git a/src/lib/libcrypto/engine/eng_err.c b/src/lib/libcrypto/engine/eng_err.c
new file mode 100644
index 0000000000..f6c5630395
--- /dev/null
+++ b/src/lib/libcrypto/engine/eng_err.c
@@ -0,0 +1,165 @@
1/* crypto/engine/eng_err.c */
2/* ====================================================================
3 * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
16 *
17 * 3. All advertising materials mentioning features or use of this
18 * software must display the following acknowledgment:
19 * "This product includes software developed by the OpenSSL Project
20 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
21 *
22 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
23 * endorse or promote products derived from this software without
24 * prior written permission. For written permission, please contact
25 * openssl-core@OpenSSL.org.
26 *
27 * 5. Products derived from this software may not be called "OpenSSL"
28 * nor may "OpenSSL" appear in their names without prior written
29 * permission of the OpenSSL Project.
30 *
31 * 6. Redistributions of any form whatsoever must retain the following
32 * acknowledgment:
33 * "This product includes software developed by the OpenSSL Project
34 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
35 *
36 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
37 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
39 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
40 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
42 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
45 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
47 * OF THE POSSIBILITY OF SUCH DAMAGE.
48 * ====================================================================
49 *
50 * This product includes cryptographic software written by Eric Young
51 * (eay@cryptsoft.com). This product includes software written by Tim
52 * Hudson (tjh@cryptsoft.com).
53 *
54 */
55
56/* NOTE: this file was auto generated by the mkerr.pl script: any changes
57 * made to it will be overwritten when the script next updates this file,
58 * only reason strings will be preserved.
59 */
60
61#include <stdio.h>
62#include <openssl/err.h>
63#include <openssl/engine.h>
64
65/* BEGIN ERROR CODES */
66#ifndef OPENSSL_NO_ERR
67static ERR_STRING_DATA ENGINE_str_functs[]=
68 {
69{ERR_PACK(0,ENGINE_F_DYNAMIC_CTRL,0), "DYNAMIC_CTRL"},
70{ERR_PACK(0,ENGINE_F_DYNAMIC_GET_DATA_CTX,0), "DYNAMIC_GET_DATA_CTX"},
71{ERR_PACK(0,ENGINE_F_DYNAMIC_LOAD,0), "DYNAMIC_LOAD"},
72{ERR_PACK(0,ENGINE_F_ENGINE_ADD,0), "ENGINE_add"},
73{ERR_PACK(0,ENGINE_F_ENGINE_BY_ID,0), "ENGINE_by_id"},
74{ERR_PACK(0,ENGINE_F_ENGINE_CMD_IS_EXECUTABLE,0), "ENGINE_cmd_is_executable"},
75{ERR_PACK(0,ENGINE_F_ENGINE_CTRL,0), "ENGINE_ctrl"},
76{ERR_PACK(0,ENGINE_F_ENGINE_CTRL_CMD,0), "ENGINE_ctrl_cmd"},
77{ERR_PACK(0,ENGINE_F_ENGINE_CTRL_CMD_STRING,0), "ENGINE_ctrl_cmd_string"},
78{ERR_PACK(0,ENGINE_F_ENGINE_FINISH,0), "ENGINE_finish"},
79{ERR_PACK(0,ENGINE_F_ENGINE_FREE,0), "ENGINE_free"},
80{ERR_PACK(0,ENGINE_F_ENGINE_GET_CIPHER,0), "ENGINE_get_cipher"},
81{ERR_PACK(0,ENGINE_F_ENGINE_GET_DEFAULT_TYPE,0), "ENGINE_GET_DEFAULT_TYPE"},
82{ERR_PACK(0,ENGINE_F_ENGINE_GET_DIGEST,0), "ENGINE_get_digest"},
83{ERR_PACK(0,ENGINE_F_ENGINE_GET_NEXT,0), "ENGINE_get_next"},
84{ERR_PACK(0,ENGINE_F_ENGINE_GET_PREV,0), "ENGINE_get_prev"},
85{ERR_PACK(0,ENGINE_F_ENGINE_INIT,0), "ENGINE_init"},
86{ERR_PACK(0,ENGINE_F_ENGINE_LIST_ADD,0), "ENGINE_LIST_ADD"},
87{ERR_PACK(0,ENGINE_F_ENGINE_LIST_REMOVE,0), "ENGINE_LIST_REMOVE"},
88{ERR_PACK(0,ENGINE_F_ENGINE_LOAD_PRIVATE_KEY,0), "ENGINE_load_private_key"},
89{ERR_PACK(0,ENGINE_F_ENGINE_LOAD_PUBLIC_KEY,0), "ENGINE_load_public_key"},
90{ERR_PACK(0,ENGINE_F_ENGINE_MODULE_INIT,0), "ENGINE_MODULE_INIT"},
91{ERR_PACK(0,ENGINE_F_ENGINE_NEW,0), "ENGINE_new"},
92{ERR_PACK(0,ENGINE_F_ENGINE_REMOVE,0), "ENGINE_remove"},
93{ERR_PACK(0,ENGINE_F_ENGINE_SET_DEFAULT_STRING,0), "ENGINE_set_default_string"},
94{ERR_PACK(0,ENGINE_F_ENGINE_SET_DEFAULT_TYPE,0), "ENGINE_SET_DEFAULT_TYPE"},
95{ERR_PACK(0,ENGINE_F_ENGINE_SET_ID,0), "ENGINE_set_id"},
96{ERR_PACK(0,ENGINE_F_ENGINE_SET_NAME,0), "ENGINE_set_name"},
97{ERR_PACK(0,ENGINE_F_ENGINE_TABLE_REGISTER,0), "ENGINE_TABLE_REGISTER"},
98{ERR_PACK(0,ENGINE_F_ENGINE_UNLOAD_KEY,0), "ENGINE_UNLOAD_KEY"},
99{ERR_PACK(0,ENGINE_F_INT_CTRL_HELPER,0), "INT_CTRL_HELPER"},
100{ERR_PACK(0,ENGINE_F_INT_ENGINE_CONFIGURE,0), "INT_ENGINE_CONFIGURE"},
101{ERR_PACK(0,ENGINE_F_LOG_MESSAGE,0), "LOG_MESSAGE"},
102{ERR_PACK(0,ENGINE_F_SET_DATA_CTX,0), "SET_DATA_CTX"},
103{0,NULL}
104 };
105
106static ERR_STRING_DATA ENGINE_str_reasons[]=
107 {
108{ENGINE_R_ALREADY_LOADED ,"already loaded"},
109{ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER ,"argument is not a number"},
110{ENGINE_R_CMD_NOT_EXECUTABLE ,"cmd not executable"},
111{ENGINE_R_COMMAND_TAKES_INPUT ,"command takes input"},
112{ENGINE_R_COMMAND_TAKES_NO_INPUT ,"command takes no input"},
113{ENGINE_R_CONFLICTING_ENGINE_ID ,"conflicting engine id"},
114{ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED ,"ctrl command not implemented"},
115{ENGINE_R_DH_NOT_IMPLEMENTED ,"dh not implemented"},
116{ENGINE_R_DSA_NOT_IMPLEMENTED ,"dsa not implemented"},
117{ENGINE_R_DSO_FAILURE ,"DSO failure"},
118{ENGINE_R_DSO_NOT_FOUND ,"dso not found"},
119{ENGINE_R_ENGINES_SECTION_ERROR ,"engines section error"},
120{ENGINE_R_ENGINE_IS_NOT_IN_LIST ,"engine is not in the list"},
121{ENGINE_R_ENGINE_SECTION_ERROR ,"engine section error"},
122{ENGINE_R_FAILED_LOADING_PRIVATE_KEY ,"failed loading private key"},
123{ENGINE_R_FAILED_LOADING_PUBLIC_KEY ,"failed loading public key"},
124{ENGINE_R_FINISH_FAILED ,"finish failed"},
125{ENGINE_R_GET_HANDLE_FAILED ,"could not obtain hardware handle"},
126{ENGINE_R_ID_OR_NAME_MISSING ,"'id' or 'name' missing"},
127{ENGINE_R_INIT_FAILED ,"init failed"},
128{ENGINE_R_INTERNAL_LIST_ERROR ,"internal list error"},
129{ENGINE_R_INVALID_ARGUMENT ,"invalid argument"},
130{ENGINE_R_INVALID_CMD_NAME ,"invalid cmd name"},
131{ENGINE_R_INVALID_CMD_NUMBER ,"invalid cmd number"},
132{ENGINE_R_INVALID_INIT_VALUE ,"invalid init value"},
133{ENGINE_R_INVALID_STRING ,"invalid string"},
134{ENGINE_R_NOT_INITIALISED ,"not initialised"},
135{ENGINE_R_NOT_LOADED ,"not loaded"},
136{ENGINE_R_NO_CONTROL_FUNCTION ,"no control function"},
137{ENGINE_R_NO_INDEX ,"no index"},
138{ENGINE_R_NO_LOAD_FUNCTION ,"no load function"},
139{ENGINE_R_NO_REFERENCE ,"no reference"},
140{ENGINE_R_NO_SUCH_ENGINE ,"no such engine"},
141{ENGINE_R_NO_UNLOAD_FUNCTION ,"no unload function"},
142{ENGINE_R_PROVIDE_PARAMETERS ,"provide parameters"},
143{ENGINE_R_RSA_NOT_IMPLEMENTED ,"rsa not implemented"},
144{ENGINE_R_UNIMPLEMENTED_CIPHER ,"unimplemented cipher"},
145{ENGINE_R_UNIMPLEMENTED_DIGEST ,"unimplemented digest"},
146{ENGINE_R_VERSION_INCOMPATIBILITY ,"version incompatibility"},
147{0,NULL}
148 };
149
150#endif
151
152void ERR_load_ENGINE_strings(void)
153 {
154 static int init=1;
155
156 if (init)
157 {
158 init=0;
159#ifndef OPENSSL_NO_ERR
160 ERR_load_strings(ERR_LIB_ENGINE,ENGINE_str_functs);
161 ERR_load_strings(ERR_LIB_ENGINE,ENGINE_str_reasons);
162#endif
163
164 }
165 }
diff --git a/src/lib/libcrypto/engine/eng_fat.c b/src/lib/libcrypto/engine/eng_fat.c
new file mode 100644
index 0000000000..af918b1499
--- /dev/null
+++ b/src/lib/libcrypto/engine/eng_fat.c
@@ -0,0 +1,148 @@
1/* crypto/engine/eng_fat.c */
2/* ====================================================================
3 * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
16 *
17 * 3. All advertising materials mentioning features or use of this
18 * software must display the following acknowledgment:
19 * "This product includes software developed by the OpenSSL Project
20 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
21 *
22 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
23 * endorse or promote products derived from this software without
24 * prior written permission. For written permission, please contact
25 * licensing@OpenSSL.org.
26 *
27 * 5. Products derived from this software may not be called "OpenSSL"
28 * nor may "OpenSSL" appear in their names without prior written
29 * permission of the OpenSSL Project.
30 *
31 * 6. Redistributions of any form whatsoever must retain the following
32 * acknowledgment:
33 * "This product includes software developed by the OpenSSL Project
34 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
35 *
36 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
37 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
39 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
40 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
42 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
45 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
47 * OF THE POSSIBILITY OF SUCH DAMAGE.
48 * ====================================================================
49 *
50 * This product includes cryptographic software written by Eric Young
51 * (eay@cryptsoft.com). This product includes software written by Tim
52 * Hudson (tjh@cryptsoft.com).
53 *
54 */
55
56#include <openssl/crypto.h>
57#include "cryptlib.h"
58#include "eng_int.h"
59#include <openssl/engine.h>
60#include <openssl/conf.h>
61
62int ENGINE_set_default(ENGINE *e, unsigned int flags)
63 {
64 if((flags & ENGINE_METHOD_CIPHERS) && !ENGINE_set_default_ciphers(e))
65 return 0;
66 if((flags & ENGINE_METHOD_DIGESTS) && !ENGINE_set_default_digests(e))
67 return 0;
68#ifndef OPENSSL_NO_RSA
69 if((flags & ENGINE_METHOD_RSA) & !ENGINE_set_default_RSA(e))
70 return 0;
71#endif
72#ifndef OPENSSL_NO_DSA
73 if((flags & ENGINE_METHOD_DSA) & !ENGINE_set_default_DSA(e))
74 return 0;
75#endif
76#ifndef OPENSSL_NO_DH
77 if((flags & ENGINE_METHOD_DH) & !ENGINE_set_default_DH(e))
78 return 0;
79#endif
80 if((flags & ENGINE_METHOD_RAND) & !ENGINE_set_default_RAND(e))
81 return 0;
82 return 1;
83 }
84
85/* Set default algorithms using a string */
86
87int int_def_cb(const char *alg, int len, void *arg)
88 {
89 unsigned int *pflags = arg;
90 if (!strncmp(alg, "ALL", len))
91 *pflags |= ENGINE_METHOD_ALL;
92 else if (!strncmp(alg, "RSA", len))
93 *pflags |= ENGINE_METHOD_RSA;
94 else if (!strncmp(alg, "DSA", len))
95 *pflags |= ENGINE_METHOD_DSA;
96 else if (!strncmp(alg, "DH", len))
97 *pflags |= ENGINE_METHOD_DH;
98 else if (!strncmp(alg, "RAND", len))
99 *pflags |= ENGINE_METHOD_RAND;
100 else if (!strncmp(alg, "CIPHERS", len))
101 *pflags |= ENGINE_METHOD_CIPHERS;
102 else if (!strncmp(alg, "DIGESTS", len))
103 *pflags |= ENGINE_METHOD_DIGESTS;
104 else
105 return 0;
106 return 1;
107 }
108
109
110int ENGINE_set_default_string(ENGINE *e, const char *list)
111 {
112 unsigned int flags = 0;
113 if (!CONF_parse_list(list, ',', 1, int_def_cb, &flags))
114 {
115 ENGINEerr(ENGINE_F_ENGINE_SET_DEFAULT_STRING,
116 ENGINE_R_INVALID_STRING);
117 ERR_add_error_data(2, "str=",list);
118 return 0;
119 }
120 return ENGINE_set_default(e, flags);
121 }
122
123int ENGINE_register_complete(ENGINE *e)
124 {
125 ENGINE_register_ciphers(e);
126 ENGINE_register_digests(e);
127#ifndef OPENSSL_NO_RSA
128 ENGINE_register_RSA(e);
129#endif
130#ifndef OPENSSL_NO_DSA
131 ENGINE_register_DSA(e);
132#endif
133#ifndef OPENSSL_NO_DH
134 ENGINE_register_DH(e);
135#endif
136 ENGINE_register_RAND(e);
137 return 1;
138 }
139
140int ENGINE_register_all_complete(void)
141 {
142 ENGINE *e;
143
144 for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e)) {
145 ENGINE_register_complete(e);
146 }
147 return 1;
148 }
diff --git a/src/lib/libcrypto/engine/eng_init.c b/src/lib/libcrypto/engine/eng_init.c
new file mode 100644
index 0000000000..cc9396e863
--- /dev/null
+++ b/src/lib/libcrypto/engine/eng_init.c
@@ -0,0 +1,158 @@
1/* crypto/engine/eng_init.c */
2/* ====================================================================
3 * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
16 *
17 * 3. All advertising materials mentioning features or use of this
18 * software must display the following acknowledgment:
19 * "This product includes software developed by the OpenSSL Project
20 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
21 *
22 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
23 * endorse or promote products derived from this software without
24 * prior written permission. For written permission, please contact
25 * licensing@OpenSSL.org.
26 *
27 * 5. Products derived from this software may not be called "OpenSSL"
28 * nor may "OpenSSL" appear in their names without prior written
29 * permission of the OpenSSL Project.
30 *
31 * 6. Redistributions of any form whatsoever must retain the following
32 * acknowledgment:
33 * "This product includes software developed by the OpenSSL Project
34 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
35 *
36 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
37 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
39 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
40 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
42 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
45 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
47 * OF THE POSSIBILITY OF SUCH DAMAGE.
48 * ====================================================================
49 *
50 * This product includes cryptographic software written by Eric Young
51 * (eay@cryptsoft.com). This product includes software written by Tim
52 * Hudson (tjh@cryptsoft.com).
53 *
54 */
55
56#include <openssl/crypto.h>
57#include "cryptlib.h"
58#include "eng_int.h"
59#include <openssl/engine.h>
60
61/* Initialise a engine type for use (or up its functional reference count
62 * if it's already in use). This version is only used internally. */
63int engine_unlocked_init(ENGINE *e)
64 {
65 int to_return = 1;
66
67 if((e->funct_ref == 0) && e->init)
68 /* This is the first functional reference and the engine
69 * requires initialisation so we do it now. */
70 to_return = e->init(e);
71 if(to_return)
72 {
73 /* OK, we return a functional reference which is also a
74 * structural reference. */
75 e->struct_ref++;
76 e->funct_ref++;
77 engine_ref_debug(e, 0, 1)
78 engine_ref_debug(e, 1, 1)
79 }
80 return to_return;
81 }
82
83/* Free a functional reference to a engine type. This version is only used
84 * internally. */
85int engine_unlocked_finish(ENGINE *e, int unlock_for_handlers)
86 {
87 int to_return = 1;
88
89 /* Reduce the functional reference count here so if it's the terminating
90 * case, we can release the lock safely and call the finish() handler
91 * without risk of a race. We get a race if we leave the count until
92 * after and something else is calling "finish" at the same time -
93 * there's a chance that both threads will together take the count from
94 * 2 to 0 without either calling finish(). */
95 e->funct_ref--;
96 engine_ref_debug(e, 1, -1);
97 if((e->funct_ref == 0) && e->finish)
98 {
99 if(unlock_for_handlers)
100 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
101 to_return = e->finish(e);
102 if(unlock_for_handlers)
103 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
104 if(!to_return)
105 return 0;
106 }
107#ifdef REF_CHECK
108 if(e->funct_ref < 0)
109 {
110 fprintf(stderr,"ENGINE_finish, bad functional reference count\n");
111 abort();
112 }
113#endif
114 /* Release the structural reference too */
115 if(!engine_free_util(e, 0))
116 {
117 ENGINEerr(ENGINE_F_ENGINE_FINISH,ENGINE_R_FINISH_FAILED);
118 return 0;
119 }
120 return to_return;
121 }
122
123/* The API (locked) version of "init" */
124int ENGINE_init(ENGINE *e)
125 {
126 int ret;
127 if(e == NULL)
128 {
129 ENGINEerr(ENGINE_F_ENGINE_INIT,ERR_R_PASSED_NULL_PARAMETER);
130 return 0;
131 }
132 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
133 ret = engine_unlocked_init(e);
134 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
135 return ret;
136 }
137
138/* The API (locked) version of "finish" */
139int ENGINE_finish(ENGINE *e)
140 {
141 int to_return = 1;
142
143 if(e == NULL)
144 {
145 ENGINEerr(ENGINE_F_ENGINE_FINISH,ERR_R_PASSED_NULL_PARAMETER);
146 return 0;
147 }
148 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
149 to_return = engine_unlocked_finish(e, 1);
150 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
151 if(!to_return)
152 {
153 ENGINEerr(ENGINE_F_ENGINE_FINISH,ENGINE_R_FINISH_FAILED);
154 return 0;
155 }
156 return to_return;
157 }
158
diff --git a/src/lib/libcrypto/engine/eng_int.h b/src/lib/libcrypto/engine/eng_int.h
new file mode 100644
index 0000000000..38335f99cd
--- /dev/null
+++ b/src/lib/libcrypto/engine/eng_int.h
@@ -0,0 +1,185 @@
1/* crypto/engine/eng_int.h */
2/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
3 * project 2000.
4 */
5/* ====================================================================
6 * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59#ifndef HEADER_ENGINE_INT_H
60#define HEADER_ENGINE_INT_H
61
62/* Take public definitions from engine.h */
63#include <openssl/engine.h>
64
65#ifdef __cplusplus
66extern "C" {
67#endif
68
69/* If we compile with this symbol defined, then both reference counts in the
70 * ENGINE structure will be monitored with a line of output on stderr for each
71 * change. This prints the engine's pointer address (truncated to unsigned int),
72 * "struct" or "funct" to indicate the reference type, the before and after
73 * reference count, and the file:line-number pair. The "engine_ref_debug"
74 * statements must come *after* the change. */
75#ifdef ENGINE_REF_COUNT_DEBUG
76
77#define engine_ref_debug(e, isfunct, diff) \
78 fprintf(stderr, "engine: %08x %s from %d to %d (%s:%d)\n", \
79 (unsigned int)(e), (isfunct ? "funct" : "struct"), \
80 ((isfunct) ? ((e)->funct_ref - (diff)) : ((e)->struct_ref - (diff))), \
81 ((isfunct) ? (e)->funct_ref : (e)->struct_ref), \
82 (__FILE__), (__LINE__));
83
84#else
85
86#define engine_ref_debug(e, isfunct, diff)
87
88#endif
89
90/* Any code that will need cleanup operations should use these functions to
91 * register callbacks. ENGINE_cleanup() will call all registered callbacks in
92 * order. NB: both the "add" functions assume CRYPTO_LOCK_ENGINE to already be
93 * held (in "write" mode). */
94typedef void (ENGINE_CLEANUP_CB)(void);
95typedef struct st_engine_cleanup_item
96 {
97 ENGINE_CLEANUP_CB *cb;
98 } ENGINE_CLEANUP_ITEM;
99DECLARE_STACK_OF(ENGINE_CLEANUP_ITEM)
100void engine_cleanup_add_first(ENGINE_CLEANUP_CB *cb);
101void engine_cleanup_add_last(ENGINE_CLEANUP_CB *cb);
102
103/* We need stacks of ENGINEs for use in eng_table.c */
104DECLARE_STACK_OF(ENGINE)
105
106/* If this symbol is defined then engine_table_select(), the function that is
107 * used by RSA, DSA (etc) code to select registered ENGINEs, cache defaults and
108 * functional references (etc), will display debugging summaries to stderr. */
109/* #define ENGINE_TABLE_DEBUG */
110
111/* This represents an implementation table. Dependent code should instantiate it
112 * as a (ENGINE_TABLE *) pointer value set initially to NULL. */
113typedef struct st_engine_table ENGINE_TABLE;
114int engine_table_register(ENGINE_TABLE **table, ENGINE_CLEANUP_CB *cleanup,
115 ENGINE *e, const int *nids, int num_nids, int setdefault);
116void engine_table_unregister(ENGINE_TABLE **table, ENGINE *e);
117void engine_table_cleanup(ENGINE_TABLE **table);
118#ifndef ENGINE_TABLE_DEBUG
119ENGINE *engine_table_select(ENGINE_TABLE **table, int nid);
120#else
121ENGINE *engine_table_select_tmp(ENGINE_TABLE **table, int nid, const char *f, int l);
122#define engine_table_select(t,n) engine_table_select_tmp(t,n,__FILE__,__LINE__)
123#endif
124
125/* Internal versions of API functions that have control over locking. These are
126 * used between C files when functionality needs to be shared but the caller may
127 * already be controlling of the CRYPTO_LOCK_ENGINE lock. */
128int engine_unlocked_init(ENGINE *e);
129int engine_unlocked_finish(ENGINE *e, int unlock_for_handlers);
130int engine_free_util(ENGINE *e, int locked);
131
132/* This function will reset all "set"able values in an ENGINE to NULL. This
133 * won't touch reference counts or ex_data, but is equivalent to calling all the
134 * ENGINE_set_***() functions with a NULL value. */
135void engine_set_all_null(ENGINE *e);
136
137/* NB: Bitwise OR-able values for the "flags" variable in ENGINE are now exposed
138 * in engine.h. */
139
140/* This is a structure for storing implementations of various crypto
141 * algorithms and functions. */
142struct engine_st
143 {
144 const char *id;
145 const char *name;
146 const RSA_METHOD *rsa_meth;
147 const DSA_METHOD *dsa_meth;
148 const DH_METHOD *dh_meth;
149 const RAND_METHOD *rand_meth;
150 /* Cipher handling is via this callback */
151 ENGINE_CIPHERS_PTR ciphers;
152 /* Digest handling is via this callback */
153 ENGINE_DIGESTS_PTR digests;
154
155
156 ENGINE_GEN_INT_FUNC_PTR destroy;
157
158 ENGINE_GEN_INT_FUNC_PTR init;
159 ENGINE_GEN_INT_FUNC_PTR finish;
160 ENGINE_CTRL_FUNC_PTR ctrl;
161 ENGINE_LOAD_KEY_PTR load_privkey;
162 ENGINE_LOAD_KEY_PTR load_pubkey;
163
164 const ENGINE_CMD_DEFN *cmd_defns;
165 int flags;
166 /* reference count on the structure itself */
167 int struct_ref;
168 /* reference count on usability of the engine type. NB: This
169 * controls the loading and initialisation of any functionlity
170 * required by this engine, whereas the previous count is
171 * simply to cope with (de)allocation of this structure. Hence,
172 * running_ref <= struct_ref at all times. */
173 int funct_ref;
174 /* A place to store per-ENGINE data */
175 CRYPTO_EX_DATA ex_data;
176 /* Used to maintain the linked-list of engines. */
177 struct engine_st *prev;
178 struct engine_st *next;
179 };
180
181#ifdef __cplusplus
182}
183#endif
184
185#endif /* HEADER_ENGINE_INT_H */
diff --git a/src/lib/libcrypto/engine/eng_lib.c b/src/lib/libcrypto/engine/eng_lib.c
new file mode 100644
index 0000000000..a66d0f08af
--- /dev/null
+++ b/src/lib/libcrypto/engine/eng_lib.c
@@ -0,0 +1,321 @@
1/* crypto/engine/eng_lib.c */
2/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
3 * project 2000.
4 */
5/* ====================================================================
6 * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59#include <openssl/crypto.h>
60#include "cryptlib.h"
61#include "eng_int.h"
62#include <openssl/rand.h> /* FIXME: This shouldn't be needed */
63#include <openssl/engine.h>
64
65/* The "new"/"free" stuff first */
66
67ENGINE *ENGINE_new(void)
68 {
69 ENGINE *ret;
70
71 ret = (ENGINE *)OPENSSL_malloc(sizeof(ENGINE));
72 if(ret == NULL)
73 {
74 ENGINEerr(ENGINE_F_ENGINE_NEW, ERR_R_MALLOC_FAILURE);
75 return NULL;
76 }
77 memset(ret, 0, sizeof(ENGINE));
78 ret->struct_ref = 1;
79 engine_ref_debug(ret, 0, 1)
80 CRYPTO_new_ex_data(CRYPTO_EX_INDEX_ENGINE, ret, &ret->ex_data);
81 return ret;
82 }
83
84/* Placed here (close proximity to ENGINE_new) so that modifications to the
85 * elements of the ENGINE structure are more likely to be caught and changed
86 * here. */
87void engine_set_all_null(ENGINE *e)
88 {
89 e->id = NULL;
90 e->name = NULL;
91 e->rsa_meth = NULL;
92 e->dsa_meth = NULL;
93 e->dh_meth = NULL;
94 e->rand_meth = NULL;
95 e->ciphers = NULL;
96 e->digests = NULL;
97 e->destroy = NULL;
98 e->init = NULL;
99 e->finish = NULL;
100 e->ctrl = NULL;
101 e->load_privkey = NULL;
102 e->load_pubkey = NULL;
103 e->cmd_defns = NULL;
104 e->flags = 0;
105 }
106
107int engine_free_util(ENGINE *e, int locked)
108 {
109 int i;
110
111 if(e == NULL)
112 {
113 ENGINEerr(ENGINE_F_ENGINE_FREE,
114 ERR_R_PASSED_NULL_PARAMETER);
115 return 0;
116 }
117 if(locked)
118 i = CRYPTO_add(&e->struct_ref,-1,CRYPTO_LOCK_ENGINE);
119 else
120 i = --e->struct_ref;
121 engine_ref_debug(e, 0, -1)
122 if (i > 0) return 1;
123#ifdef REF_CHECK
124 if (i < 0)
125 {
126 fprintf(stderr,"ENGINE_free, bad structural reference count\n");
127 abort();
128 }
129#endif
130 /* Give the ENGINE a chance to do any structural cleanup corresponding
131 * to allocation it did in its constructor (eg. unload error strings) */
132 if(e->destroy)
133 e->destroy(e);
134 CRYPTO_free_ex_data(CRYPTO_EX_INDEX_ENGINE, e, &e->ex_data);
135 OPENSSL_free(e);
136 return 1;
137 }
138
139int ENGINE_free(ENGINE *e)
140 {
141 return engine_free_util(e, 1);
142 }
143
144/* Cleanup stuff */
145
146/* ENGINE_cleanup() is coded such that anything that does work that will need
147 * cleanup can register a "cleanup" callback here. That way we don't get linker
148 * bloat by referring to all *possible* cleanups, but any linker bloat into code
149 * "X" will cause X's cleanup function to end up here. */
150static STACK_OF(ENGINE_CLEANUP_ITEM) *cleanup_stack = NULL;
151static int int_cleanup_check(int create)
152 {
153 if(cleanup_stack) return 1;
154 if(!create) return 0;
155 cleanup_stack = sk_ENGINE_CLEANUP_ITEM_new_null();
156 return (cleanup_stack ? 1 : 0);
157 }
158static ENGINE_CLEANUP_ITEM *int_cleanup_item(ENGINE_CLEANUP_CB *cb)
159 {
160 ENGINE_CLEANUP_ITEM *item = OPENSSL_malloc(sizeof(
161 ENGINE_CLEANUP_ITEM));
162 if(!item) return NULL;
163 item->cb = cb;
164 return item;
165 }
166void engine_cleanup_add_first(ENGINE_CLEANUP_CB *cb)
167 {
168 ENGINE_CLEANUP_ITEM *item;
169 if(!int_cleanup_check(1)) return;
170 item = int_cleanup_item(cb);
171 if(item)
172 sk_ENGINE_CLEANUP_ITEM_insert(cleanup_stack, item, 0);
173 }
174void engine_cleanup_add_last(ENGINE_CLEANUP_CB *cb)
175 {
176 ENGINE_CLEANUP_ITEM *item;
177 if(!int_cleanup_check(1)) return;
178 item = int_cleanup_item(cb);
179 if(item)
180 sk_ENGINE_CLEANUP_ITEM_push(cleanup_stack, item);
181 }
182/* The API function that performs all cleanup */
183static void engine_cleanup_cb_free(ENGINE_CLEANUP_ITEM *item)
184 {
185 (*(item->cb))();
186 OPENSSL_free(item);
187 }
188void ENGINE_cleanup(void)
189 {
190 if(int_cleanup_check(0))
191 {
192 sk_ENGINE_CLEANUP_ITEM_pop_free(cleanup_stack,
193 engine_cleanup_cb_free);
194 cleanup_stack = NULL;
195 }
196 /* FIXME: This should be handled (somehow) through RAND, eg. by it
197 * registering a cleanup callback. */
198 RAND_set_rand_method(NULL);
199 }
200
201/* Now the "ex_data" support */
202
203int ENGINE_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
204 CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
205 {
206 return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_ENGINE, argl, argp,
207 new_func, dup_func, free_func);
208 }
209
210int ENGINE_set_ex_data(ENGINE *e, int idx, void *arg)
211 {
212 return(CRYPTO_set_ex_data(&e->ex_data, idx, arg));
213 }
214
215void *ENGINE_get_ex_data(const ENGINE *e, int idx)
216 {
217 return(CRYPTO_get_ex_data(&e->ex_data, idx));
218 }
219
220/* Functions to get/set an ENGINE's elements - mainly to avoid exposing the
221 * ENGINE structure itself. */
222
223int ENGINE_set_id(ENGINE *e, const char *id)
224 {
225 if(id == NULL)
226 {
227 ENGINEerr(ENGINE_F_ENGINE_SET_ID,
228 ERR_R_PASSED_NULL_PARAMETER);
229 return 0;
230 }
231 e->id = id;
232 return 1;
233 }
234
235int ENGINE_set_name(ENGINE *e, const char *name)
236 {
237 if(name == NULL)
238 {
239 ENGINEerr(ENGINE_F_ENGINE_SET_NAME,
240 ERR_R_PASSED_NULL_PARAMETER);
241 return 0;
242 }
243 e->name = name;
244 return 1;
245 }
246
247int ENGINE_set_destroy_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR destroy_f)
248 {
249 e->destroy = destroy_f;
250 return 1;
251 }
252
253int ENGINE_set_init_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR init_f)
254 {
255 e->init = init_f;
256 return 1;
257 }
258
259int ENGINE_set_finish_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR finish_f)
260 {
261 e->finish = finish_f;
262 return 1;
263 }
264
265int ENGINE_set_ctrl_function(ENGINE *e, ENGINE_CTRL_FUNC_PTR ctrl_f)
266 {
267 e->ctrl = ctrl_f;
268 return 1;
269 }
270
271int ENGINE_set_flags(ENGINE *e, int flags)
272 {
273 e->flags = flags;
274 return 1;
275 }
276
277int ENGINE_set_cmd_defns(ENGINE *e, const ENGINE_CMD_DEFN *defns)
278 {
279 e->cmd_defns = defns;
280 return 1;
281 }
282
283const char *ENGINE_get_id(const ENGINE *e)
284 {
285 return e->id;
286 }
287
288const char *ENGINE_get_name(const ENGINE *e)
289 {
290 return e->name;
291 }
292
293ENGINE_GEN_INT_FUNC_PTR ENGINE_get_destroy_function(const ENGINE *e)
294 {
295 return e->destroy;
296 }
297
298ENGINE_GEN_INT_FUNC_PTR ENGINE_get_init_function(const ENGINE *e)
299 {
300 return e->init;
301 }
302
303ENGINE_GEN_INT_FUNC_PTR ENGINE_get_finish_function(const ENGINE *e)
304 {
305 return e->finish;
306 }
307
308ENGINE_CTRL_FUNC_PTR ENGINE_get_ctrl_function(const ENGINE *e)
309 {
310 return e->ctrl;
311 }
312
313int ENGINE_get_flags(const ENGINE *e)
314 {
315 return e->flags;
316 }
317
318const ENGINE_CMD_DEFN *ENGINE_get_cmd_defns(const ENGINE *e)
319 {
320 return e->cmd_defns;
321 }
diff --git a/src/lib/libcrypto/engine/eng_list.c b/src/lib/libcrypto/engine/eng_list.c
new file mode 100644
index 0000000000..ce48d2255a
--- /dev/null
+++ b/src/lib/libcrypto/engine/eng_list.c
@@ -0,0 +1,383 @@
1/* crypto/engine/eng_list.c */
2/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
3 * project 2000.
4 */
5/* ====================================================================
6 * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59#include <openssl/crypto.h>
60#include "cryptlib.h"
61#include "eng_int.h"
62#include <openssl/engine.h>
63
64/* The linked-list of pointers to engine types. engine_list_head
65 * incorporates an implicit structural reference but engine_list_tail
66 * does not - the latter is a computational niceity and only points
67 * to something that is already pointed to by its predecessor in the
68 * list (or engine_list_head itself). In the same way, the use of the
69 * "prev" pointer in each ENGINE is to save excessive list iteration,
70 * it doesn't correspond to an extra structural reference. Hence,
71 * engine_list_head, and each non-null "next" pointer account for
72 * the list itself assuming exactly 1 structural reference on each
73 * list member. */
74static ENGINE *engine_list_head = NULL;
75static ENGINE *engine_list_tail = NULL;
76
77/* This cleanup function is only needed internally. If it should be called, we
78 * register it with the "ENGINE_cleanup()" stack to be called during cleanup. */
79
80static void engine_list_cleanup(void)
81 {
82 ENGINE *iterator = engine_list_head;
83
84 while(iterator != NULL)
85 {
86 ENGINE_remove(iterator);
87 iterator = engine_list_head;
88 }
89 return;
90 }
91
92/* These static functions starting with a lower case "engine_" always
93 * take place when CRYPTO_LOCK_ENGINE has been locked up. */
94static int engine_list_add(ENGINE *e)
95 {
96 int conflict = 0;
97 ENGINE *iterator = NULL;
98
99 if(e == NULL)
100 {
101 ENGINEerr(ENGINE_F_ENGINE_LIST_ADD,
102 ERR_R_PASSED_NULL_PARAMETER);
103 return 0;
104 }
105 iterator = engine_list_head;
106 while(iterator && !conflict)
107 {
108 conflict = (strcmp(iterator->id, e->id) == 0);
109 iterator = iterator->next;
110 }
111 if(conflict)
112 {
113 ENGINEerr(ENGINE_F_ENGINE_LIST_ADD,
114 ENGINE_R_CONFLICTING_ENGINE_ID);
115 return 0;
116 }
117 if(engine_list_head == NULL)
118 {
119 /* We are adding to an empty list. */
120 if(engine_list_tail)
121 {
122 ENGINEerr(ENGINE_F_ENGINE_LIST_ADD,
123 ENGINE_R_INTERNAL_LIST_ERROR);
124 return 0;
125 }
126 engine_list_head = e;
127 e->prev = NULL;
128 /* The first time the list allocates, we should register the
129 * cleanup. */
130 engine_cleanup_add_last(engine_list_cleanup);
131 }
132 else
133 {
134 /* We are adding to the tail of an existing list. */
135 if((engine_list_tail == NULL) ||
136 (engine_list_tail->next != NULL))
137 {
138 ENGINEerr(ENGINE_F_ENGINE_LIST_ADD,
139 ENGINE_R_INTERNAL_LIST_ERROR);
140 return 0;
141 }
142 engine_list_tail->next = e;
143 e->prev = engine_list_tail;
144 }
145 /* Having the engine in the list assumes a structural
146 * reference. */
147 e->struct_ref++;
148 engine_ref_debug(e, 0, 1)
149 /* However it came to be, e is the last item in the list. */
150 engine_list_tail = e;
151 e->next = NULL;
152 return 1;
153 }
154
155static int engine_list_remove(ENGINE *e)
156 {
157 ENGINE *iterator;
158
159 if(e == NULL)
160 {
161 ENGINEerr(ENGINE_F_ENGINE_LIST_REMOVE,
162 ERR_R_PASSED_NULL_PARAMETER);
163 return 0;
164 }
165 /* We need to check that e is in our linked list! */
166 iterator = engine_list_head;
167 while(iterator && (iterator != e))
168 iterator = iterator->next;
169 if(iterator == NULL)
170 {
171 ENGINEerr(ENGINE_F_ENGINE_LIST_REMOVE,
172 ENGINE_R_ENGINE_IS_NOT_IN_LIST);
173 return 0;
174 }
175 /* un-link e from the chain. */
176 if(e->next)
177 e->next->prev = e->prev;
178 if(e->prev)
179 e->prev->next = e->next;
180 /* Correct our head/tail if necessary. */
181 if(engine_list_head == e)
182 engine_list_head = e->next;
183 if(engine_list_tail == e)
184 engine_list_tail = e->prev;
185 engine_free_util(e, 0);
186 return 1;
187 }
188
189/* Get the first/last "ENGINE" type available. */
190ENGINE *ENGINE_get_first(void)
191 {
192 ENGINE *ret;
193
194 CRYPTO_r_lock(CRYPTO_LOCK_ENGINE);
195 ret = engine_list_head;
196 if(ret)
197 {
198 ret->struct_ref++;
199 engine_ref_debug(ret, 0, 1)
200 }
201 CRYPTO_r_unlock(CRYPTO_LOCK_ENGINE);
202 return ret;
203 }
204
205ENGINE *ENGINE_get_last(void)
206 {
207 ENGINE *ret;
208
209 CRYPTO_r_lock(CRYPTO_LOCK_ENGINE);
210 ret = engine_list_tail;
211 if(ret)
212 {
213 ret->struct_ref++;
214 engine_ref_debug(ret, 0, 1)
215 }
216 CRYPTO_r_unlock(CRYPTO_LOCK_ENGINE);
217 return ret;
218 }
219
220/* Iterate to the next/previous "ENGINE" type (NULL = end of the list). */
221ENGINE *ENGINE_get_next(ENGINE *e)
222 {
223 ENGINE *ret = NULL;
224 if(e == NULL)
225 {
226 ENGINEerr(ENGINE_F_ENGINE_GET_NEXT,
227 ERR_R_PASSED_NULL_PARAMETER);
228 return 0;
229 }
230 CRYPTO_r_lock(CRYPTO_LOCK_ENGINE);
231 ret = e->next;
232 if(ret)
233 {
234 /* Return a valid structural refernce to the next ENGINE */
235 ret->struct_ref++;
236 engine_ref_debug(ret, 0, 1)
237 }
238 CRYPTO_r_unlock(CRYPTO_LOCK_ENGINE);
239 /* Release the structural reference to the previous ENGINE */
240 ENGINE_free(e);
241 return ret;
242 }
243
244ENGINE *ENGINE_get_prev(ENGINE *e)
245 {
246 ENGINE *ret = NULL;
247 if(e == NULL)
248 {
249 ENGINEerr(ENGINE_F_ENGINE_GET_PREV,
250 ERR_R_PASSED_NULL_PARAMETER);
251 return 0;
252 }
253 CRYPTO_r_lock(CRYPTO_LOCK_ENGINE);
254 ret = e->prev;
255 if(ret)
256 {
257 /* Return a valid structural reference to the next ENGINE */
258 ret->struct_ref++;
259 engine_ref_debug(ret, 0, 1)
260 }
261 CRYPTO_r_unlock(CRYPTO_LOCK_ENGINE);
262 /* Release the structural reference to the previous ENGINE */
263 ENGINE_free(e);
264 return ret;
265 }
266
267/* Add another "ENGINE" type into the list. */
268int ENGINE_add(ENGINE *e)
269 {
270 int to_return = 1;
271 if(e == NULL)
272 {
273 ENGINEerr(ENGINE_F_ENGINE_ADD,
274 ERR_R_PASSED_NULL_PARAMETER);
275 return 0;
276 }
277 if((e->id == NULL) || (e->name == NULL))
278 {
279 ENGINEerr(ENGINE_F_ENGINE_ADD,
280 ENGINE_R_ID_OR_NAME_MISSING);
281 }
282 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
283 if(!engine_list_add(e))
284 {
285 ENGINEerr(ENGINE_F_ENGINE_ADD,
286 ENGINE_R_INTERNAL_LIST_ERROR);
287 to_return = 0;
288 }
289 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
290 return to_return;
291 }
292
293/* Remove an existing "ENGINE" type from the array. */
294int ENGINE_remove(ENGINE *e)
295 {
296 int to_return = 1;
297 if(e == NULL)
298 {
299 ENGINEerr(ENGINE_F_ENGINE_REMOVE,
300 ERR_R_PASSED_NULL_PARAMETER);
301 return 0;
302 }
303 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
304 if(!engine_list_remove(e))
305 {
306 ENGINEerr(ENGINE_F_ENGINE_REMOVE,
307 ENGINE_R_INTERNAL_LIST_ERROR);
308 to_return = 0;
309 }
310 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
311 return to_return;
312 }
313
314static void engine_cpy(ENGINE *dest, const ENGINE *src)
315 {
316 dest->id = src->id;
317 dest->name = src->name;
318#ifndef OPENSSL_NO_RSA
319 dest->rsa_meth = src->rsa_meth;
320#endif
321#ifndef OPENSSL_NO_DSA
322 dest->dsa_meth = src->dsa_meth;
323#endif
324#ifndef OPENSSL_NO_DH
325 dest->dh_meth = src->dh_meth;
326#endif
327 dest->rand_meth = src->rand_meth;
328 dest->ciphers = src->ciphers;
329 dest->digests = src->digests;
330 dest->destroy = src->destroy;
331 dest->init = src->init;
332 dest->finish = src->finish;
333 dest->ctrl = src->ctrl;
334 dest->load_privkey = src->load_privkey;
335 dest->load_pubkey = src->load_pubkey;
336 dest->cmd_defns = src->cmd_defns;
337 dest->flags = src->flags;
338 }
339
340ENGINE *ENGINE_by_id(const char *id)
341 {
342 ENGINE *iterator;
343 if(id == NULL)
344 {
345 ENGINEerr(ENGINE_F_ENGINE_BY_ID,
346 ERR_R_PASSED_NULL_PARAMETER);
347 return NULL;
348 }
349 CRYPTO_r_lock(CRYPTO_LOCK_ENGINE);
350 iterator = engine_list_head;
351 while(iterator && (strcmp(id, iterator->id) != 0))
352 iterator = iterator->next;
353 if(iterator)
354 {
355 /* We need to return a structural reference. If this is an
356 * ENGINE type that returns copies, make a duplicate - otherwise
357 * increment the existing ENGINE's reference count. */
358 if(iterator->flags & ENGINE_FLAGS_BY_ID_COPY)
359 {
360 ENGINE *cp = ENGINE_new();
361 if(!cp)
362 iterator = NULL;
363 else
364 {
365 engine_cpy(cp, iterator);
366 iterator = cp;
367 }
368 }
369 else
370 {
371 iterator->struct_ref++;
372 engine_ref_debug(iterator, 0, 1)
373 }
374 }
375 CRYPTO_r_unlock(CRYPTO_LOCK_ENGINE);
376 if(iterator == NULL)
377 {
378 ENGINEerr(ENGINE_F_ENGINE_BY_ID,
379 ENGINE_R_NO_SUCH_ENGINE);
380 ERR_add_error_data(2, "id=", id);
381 }
382 return iterator;
383 }
diff --git a/src/lib/libcrypto/engine/eng_openssl.c b/src/lib/libcrypto/engine/eng_openssl.c
new file mode 100644
index 0000000000..e9d976f46b
--- /dev/null
+++ b/src/lib/libcrypto/engine/eng_openssl.c
@@ -0,0 +1,347 @@
1/* crypto/engine/eng_openssl.c */
2/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
3 * project 2000.
4 */
5/* ====================================================================
6 * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59
60#include <stdio.h>
61#include <openssl/crypto.h>
62#include "cryptlib.h"
63#include <openssl/engine.h>
64#include <openssl/dso.h>
65#include <openssl/pem.h>
66
67/* This testing gunk is implemented (and explained) lower down. It also assumes
68 * the application explicitly calls "ENGINE_load_openssl()" because this is no
69 * longer automatic in ENGINE_load_builtin_engines(). */
70#define TEST_ENG_OPENSSL_RC4
71#define TEST_ENG_OPENSSL_PKEY
72/* #define TEST_ENG_OPENSSL_RC4_OTHERS */
73#define TEST_ENG_OPENSSL_RC4_P_INIT
74/* #define TEST_ENG_OPENSSL_RC4_P_CIPHER */
75#define TEST_ENG_OPENSSL_SHA
76/* #define TEST_ENG_OPENSSL_SHA_OTHERS */
77/* #define TEST_ENG_OPENSSL_SHA_P_INIT */
78/* #define TEST_ENG_OPENSSL_SHA_P_UPDATE */
79/* #define TEST_ENG_OPENSSL_SHA_P_FINAL */
80
81#ifdef TEST_ENG_OPENSSL_RC4
82static int openssl_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
83 const int **nids, int nid);
84#endif
85#ifdef TEST_ENG_OPENSSL_SHA
86static int openssl_digests(ENGINE *e, const EVP_MD **digest,
87 const int **nids, int nid);
88#endif
89
90#ifdef TEST_ENG_OPENSSL_PKEY
91static EVP_PKEY *openssl_load_privkey(ENGINE *eng, const char *key_id,
92 UI_METHOD *ui_method, void *callback_data);
93#endif
94
95/* The constants used when creating the ENGINE */
96static const char *engine_openssl_id = "openssl";
97static const char *engine_openssl_name = "Software engine support";
98
99/* This internal function is used by ENGINE_openssl() and possibly by the
100 * "dynamic" ENGINE support too */
101static int bind_helper(ENGINE *e)
102 {
103 if(!ENGINE_set_id(e, engine_openssl_id)
104 || !ENGINE_set_name(e, engine_openssl_name)
105#ifndef TEST_ENG_OPENSSL_NO_ALGORITHMS
106#ifndef OPENSSL_NO_RSA
107 || !ENGINE_set_RSA(e, RSA_get_default_method())
108#endif
109#ifndef OPENSSL_NO_DSA
110 || !ENGINE_set_DSA(e, DSA_get_default_method())
111#endif
112#ifndef OPENSSL_NO_DH
113 || !ENGINE_set_DH(e, DH_get_default_method())
114#endif
115 || !ENGINE_set_RAND(e, RAND_SSLeay())
116#ifdef TEST_ENG_OPENSSL_RC4
117 || !ENGINE_set_ciphers(e, openssl_ciphers)
118#endif
119#ifdef TEST_ENG_OPENSSL_SHA
120 || !ENGINE_set_digests(e, openssl_digests)
121#endif
122#endif
123#ifdef TEST_ENG_OPENSSL_PKEY
124 || !ENGINE_set_load_privkey_function(e, openssl_load_privkey)
125#endif
126 )
127 return 0;
128 /* If we add errors to this ENGINE, ensure the error handling is setup here */
129 /* openssl_load_error_strings(); */
130 return 1;
131 }
132
133static ENGINE *engine_openssl(void)
134 {
135 ENGINE *ret = ENGINE_new();
136 if(!ret)
137 return NULL;
138 if(!bind_helper(ret))
139 {
140 ENGINE_free(ret);
141 return NULL;
142 }
143 return ret;
144 }
145
146void ENGINE_load_openssl(void)
147 {
148 ENGINE *toadd = engine_openssl();
149 if(!toadd) return;
150 ENGINE_add(toadd);
151 /* If the "add" worked, it gets a structural reference. So either way,
152 * we release our just-created reference. */
153 ENGINE_free(toadd);
154 ERR_clear_error();
155 }
156
157/* This stuff is needed if this ENGINE is being compiled into a self-contained
158 * shared-library. */
159#ifdef ENGINE_DYNAMIC_SUPPORT
160static int bind_fn(ENGINE *e, const char *id)
161 {
162 if(id && (strcmp(id, engine_openssl_id) != 0))
163 return 0;
164 if(!bind_helper(e))
165 return 0;
166 return 1;
167 }
168IMPLEMENT_DYNAMIC_CHECK_FN()
169IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
170#endif /* ENGINE_DYNAMIC_SUPPORT */
171
172#ifdef TEST_ENG_OPENSSL_RC4
173/* This section of code compiles an "alternative implementation" of two modes of
174 * RC4 into this ENGINE. The result is that EVP_CIPHER operation for "rc4"
175 * should under normal circumstances go via this support rather than the default
176 * EVP support. There are other symbols to tweak the testing;
177 * TEST_ENC_OPENSSL_RC4_OTHERS - print a one line message to stderr each time
178 * we're asked for a cipher we don't support (should not happen).
179 * TEST_ENG_OPENSSL_RC4_P_INIT - print a one line message to stderr each time
180 * the "init_key" handler is called.
181 * TEST_ENG_OPENSSL_RC4_P_CIPHER - ditto for the "cipher" handler.
182 */
183#include <openssl/evp.h>
184#include <openssl/rc4.h>
185#define TEST_RC4_KEY_SIZE 16
186static int test_cipher_nids[] = {NID_rc4,NID_rc4_40};
187static int test_cipher_nids_number = 2;
188typedef struct {
189 unsigned char key[TEST_RC4_KEY_SIZE];
190 RC4_KEY ks;
191 } TEST_RC4_KEY;
192#define test(ctx) ((TEST_RC4_KEY *)(ctx)->cipher_data)
193static int test_rc4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
194 const unsigned char *iv, int enc)
195 {
196#ifdef TEST_ENG_OPENSSL_RC4_P_INIT
197 fprintf(stderr, "(TEST_ENG_OPENSSL_RC4) test_init_key() called\n");
198#endif
199 memcpy(&test(ctx)->key[0],key,EVP_CIPHER_CTX_key_length(ctx));
200 RC4_set_key(&test(ctx)->ks,EVP_CIPHER_CTX_key_length(ctx),
201 test(ctx)->key);
202 return 1;
203 }
204static int test_rc4_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
205 const unsigned char *in, unsigned int inl)
206 {
207#ifdef TEST_ENG_OPENSSL_RC4_P_CIPHER
208 fprintf(stderr, "(TEST_ENG_OPENSSL_RC4) test_cipher() called\n");
209#endif
210 RC4(&test(ctx)->ks,inl,in,out);
211 return 1;
212 }
213static const EVP_CIPHER test_r4_cipher=
214 {
215 NID_rc4,
216 1,TEST_RC4_KEY_SIZE,0,
217 EVP_CIPH_VARIABLE_LENGTH,
218 test_rc4_init_key,
219 test_rc4_cipher,
220 NULL,
221 sizeof(TEST_RC4_KEY),
222 NULL,
223 NULL,
224 NULL
225 };
226static const EVP_CIPHER test_r4_40_cipher=
227 {
228 NID_rc4_40,
229 1,5 /* 40 bit */,0,
230 EVP_CIPH_VARIABLE_LENGTH,
231 test_rc4_init_key,
232 test_rc4_cipher,
233 NULL,
234 sizeof(TEST_RC4_KEY),
235 NULL,
236 NULL,
237 NULL
238 };
239static int openssl_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
240 const int **nids, int nid)
241 {
242 if(!cipher)
243 {
244 /* We are returning a list of supported nids */
245 *nids = test_cipher_nids;
246 return test_cipher_nids_number;
247 }
248 /* We are being asked for a specific cipher */
249 if(nid == NID_rc4)
250 *cipher = &test_r4_cipher;
251 else if(nid == NID_rc4_40)
252 *cipher = &test_r4_40_cipher;
253 else
254 {
255#ifdef TEST_ENG_OPENSSL_RC4_OTHERS
256 fprintf(stderr, "(TEST_ENG_OPENSSL_RC4) returning NULL for "
257 "nid %d\n", nid);
258#endif
259 *cipher = NULL;
260 return 0;
261 }
262 return 1;
263 }
264#endif
265
266#ifdef TEST_ENG_OPENSSL_SHA
267/* Much the same sort of comment as for TEST_ENG_OPENSSL_RC4 */
268#include <openssl/evp.h>
269#include <openssl/sha.h>
270static int test_digest_nids[] = {NID_sha1};
271static int test_digest_nids_number = 1;
272static int test_sha1_init(EVP_MD_CTX *ctx)
273 {
274#ifdef TEST_ENG_OPENSSL_SHA_P_INIT
275 fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) test_sha1_init() called\n");
276#endif
277 return SHA1_Init(ctx->md_data);
278 }
279static int test_sha1_update(EVP_MD_CTX *ctx,const void *data,unsigned long count)
280 {
281#ifdef TEST_ENG_OPENSSL_SHA_P_UPDATE
282 fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) test_sha1_update() called\n");
283#endif
284 return SHA1_Update(ctx->md_data,data,count);
285 }
286static int test_sha1_final(EVP_MD_CTX *ctx,unsigned char *md)
287 {
288#ifdef TEST_ENG_OPENSSL_SHA_P_FINAL
289 fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) test_sha1_final() called\n");
290#endif
291 return SHA1_Final(md,ctx->md_data);
292 }
293static const EVP_MD test_sha_md=
294 {
295 NID_sha1,
296 NID_sha1WithRSAEncryption,
297 SHA_DIGEST_LENGTH,
298 0,
299 test_sha1_init,
300 test_sha1_update,
301 test_sha1_final,
302 NULL,
303 NULL,
304 EVP_PKEY_RSA_method,
305 SHA_CBLOCK,
306 sizeof(EVP_MD *)+sizeof(SHA_CTX),
307 };
308static int openssl_digests(ENGINE *e, const EVP_MD **digest,
309 const int **nids, int nid)
310 {
311 if(!digest)
312 {
313 /* We are returning a list of supported nids */
314 *nids = test_digest_nids;
315 return test_digest_nids_number;
316 }
317 /* We are being asked for a specific digest */
318 if(nid == NID_sha1)
319 *digest = &test_sha_md;
320 else
321 {
322#ifdef TEST_ENG_OPENSSL_SHA_OTHERS
323 fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) returning NULL for "
324 "nid %d\n", nid);
325#endif
326 *digest = NULL;
327 return 0;
328 }
329 return 1;
330 }
331#endif
332
333#ifdef TEST_ENG_OPENSSL_PKEY
334static EVP_PKEY *openssl_load_privkey(ENGINE *eng, const char *key_id,
335 UI_METHOD *ui_method, void *callback_data)
336 {
337 BIO *in;
338 EVP_PKEY *key;
339 fprintf(stderr, "(TEST_ENG_OPENSSL_PKEY)Loading Private key %s\n", key_id);
340 in = BIO_new_file(key_id, "r");
341 if (!in)
342 return NULL;
343 key = PEM_read_bio_PrivateKey(in, NULL, 0, NULL);
344 BIO_free(in);
345 return key;
346 }
347#endif
diff --git a/src/lib/libcrypto/engine/eng_pkey.c b/src/lib/libcrypto/engine/eng_pkey.c
new file mode 100644
index 0000000000..8c69171511
--- /dev/null
+++ b/src/lib/libcrypto/engine/eng_pkey.c
@@ -0,0 +1,157 @@
1/* crypto/engine/eng_pkey.c */
2/* ====================================================================
3 * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
16 *
17 * 3. All advertising materials mentioning features or use of this
18 * software must display the following acknowledgment:
19 * "This product includes software developed by the OpenSSL Project
20 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
21 *
22 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
23 * endorse or promote products derived from this software without
24 * prior written permission. For written permission, please contact
25 * licensing@OpenSSL.org.
26 *
27 * 5. Products derived from this software may not be called "OpenSSL"
28 * nor may "OpenSSL" appear in their names without prior written
29 * permission of the OpenSSL Project.
30 *
31 * 6. Redistributions of any form whatsoever must retain the following
32 * acknowledgment:
33 * "This product includes software developed by the OpenSSL Project
34 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
35 *
36 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
37 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
39 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
40 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
42 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
45 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
47 * OF THE POSSIBILITY OF SUCH DAMAGE.
48 * ====================================================================
49 *
50 * This product includes cryptographic software written by Eric Young
51 * (eay@cryptsoft.com). This product includes software written by Tim
52 * Hudson (tjh@cryptsoft.com).
53 *
54 */
55
56#include <openssl/crypto.h>
57#include "cryptlib.h"
58#include "eng_int.h"
59#include <openssl/engine.h>
60
61/* Basic get/set stuff */
62
63int ENGINE_set_load_privkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpriv_f)
64 {
65 e->load_privkey = loadpriv_f;
66 return 1;
67 }
68
69int ENGINE_set_load_pubkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpub_f)
70 {
71 e->load_pubkey = loadpub_f;
72 return 1;
73 }
74
75ENGINE_LOAD_KEY_PTR ENGINE_get_load_privkey_function(const ENGINE *e)
76 {
77 return e->load_privkey;
78 }
79
80ENGINE_LOAD_KEY_PTR ENGINE_get_load_pubkey_function(const ENGINE *e)
81 {
82 return e->load_pubkey;
83 }
84
85/* API functions to load public/private keys */
86
87EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id,
88 UI_METHOD *ui_method, void *callback_data)
89 {
90 EVP_PKEY *pkey;
91
92 if(e == NULL)
93 {
94 ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY,
95 ERR_R_PASSED_NULL_PARAMETER);
96 return 0;
97 }
98 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
99 if(e->funct_ref == 0)
100 {
101 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
102 ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY,
103 ENGINE_R_NOT_INITIALISED);
104 return 0;
105 }
106 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
107 if (!e->load_privkey)
108 {
109 ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY,
110 ENGINE_R_NO_LOAD_FUNCTION);
111 return 0;
112 }
113 pkey = e->load_privkey(e, key_id, ui_method, callback_data);
114 if (!pkey)
115 {
116 ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY,
117 ENGINE_R_FAILED_LOADING_PRIVATE_KEY);
118 return 0;
119 }
120 return pkey;
121 }
122
123EVP_PKEY *ENGINE_load_public_key(ENGINE *e, const char *key_id,
124 UI_METHOD *ui_method, void *callback_data)
125 {
126 EVP_PKEY *pkey;
127
128 if(e == NULL)
129 {
130 ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY,
131 ERR_R_PASSED_NULL_PARAMETER);
132 return 0;
133 }
134 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
135 if(e->funct_ref == 0)
136 {
137 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
138 ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY,
139 ENGINE_R_NOT_INITIALISED);
140 return 0;
141 }
142 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
143 if (!e->load_pubkey)
144 {
145 ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY,
146 ENGINE_R_NO_LOAD_FUNCTION);
147 return 0;
148 }
149 pkey = e->load_pubkey(e, key_id, ui_method, callback_data);
150 if (!pkey)
151 {
152 ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY,
153 ENGINE_R_FAILED_LOADING_PUBLIC_KEY);
154 return 0;
155 }
156 return pkey;
157 }
diff --git a/src/lib/libcrypto/engine/eng_table.c b/src/lib/libcrypto/engine/eng_table.c
new file mode 100644
index 0000000000..c69a84a8bf
--- /dev/null
+++ b/src/lib/libcrypto/engine/eng_table.c
@@ -0,0 +1,361 @@
1/* ====================================================================
2 * Copyright (c) 2001 The OpenSSL Project. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * 3. All advertising materials mentioning features or use of this
17 * software must display the following acknowledgment:
18 * "This product includes software developed by the OpenSSL Project
19 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
20 *
21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22 * endorse or promote products derived from this software without
23 * prior written permission. For written permission, please contact
24 * licensing@OpenSSL.org.
25 *
26 * 5. Products derived from this software may not be called "OpenSSL"
27 * nor may "OpenSSL" appear in their names without prior written
28 * permission of the OpenSSL Project.
29 *
30 * 6. Redistributions of any form whatsoever must retain the following
31 * acknowledgment:
32 * "This product includes software developed by the OpenSSL Project
33 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
34 *
35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46 * OF THE POSSIBILITY OF SUCH DAMAGE.
47 * ====================================================================
48 *
49 * This product includes cryptographic software written by Eric Young
50 * (eay@cryptsoft.com). This product includes software written by Tim
51 * Hudson (tjh@cryptsoft.com).
52 *
53 */
54
55#include <openssl/evp.h>
56#include <openssl/engine.h>
57#include "eng_int.h"
58
59/* This is the type of item in the 'implementation' table. Each 'nid' hashes to
60 * a (potentially NULL) ENGINE_PILE structure which contains a stack of ENGINE*
61 * pointers. These pointers aren't references, because they're inserted and
62 * removed during ENGINE creation and ENGINE destruction. They point to ENGINEs
63 * that *exist* (ie. have a structural reference count greater than zero) rather
64 * than ENGINEs that are *functional*. Each pointer in those stacks are to
65 * ENGINEs that implements the algorithm corresponding to each 'nid'. */
66
67/* The type of the items in the table */
68typedef struct st_engine_pile
69 {
70 /* The 'nid' of the algorithm/mode this ENGINE_PILE structure represents
71 * */
72 int nid;
73 /* A stack of ENGINE pointers for ENGINEs that support this
74 * algorithm/mode. In the event that 'funct' is NULL, the first entry in
75 * this stack that initialises will be set as 'funct' and assumed as the
76 * default for operations of this type. */
77 STACK_OF(ENGINE) *sk;
78 /* The default ENGINE to perform this algorithm/mode. */
79 ENGINE *funct;
80 /* This value optimises engine_table_select(). If it is called it sets
81 * this value to 1. Any changes to this ENGINE_PILE resets it to zero.
82 * As such, no ENGINE_init() thrashing is done unless ENGINEs
83 * continually register (and/or unregister). */
84 int uptodate;
85 } ENGINE_PILE;
86
87/* The type of the hash table of ENGINE_PILE structures such that each are
88 * unique and keyed by the 'nid' value. */
89struct st_engine_table
90 {
91 LHASH piles;
92 }; /* ENGINE_TABLE */
93
94/* This value stores global options controlling behaviour of (mostly) the
95 * engine_table_select() function. It's a bitmask of flag values of the form
96 * ENGINE_TABLE_FLAG_*** (as defined in engine.h) and is controlled by the
97 * ENGINE_[get|set]_table_flags() function. */
98static unsigned int table_flags = 0;
99
100/* API function manipulating 'table_flags' */
101unsigned int ENGINE_get_table_flags(void)
102 {
103 return table_flags;
104 }
105void ENGINE_set_table_flags(unsigned int flags)
106 {
107 table_flags = flags;
108 }
109
110/* Internal functions for the "piles" hash table */
111static unsigned long engine_pile_hash(const ENGINE_PILE *c)
112 {
113 return c->nid;
114 }
115static int engine_pile_cmp(const ENGINE_PILE *a, const ENGINE_PILE *b)
116 {
117 return a->nid - b->nid;
118 }
119static IMPLEMENT_LHASH_HASH_FN(engine_pile_hash, const ENGINE_PILE *)
120static IMPLEMENT_LHASH_COMP_FN(engine_pile_cmp, const ENGINE_PILE *)
121static int int_table_check(ENGINE_TABLE **t, int create)
122 {
123 LHASH *lh;
124 if(*t)
125 return 1;
126 if(!create)
127 return 0;
128 if((lh = lh_new(LHASH_HASH_FN(engine_pile_hash),
129 LHASH_COMP_FN(engine_pile_cmp))) == NULL)
130 return 0;
131 *t = (ENGINE_TABLE *)lh;
132 return 1;
133 }
134
135/* Privately exposed (via eng_int.h) functions for adding and/or removing
136 * ENGINEs from the implementation table */
137int engine_table_register(ENGINE_TABLE **table, ENGINE_CLEANUP_CB *cleanup,
138 ENGINE *e, const int *nids, int num_nids, int setdefault)
139 {
140 int ret = 0, added = 0;
141 ENGINE_PILE tmplate, *fnd;
142 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
143 if(!(*table))
144 added = 1;
145 if(!int_table_check(table, 1))
146 goto end;
147 if(added)
148 /* The cleanup callback needs to be added */
149 engine_cleanup_add_first(cleanup);
150 while(num_nids--)
151 {
152 tmplate.nid = *nids;
153 fnd = lh_retrieve(&(*table)->piles, &tmplate);
154 if(!fnd)
155 {
156 fnd = OPENSSL_malloc(sizeof(ENGINE_PILE));
157 if(!fnd)
158 goto end;
159 fnd->uptodate = 1;
160 fnd->nid = *nids;
161 fnd->sk = sk_ENGINE_new_null();
162 if(!fnd->sk)
163 {
164 OPENSSL_free(fnd);
165 goto end;
166 }
167 fnd->funct= NULL;
168 lh_insert(&(*table)->piles, fnd);
169 }
170 /* A registration shouldn't add duplciate entries */
171 sk_ENGINE_delete_ptr(fnd->sk, e);
172 /* if 'setdefault', this ENGINE goes to the head of the list */
173 if(!sk_ENGINE_push(fnd->sk, e))
174 goto end;
175 /* "touch" this ENGINE_PILE */
176 fnd->uptodate = 0;
177 if(setdefault)
178 {
179 if(!engine_unlocked_init(e))
180 {
181 ENGINEerr(ENGINE_F_ENGINE_TABLE_REGISTER,
182 ENGINE_R_INIT_FAILED);
183 goto end;
184 }
185 if(fnd->funct)
186 engine_unlocked_finish(fnd->funct, 0);
187 fnd->funct = e;
188 }
189 nids++;
190 }
191 ret = 1;
192end:
193 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
194 return ret;
195 }
196static void int_unregister_cb(ENGINE_PILE *pile, ENGINE *e)
197 {
198 int n;
199 /* Iterate the 'c->sk' stack removing any occurance of 'e' */
200 while((n = sk_ENGINE_find(pile->sk, e)) >= 0)
201 {
202 sk_ENGINE_delete(pile->sk, n);
203 /* "touch" this ENGINE_CIPHER */
204 pile->uptodate = 0;
205 }
206 if(pile->funct == e)
207 {
208 engine_unlocked_finish(e, 0);
209 pile->funct = NULL;
210 }
211 }
212static IMPLEMENT_LHASH_DOALL_ARG_FN(int_unregister_cb,ENGINE_PILE *,ENGINE *)
213void engine_table_unregister(ENGINE_TABLE **table, ENGINE *e)
214 {
215 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
216 if(int_table_check(table, 0))
217 lh_doall_arg(&(*table)->piles,
218 LHASH_DOALL_ARG_FN(int_unregister_cb), e);
219 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
220 }
221
222static void int_cleanup_cb(ENGINE_PILE *p)
223 {
224 sk_ENGINE_free(p->sk);
225 if(p->funct)
226 engine_unlocked_finish(p->funct, 0);
227 OPENSSL_free(p);
228 }
229static IMPLEMENT_LHASH_DOALL_FN(int_cleanup_cb,ENGINE_PILE *)
230void engine_table_cleanup(ENGINE_TABLE **table)
231 {
232 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
233 if(*table)
234 {
235 lh_doall(&(*table)->piles, LHASH_DOALL_FN(int_cleanup_cb));
236 lh_free(&(*table)->piles);
237 *table = NULL;
238 }
239 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
240 }
241
242/* Exposed API function to get a functional reference from the implementation
243 * table (ie. try to get a functional reference from the tabled structural
244 * references) for a given cipher 'nid' */
245#ifndef ENGINE_TABLE_DEBUG
246ENGINE *engine_table_select(ENGINE_TABLE **table, int nid)
247#else
248ENGINE *engine_table_select_tmp(ENGINE_TABLE **table, int nid, const char *f, int l)
249#endif
250 {
251 ENGINE *ret = NULL;
252 ENGINE_PILE tmplate, *fnd=NULL;
253 int initres, loop = 0;
254
255 /* If 'engine_ciphers' is NULL, then it's absolutely *sure* that no
256 * ENGINEs have registered any implementations! */
257 if(!(*table))
258 {
259#ifdef ENGINE_TABLE_DEBUG
260 fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, no "
261 "registered for anything!\n", f, l, nid);
262#endif
263 return NULL;
264 }
265 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
266 /* Check again inside the lock otherwise we could race against cleanup
267 * operations. But don't worry about a fprintf(stderr). */
268 if(!int_table_check(table, 0))
269 goto end;
270 tmplate.nid = nid;
271 fnd = lh_retrieve(&(*table)->piles, &tmplate);
272 if(!fnd)
273 goto end;
274 if(fnd->funct && engine_unlocked_init(fnd->funct))
275 {
276#ifdef ENGINE_TABLE_DEBUG
277 fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, using "
278 "ENGINE '%s' cached\n", f, l, nid, fnd->funct->id);
279#endif
280 ret = fnd->funct;
281 goto end;
282 }
283 if(fnd->uptodate)
284 {
285 ret = fnd->funct;
286 goto end;
287 }
288trynext:
289 ret = sk_ENGINE_value(fnd->sk, loop++);
290 if(!ret)
291 {
292#ifdef ENGINE_TABLE_DEBUG
293 fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, no "
294 "registered implementations would initialise\n",
295 f, l, nid);
296#endif
297 goto end;
298 }
299#if 0
300 /* Don't need to get a reference if we hold the lock. If the locking has
301 * to change in future, that would be different ... */
302 ret->struct_ref++; engine_ref_debug(ret, 0, 1)
303#endif
304 /* Try and initialise the ENGINE if it's already functional *or* if the
305 * ENGINE_TABLE_FLAG_NOINIT flag is not set. */
306 if((ret->funct_ref > 0) || !(table_flags & ENGINE_TABLE_FLAG_NOINIT))
307 initres = engine_unlocked_init(ret);
308 else
309 initres = 0;
310#if 0
311 /* Release the structural reference */
312 ret->struct_ref--; engine_ref_debug(ret, 0, -1);
313#endif
314 if(initres)
315 {
316 /* If we didn't have a default (functional reference) for this
317 * 'nid' (or we had one but for whatever reason we're now
318 * initialising a different one), use this opportunity to set
319 * 'funct'. */
320 if((fnd->funct != ret) && engine_unlocked_init(ret))
321 {
322 /* If there was a previous default we release it. */
323 if(fnd->funct)
324 engine_unlocked_finish(fnd->funct, 0);
325 /* We got an extra functional reference for the
326 * per-'nid' default */
327 fnd->funct = ret;
328#ifdef ENGINE_TABLE_DEBUG
329 fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, "
330 "setting default to '%s'\n", f, l, nid, ret->id);
331#endif
332 }
333#ifdef ENGINE_TABLE_DEBUG
334 fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, using "
335 "newly initialised '%s'\n", f, l, nid, ret->id);
336#endif
337 goto end;
338 }
339 goto trynext;
340end:
341 /* Whatever happened - we should "untouch" our uptodate file seeing as
342 * we have tried our best to find a functional reference for 'nid'. If
343 * it failed, it is unlikely to succeed again until some future
344 * registrations (or unregistrations) have taken place that affect that
345 * 'nid'. */
346 if(fnd)
347 fnd->uptodate = 1;
348#ifdef ENGINE_TABLE_DEBUG
349 if(ret)
350 fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, caching "
351 "ENGINE '%s'\n", f, l, nid, ret->id);
352 else
353 fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, caching "
354 "'no matching ENGINE'\n", f, l, nid);
355#endif
356 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
357 /* Whatever happened, any failed init()s are not failures in this
358 * context, so clear our error state. */
359 ERR_clear_error();
360 return ret;
361 }
diff --git a/src/lib/libcrypto/engine/engine.h b/src/lib/libcrypto/engine/engine.h
new file mode 100644
index 0000000000..2983f47034
--- /dev/null
+++ b/src/lib/libcrypto/engine/engine.h
@@ -0,0 +1,398 @@
1/* openssl/engine.h */
2/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
3 * project 2000.
4 */
5/* ====================================================================
6 * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59#ifndef HEADER_ENGINE_H
60#define HEADER_ENGINE_H
61
62#include <openssl/bn.h>
63#include <openssl/rsa.h>
64#include <openssl/dsa.h>
65#include <openssl/dh.h>
66#include <openssl/rand.h>
67#include <openssl/evp.h>
68#include <openssl/symhacks.h>
69
70#ifdef __cplusplus
71extern "C" {
72#endif
73
74/* These flags are used to control combinations of algorithm (methods)
75 * by bitwise "OR"ing. */
76#define ENGINE_METHOD_RSA (unsigned int)0x0001
77#define ENGINE_METHOD_DSA (unsigned int)0x0002
78#define ENGINE_METHOD_DH (unsigned int)0x0004
79#define ENGINE_METHOD_RAND (unsigned int)0x0008
80#define ENGINE_METHOD_BN_MOD_EXP (unsigned int)0x0010
81#define ENGINE_METHOD_BN_MOD_EXP_CRT (unsigned int)0x0020
82/* Obvious all-or-nothing cases. */
83#define ENGINE_METHOD_ALL (unsigned int)0xFFFF
84#define ENGINE_METHOD_NONE (unsigned int)0x0000
85
86/* These flags are used to tell the ctrl function what should be done.
87 * All command numbers are shared between all engines, even if some don't
88 * make sense to some engines. In such a case, they do nothing but return
89 * the error ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED. */
90#define ENGINE_CTRL_SET_LOGSTREAM 1
91#define ENGINE_CTRL_SET_PASSWORD_CALLBACK 2
92/* Flags specific to the nCipher "chil" engine */
93#define ENGINE_CTRL_CHIL_SET_FORKCHECK 100
94 /* Depending on the value of the (long)i argument, this sets or
95 * unsets the SimpleForkCheck flag in the CHIL API to enable or
96 * disable checking and workarounds for applications that fork().
97 */
98#define ENGINE_CTRL_CHIL_NO_LOCKING 101
99 /* This prevents the initialisation function from providing mutex
100 * callbacks to the nCipher library. */
101
102/* As we're missing a BIGNUM_METHOD, we need a couple of locally
103 * defined function types that engines can implement. */
104
105#ifndef HEADER_ENGINE_INT_H
106/* mod_exp operation, calculates; r = a ^ p mod m
107 * NB: ctx can be NULL, but if supplied, the implementation may use
108 * it if it wishes. */
109typedef int (*BN_MOD_EXP)(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
110 const BIGNUM *m, BN_CTX *ctx);
111
112/* private key operation for RSA, provided seperately in case other
113 * RSA implementations wish to use it. */
114typedef int (*BN_MOD_EXP_CRT)(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
115 const BIGNUM *q, const BIGNUM *dmp1, const BIGNUM *dmq1,
116 const BIGNUM *iqmp, BN_CTX *ctx);
117
118/* Generic function pointer */
119typedef void (*ENGINE_GEN_FUNC_PTR)();
120/* Generic function pointer taking no arguments */
121typedef void (*ENGINE_GEN_INT_FUNC_PTR)(void);
122/* Specific control function pointer */
123typedef int (*ENGINE_CTRL_FUNC_PTR)(int cmd, long i, void *p, void (*f)());
124
125/* The list of "engine" types is a static array of (const ENGINE*)
126 * pointers (not dynamic because static is fine for now and we otherwise
127 * have to hook an appropriate load/unload function in to initialise and
128 * cleanup). */
129typedef struct engine_st ENGINE;
130#endif
131
132/* STRUCTURE functions ... all of these functions deal with pointers to
133 * ENGINE structures where the pointers have a "structural reference".
134 * This means that their reference is to allow access to the structure
135 * but it does not imply that the structure is functional. To simply
136 * increment or decrement the structural reference count, use ENGINE_new
137 * and ENGINE_free. NB: This is not required when iterating using
138 * ENGINE_get_next as it will automatically decrement the structural
139 * reference count of the "current" ENGINE and increment the structural
140 * reference count of the ENGINE it returns (unless it is NULL). */
141
142/* Get the first/last "ENGINE" type available. */
143ENGINE *ENGINE_get_first(void);
144ENGINE *ENGINE_get_last(void);
145/* Iterate to the next/previous "ENGINE" type (NULL = end of the list). */
146ENGINE *ENGINE_get_next(ENGINE *e);
147ENGINE *ENGINE_get_prev(ENGINE *e);
148/* Add another "ENGINE" type into the array. */
149int ENGINE_add(ENGINE *e);
150/* Remove an existing "ENGINE" type from the array. */
151int ENGINE_remove(ENGINE *e);
152/* Retrieve an engine from the list by its unique "id" value. */
153ENGINE *ENGINE_by_id(const char *id);
154
155/* These functions are useful for manufacturing new ENGINE
156 * structures. They don't address reference counting at all -
157 * one uses them to populate an ENGINE structure with personalised
158 * implementations of things prior to using it directly or adding
159 * it to the builtin ENGINE list in OpenSSL. These are also here
160 * so that the ENGINE structure doesn't have to be exposed and
161 * break binary compatibility!
162 *
163 * NB: I'm changing ENGINE_new to force the ENGINE structure to
164 * be allocated from within OpenSSL. See the comment for
165 * ENGINE_get_struct_size().
166 */
167#if 0
168ENGINE *ENGINE_new(ENGINE *e);
169#else
170ENGINE *ENGINE_new(void);
171#endif
172int ENGINE_free(ENGINE *e);
173int ENGINE_set_id(ENGINE *e, const char *id);
174int ENGINE_set_name(ENGINE *e, const char *name);
175int ENGINE_set_RSA(ENGINE *e, RSA_METHOD *rsa_meth);
176int ENGINE_set_DSA(ENGINE *e, DSA_METHOD *dsa_meth);
177int ENGINE_set_DH(ENGINE *e, DH_METHOD *dh_meth);
178int ENGINE_set_RAND(ENGINE *e, RAND_METHOD *rand_meth);
179int ENGINE_set_BN_mod_exp(ENGINE *e, BN_MOD_EXP bn_mod_exp);
180int ENGINE_set_BN_mod_exp_crt(ENGINE *e, BN_MOD_EXP_CRT bn_mod_exp_crt);
181int ENGINE_set_init_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR init_f);
182int ENGINE_set_finish_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR finish_f);
183int ENGINE_set_ctrl_function(ENGINE *e, ENGINE_CTRL_FUNC_PTR ctrl_f);
184
185/* These return values from within the ENGINE structure. These can
186 * be useful with functional references as well as structural
187 * references - it depends which you obtained. Using the result
188 * for functional purposes if you only obtained a structural
189 * reference may be problematic! */
190const char *ENGINE_get_id(ENGINE *e);
191const char *ENGINE_get_name(ENGINE *e);
192RSA_METHOD *ENGINE_get_RSA(ENGINE *e);
193DSA_METHOD *ENGINE_get_DSA(ENGINE *e);
194DH_METHOD *ENGINE_get_DH(ENGINE *e);
195RAND_METHOD *ENGINE_get_RAND(ENGINE *e);
196BN_MOD_EXP ENGINE_get_BN_mod_exp(ENGINE *e);
197BN_MOD_EXP_CRT ENGINE_get_BN_mod_exp_crt(ENGINE *e);
198ENGINE_GEN_INT_FUNC_PTR ENGINE_get_init_function(ENGINE *e);
199ENGINE_GEN_INT_FUNC_PTR ENGINE_get_finish_function(ENGINE *e);
200ENGINE_CTRL_FUNC_PTR ENGINE_get_ctrl_function(ENGINE *e);
201
202/* ENGINE_new is normally passed a NULL in the first parameter because
203 * the calling code doesn't have access to the definition of the ENGINE
204 * structure (for good reason). However, if the caller wishes to use
205 * its own memory allocation or use a static array, the following call
206 * should be used to check the amount of memory the ENGINE structure
207 * will occupy. This will make the code more future-proof.
208 *
209 * NB: I'm "#if 0"-ing this out because it's better to force the use of
210 * internally allocated memory. See similar change in ENGINE_new().
211 */
212#if 0
213int ENGINE_get_struct_size(void);
214#endif
215
216/* FUNCTIONAL functions. These functions deal with ENGINE structures
217 * that have (or will) be initialised for use. Broadly speaking, the
218 * structural functions are useful for iterating the list of available
219 * engine types, creating new engine types, and other "list" operations.
220 * These functions actually deal with ENGINEs that are to be used. As
221 * such these functions can fail (if applicable) when particular
222 * engines are unavailable - eg. if a hardware accelerator is not
223 * attached or not functioning correctly. Each ENGINE has 2 reference
224 * counts; structural and functional. Every time a functional reference
225 * is obtained or released, a corresponding structural reference is
226 * automatically obtained or released too. */
227
228/* Initialise a engine type for use (or up its reference count if it's
229 * already in use). This will fail if the engine is not currently
230 * operational and cannot initialise. */
231int ENGINE_init(ENGINE *e);
232/* Free a functional reference to a engine type. This does not require
233 * a corresponding call to ENGINE_free as it also releases a structural
234 * reference. */
235int ENGINE_finish(ENGINE *e);
236/* Send control parametrised commands to the engine. The possibilities
237 * to send down an integer, a pointer to data or a function pointer are
238 * provided. Any of the parameters may or may not be NULL, depending
239 * on the command number */
240/* WARNING: This is currently experimental and may change radically! */
241int ENGINE_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)());
242
243/* The following functions handle keys that are stored in some secondary
244 * location, handled by the engine. The storage may be on a card or
245 * whatever. */
246EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id,
247 const char *passphrase);
248EVP_PKEY *ENGINE_load_public_key(ENGINE *e, const char *key_id,
249 const char *passphrase);
250
251/* This returns a pointer for the current ENGINE structure that
252 * is (by default) performing any RSA operations. The value returned
253 * is an incremented reference, so it should be free'd (ENGINE_finish)
254 * before it is discarded. */
255ENGINE *ENGINE_get_default_RSA(void);
256/* Same for the other "methods" */
257ENGINE *ENGINE_get_default_DSA(void);
258ENGINE *ENGINE_get_default_DH(void);
259ENGINE *ENGINE_get_default_RAND(void);
260ENGINE *ENGINE_get_default_BN_mod_exp(void);
261ENGINE *ENGINE_get_default_BN_mod_exp_crt(void);
262
263/* This sets a new default ENGINE structure for performing RSA
264 * operations. If the result is non-zero (success) then the ENGINE
265 * structure will have had its reference count up'd so the caller
266 * should still free their own reference 'e'. */
267int ENGINE_set_default_RSA(ENGINE *e);
268/* Same for the other "methods" */
269int ENGINE_set_default_DSA(ENGINE *e);
270int ENGINE_set_default_DH(ENGINE *e);
271int ENGINE_set_default_RAND(ENGINE *e);
272int ENGINE_set_default_BN_mod_exp(ENGINE *e);
273int ENGINE_set_default_BN_mod_exp_crt(ENGINE *e);
274
275/* The combination "set" - the flags are bitwise "OR"d from the
276 * ENGINE_METHOD_*** defines above. */
277int ENGINE_set_default(ENGINE *e, unsigned int flags);
278
279/* Obligatory error function. */
280void ERR_load_ENGINE_strings(void);
281
282/*
283 * Error codes for all engine functions. NB: We use "generic"
284 * function names instead of per-implementation ones because this
285 * levels the playing field for externally implemented bootstrapped
286 * support code. As the filename and line number is included, it's
287 * more important to indicate the type of function, so that
288 * bootstrapped code (that can't easily add its own errors in) can
289 * use the same error codes too.
290 */
291
292/* BEGIN ERROR CODES */
293/* The following lines are auto generated by the script mkerr.pl. Any changes
294 * made after this point may be overwritten when the script is next run.
295 */
296
297/* Error codes for the ENGINE functions. */
298
299/* Function codes. */
300#define ENGINE_F_ATALLA_FINISH 135
301#define ENGINE_F_ATALLA_INIT 136
302#define ENGINE_F_ATALLA_MOD_EXP 137
303#define ENGINE_F_ATALLA_RSA_MOD_EXP 138
304#define ENGINE_F_CSWIFT_DSA_SIGN 133
305#define ENGINE_F_CSWIFT_DSA_VERIFY 134
306#define ENGINE_F_CSWIFT_FINISH 100
307#define ENGINE_F_CSWIFT_INIT 101
308#define ENGINE_F_CSWIFT_MOD_EXP 102
309#define ENGINE_F_CSWIFT_MOD_EXP_CRT 103
310#define ENGINE_F_CSWIFT_RSA_MOD_EXP 104
311#define ENGINE_F_ENGINE_ADD 105
312#define ENGINE_F_ENGINE_BY_ID 106
313#define ENGINE_F_ENGINE_CTRL 142
314#define ENGINE_F_ENGINE_FINISH 107
315#define ENGINE_F_ENGINE_FREE 108
316#define ENGINE_F_ENGINE_GET_BN_MOD_EXP 109
317#define ENGINE_F_ENGINE_GET_BN_MOD_EXP_CRT 110
318#define ENGINE_F_ENGINE_GET_CTRL_FUNCTION 144
319#define ENGINE_F_ENGINE_GET_DH 111
320#define ENGINE_F_ENGINE_GET_DSA 112
321#define ENGINE_F_ENGINE_GET_FINISH_FUNCTION 145
322#define ENGINE_F_ENGINE_GET_ID 113
323#define ENGINE_F_ENGINE_GET_INIT_FUNCTION 146
324#define ENGINE_F_ENGINE_GET_NAME 114
325#define ENGINE_F_ENGINE_GET_NEXT 115
326#define ENGINE_F_ENGINE_GET_PREV 116
327#define ENGINE_F_ENGINE_GET_RAND 117
328#define ENGINE_F_ENGINE_GET_RSA 118
329#define ENGINE_F_ENGINE_INIT 119
330#define ENGINE_F_ENGINE_LIST_ADD 120
331#define ENGINE_F_ENGINE_LIST_REMOVE 121
332#define ENGINE_F_ENGINE_LOAD_PRIVATE_KEY 150
333#define ENGINE_F_ENGINE_LOAD_PUBLIC_KEY 151
334#define ENGINE_F_ENGINE_NEW 122
335#define ENGINE_F_ENGINE_REMOVE 123
336#define ENGINE_F_ENGINE_SET_BN_MOD_EXP 124
337#define ENGINE_F_ENGINE_SET_BN_MOD_EXP_CRT 125
338#define ENGINE_F_ENGINE_SET_CTRL_FUNCTION 147
339#define ENGINE_F_ENGINE_SET_DEFAULT_TYPE 126
340#define ENGINE_F_ENGINE_SET_DH 127
341#define ENGINE_F_ENGINE_SET_DSA 128
342#define ENGINE_F_ENGINE_SET_FINISH_FUNCTION 148
343#define ENGINE_F_ENGINE_SET_ID 129
344#define ENGINE_F_ENGINE_SET_INIT_FUNCTION 149
345#define ENGINE_F_ENGINE_SET_NAME 130
346#define ENGINE_F_ENGINE_SET_RAND 131
347#define ENGINE_F_ENGINE_SET_RSA 132
348#define ENGINE_F_ENGINE_UNLOAD_KEY 152
349#define ENGINE_F_HWCRHK_CTRL 143
350#define ENGINE_F_HWCRHK_FINISH 135
351#define ENGINE_F_HWCRHK_GET_PASS 155
352#define ENGINE_F_HWCRHK_INIT 136
353#define ENGINE_F_HWCRHK_LOAD_PRIVKEY 153
354#define ENGINE_F_HWCRHK_LOAD_PUBKEY 154
355#define ENGINE_F_HWCRHK_MOD_EXP 137
356#define ENGINE_F_HWCRHK_MOD_EXP_CRT 138
357#define ENGINE_F_HWCRHK_RAND_BYTES 139
358#define ENGINE_F_HWCRHK_RSA_MOD_EXP 140
359#define ENGINE_F_LOG_MESSAGE 141
360
361/* Reason codes. */
362#define ENGINE_R_ALREADY_LOADED 100
363#define ENGINE_R_BIO_WAS_FREED 121
364#define ENGINE_R_BN_CTX_FULL 101
365#define ENGINE_R_BN_EXPAND_FAIL 102
366#define ENGINE_R_CHIL_ERROR 123
367#define ENGINE_R_CONFLICTING_ENGINE_ID 103
368#define ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED 119
369#define ENGINE_R_DSO_FAILURE 104
370#define ENGINE_R_ENGINE_IS_NOT_IN_LIST 105
371#define ENGINE_R_FAILED_LOADING_PRIVATE_KEY 128
372#define ENGINE_R_FAILED_LOADING_PUBLIC_KEY 129
373#define ENGINE_R_FINISH_FAILED 106
374#define ENGINE_R_GET_HANDLE_FAILED 107
375#define ENGINE_R_ID_OR_NAME_MISSING 108
376#define ENGINE_R_INIT_FAILED 109
377#define ENGINE_R_INTERNAL_LIST_ERROR 110
378#define ENGINE_R_MISSING_KEY_COMPONENTS 111
379#define ENGINE_R_NOT_INITIALISED 117
380#define ENGINE_R_NOT_LOADED 112
381#define ENGINE_R_NO_CALLBACK 127
382#define ENGINE_R_NO_CONTROL_FUNCTION 120
383#define ENGINE_R_NO_KEY 124
384#define ENGINE_R_NO_LOAD_FUNCTION 125
385#define ENGINE_R_NO_REFERENCE 130
386#define ENGINE_R_NO_SUCH_ENGINE 116
387#define ENGINE_R_NO_UNLOAD_FUNCTION 126
388#define ENGINE_R_PROVIDE_PARAMETERS 113
389#define ENGINE_R_REQUEST_FAILED 114
390#define ENGINE_R_REQUEST_FALLBACK 118
391#define ENGINE_R_SIZE_TOO_LARGE_OR_TOO_SMALL 122
392#define ENGINE_R_UNIT_FAILURE 115
393
394#ifdef __cplusplus
395}
396#endif
397#endif
398
diff --git a/src/lib/libcrypto/engine/tb_cipher.c b/src/lib/libcrypto/engine/tb_cipher.c
new file mode 100644
index 0000000000..c5a50fc910
--- /dev/null
+++ b/src/lib/libcrypto/engine/tb_cipher.c
@@ -0,0 +1,145 @@
1/* ====================================================================
2 * Copyright (c) 2000 The OpenSSL Project. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * 3. All advertising materials mentioning features or use of this
17 * software must display the following acknowledgment:
18 * "This product includes software developed by the OpenSSL Project
19 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
20 *
21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22 * endorse or promote products derived from this software without
23 * prior written permission. For written permission, please contact
24 * licensing@OpenSSL.org.
25 *
26 * 5. Products derived from this software may not be called "OpenSSL"
27 * nor may "OpenSSL" appear in their names without prior written
28 * permission of the OpenSSL Project.
29 *
30 * 6. Redistributions of any form whatsoever must retain the following
31 * acknowledgment:
32 * "This product includes software developed by the OpenSSL Project
33 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
34 *
35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46 * OF THE POSSIBILITY OF SUCH DAMAGE.
47 * ====================================================================
48 *
49 * This product includes cryptographic software written by Eric Young
50 * (eay@cryptsoft.com). This product includes software written by Tim
51 * Hudson (tjh@cryptsoft.com).
52 *
53 */
54
55#include <openssl/evp.h>
56#include <openssl/engine.h>
57#include "eng_int.h"
58
59/* If this symbol is defined then ENGINE_get_cipher_engine(), the function that
60 * is used by EVP to hook in cipher code and cache defaults (etc), will display
61 * brief debugging summaries to stderr with the 'nid'. */
62/* #define ENGINE_CIPHER_DEBUG */
63
64static ENGINE_TABLE *cipher_table = NULL;
65
66void ENGINE_unregister_ciphers(ENGINE *e)
67 {
68 engine_table_unregister(&cipher_table, e);
69 }
70
71static void engine_unregister_all_ciphers(void)
72 {
73 engine_table_cleanup(&cipher_table);
74 }
75
76int ENGINE_register_ciphers(ENGINE *e)
77 {
78 if(e->ciphers)
79 {
80 const int *nids;
81 int num_nids = e->ciphers(e, NULL, &nids, 0);
82 if(num_nids > 0)
83 return engine_table_register(&cipher_table,
84 &engine_unregister_all_ciphers, e, nids,
85 num_nids, 0);
86 }
87 return 1;
88 }
89
90void ENGINE_register_all_ciphers()
91 {
92 ENGINE *e;
93
94 for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
95 ENGINE_register_ciphers(e);
96 }
97
98int ENGINE_set_default_ciphers(ENGINE *e)
99 {
100 if(e->ciphers)
101 {
102 const int *nids;
103 int num_nids = e->ciphers(e, NULL, &nids, 0);
104 if(num_nids > 0)
105 return engine_table_register(&cipher_table,
106 &engine_unregister_all_ciphers, e, nids,
107 num_nids, 1);
108 }
109 return 1;
110 }
111
112/* Exposed API function to get a functional reference from the implementation
113 * table (ie. try to get a functional reference from the tabled structural
114 * references) for a given cipher 'nid' */
115ENGINE *ENGINE_get_cipher_engine(int nid)
116 {
117 return engine_table_select(&cipher_table, nid);
118 }
119
120/* Obtains a cipher implementation from an ENGINE functional reference */
121const EVP_CIPHER *ENGINE_get_cipher(ENGINE *e, int nid)
122 {
123 const EVP_CIPHER *ret;
124 ENGINE_CIPHERS_PTR fn = ENGINE_get_ciphers(e);
125 if(!fn || !fn(e, &ret, NULL, nid))
126 {
127 ENGINEerr(ENGINE_F_ENGINE_GET_CIPHER,
128 ENGINE_R_UNIMPLEMENTED_CIPHER);
129 return NULL;
130 }
131 return ret;
132 }
133
134/* Gets the cipher callback from an ENGINE structure */
135ENGINE_CIPHERS_PTR ENGINE_get_ciphers(const ENGINE *e)
136 {
137 return e->ciphers;
138 }
139
140/* Sets the cipher callback in an ENGINE structure */
141int ENGINE_set_ciphers(ENGINE *e, ENGINE_CIPHERS_PTR f)
142 {
143 e->ciphers = f;
144 return 1;
145 }
diff --git a/src/lib/libcrypto/engine/tb_dh.c b/src/lib/libcrypto/engine/tb_dh.c
new file mode 100644
index 0000000000..c9347235ea
--- /dev/null
+++ b/src/lib/libcrypto/engine/tb_dh.c
@@ -0,0 +1,120 @@
1/* ====================================================================
2 * Copyright (c) 2000 The OpenSSL Project. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * 3. All advertising materials mentioning features or use of this
17 * software must display the following acknowledgment:
18 * "This product includes software developed by the OpenSSL Project
19 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
20 *
21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22 * endorse or promote products derived from this software without
23 * prior written permission. For written permission, please contact
24 * licensing@OpenSSL.org.
25 *
26 * 5. Products derived from this software may not be called "OpenSSL"
27 * nor may "OpenSSL" appear in their names without prior written
28 * permission of the OpenSSL Project.
29 *
30 * 6. Redistributions of any form whatsoever must retain the following
31 * acknowledgment:
32 * "This product includes software developed by the OpenSSL Project
33 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
34 *
35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46 * OF THE POSSIBILITY OF SUCH DAMAGE.
47 * ====================================================================
48 *
49 * This product includes cryptographic software written by Eric Young
50 * (eay@cryptsoft.com). This product includes software written by Tim
51 * Hudson (tjh@cryptsoft.com).
52 *
53 */
54
55#include <openssl/evp.h>
56#include <openssl/engine.h>
57#include "eng_int.h"
58
59/* If this symbol is defined then ENGINE_get_default_DH(), the function that is
60 * used by DH to hook in implementation code and cache defaults (etc), will
61 * display brief debugging summaries to stderr with the 'nid'. */
62/* #define ENGINE_DH_DEBUG */
63
64static ENGINE_TABLE *dh_table = NULL;
65static const int dummy_nid = 1;
66
67void ENGINE_unregister_DH(ENGINE *e)
68 {
69 engine_table_unregister(&dh_table, e);
70 }
71
72static void engine_unregister_all_DH(void)
73 {
74 engine_table_cleanup(&dh_table);
75 }
76
77int ENGINE_register_DH(ENGINE *e)
78 {
79 if(e->dh_meth)
80 return engine_table_register(&dh_table,
81 &engine_unregister_all_DH, e, &dummy_nid, 1, 0);
82 return 1;
83 }
84
85void ENGINE_register_all_DH()
86 {
87 ENGINE *e;
88
89 for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
90 ENGINE_register_DH(e);
91 }
92
93int ENGINE_set_default_DH(ENGINE *e)
94 {
95 if(e->dh_meth)
96 return engine_table_register(&dh_table,
97 &engine_unregister_all_DH, e, &dummy_nid, 1, 1);
98 return 1;
99 }
100
101/* Exposed API function to get a functional reference from the implementation
102 * table (ie. try to get a functional reference from the tabled structural
103 * references). */
104ENGINE *ENGINE_get_default_DH(void)
105 {
106 return engine_table_select(&dh_table, dummy_nid);
107 }
108
109/* Obtains an DH implementation from an ENGINE functional reference */
110const DH_METHOD *ENGINE_get_DH(const ENGINE *e)
111 {
112 return e->dh_meth;
113 }
114
115/* Sets an DH implementation in an ENGINE structure */
116int ENGINE_set_DH(ENGINE *e, const DH_METHOD *dh_meth)
117 {
118 e->dh_meth = dh_meth;
119 return 1;
120 }
diff --git a/src/lib/libcrypto/engine/tb_digest.c b/src/lib/libcrypto/engine/tb_digest.c
new file mode 100644
index 0000000000..2c4dd6f796
--- /dev/null
+++ b/src/lib/libcrypto/engine/tb_digest.c
@@ -0,0 +1,145 @@
1/* ====================================================================
2 * Copyright (c) 2000 The OpenSSL Project. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * 3. All advertising materials mentioning features or use of this
17 * software must display the following acknowledgment:
18 * "This product includes software developed by the OpenSSL Project
19 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
20 *
21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22 * endorse or promote products derived from this software without
23 * prior written permission. For written permission, please contact
24 * licensing@OpenSSL.org.
25 *
26 * 5. Products derived from this software may not be called "OpenSSL"
27 * nor may "OpenSSL" appear in their names without prior written
28 * permission of the OpenSSL Project.
29 *
30 * 6. Redistributions of any form whatsoever must retain the following
31 * acknowledgment:
32 * "This product includes software developed by the OpenSSL Project
33 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
34 *
35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46 * OF THE POSSIBILITY OF SUCH DAMAGE.
47 * ====================================================================
48 *
49 * This product includes cryptographic software written by Eric Young
50 * (eay@cryptsoft.com). This product includes software written by Tim
51 * Hudson (tjh@cryptsoft.com).
52 *
53 */
54
55#include <openssl/evp.h>
56#include <openssl/engine.h>
57#include "eng_int.h"
58
59/* If this symbol is defined then ENGINE_get_digest_engine(), the function that
60 * is used by EVP to hook in digest code and cache defaults (etc), will display
61 * brief debugging summaries to stderr with the 'nid'. */
62/* #define ENGINE_DIGEST_DEBUG */
63
64static ENGINE_TABLE *digest_table = NULL;
65
66void ENGINE_unregister_digests(ENGINE *e)
67 {
68 engine_table_unregister(&digest_table, e);
69 }
70
71static void engine_unregister_all_digests(void)
72 {
73 engine_table_cleanup(&digest_table);
74 }
75
76int ENGINE_register_digests(ENGINE *e)
77 {
78 if(e->digests)
79 {
80 const int *nids;
81 int num_nids = e->digests(e, NULL, &nids, 0);
82 if(num_nids > 0)
83 return engine_table_register(&digest_table,
84 &engine_unregister_all_digests, e, nids,
85 num_nids, 0);
86 }
87 return 1;
88 }
89
90void ENGINE_register_all_digests()
91 {
92 ENGINE *e;
93
94 for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
95 ENGINE_register_digests(e);
96 }
97
98int ENGINE_set_default_digests(ENGINE *e)
99 {
100 if(e->digests)
101 {
102 const int *nids;
103 int num_nids = e->digests(e, NULL, &nids, 0);
104 if(num_nids > 0)
105 return engine_table_register(&digest_table,
106 &engine_unregister_all_digests, e, nids,
107 num_nids, 1);
108 }
109 return 1;
110 }
111
112/* Exposed API function to get a functional reference from the implementation
113 * table (ie. try to get a functional reference from the tabled structural
114 * references) for a given digest 'nid' */
115ENGINE *ENGINE_get_digest_engine(int nid)
116 {
117 return engine_table_select(&digest_table, nid);
118 }
119
120/* Obtains a digest implementation from an ENGINE functional reference */
121const EVP_MD *ENGINE_get_digest(ENGINE *e, int nid)
122 {
123 const EVP_MD *ret;
124 ENGINE_DIGESTS_PTR fn = ENGINE_get_digests(e);
125 if(!fn || !fn(e, &ret, NULL, nid))
126 {
127 ENGINEerr(ENGINE_F_ENGINE_GET_DIGEST,
128 ENGINE_R_UNIMPLEMENTED_DIGEST);
129 return NULL;
130 }
131 return ret;
132 }
133
134/* Gets the digest callback from an ENGINE structure */
135ENGINE_DIGESTS_PTR ENGINE_get_digests(const ENGINE *e)
136 {
137 return e->digests;
138 }
139
140/* Sets the digest callback in an ENGINE structure */
141int ENGINE_set_digests(ENGINE *e, ENGINE_DIGESTS_PTR f)
142 {
143 e->digests = f;
144 return 1;
145 }
diff --git a/src/lib/libcrypto/engine/tb_dsa.c b/src/lib/libcrypto/engine/tb_dsa.c
new file mode 100644
index 0000000000..e9209476b8
--- /dev/null
+++ b/src/lib/libcrypto/engine/tb_dsa.c
@@ -0,0 +1,120 @@
1/* ====================================================================
2 * Copyright (c) 2000 The OpenSSL Project. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * 3. All advertising materials mentioning features or use of this
17 * software must display the following acknowledgment:
18 * "This product includes software developed by the OpenSSL Project
19 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
20 *
21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22 * endorse or promote products derived from this software without
23 * prior written permission. For written permission, please contact
24 * licensing@OpenSSL.org.
25 *
26 * 5. Products derived from this software may not be called "OpenSSL"
27 * nor may "OpenSSL" appear in their names without prior written
28 * permission of the OpenSSL Project.
29 *
30 * 6. Redistributions of any form whatsoever must retain the following
31 * acknowledgment:
32 * "This product includes software developed by the OpenSSL Project
33 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
34 *
35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46 * OF THE POSSIBILITY OF SUCH DAMAGE.
47 * ====================================================================
48 *
49 * This product includes cryptographic software written by Eric Young
50 * (eay@cryptsoft.com). This product includes software written by Tim
51 * Hudson (tjh@cryptsoft.com).
52 *
53 */
54
55#include <openssl/evp.h>
56#include <openssl/engine.h>
57#include "eng_int.h"
58
59/* If this symbol is defined then ENGINE_get_default_DSA(), the function that is
60 * used by DSA to hook in implementation code and cache defaults (etc), will
61 * display brief debugging summaries to stderr with the 'nid'. */
62/* #define ENGINE_DSA_DEBUG */
63
64static ENGINE_TABLE *dsa_table = NULL;
65static const int dummy_nid = 1;
66
67void ENGINE_unregister_DSA(ENGINE *e)
68 {
69 engine_table_unregister(&dsa_table, e);
70 }
71
72static void engine_unregister_all_DSA(void)
73 {
74 engine_table_cleanup(&dsa_table);
75 }
76
77int ENGINE_register_DSA(ENGINE *e)
78 {
79 if(e->dsa_meth)
80 return engine_table_register(&dsa_table,
81 &engine_unregister_all_DSA, e, &dummy_nid, 1, 0);
82 return 1;
83 }
84
85void ENGINE_register_all_DSA()
86 {
87 ENGINE *e;
88
89 for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
90 ENGINE_register_DSA(e);
91 }
92
93int ENGINE_set_default_DSA(ENGINE *e)
94 {
95 if(e->dsa_meth)
96 return engine_table_register(&dsa_table,
97 &engine_unregister_all_DSA, e, &dummy_nid, 1, 0);
98 return 1;
99 }
100
101/* Exposed API function to get a functional reference from the implementation
102 * table (ie. try to get a functional reference from the tabled structural
103 * references). */
104ENGINE *ENGINE_get_default_DSA(void)
105 {
106 return engine_table_select(&dsa_table, dummy_nid);
107 }
108
109/* Obtains an DSA implementation from an ENGINE functional reference */
110const DSA_METHOD *ENGINE_get_DSA(const ENGINE *e)
111 {
112 return e->dsa_meth;
113 }
114
115/* Sets an DSA implementation in an ENGINE structure */
116int ENGINE_set_DSA(ENGINE *e, const DSA_METHOD *dsa_meth)
117 {
118 e->dsa_meth = dsa_meth;
119 return 1;
120 }
diff --git a/src/lib/libcrypto/engine/tb_rand.c b/src/lib/libcrypto/engine/tb_rand.c
new file mode 100644
index 0000000000..0b1d031f1e
--- /dev/null
+++ b/src/lib/libcrypto/engine/tb_rand.c
@@ -0,0 +1,120 @@
1/* ====================================================================
2 * Copyright (c) 2000 The OpenSSL Project. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * 3. All advertising materials mentioning features or use of this
17 * software must display the following acknowledgment:
18 * "This product includes software developed by the OpenSSL Project
19 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
20 *
21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22 * endorse or promote products derived from this software without
23 * prior written permission. For written permission, please contact
24 * licensing@OpenSSL.org.
25 *
26 * 5. Products derived from this software may not be called "OpenSSL"
27 * nor may "OpenSSL" appear in their names without prior written
28 * permission of the OpenSSL Project.
29 *
30 * 6. Redistributions of any form whatsoever must retain the following
31 * acknowledgment:
32 * "This product includes software developed by the OpenSSL Project
33 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
34 *
35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46 * OF THE POSSIBILITY OF SUCH DAMAGE.
47 * ====================================================================
48 *
49 * This product includes cryptographic software written by Eric Young
50 * (eay@cryptsoft.com). This product includes software written by Tim
51 * Hudson (tjh@cryptsoft.com).
52 *
53 */
54
55#include <openssl/evp.h>
56#include <openssl/engine.h>
57#include "eng_int.h"
58
59/* If this symbol is defined then ENGINE_get_default_RAND(), the function that is
60 * used by RAND to hook in implementation code and cache defaults (etc), will
61 * display brief debugging summaries to stderr with the 'nid'. */
62/* #define ENGINE_RAND_DEBUG */
63
64static ENGINE_TABLE *rand_table = NULL;
65static const int dummy_nid = 1;
66
67void ENGINE_unregister_RAND(ENGINE *e)
68 {
69 engine_table_unregister(&rand_table, e);
70 }
71
72static void engine_unregister_all_RAND(void)
73 {
74 engine_table_cleanup(&rand_table);
75 }
76
77int ENGINE_register_RAND(ENGINE *e)
78 {
79 if(e->rand_meth)
80 return engine_table_register(&rand_table,
81 &engine_unregister_all_RAND, e, &dummy_nid, 1, 0);
82 return 1;
83 }
84
85void ENGINE_register_all_RAND()
86 {
87 ENGINE *e;
88
89 for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
90 ENGINE_register_RAND(e);
91 }
92
93int ENGINE_set_default_RAND(ENGINE *e)
94 {
95 if(e->rand_meth)
96 return engine_table_register(&rand_table,
97 &engine_unregister_all_RAND, e, &dummy_nid, 1, 1);
98 return 1;
99 }
100
101/* Exposed API function to get a functional reference from the implementation
102 * table (ie. try to get a functional reference from the tabled structural
103 * references). */
104ENGINE *ENGINE_get_default_RAND(void)
105 {
106 return engine_table_select(&rand_table, dummy_nid);
107 }
108
109/* Obtains an RAND implementation from an ENGINE functional reference */
110const RAND_METHOD *ENGINE_get_RAND(const ENGINE *e)
111 {
112 return e->rand_meth;
113 }
114
115/* Sets an RAND implementation in an ENGINE structure */
116int ENGINE_set_RAND(ENGINE *e, const RAND_METHOD *rand_meth)
117 {
118 e->rand_meth = rand_meth;
119 return 1;
120 }
diff --git a/src/lib/libcrypto/engine/tb_rsa.c b/src/lib/libcrypto/engine/tb_rsa.c
new file mode 100644
index 0000000000..f84fea3968
--- /dev/null
+++ b/src/lib/libcrypto/engine/tb_rsa.c
@@ -0,0 +1,120 @@
1/* ====================================================================
2 * Copyright (c) 2000 The OpenSSL Project. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * 3. All advertising materials mentioning features or use of this
17 * software must display the following acknowledgment:
18 * "This product includes software developed by the OpenSSL Project
19 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
20 *
21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22 * endorse or promote products derived from this software without
23 * prior written permission. For written permission, please contact
24 * licensing@OpenSSL.org.
25 *
26 * 5. Products derived from this software may not be called "OpenSSL"
27 * nor may "OpenSSL" appear in their names without prior written
28 * permission of the OpenSSL Project.
29 *
30 * 6. Redistributions of any form whatsoever must retain the following
31 * acknowledgment:
32 * "This product includes software developed by the OpenSSL Project
33 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
34 *
35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46 * OF THE POSSIBILITY OF SUCH DAMAGE.
47 * ====================================================================
48 *
49 * This product includes cryptographic software written by Eric Young
50 * (eay@cryptsoft.com). This product includes software written by Tim
51 * Hudson (tjh@cryptsoft.com).
52 *
53 */
54
55#include <openssl/evp.h>
56#include <openssl/engine.h>
57#include "eng_int.h"
58
59/* If this symbol is defined then ENGINE_get_default_RSA(), the function that is
60 * used by RSA to hook in implementation code and cache defaults (etc), will
61 * display brief debugging summaries to stderr with the 'nid'. */
62/* #define ENGINE_RSA_DEBUG */
63
64static ENGINE_TABLE *rsa_table = NULL;
65static const int dummy_nid = 1;
66
67void ENGINE_unregister_RSA(ENGINE *e)
68 {
69 engine_table_unregister(&rsa_table, e);
70 }
71
72static void engine_unregister_all_RSA(void)
73 {
74 engine_table_cleanup(&rsa_table);
75 }
76
77int ENGINE_register_RSA(ENGINE *e)
78 {
79 if(e->rsa_meth)
80 return engine_table_register(&rsa_table,
81 &engine_unregister_all_RSA, e, &dummy_nid, 1, 0);
82 return 1;
83 }
84
85void ENGINE_register_all_RSA()
86 {
87 ENGINE *e;
88
89 for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
90 ENGINE_register_RSA(e);
91 }
92
93int ENGINE_set_default_RSA(ENGINE *e)
94 {
95 if(e->rsa_meth)
96 return engine_table_register(&rsa_table,
97 &engine_unregister_all_RSA, e, &dummy_nid, 1, 1);
98 return 1;
99 }
100
101/* Exposed API function to get a functional reference from the implementation
102 * table (ie. try to get a functional reference from the tabled structural
103 * references). */
104ENGINE *ENGINE_get_default_RSA(void)
105 {
106 return engine_table_select(&rsa_table, dummy_nid);
107 }
108
109/* Obtains an RSA implementation from an ENGINE functional reference */
110const RSA_METHOD *ENGINE_get_RSA(const ENGINE *e)
111 {
112 return e->rsa_meth;
113 }
114
115/* Sets an RSA implementation in an ENGINE structure */
116int ENGINE_set_RSA(ENGINE *e, const RSA_METHOD *rsa_meth)
117 {
118 e->rsa_meth = rsa_meth;
119 return 1;
120 }