~zulcss/samba/server-dailies-3.4

« back to all changes in this revision

Viewing changes to source4/heimdal/lib/hcrypto/engine.c

  • Committer: Chuck Short
  • Date: 2010-09-28 20:38:39 UTC
  • Revision ID: zulcss@ubuntu.com-20100928203839-pgjulytsi9ue63x1
Initial version

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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)
 
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)
 
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)
 
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)
 
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)
 
111
{
 
112
    engine->rsa = method;
 
113
    return 1;
 
114
}
 
115
 
 
116
int
 
117
ENGINE_set_DH(ENGINE *engine, const DH_METHOD *method)
 
118
{
 
119
    engine->dh = method;
 
120
    return 1;
 
121
}
 
122
 
 
123
int
 
124
ENGINE_set_destroy_function(ENGINE *e, void (*destroy)(ENGINE *))
 
125
{
 
126
    e->destroy = destroy;
 
127
    return 1;
 
128
}
 
129
 
 
130
const char *
 
131
ENGINE_get_id(const ENGINE *engine)
 
132
{
 
133
    return engine->id;
 
134
}
 
135
 
 
136
const char *
 
137
ENGINE_get_name(const ENGINE *engine)
 
138
{
 
139
    return engine->name;
 
140
}
 
141
 
 
142
const RSA_METHOD *
 
143
ENGINE_get_RSA(const ENGINE *engine)
 
144
{
 
145
    return engine->rsa;
 
146
}
 
147
 
 
148
const DH_METHOD *
 
149
ENGINE_get_DH(const ENGINE *engine)
 
150
{
 
151
    return engine->dh;
 
152
}
 
153
 
 
154
const RAND_METHOD *
 
155
ENGINE_get_RAND(const ENGINE *engine)
 
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)
 
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)
 
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)
 
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)
 
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)
 
324
{
 
325
}