Line data Source code
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 : #include <config.h>
35 :
36 : #include <stdio.h>
37 : #include <stdlib.h>
38 : #include <string.h>
39 :
40 : #include <engine.h>
41 :
42 : #ifdef HAVE_DLFCN_H
43 : #include <dlfcn.h>
44 : #ifndef RTLD_NOW
45 : #define RTLD_NOW 0
46 : #endif
47 : #endif
48 :
49 : struct hc_engine {
50 : int references;
51 : char *name;
52 : char *id;
53 : void (*destroy)(ENGINE *);
54 : const RSA_METHOD *rsa;
55 : const DH_METHOD *dh;
56 : const RAND_METHOD *rand;
57 : };
58 :
59 : ENGINE *
60 0 : ENGINE_new(void)
61 : {
62 : ENGINE *engine;
63 :
64 0 : engine = calloc(1, sizeof(*engine));
65 0 : engine->references = 1;
66 :
67 0 : return engine;
68 : }
69 :
70 : int
71 0 : ENGINE_free(ENGINE *engine)
72 : {
73 0 : return ENGINE_finish(engine);
74 : }
75 :
76 : int
77 0 : ENGINE_finish(ENGINE *engine)
78 : {
79 0 : if (engine->references-- <= 0)
80 0 : abort();
81 0 : if (engine->references > 0)
82 0 : return 1;
83 :
84 0 : if (engine->name)
85 0 : free(engine->name);
86 0 : if (engine->id)
87 0 : free(engine->id);
88 0 : if(engine->destroy)
89 0 : (*engine->destroy)(engine);
90 :
91 0 : memset(engine, 0, sizeof(*engine));
92 0 : engine->references = -1;
93 :
94 :
95 0 : free(engine);
96 0 : return 1;
97 : }
98 :
99 : int
100 0 : ENGINE_up_ref(ENGINE *engine)
101 : {
102 0 : if (engine->references < 0)
103 0 : abort();
104 0 : engine->references++;
105 0 : return 1;
106 : }
107 :
108 : int
109 0 : ENGINE_set_id(ENGINE *engine, const char *id)
110 : {
111 0 : engine->id = strdup(id);
112 0 : return (engine->id == NULL) ? 0 : 1;
113 : }
114 :
115 : int
116 0 : ENGINE_set_name(ENGINE *engine, const char *name)
117 : {
118 0 : engine->name = strdup(name);
119 0 : return (engine->name == NULL) ? 0 : 1;
120 : }
121 :
122 : int
123 0 : ENGINE_set_RSA(ENGINE *engine, const RSA_METHOD *method)
124 : {
125 0 : engine->rsa = method;
126 0 : return 1;
127 : }
128 :
129 : int
130 0 : ENGINE_set_DH(ENGINE *engine, const DH_METHOD *method)
131 : {
132 0 : engine->dh = method;
133 0 : return 1;
134 : }
135 :
136 : int
137 0 : ENGINE_set_destroy_function(ENGINE *e, void (*destroy)(ENGINE *))
138 : {
139 0 : e->destroy = destroy;
140 0 : return 1;
141 : }
142 :
143 : const char *
144 0 : ENGINE_get_id(const ENGINE *engine)
145 : {
146 0 : return engine->id;
147 : }
148 :
149 : const char *
150 0 : ENGINE_get_name(const ENGINE *engine)
151 : {
152 0 : return engine->name;
153 : }
154 :
155 : const RSA_METHOD *
156 0 : ENGINE_get_RSA(const ENGINE *engine)
157 : {
158 0 : return engine->rsa;
159 : }
160 :
161 : const DH_METHOD *
162 0 : ENGINE_get_DH(const ENGINE *engine)
163 : {
164 0 : return engine->dh;
165 : }
166 :
167 : const RAND_METHOD *
168 0 : ENGINE_get_RAND(const ENGINE *engine)
169 : {
170 0 : return engine->rand;
171 : }
172 :
173 : /*
174 : *
175 : */
176 :
177 : #define SG_default_engine(type) \
178 : static ENGINE *type##_engine; \
179 : int \
180 : ENGINE_set_default_##type(ENGINE *engine) \
181 : { \
182 : if (type##_engine) \
183 : ENGINE_finish(type##_engine); \
184 : type##_engine = engine; \
185 : if (type##_engine) \
186 : ENGINE_up_ref(type##_engine); \
187 : return 1; \
188 : } \
189 : ENGINE * \
190 : ENGINE_get_default_##type(void) \
191 : { \
192 : if (type##_engine) \
193 : ENGINE_up_ref(type##_engine); \
194 : return type##_engine; \
195 : }
196 :
197 368 : SG_default_engine(RSA)
198 74 : SG_default_engine(DH)
199 :
200 : #undef SG_default_engine
201 :
202 : /*
203 : *
204 : */
205 :
206 : static ENGINE **engines;
207 : static unsigned int num_engines;
208 :
209 : static int
210 0 : add_engine(ENGINE *engine)
211 : {
212 : ENGINE **d, *dup;
213 :
214 0 : dup = ENGINE_by_id(engine->id);
215 0 : if (dup)
216 0 : return 0;
217 :
218 0 : d = realloc(engines, (num_engines + 1) * sizeof(*engines));
219 0 : if (d == NULL)
220 0 : return 1;
221 0 : engines = d;
222 0 : engines[num_engines++] = engine;
223 :
224 0 : return 1;
225 : }
226 :
227 : void
228 0 : ENGINE_load_builtin_engines(void)
229 : {
230 : ENGINE *engine;
231 : int ret;
232 :
233 0 : engine = ENGINE_new();
234 0 : if (engine == NULL)
235 0 : return;
236 :
237 0 : ENGINE_set_id(engine, "builtin");
238 0 : ENGINE_set_name(engine,
239 : "Heimdal crypto builtin (ltm) engine version " PACKAGE_VERSION);
240 0 : ENGINE_set_RSA(engine, RSA_ltm_method());
241 0 : ENGINE_set_DH(engine, DH_ltm_method());
242 :
243 0 : ret = add_engine(engine);
244 0 : if (ret != 1)
245 0 : ENGINE_finish(engine);
246 :
247 : #ifdef USE_HCRYPTO_TFM
248 : /*
249 : * TFM
250 : */
251 :
252 : engine = ENGINE_new();
253 : if (engine == NULL)
254 : return;
255 :
256 : ENGINE_set_id(engine, "tfm");
257 : ENGINE_set_name(engine,
258 : "Heimdal crypto tfm engine version " PACKAGE_VERSION);
259 : ENGINE_set_RSA(engine, RSA_tfm_method());
260 : ENGINE_set_DH(engine, DH_tfm_method());
261 :
262 : ret = add_engine(engine);
263 : if (ret != 1)
264 : ENGINE_finish(engine);
265 : #endif /* USE_HCRYPTO_TFM */
266 :
267 : #ifdef USE_HCRYPTO_LTM
268 : /*
269 : * ltm
270 : */
271 :
272 : engine = ENGINE_new();
273 : if (engine == NULL)
274 : return;
275 :
276 : ENGINE_set_id(engine, "ltm");
277 : ENGINE_set_name(engine,
278 : "Heimdal crypto ltm engine version " PACKAGE_VERSION);
279 : ENGINE_set_RSA(engine, RSA_ltm_method());
280 : ENGINE_set_DH(engine, DH_ltm_method());
281 :
282 : ret = add_engine(engine);
283 : if (ret != 1)
284 : ENGINE_finish(engine);
285 : #endif
286 :
287 : #ifdef HAVE_GMP
288 : /*
289 : * gmp
290 : */
291 :
292 : engine = ENGINE_new();
293 : if (engine == NULL)
294 : return;
295 :
296 : ENGINE_set_id(engine, "gmp");
297 : ENGINE_set_name(engine,
298 : "Heimdal crypto gmp engine version " PACKAGE_VERSION);
299 : ENGINE_set_RSA(engine, RSA_gmp_method());
300 :
301 : ret = add_engine(engine);
302 : if (ret != 1)
303 : ENGINE_finish(engine);
304 : #endif
305 : }
306 :
307 : ENGINE *
308 0 : ENGINE_by_dso(const char *path, const char *id)
309 : {
310 : #ifdef HAVE_DLOPEN
311 : ENGINE *engine;
312 : void *handle;
313 : int ret;
314 :
315 0 : engine = calloc(1, sizeof(*engine));
316 0 : if (engine == NULL)
317 0 : return NULL;
318 :
319 0 : handle = dlopen(path, RTLD_NOW);
320 0 : if (handle == NULL) {
321 : /* printf("error: %s\n", dlerror()); */
322 0 : free(engine);
323 0 : return NULL;
324 : }
325 :
326 : {
327 : unsigned long version;
328 : openssl_v_check v_check;
329 :
330 0 : v_check = (openssl_v_check)dlsym(handle, "v_check");
331 0 : if (v_check == NULL) {
332 0 : dlclose(handle);
333 0 : free(engine);
334 0 : return NULL;
335 : }
336 :
337 0 : version = (*v_check)(OPENSSL_DYNAMIC_VERSION);
338 0 : if (version == 0) {
339 0 : dlclose(handle);
340 0 : free(engine);
341 0 : return NULL;
342 : }
343 : }
344 :
345 : {
346 : openssl_bind_engine bind_engine;
347 :
348 0 : bind_engine = (openssl_bind_engine)dlsym(handle, "bind_engine");
349 0 : if (bind_engine == NULL) {
350 0 : dlclose(handle);
351 0 : free(engine);
352 0 : return NULL;
353 : }
354 :
355 0 : ret = (*bind_engine)(engine, id, NULL); /* XXX fix third arg */
356 0 : if (ret != 1) {
357 0 : dlclose(handle);
358 0 : free(engine);
359 0 : return NULL;
360 : }
361 : }
362 :
363 0 : ENGINE_up_ref(engine);
364 :
365 0 : ret = add_engine(engine);
366 0 : if (ret != 1) {
367 0 : dlclose(handle);
368 0 : ENGINE_finish(engine);
369 0 : return NULL;
370 : }
371 :
372 0 : return engine;
373 : #else
374 : return NULL;
375 : #endif
376 : }
377 :
378 : ENGINE *
379 0 : ENGINE_by_id(const char *id)
380 : {
381 : int i;
382 :
383 0 : for (i = 0; i < num_engines; i++) {
384 0 : if (strcmp(id, engines[i]->id) == 0) {
385 0 : ENGINE_up_ref(engines[i]);
386 0 : return engines[i];
387 : }
388 : }
389 0 : return NULL;
390 : }
391 :
392 : void
393 908739 : ENGINE_add_conf_module(void)
394 : {
395 908739 : }
|