No empty .Rs/.Re
[netbsd-mini2440.git] / crypto / dist / heimdal / lib / hcrypto / engine.c
blob5117de80cdc23074be12d87a05324a9ff7a78d35
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 #ifdef HAVE_CONFIG_H
35 #include <config.h>
36 #endif
38 __RCSID("$Heimdal: engine.c 20828 2007-06-03 05:10:20Z lha $"
39 "$NetBSD$");
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <string.h>
45 #include <engine.h>
47 #ifdef HAVE_DLFCN_H
48 #include <dlfcn.h>
49 #ifndef RTLD_NOW
50 #define RTLD_NOW 0
51 #endif
52 #endif
54 struct hc_engine {
55 int references;
56 char *name;
57 char *id;
58 void (*destroy)(ENGINE *);
59 const RSA_METHOD *rsa;
60 const DH_METHOD *dh;
61 const RAND_METHOD *rand;
64 int
65 ENGINE_finish(ENGINE *engine)
67 if (engine->references-- <= 0)
68 abort();
69 if (engine->references > 0)
70 return 1;
72 if (engine->name)
73 free(engine->name);
74 if (engine->id)
75 free(engine->id);
76 if(engine->destroy)
77 (*engine->destroy)(engine);
79 memset(engine, 0, sizeof(engine));
80 engine->references = -1;
83 free(engine);
84 return 1;
87 int
88 ENGINE_up_ref(ENGINE *engine)
90 if (engine->references < 0)
91 abort();
92 engine->references++;
93 return 1;
96 int
97 ENGINE_set_id(ENGINE *engine, const char *id)
99 engine->id = strdup(id);
100 return (engine->id == NULL) ? 0 : 1;
104 ENGINE_set_name(ENGINE *engine, const char *name)
106 engine->name = strdup(name);
107 return (engine->name == NULL) ? 0 : 1;
111 ENGINE_set_RSA(ENGINE *engine, const RSA_METHOD *method)
113 engine->rsa = method;
114 return 1;
118 ENGINE_set_DH(ENGINE *engine, const DH_METHOD *method)
120 engine->dh = method;
121 return 1;
125 ENGINE_set_destroy_function(ENGINE *e, void (*destroy)(ENGINE *))
127 e->destroy = destroy;
128 return 1;
131 const char *
132 ENGINE_get_id(const ENGINE *engine)
134 return engine->id;
137 const char *
138 ENGINE_get_name(const ENGINE *engine)
140 return engine->name;
143 const RSA_METHOD *
144 ENGINE_get_RSA(const ENGINE *engine)
146 return engine->rsa;
149 const DH_METHOD *
150 ENGINE_get_DH(const ENGINE *engine)
152 return engine->dh;
155 const RAND_METHOD *
156 ENGINE_get_RAND(const ENGINE *engine)
158 return engine->rand;
165 #define SG_default_engine(type) \
166 static ENGINE *type##_engine; \
167 int \
168 ENGINE_set_default_##type(ENGINE *engine) \
170 if (type##_engine) \
171 ENGINE_finish(type##_engine); \
172 type##_engine = engine; \
173 if (type##_engine) \
174 ENGINE_up_ref(type##_engine); \
175 return 1; \
177 ENGINE * \
178 ENGINE_get_default_##type(void) \
180 if (type##_engine) \
181 ENGINE_up_ref(type##_engine); \
182 return type##_engine; \
185 SG_default_engine(RSA)
186 SG_default_engine(DH)
188 #undef SG_default_engine
194 static ENGINE **engines;
195 static unsigned int num_engines;
197 static int
198 add_engine(ENGINE *engine)
200 ENGINE **d, *dup;
202 dup = ENGINE_by_id(engine->id);
203 if (dup) {
204 ENGINE_finish(dup);
205 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 = calloc(1, sizeof(*engine));
224 if (engine == NULL)
225 return;
227 ENGINE_set_id(engine, "builtin");
228 ENGINE_set_name(engine,
229 "Heimdal crypto builtin engine version " PACKAGE_VERSION);
230 ENGINE_set_RSA(engine, RSA_imath_method());
231 ENGINE_set_DH(engine, DH_imath_method());
233 ret = add_engine(engine);
234 if (ret != 1)
235 ENGINE_finish(engine);
238 ENGINE *
239 ENGINE_by_dso(const char *path, const char *id)
241 #ifdef HAVE_DLOPEN
242 ENGINE *engine;
243 void *handle;
244 int ret;
246 engine = calloc(1, sizeof(*engine));
247 if (engine == NULL)
248 return NULL;
250 handle = dlopen(path, RTLD_NOW);
251 if (handle == NULL) {
252 /* printf("error: %s\n", dlerror()); */
253 free(engine);
254 return NULL;
258 unsigned long version;
259 openssl_v_check v_check;
261 v_check = (openssl_v_check)dlsym(handle, "v_check");
262 if (v_check == NULL) {
263 dlclose(handle);
264 free(engine);
265 return NULL;
268 version = (*v_check)(OPENSSL_DYNAMIC_VERSION);
269 if (version == 0) {
270 dlclose(handle);
271 free(engine);
272 return NULL;
277 openssl_bind_engine bind_engine;
279 bind_engine = (openssl_bind_engine)dlsym(handle, "bind_engine");
280 if (bind_engine == NULL) {
281 dlclose(handle);
282 free(engine);
283 return NULL;
286 ret = (*bind_engine)(engine, id, NULL); /* XXX fix third arg */
287 if (ret != 1) {
288 dlclose(handle);
289 free(engine);
290 return NULL;
294 ENGINE_up_ref(engine);
296 ret = add_engine(engine);
297 if (ret != 1) {
298 dlclose(handle);
299 ENGINE_finish(engine);
300 return NULL;
303 return engine;
304 #else
305 return NULL;
306 #endif
309 ENGINE *
310 ENGINE_by_id(const char *id)
312 int i;
314 for (i = 0; i < num_engines; i++) {
315 if (strcmp(id, engines[i]->id) == 0) {
316 ENGINE_up_ref(engines[i]);
317 return engines[i];
320 return NULL;
323 void
324 ENGINE_add_conf_module(void)