/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following definitions.
- ENGINE_finish
- ENGINE_up_ref
- ENGINE_set_id
- ENGINE_set_name
- ENGINE_set_RSA
- ENGINE_set_DH
- ENGINE_set_destroy_function
- ENGINE_get_id
- ENGINE_get_name
- ENGINE_get_RSA
- ENGINE_get_DH
- ENGINE_get_RAND
- SG_default_engine
- ENGINE_load_builtin_engines
- ENGINE_by_dso
- ENGINE_by_id
- ENGINE_add_conf_module
1 /*
2 * Copyright (c) 2006 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * 3. Neither the name of the Institute nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34 #ifdef HAVE_CONFIG_H
35 #include <config.h>
36 #endif
37
38 RCSID("$Id$");
39
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <string.h>
43
44 #include <engine.h>
45
46 #ifdef HAVE_DLFCN_H
47 #include <dlfcn.h>
48 #ifndef RTLD_NOW
49 #define RTLD_NOW 0
50 #endif
51 #endif
52
53 struct hc_engine {
54 int references;
55 char *name;
56 char *id;
57 void (*destroy)(ENGINE *);
58 const RSA_METHOD *rsa;
59 const DH_METHOD *dh;
60 const RAND_METHOD *rand;
61 };
62
63 int
64 ENGINE_finish(ENGINE *engine)
/* [<][>][^][v][top][bottom][index][help] */
65 {
66 if (engine->references-- <= 0)
67 abort();
68 if (engine->references > 0)
69 return 1;
70
71 if (engine->name)
72 free(engine->name);
73 if (engine->id)
74 free(engine->id);
75 if(engine->destroy)
76 (*engine->destroy)(engine);
77
78 memset(engine, 0, sizeof(engine));
79 engine->references = -1;
80
81
82 free(engine);
83 return 1;
84 }
85
86 int
87 ENGINE_up_ref(ENGINE *engine)
/* [<][>][^][v][top][bottom][index][help] */
88 {
89 if (engine->references < 0)
90 abort();
91 engine->references++;
92 return 1;
93 }
94
95 int
96 ENGINE_set_id(ENGINE *engine, const char *id)
/* [<][>][^][v][top][bottom][index][help] */
97 {
98 engine->id = strdup(id);
99 return (engine->id == NULL) ? 0 : 1;
100 }
101
102 int
103 ENGINE_set_name(ENGINE *engine, const char *name)
/* [<][>][^][v][top][bottom][index][help] */
104 {
105 engine->name = strdup(name);
106 return (engine->name == NULL) ? 0 : 1;
107 }
108
109 int
110 ENGINE_set_RSA(ENGINE *engine, const RSA_METHOD *method)
/* [<][>][^][v][top][bottom][index][help] */
111 {
112 engine->rsa = method;
113 return 1;
114 }
115
116 int
117 ENGINE_set_DH(ENGINE *engine, const DH_METHOD *method)
/* [<][>][^][v][top][bottom][index][help] */
118 {
119 engine->dh = method;
120 return 1;
121 }
122
123 int
124 ENGINE_set_destroy_function(ENGINE *e, void (*destroy)(ENGINE *))
/* [<][>][^][v][top][bottom][index][help] */
125 {
126 e->destroy = destroy;
127 return 1;
128 }
129
130 const char *
131 ENGINE_get_id(const ENGINE *engine)
/* [<][>][^][v][top][bottom][index][help] */
132 {
133 return engine->id;
134 }
135
136 const char *
137 ENGINE_get_name(const ENGINE *engine)
/* [<][>][^][v][top][bottom][index][help] */
138 {
139 return engine->name;
140 }
141
142 const RSA_METHOD *
143 ENGINE_get_RSA(const ENGINE *engine)
/* [<][>][^][v][top][bottom][index][help] */
144 {
145 return engine->rsa;
146 }
147
148 const DH_METHOD *
149 ENGINE_get_DH(const ENGINE *engine)
/* [<][>][^][v][top][bottom][index][help] */
150 {
151 return engine->dh;
152 }
153
154 const RAND_METHOD *
155 ENGINE_get_RAND(const ENGINE *engine)
/* [<][>][^][v][top][bottom][index][help] */
156 {
157 return engine->rand;
158 }
159
160 /*
161 *
162 */
163
164 #define SG_default_engine(type) \
165 static ENGINE *type##_engine; \
166 int \
167 ENGINE_set_default_##type(ENGINE *engine) \
168 { \
169 if (type##_engine) \
170 ENGINE_finish(type##_engine); \
171 type##_engine = engine; \
172 if (type##_engine) \
173 ENGINE_up_ref(type##_engine); \
174 return 1; \
175 } \
176 ENGINE * \
177 ENGINE_get_default_##type(void) \
178 { \
179 if (type##_engine) \
180 ENGINE_up_ref(type##_engine); \
181 return type##_engine; \
182 }
183
184 SG_default_engine(RSA)
/* [<][>][^][v][top][bottom][index][help] */
185 SG_default_engine(DH)
186
187 #undef SG_default_engine
188
189 /*
190 *
191 */
192
193 static ENGINE **engines;
194 static unsigned int num_engines;
195
196 static int
197 add_engine(ENGINE *engine)
198 {
199 ENGINE **d, *dup;
200
201 dup = ENGINE_by_id(engine->id);
202 if (dup) {
203 ENGINE_finish(dup);
204 return 0;
205 }
206
207 d = realloc(engines, (num_engines + 1) * sizeof(*engines));
208 if (d == NULL)
209 return 1;
210 engines = d;
211 engines[num_engines++] = engine;
212
213 return 1;
214 }
215
216 void
217 ENGINE_load_builtin_engines(void)
/* [<][>][^][v][top][bottom][index][help] */
218 {
219 ENGINE *engine;
220 int ret;
221
222 engine = calloc(1, sizeof(*engine));
223 if (engine == NULL)
224 return;
225
226 ENGINE_set_id(engine, "builtin");
227 ENGINE_set_name(engine,
228 "Heimdal crypto builtin engine version " PACKAGE_VERSION);
229 ENGINE_set_RSA(engine, RSA_imath_method());
230 ENGINE_set_DH(engine, DH_imath_method());
231
232 ret = add_engine(engine);
233 if (ret != 1)
234 ENGINE_finish(engine);
235 }
236
237 ENGINE *
238 ENGINE_by_dso(const char *path, const char *id)
/* [<][>][^][v][top][bottom][index][help] */
239 {
240 #ifdef HAVE_DLOPEN
241 ENGINE *engine;
242 void *handle;
243 int ret;
244
245 engine = calloc(1, sizeof(*engine));
246 if (engine == NULL)
247 return NULL;
248
249 handle = dlopen(path, RTLD_NOW);
250 if (handle == NULL) {
251 /* printf("error: %s\n", dlerror()); */
252 free(engine);
253 return NULL;
254 }
255
256 {
257 unsigned long version;
258 openssl_v_check v_check;
259
260 v_check = (openssl_v_check)dlsym(handle, "v_check");
261 if (v_check == NULL) {
262 dlclose(handle);
263 free(engine);
264 return NULL;
265 }
266
267 version = (*v_check)(OPENSSL_DYNAMIC_VERSION);
268 if (version == 0) {
269 dlclose(handle);
270 free(engine);
271 return NULL;
272 }
273 }
274
275 {
276 openssl_bind_engine bind_engine;
277
278 bind_engine = (openssl_bind_engine)dlsym(handle, "bind_engine");
279 if (bind_engine == NULL) {
280 dlclose(handle);
281 free(engine);
282 return NULL;
283 }
284
285 ret = (*bind_engine)(engine, id, NULL); /* XXX fix third arg */
286 if (ret != 1) {
287 dlclose(handle);
288 free(engine);
289 return NULL;
290 }
291 }
292
293 ENGINE_up_ref(engine);
294
295 ret = add_engine(engine);
296 if (ret != 1) {
297 dlclose(handle);
298 ENGINE_finish(engine);
299 return NULL;
300 }
301
302 return engine;
303 #else
304 return NULL;
305 #endif
306 }
307
308 ENGINE *
309 ENGINE_by_id(const char *id)
/* [<][>][^][v][top][bottom][index][help] */
310 {
311 int i;
312
313 for (i = 0; i < num_engines; i++) {
314 if (strcmp(id, engines[i]->id) == 0) {
315 ENGINE_up_ref(engines[i]);
316 return engines[i];
317 }
318 }
319 return NULL;
320 }
321
322 void
323 ENGINE_add_conf_module(void)
/* [<][>][^][v][top][bottom][index][help] */
324 {
325 }