Windows: update default timestamping service
[heimdal.git] / lib / hcrypto / engine.c
blob9cea24821767fd4a9f4b5da966cc23d0bfe9c7af
1 /*
2 * Copyright (c) 2006 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
4 * All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
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.
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.
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.
34 #include <config.h>
35 #include <roken.h>
37 #include <engine.h>
39 struct hc_engine {
40 int references;
41 char *name;
42 char *id;
43 void (*destroy)(ENGINE *);
44 const RSA_METHOD *rsa;
45 const DH_METHOD *dh;
46 const RAND_METHOD *rand;
49 ENGINE *
50 ENGINE_new(void)
52 ENGINE *engine;
54 engine = calloc(1, sizeof(*engine));
55 engine->references = 1;
57 return engine;
60 int
61 ENGINE_free(ENGINE *engine)
63 return ENGINE_finish(engine);
66 int
67 ENGINE_finish(ENGINE *engine)
69 if (engine->references-- <= 0)
70 abort();
71 if (engine->references > 0)
72 return 1;
74 if (engine->name)
75 free(engine->name);
76 if (engine->id)
77 free(engine->id);
78 if(engine->destroy)
79 (*engine->destroy)(engine);
81 memset(engine, 0, sizeof(*engine));
82 engine->references = -1;
85 free(engine);
86 return 1;
89 int
90 ENGINE_up_ref(ENGINE *engine)
92 if (engine->references < 0)
93 abort();
94 engine->references++;
95 return 1;
98 int
99 ENGINE_set_id(ENGINE *engine, const char *id)
101 engine->id = strdup(id);
102 return (engine->id == NULL) ? 0 : 1;
106 ENGINE_set_name(ENGINE *engine, const char *name)
108 engine->name = strdup(name);
109 return (engine->name == NULL) ? 0 : 1;
113 ENGINE_set_RSA(ENGINE *engine, const RSA_METHOD *method)
115 engine->rsa = method;
116 return 1;
120 ENGINE_set_DH(ENGINE *engine, const DH_METHOD *method)
122 engine->dh = method;
123 return 1;
127 ENGINE_set_destroy_function(ENGINE *e, void (*destroy)(ENGINE *))
129 e->destroy = destroy;
130 return 1;
133 const char *
134 ENGINE_get_id(const ENGINE *engine)
136 return engine->id;
139 const char *
140 ENGINE_get_name(const ENGINE *engine)
142 return engine->name;
145 const RSA_METHOD *
146 ENGINE_get_RSA(const ENGINE *engine)
148 return engine->rsa;
151 const DH_METHOD *
152 ENGINE_get_DH(const ENGINE *engine)
154 return engine->dh;
157 const RAND_METHOD *
158 ENGINE_get_RAND(const ENGINE *engine)
160 return engine->rand;
167 #define SG_default_engine(type) \
168 static ENGINE *type##_engine; \
169 int \
170 ENGINE_set_default_##type(ENGINE *engine) \
172 if (type##_engine) \
173 ENGINE_finish(type##_engine); \
174 type##_engine = engine; \
175 if (type##_engine) \
176 ENGINE_up_ref(type##_engine); \
177 return 1; \
179 ENGINE * \
180 ENGINE_get_default_##type(void) \
182 if (type##_engine) \
183 ENGINE_up_ref(type##_engine); \
184 return type##_engine; \
187 SG_default_engine(RSA)
188 SG_default_engine(DH)
190 #undef SG_default_engine
196 static ENGINE **engines;
197 static unsigned int num_engines;
199 static int
200 add_engine(ENGINE *engine)
202 ENGINE **d, *dup;
204 dup = ENGINE_by_id(engine->id);
205 if (dup)
206 return 0;
208 d = realloc(engines, (num_engines + 1) * sizeof(*engines));
209 if (d == NULL)
210 return 1;
211 engines = d;
212 engines[num_engines++] = engine;
214 return 1;
217 void
218 ENGINE_load_builtin_engines(void)
220 ENGINE *engine;
221 int ret;
223 engine = ENGINE_new();
224 if (engine == NULL)
225 return;
227 ENGINE_set_id(engine, "builtin");
228 ENGINE_set_name(engine,
229 "Heimdal crypto builtin (ltm) engine version " PACKAGE_VERSION);
230 ENGINE_set_RSA(engine, RSA_ltm_method());
231 ENGINE_set_DH(engine, DH_ltm_method());
233 ret = add_engine(engine);
234 if (ret != 1)
235 ENGINE_finish(engine);
237 #ifdef USE_HCRYPTO_TFM
239 * TFM
242 engine = ENGINE_new();
243 if (engine == NULL)
244 return;
246 ENGINE_set_id(engine, "tfm");
247 ENGINE_set_name(engine,
248 "Heimdal crypto tfm engine version " PACKAGE_VERSION);
249 ENGINE_set_RSA(engine, RSA_tfm_method());
250 ENGINE_set_DH(engine, DH_tfm_method());
252 ret = add_engine(engine);
253 if (ret != 1)
254 ENGINE_finish(engine);
255 #endif /* USE_HCRYPTO_TFM */
257 #ifdef USE_HCRYPTO_LTM
259 * ltm
262 engine = ENGINE_new();
263 if (engine == NULL)
264 return;
266 ENGINE_set_id(engine, "ltm");
267 ENGINE_set_name(engine,
268 "Heimdal crypto ltm engine version " PACKAGE_VERSION);
269 ENGINE_set_RSA(engine, RSA_ltm_method());
270 ENGINE_set_DH(engine, DH_ltm_method());
272 ret = add_engine(engine);
273 if (ret != 1)
274 ENGINE_finish(engine);
275 #endif
277 #ifdef HAVE_GMP
279 * gmp
282 engine = ENGINE_new();
283 if (engine == NULL)
284 return;
286 ENGINE_set_id(engine, "gmp");
287 ENGINE_set_name(engine,
288 "Heimdal crypto gmp engine version " PACKAGE_VERSION);
289 ENGINE_set_RSA(engine, RSA_gmp_method());
291 ret = add_engine(engine);
292 if (ret != 1)
293 ENGINE_finish(engine);
294 #endif
297 ENGINE *
298 ENGINE_by_dso(const char *path, const char *id)
300 #ifdef HAVE_DLOPEN
301 ENGINE *engine;
302 void *handle;
303 int ret;
305 engine = calloc(1, sizeof(*engine));
306 if (engine == NULL)
307 return NULL;
309 handle = dlopen(path, RTLD_NOW | RTLD_LOCAL | RTLD_GROUP);
310 if (handle == NULL) {
311 /* printf("error: %s\n", dlerror()); */
312 free(engine);
313 return NULL;
317 unsigned long version;
318 openssl_v_check v_check;
320 v_check = (openssl_v_check)dlsym(handle, "v_check");
321 if (v_check == NULL) {
322 dlclose(handle);
323 free(engine);
324 return NULL;
327 version = (*v_check)(OPENSSL_DYNAMIC_VERSION);
328 if (version == 0) {
329 dlclose(handle);
330 free(engine);
331 return NULL;
336 openssl_bind_engine bind_engine;
338 bind_engine = (openssl_bind_engine)dlsym(handle, "bind_engine");
339 if (bind_engine == NULL) {
340 dlclose(handle);
341 free(engine);
342 return NULL;
345 ret = (*bind_engine)(engine, id, NULL); /* XXX fix third arg */
346 if (ret != 1) {
347 dlclose(handle);
348 free(engine);
349 return NULL;
353 ENGINE_up_ref(engine);
355 ret = add_engine(engine);
356 if (ret != 1) {
357 dlclose(handle);
358 ENGINE_finish(engine);
359 return NULL;
362 return engine;
363 #else
364 return NULL;
365 #endif
368 ENGINE *
369 ENGINE_by_id(const char *id)
371 int i;
373 for (i = 0; i < num_engines; i++) {
374 if (strcmp(id, engines[i]->id) == 0) {
375 ENGINE_up_ref(engines[i]);
376 return engines[i];
379 return NULL;
382 void
383 ENGINE_add_conf_module(void)