summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/engine/eng_dyn.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/engine/eng_dyn.c')
-rw-r--r--src/lib/libcrypto/engine/eng_dyn.c108
1 files changed, 98 insertions, 10 deletions
diff --git a/src/lib/libcrypto/engine/eng_dyn.c b/src/lib/libcrypto/engine/eng_dyn.c
index 4139a16e76..acb30c34d8 100644
--- a/src/lib/libcrypto/engine/eng_dyn.c
+++ b/src/lib/libcrypto/engine/eng_dyn.c
@@ -57,11 +57,7 @@
57 */ 57 */
58 58
59 59
60#include <stdio.h>
61#include <openssl/crypto.h>
62#include "cryptlib.h"
63#include "eng_int.h" 60#include "eng_int.h"
64#include <openssl/engine.h>
65#include <openssl/dso.h> 61#include <openssl/dso.h>
66 62
67/* Shared libraries implementing ENGINEs for use by the "dynamic" ENGINE loader 63/* Shared libraries implementing ENGINEs for use by the "dynamic" ENGINE loader
@@ -70,7 +66,7 @@
70/* Our ENGINE handlers */ 66/* Our ENGINE handlers */
71static int dynamic_init(ENGINE *e); 67static int dynamic_init(ENGINE *e);
72static int dynamic_finish(ENGINE *e); 68static int dynamic_finish(ENGINE *e);
73static int dynamic_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)()); 69static int dynamic_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void));
74/* Predeclare our context type */ 70/* Predeclare our context type */
75typedef struct st_dynamic_data_ctx dynamic_data_ctx; 71typedef struct st_dynamic_data_ctx dynamic_data_ctx;
76/* The implementation for the important control command */ 72/* The implementation for the important control command */
@@ -80,7 +76,9 @@ static int dynamic_load(ENGINE *e, dynamic_data_ctx *ctx);
80#define DYNAMIC_CMD_NO_VCHECK (ENGINE_CMD_BASE + 1) 76#define DYNAMIC_CMD_NO_VCHECK (ENGINE_CMD_BASE + 1)
81#define DYNAMIC_CMD_ID (ENGINE_CMD_BASE + 2) 77#define DYNAMIC_CMD_ID (ENGINE_CMD_BASE + 2)
82#define DYNAMIC_CMD_LIST_ADD (ENGINE_CMD_BASE + 3) 78#define DYNAMIC_CMD_LIST_ADD (ENGINE_CMD_BASE + 3)
83#define DYNAMIC_CMD_LOAD (ENGINE_CMD_BASE + 4) 79#define DYNAMIC_CMD_DIR_LOAD (ENGINE_CMD_BASE + 4)
80#define DYNAMIC_CMD_DIR_ADD (ENGINE_CMD_BASE + 5)
81#define DYNAMIC_CMD_LOAD (ENGINE_CMD_BASE + 6)
84 82
85/* The constants used when creating the ENGINE */ 83/* The constants used when creating the ENGINE */
86static const char *engine_dynamic_id = "dynamic"; 84static const char *engine_dynamic_id = "dynamic";
@@ -102,6 +100,14 @@ static const ENGINE_CMD_DEFN dynamic_cmd_defns[] = {
102 "LIST_ADD", 100 "LIST_ADD",
103 "Whether to add a loaded ENGINE to the internal list (0=no,1=yes,2=mandatory)", 101 "Whether to add a loaded ENGINE to the internal list (0=no,1=yes,2=mandatory)",
104 ENGINE_CMD_FLAG_NUMERIC}, 102 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},
105 {DYNAMIC_CMD_LOAD, 111 {DYNAMIC_CMD_LOAD,
106 "LOAD", 112 "LOAD",
107 "Load up the ENGINE specified by other settings", 113 "Load up the ENGINE specified by other settings",
@@ -136,12 +142,18 @@ struct st_dynamic_data_ctx
136 const char *DYNAMIC_F1; 142 const char *DYNAMIC_F1;
137 /* The symbol name for the "initialise ENGINE structure" function */ 143 /* The symbol name for the "initialise ENGINE structure" function */
138 const char *DYNAMIC_F2; 144 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;
139 }; 150 };
140 151
141/* This is the "ex_data" index we obtain and reserve for use with our context 152/* This is the "ex_data" index we obtain and reserve for use with our context
142 * structure. */ 153 * structure. */
143static int dynamic_ex_data_idx = -1; 154static int dynamic_ex_data_idx = -1;
144 155
156static void int_free_str(void *s) { OPENSSL_free(s); }
145/* Because our ex_data element may or may not get allocated depending on whether 157/* Because our ex_data element may or may not get allocated depending on whether
146 * a "first-use" occurs before the ENGINE is freed, we have a memory leak 158 * a "first-use" occurs before the ENGINE is freed, we have a memory leak
147 * problem to solve. We can't declare a "new" handler for the ex_data as we 159 * problem to solve. We can't declare a "new" handler for the ex_data as we
@@ -161,6 +173,8 @@ static void dynamic_data_ctx_free_func(void *parent, void *ptr,
161 OPENSSL_free((void*)ctx->DYNAMIC_LIBNAME); 173 OPENSSL_free((void*)ctx->DYNAMIC_LIBNAME);
162 if(ctx->engine_id) 174 if(ctx->engine_id)
163 OPENSSL_free((void*)ctx->engine_id); 175 OPENSSL_free((void*)ctx->engine_id);
176 if(ctx->dirs)
177 sk_pop_free(ctx->dirs, int_free_str);
164 OPENSSL_free(ctx); 178 OPENSSL_free(ctx);
165 } 179 }
166 } 180 }
@@ -175,7 +189,7 @@ static int dynamic_set_data_ctx(ENGINE *e, dynamic_data_ctx **ctx)
175 c = OPENSSL_malloc(sizeof(dynamic_data_ctx)); 189 c = OPENSSL_malloc(sizeof(dynamic_data_ctx));
176 if(!c) 190 if(!c)
177 { 191 {
178 ENGINEerr(ENGINE_F_SET_DATA_CTX,ERR_R_MALLOC_FAILURE); 192 ENGINEerr(ENGINE_F_DYNAMIC_SET_DATA_CTX,ERR_R_MALLOC_FAILURE);
179 return 0; 193 return 0;
180 } 194 }
181 memset(c, 0, sizeof(dynamic_data_ctx)); 195 memset(c, 0, sizeof(dynamic_data_ctx));
@@ -188,6 +202,14 @@ static int dynamic_set_data_ctx(ENGINE *e, dynamic_data_ctx **ctx)
188 c->list_add_value = 0; 202 c->list_add_value = 0;
189 c->DYNAMIC_F1 = "v_check"; 203 c->DYNAMIC_F1 = "v_check";
190 c->DYNAMIC_F2 = "bind_engine"; 204 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 }
191 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); 213 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
192 if((*ctx = (dynamic_data_ctx *)ENGINE_get_ex_data(e, 214 if((*ctx = (dynamic_data_ctx *)ENGINE_get_ex_data(e,
193 dynamic_ex_data_idx)) == NULL) 215 dynamic_ex_data_idx)) == NULL)
@@ -290,7 +312,7 @@ static int dynamic_finish(ENGINE *e)
290 return 0; 312 return 0;
291 } 313 }
292 314
293static int dynamic_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)()) 315static int dynamic_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
294 { 316 {
295 dynamic_data_ctx *ctx = dynamic_get_data_ctx(e); 317 dynamic_data_ctx *ctx = dynamic_get_data_ctx(e);
296 int initialised; 318 int initialised;
@@ -346,6 +368,34 @@ static int dynamic_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)())
346 return 1; 368 return 1;
347 case DYNAMIC_CMD_LOAD: 369 case DYNAMIC_CMD_LOAD:
348 return dynamic_load(e, ctx); 370 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;
349 default: 399 default:
350 break; 400 break;
351 } 401 }
@@ -353,16 +403,53 @@ static int dynamic_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)())
353 return 0; 403 return 0;
354 } 404 }
355 405
406static 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
356static int dynamic_load(ENGINE *e, dynamic_data_ctx *ctx) 433static int dynamic_load(ENGINE *e, dynamic_data_ctx *ctx)
357 { 434 {
358 ENGINE cpy; 435 ENGINE cpy;
359 dynamic_fns fns; 436 dynamic_fns fns;
360 437
361 if(!ctx->DYNAMIC_LIBNAME || ((ctx->dynamic_dso = DSO_load(NULL, 438 if(!ctx->dynamic_dso)
362 ctx->DYNAMIC_LIBNAME, NULL, 0)) == NULL)) 439 ctx->dynamic_dso = DSO_new();
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))
363 { 448 {
364 ENGINEerr(ENGINE_F_DYNAMIC_LOAD, 449 ENGINEerr(ENGINE_F_DYNAMIC_LOAD,
365 ENGINE_R_DSO_NOT_FOUND); 450 ENGINE_R_DSO_NOT_FOUND);
451 DSO_free(ctx->dynamic_dso);
452 ctx->dynamic_dso = NULL;
366 return 0; 453 return 0;
367 } 454 }
368 /* We have to find a bind function otherwise it'll always end badly */ 455 /* We have to find a bind function otherwise it'll always end badly */
@@ -409,6 +496,7 @@ static int dynamic_load(ENGINE *e, dynamic_data_ctx *ctx)
409 * engine.h, much of this would be simplified if each area of code 496 * engine.h, much of this would be simplified if each area of code
410 * provided its own "summary" structure of all related callbacks. It 497 * provided its own "summary" structure of all related callbacks. It
411 * would also increase opaqueness. */ 498 * would also increase opaqueness. */
499 fns.static_state = ENGINE_get_static_state();
412 fns.err_fns = ERR_get_implementation(); 500 fns.err_fns = ERR_get_implementation();
413 fns.ex_data_fns = CRYPTO_get_ex_data_implementation(); 501 fns.ex_data_fns = CRYPTO_get_ex_data_implementation();
414 CRYPTO_get_mem_functions(&fns.mem_fns.malloc_cb, 502 CRYPTO_get_mem_functions(&fns.mem_fns.malloc_cb,