Coverage Report

Created: 2025-12-31 06:20

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