diff options
Diffstat (limited to 'src/lib/libcrypto/engine/eng_dyn.c')
-rw-r--r-- | src/lib/libcrypto/engine/eng_dyn.c | 108 |
1 files changed, 10 insertions, 98 deletions
diff --git a/src/lib/libcrypto/engine/eng_dyn.c b/src/lib/libcrypto/engine/eng_dyn.c index acb30c34d8..4139a16e76 100644 --- a/src/lib/libcrypto/engine/eng_dyn.c +++ b/src/lib/libcrypto/engine/eng_dyn.c | |||
@@ -57,7 +57,11 @@ | |||
57 | */ | 57 | */ |
58 | 58 | ||
59 | 59 | ||
60 | #include <stdio.h> | ||
61 | #include <openssl/crypto.h> | ||
62 | #include "cryptlib.h" | ||
60 | #include "eng_int.h" | 63 | #include "eng_int.h" |
64 | #include <openssl/engine.h> | ||
61 | #include <openssl/dso.h> | 65 | #include <openssl/dso.h> |
62 | 66 | ||
63 | /* Shared libraries implementing ENGINEs for use by the "dynamic" ENGINE loader | 67 | /* Shared libraries implementing ENGINEs for use by the "dynamic" ENGINE loader |
@@ -66,7 +70,7 @@ | |||
66 | /* Our ENGINE handlers */ | 70 | /* Our ENGINE handlers */ |
67 | static int dynamic_init(ENGINE *e); | 71 | static int dynamic_init(ENGINE *e); |
68 | static int dynamic_finish(ENGINE *e); | 72 | static int dynamic_finish(ENGINE *e); |
69 | static int dynamic_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void)); | 73 | static int dynamic_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)()); |
70 | /* Predeclare our context type */ | 74 | /* Predeclare our context type */ |
71 | typedef struct st_dynamic_data_ctx dynamic_data_ctx; | 75 | typedef struct st_dynamic_data_ctx dynamic_data_ctx; |
72 | /* The implementation for the important control command */ | 76 | /* The implementation for the important control command */ |
@@ -76,9 +80,7 @@ static int dynamic_load(ENGINE *e, dynamic_data_ctx *ctx); | |||
76 | #define DYNAMIC_CMD_NO_VCHECK (ENGINE_CMD_BASE + 1) | 80 | #define DYNAMIC_CMD_NO_VCHECK (ENGINE_CMD_BASE + 1) |
77 | #define DYNAMIC_CMD_ID (ENGINE_CMD_BASE + 2) | 81 | #define DYNAMIC_CMD_ID (ENGINE_CMD_BASE + 2) |
78 | #define DYNAMIC_CMD_LIST_ADD (ENGINE_CMD_BASE + 3) | 82 | #define DYNAMIC_CMD_LIST_ADD (ENGINE_CMD_BASE + 3) |
79 | #define DYNAMIC_CMD_DIR_LOAD (ENGINE_CMD_BASE + 4) | 83 | #define DYNAMIC_CMD_LOAD (ENGINE_CMD_BASE + 4) |
80 | #define DYNAMIC_CMD_DIR_ADD (ENGINE_CMD_BASE + 5) | ||
81 | #define DYNAMIC_CMD_LOAD (ENGINE_CMD_BASE + 6) | ||
82 | 84 | ||
83 | /* The constants used when creating the ENGINE */ | 85 | /* The constants used when creating the ENGINE */ |
84 | static const char *engine_dynamic_id = "dynamic"; | 86 | static const char *engine_dynamic_id = "dynamic"; |
@@ -100,14 +102,6 @@ static const ENGINE_CMD_DEFN dynamic_cmd_defns[] = { | |||
100 | "LIST_ADD", | 102 | "LIST_ADD", |
101 | "Whether to add a loaded ENGINE to the internal list (0=no,1=yes,2=mandatory)", | 103 | "Whether to add a loaded ENGINE to the internal list (0=no,1=yes,2=mandatory)", |
102 | ENGINE_CMD_FLAG_NUMERIC}, | 104 | ENGINE_CMD_FLAG_NUMERIC}, |
103 | {DYNAMIC_CMD_DIR_LOAD, | ||
104 | "DIR_LOAD", | ||
105 | "Specifies whether to load from 'DIR_ADD' directories (0=no,1=yes,2=mandatory)", | ||
106 | ENGINE_CMD_FLAG_NUMERIC}, | ||
107 | {DYNAMIC_CMD_DIR_ADD, | ||
108 | "DIR_ADD", | ||
109 | "Adds a directory from which ENGINEs can be loaded", | ||
110 | ENGINE_CMD_FLAG_STRING}, | ||
111 | {DYNAMIC_CMD_LOAD, | 105 | {DYNAMIC_CMD_LOAD, |
112 | "LOAD", | 106 | "LOAD", |
113 | "Load up the ENGINE specified by other settings", | 107 | "Load up the ENGINE specified by other settings", |
@@ -142,18 +136,12 @@ struct st_dynamic_data_ctx | |||
142 | const char *DYNAMIC_F1; | 136 | const char *DYNAMIC_F1; |
143 | /* The symbol name for the "initialise ENGINE structure" function */ | 137 | /* The symbol name for the "initialise ENGINE structure" function */ |
144 | const char *DYNAMIC_F2; | 138 | const char *DYNAMIC_F2; |
145 | /* Whether to never use 'dirs', use 'dirs' as a fallback, or only use | ||
146 | * 'dirs' for loading. Default is to use 'dirs' as a fallback. */ | ||
147 | int dir_load; | ||
148 | /* A stack of directories from which ENGINEs could be loaded */ | ||
149 | STACK *dirs; | ||
150 | }; | 139 | }; |
151 | 140 | ||
152 | /* This is the "ex_data" index we obtain and reserve for use with our context | 141 | /* This is the "ex_data" index we obtain and reserve for use with our context |
153 | * structure. */ | 142 | * structure. */ |
154 | static int dynamic_ex_data_idx = -1; | 143 | static int dynamic_ex_data_idx = -1; |
155 | 144 | ||
156 | static void int_free_str(void *s) { OPENSSL_free(s); } | ||
157 | /* Because our ex_data element may or may not get allocated depending on whether | 145 | /* Because our ex_data element may or may not get allocated depending on whether |
158 | * a "first-use" occurs before the ENGINE is freed, we have a memory leak | 146 | * a "first-use" occurs before the ENGINE is freed, we have a memory leak |
159 | * problem to solve. We can't declare a "new" handler for the ex_data as we | 147 | * problem to solve. We can't declare a "new" handler for the ex_data as we |
@@ -173,8 +161,6 @@ static void dynamic_data_ctx_free_func(void *parent, void *ptr, | |||
173 | OPENSSL_free((void*)ctx->DYNAMIC_LIBNAME); | 161 | OPENSSL_free((void*)ctx->DYNAMIC_LIBNAME); |
174 | if(ctx->engine_id) | 162 | if(ctx->engine_id) |
175 | OPENSSL_free((void*)ctx->engine_id); | 163 | OPENSSL_free((void*)ctx->engine_id); |
176 | if(ctx->dirs) | ||
177 | sk_pop_free(ctx->dirs, int_free_str); | ||
178 | OPENSSL_free(ctx); | 164 | OPENSSL_free(ctx); |
179 | } | 165 | } |
180 | } | 166 | } |
@@ -189,7 +175,7 @@ static int dynamic_set_data_ctx(ENGINE *e, dynamic_data_ctx **ctx) | |||
189 | c = OPENSSL_malloc(sizeof(dynamic_data_ctx)); | 175 | c = OPENSSL_malloc(sizeof(dynamic_data_ctx)); |
190 | if(!c) | 176 | if(!c) |
191 | { | 177 | { |
192 | ENGINEerr(ENGINE_F_DYNAMIC_SET_DATA_CTX,ERR_R_MALLOC_FAILURE); | 178 | ENGINEerr(ENGINE_F_SET_DATA_CTX,ERR_R_MALLOC_FAILURE); |
193 | return 0; | 179 | return 0; |
194 | } | 180 | } |
195 | memset(c, 0, sizeof(dynamic_data_ctx)); | 181 | memset(c, 0, sizeof(dynamic_data_ctx)); |
@@ -202,14 +188,6 @@ static int dynamic_set_data_ctx(ENGINE *e, dynamic_data_ctx **ctx) | |||
202 | c->list_add_value = 0; | 188 | c->list_add_value = 0; |
203 | c->DYNAMIC_F1 = "v_check"; | 189 | c->DYNAMIC_F1 = "v_check"; |
204 | c->DYNAMIC_F2 = "bind_engine"; | 190 | c->DYNAMIC_F2 = "bind_engine"; |
205 | c->dir_load = 1; | ||
206 | c->dirs = sk_new_null(); | ||
207 | if(!c->dirs) | ||
208 | { | ||
209 | ENGINEerr(ENGINE_F_DYNAMIC_SET_DATA_CTX,ERR_R_MALLOC_FAILURE); | ||
210 | OPENSSL_free(c); | ||
211 | return 0; | ||
212 | } | ||
213 | CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); | 191 | CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); |
214 | if((*ctx = (dynamic_data_ctx *)ENGINE_get_ex_data(e, | 192 | if((*ctx = (dynamic_data_ctx *)ENGINE_get_ex_data(e, |
215 | dynamic_ex_data_idx)) == NULL) | 193 | dynamic_ex_data_idx)) == NULL) |
@@ -312,7 +290,7 @@ static int dynamic_finish(ENGINE *e) | |||
312 | return 0; | 290 | return 0; |
313 | } | 291 | } |
314 | 292 | ||
315 | static int dynamic_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void)) | 293 | static int dynamic_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)()) |
316 | { | 294 | { |
317 | dynamic_data_ctx *ctx = dynamic_get_data_ctx(e); | 295 | dynamic_data_ctx *ctx = dynamic_get_data_ctx(e); |
318 | int initialised; | 296 | int initialised; |
@@ -368,34 +346,6 @@ static int dynamic_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void)) | |||
368 | return 1; | 346 | return 1; |
369 | case DYNAMIC_CMD_LOAD: | 347 | case DYNAMIC_CMD_LOAD: |
370 | return dynamic_load(e, ctx); | 348 | return dynamic_load(e, ctx); |
371 | case DYNAMIC_CMD_DIR_LOAD: | ||
372 | if((i < 0) || (i > 2)) | ||
373 | { | ||
374 | ENGINEerr(ENGINE_F_DYNAMIC_CTRL, | ||
375 | ENGINE_R_INVALID_ARGUMENT); | ||
376 | return 0; | ||
377 | } | ||
378 | ctx->dir_load = (int)i; | ||
379 | return 1; | ||
380 | case DYNAMIC_CMD_DIR_ADD: | ||
381 | /* a NULL 'p' or a string of zero-length is the same thing */ | ||
382 | if(!p || (strlen((const char *)p) < 1)) | ||
383 | { | ||
384 | ENGINEerr(ENGINE_F_DYNAMIC_CTRL, | ||
385 | ENGINE_R_INVALID_ARGUMENT); | ||
386 | return 0; | ||
387 | } | ||
388 | { | ||
389 | char *tmp_str = BUF_strdup(p); | ||
390 | if(!tmp_str) | ||
391 | { | ||
392 | ENGINEerr(ENGINE_F_DYNAMIC_CTRL, | ||
393 | ERR_R_MALLOC_FAILURE); | ||
394 | return 0; | ||
395 | } | ||
396 | sk_insert(ctx->dirs, tmp_str, -1); | ||
397 | } | ||
398 | return 1; | ||
399 | default: | 349 | default: |
400 | break; | 350 | break; |
401 | } | 351 | } |
@@ -403,53 +353,16 @@ static int dynamic_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void)) | |||
403 | return 0; | 353 | return 0; |
404 | } | 354 | } |
405 | 355 | ||
406 | static int int_load(dynamic_data_ctx *ctx) | ||
407 | { | ||
408 | int num, loop; | ||
409 | /* Unless told not to, try a direct load */ | ||
410 | if((ctx->dir_load != 2) && (DSO_load(ctx->dynamic_dso, | ||
411 | ctx->DYNAMIC_LIBNAME, NULL, 0)) != NULL) | ||
412 | return 1; | ||
413 | /* If we're not allowed to use 'dirs' or we have none, fail */ | ||
414 | if(!ctx->dir_load || ((num = sk_num(ctx->dirs)) < 1)) | ||
415 | return 0; | ||
416 | for(loop = 0; loop < num; loop++) | ||
417 | { | ||
418 | const char *s = sk_value(ctx->dirs, loop); | ||
419 | char *merge = DSO_merge(ctx->dynamic_dso, ctx->DYNAMIC_LIBNAME, s); | ||
420 | if(!merge) | ||
421 | return 0; | ||
422 | if(DSO_load(ctx->dynamic_dso, merge, NULL, 0)) | ||
423 | { | ||
424 | /* Found what we're looking for */ | ||
425 | OPENSSL_free(merge); | ||
426 | return 1; | ||
427 | } | ||
428 | OPENSSL_free(merge); | ||
429 | } | ||
430 | return 0; | ||
431 | } | ||
432 | |||
433 | static int dynamic_load(ENGINE *e, dynamic_data_ctx *ctx) | 356 | static int dynamic_load(ENGINE *e, dynamic_data_ctx *ctx) |
434 | { | 357 | { |
435 | ENGINE cpy; | 358 | ENGINE cpy; |
436 | dynamic_fns fns; | 359 | dynamic_fns fns; |
437 | 360 | ||
438 | if(!ctx->dynamic_dso) | 361 | if(!ctx->DYNAMIC_LIBNAME || ((ctx->dynamic_dso = DSO_load(NULL, |
439 | ctx->dynamic_dso = DSO_new(); | 362 | ctx->DYNAMIC_LIBNAME, NULL, 0)) == NULL)) |
440 | if(!ctx->DYNAMIC_LIBNAME) | ||
441 | { | ||
442 | if(!ctx->engine_id) | ||
443 | return 0; | ||
444 | ctx->DYNAMIC_LIBNAME = | ||
445 | DSO_convert_filename(ctx->dynamic_dso, ctx->engine_id); | ||
446 | } | ||
447 | if(!int_load(ctx)) | ||
448 | { | 363 | { |
449 | ENGINEerr(ENGINE_F_DYNAMIC_LOAD, | 364 | ENGINEerr(ENGINE_F_DYNAMIC_LOAD, |
450 | ENGINE_R_DSO_NOT_FOUND); | 365 | ENGINE_R_DSO_NOT_FOUND); |
451 | DSO_free(ctx->dynamic_dso); | ||
452 | ctx->dynamic_dso = NULL; | ||
453 | return 0; | 366 | return 0; |
454 | } | 367 | } |
455 | /* We have to find a bind function otherwise it'll always end badly */ | 368 | /* We have to find a bind function otherwise it'll always end badly */ |
@@ -496,7 +409,6 @@ static int dynamic_load(ENGINE *e, dynamic_data_ctx *ctx) | |||
496 | * engine.h, much of this would be simplified if each area of code | 409 | * engine.h, much of this would be simplified if each area of code |
497 | * provided its own "summary" structure of all related callbacks. It | 410 | * provided its own "summary" structure of all related callbacks. It |
498 | * would also increase opaqueness. */ | 411 | * would also increase opaqueness. */ |
499 | fns.static_state = ENGINE_get_static_state(); | ||
500 | fns.err_fns = ERR_get_implementation(); | 412 | fns.err_fns = ERR_get_implementation(); |
501 | fns.ex_data_fns = CRYPTO_get_ex_data_implementation(); | 413 | fns.ex_data_fns = CRYPTO_get_ex_data_implementation(); |
502 | CRYPTO_get_mem_functions(&fns.mem_fns.malloc_cb, | 414 | CRYPTO_get_mem_functions(&fns.mem_fns.malloc_cb, |