source: trunk/server/source4/heimdal/lib/hcrypto/engine.c

Last change on this file was 745, checked in by Silvan Scherrer, 13 years ago

Samba Server: updated trunk to 3.6.0

File size: 7.9 KB
Line 
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
49struct 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
59ENGINE *
60ENGINE_new(void)
61{
62 ENGINE *engine;
63
64 engine = calloc(1, sizeof(*engine));
65 engine->references = 1;
66
67 return engine;
68}
69
70int
71ENGINE_free(ENGINE *engine)
72{
73 return ENGINE_finish(engine);
74}
75
76int
77ENGINE_finish(ENGINE *engine)
78{
79 if (engine->references-- <= 0)
80 abort();
81 if (engine->references > 0)
82 return 1;
83
84 if (engine->name)
85 free(engine->name);
86 if (engine->id)
87 free(engine->id);
88 if(engine->destroy)
89 (*engine->destroy)(engine);
90
91 memset(engine, 0, sizeof(engine));
92 engine->references = -1;
93
94
95 free(engine);
96 return 1;
97}
98
99int
100ENGINE_up_ref(ENGINE *engine)
101{
102 if (engine->references < 0)
103 abort();
104 engine->references++;
105 return 1;
106}
107
108int
109ENGINE_set_id(ENGINE *engine, const char *id)
110{
111 engine->id = strdup(id);
112 return (engine->id == NULL) ? 0 : 1;
113}
114
115int
116ENGINE_set_name(ENGINE *engine, const char *name)
117{
118 engine->name = strdup(name);
119 return (engine->name == NULL) ? 0 : 1;
120}
121
122int
123ENGINE_set_RSA(ENGINE *engine, const RSA_METHOD *method)
124{
125 engine->rsa = method;
126 return 1;
127}
128
129int
130ENGINE_set_DH(ENGINE *engine, const DH_METHOD *method)
131{
132 engine->dh = method;
133 return 1;
134}
135
136int
137ENGINE_set_destroy_function(ENGINE *e, void (*destroy)(ENGINE *))
138{
139 e->destroy = destroy;
140 return 1;
141}
142
143const char *
144ENGINE_get_id(const ENGINE *engine)
145{
146 return engine->id;
147}
148
149const char *
150ENGINE_get_name(const ENGINE *engine)
151{
152 return engine->name;
153}
154
155const RSA_METHOD *
156ENGINE_get_RSA(const ENGINE *engine)
157{
158 return engine->rsa;
159}
160
161const DH_METHOD *
162ENGINE_get_DH(const ENGINE *engine)
163{
164 return engine->dh;
165}
166
167const RAND_METHOD *
168ENGINE_get_RAND(const ENGINE *engine)
169{
170 return engine->rand;
171}
172
173/*
174 *
175 */
176
177#define SG_default_engine(type) \
178static ENGINE *type##_engine; \
179int \
180ENGINE_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} \
189ENGINE * \
190ENGINE_get_default_##type(void) \
191{ \
192 if (type##_engine) \
193 ENGINE_up_ref(type##_engine); \
194 return type##_engine; \
195}
196
197SG_default_engine(RSA)
198SG_default_engine(DH)
199
200#undef SG_default_engine
201
202/*
203 *
204 */
205
206static ENGINE **engines;
207static unsigned int num_engines;
208
209static int
210add_engine(ENGINE *engine)
211{
212 ENGINE **d, *dup;
213
214 dup = ENGINE_by_id(engine->id);
215 if (dup)
216 return 0;
217
218 d = realloc(engines, (num_engines + 1) * sizeof(*engines));
219 if (d == NULL)
220 return 1;
221 engines = d;
222 engines[num_engines++] = engine;
223
224 return 1;
225}
226
227void
228ENGINE_load_builtin_engines(void)
229{
230 ENGINE *engine;
231 int ret;
232
233 engine = ENGINE_new();
234 if (engine == NULL)
235 return;
236
237 ENGINE_set_id(engine, "builtin");
238 ENGINE_set_name(engine,
239 "Heimdal crypto builtin (ltm) engine version " PACKAGE_VERSION);
240 ENGINE_set_RSA(engine, RSA_ltm_method());
241 ENGINE_set_DH(engine, DH_ltm_method());
242
243 ret = add_engine(engine);
244 if (ret != 1)
245 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
307ENGINE *
308ENGINE_by_dso(const char *path, const char *id)
309{
310#ifdef HAVE_DLOPEN
311 ENGINE *engine;
312 void *handle;
313 int ret;
314
315 engine = calloc(1, sizeof(*engine));
316 if (engine == NULL)
317 return NULL;
318
319 handle = dlopen(path, RTLD_NOW);
320 if (handle == NULL) {
321 /* printf("error: %s\n", dlerror()); */
322 free(engine);
323 return NULL;
324 }
325
326 {
327 unsigned long version;
328 openssl_v_check v_check;
329
330 v_check = (openssl_v_check)dlsym(handle, "v_check");
331 if (v_check == NULL) {
332 dlclose(handle);
333 free(engine);
334 return NULL;
335 }
336
337 version = (*v_check)(OPENSSL_DYNAMIC_VERSION);
338 if (version == 0) {
339 dlclose(handle);
340 free(engine);
341 return NULL;
342 }
343 }
344
345 {
346 openssl_bind_engine bind_engine;
347
348 bind_engine = (openssl_bind_engine)dlsym(handle, "bind_engine");
349 if (bind_engine == NULL) {
350 dlclose(handle);
351 free(engine);
352 return NULL;
353 }
354
355 ret = (*bind_engine)(engine, id, NULL); /* XXX fix third arg */
356 if (ret != 1) {
357 dlclose(handle);
358 free(engine);
359 return NULL;
360 }
361 }
362
363 ENGINE_up_ref(engine);
364
365 ret = add_engine(engine);
366 if (ret != 1) {
367 dlclose(handle);
368 ENGINE_finish(engine);
369 return NULL;
370 }
371
372 return engine;
373#else
374 return NULL;
375#endif
376}
377
378ENGINE *
379ENGINE_by_id(const char *id)
380{
381 int i;
382
383 for (i = 0; i < num_engines; i++) {
384 if (strcmp(id, engines[i]->id) == 0) {
385 ENGINE_up_ref(engines[i]);
386 return engines[i];
387 }
388 }
389 return NULL;
390}
391
392void
393ENGINE_add_conf_module(void)
394{
395}
Note: See TracBrowser for help on using the repository browser.