summaryrefslogtreecommitdiffstats
path: root/crypto/openssl/crypto/engine/eng_dyn.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/openssl/crypto/engine/eng_dyn.c')
-rw-r--r--crypto/openssl/crypto/engine/eng_dyn.c108
1 files changed, 98 insertions, 10 deletions
diff --git a/crypto/openssl/crypto/engine/eng_dyn.c b/crypto/openssl/crypto/engine/eng_dyn.c
index 4139a16..acb30c3 100644
--- a/crypto/openssl/crypto/engine/eng_dyn.c
+++ b/crypto/openssl/crypto/engine/eng_dyn.c
@@ -57,11 +57,7 @@
*/
-#include <stdio.h>
-#include <openssl/crypto.h>
-#include "cryptlib.h"
#include "eng_int.h"
-#include <openssl/engine.h>
#include <openssl/dso.h>
/* Shared libraries implementing ENGINEs for use by the "dynamic" ENGINE loader
@@ -70,7 +66,7 @@
/* Our ENGINE handlers */
static int dynamic_init(ENGINE *e);
static int dynamic_finish(ENGINE *e);
-static int dynamic_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)());
+static int dynamic_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void));
/* Predeclare our context type */
typedef struct st_dynamic_data_ctx dynamic_data_ctx;
/* The implementation for the important control command */
@@ -80,7 +76,9 @@ static int dynamic_load(ENGINE *e, dynamic_data_ctx *ctx);
#define DYNAMIC_CMD_NO_VCHECK (ENGINE_CMD_BASE + 1)
#define DYNAMIC_CMD_ID (ENGINE_CMD_BASE + 2)
#define DYNAMIC_CMD_LIST_ADD (ENGINE_CMD_BASE + 3)
-#define DYNAMIC_CMD_LOAD (ENGINE_CMD_BASE + 4)
+#define DYNAMIC_CMD_DIR_LOAD (ENGINE_CMD_BASE + 4)
+#define DYNAMIC_CMD_DIR_ADD (ENGINE_CMD_BASE + 5)
+#define DYNAMIC_CMD_LOAD (ENGINE_CMD_BASE + 6)
/* The constants used when creating the ENGINE */
static const char *engine_dynamic_id = "dynamic";
@@ -102,6 +100,14 @@ static const ENGINE_CMD_DEFN dynamic_cmd_defns[] = {
"LIST_ADD",
"Whether to add a loaded ENGINE to the internal list (0=no,1=yes,2=mandatory)",
ENGINE_CMD_FLAG_NUMERIC},
+ {DYNAMIC_CMD_DIR_LOAD,
+ "DIR_LOAD",
+ "Specifies whether to load from 'DIR_ADD' directories (0=no,1=yes,2=mandatory)",
+ ENGINE_CMD_FLAG_NUMERIC},
+ {DYNAMIC_CMD_DIR_ADD,
+ "DIR_ADD",
+ "Adds a directory from which ENGINEs can be loaded",
+ ENGINE_CMD_FLAG_STRING},
{DYNAMIC_CMD_LOAD,
"LOAD",
"Load up the ENGINE specified by other settings",
@@ -136,12 +142,18 @@ struct st_dynamic_data_ctx
const char *DYNAMIC_F1;
/* The symbol name for the "initialise ENGINE structure" function */
const char *DYNAMIC_F2;
+ /* Whether to never use 'dirs', use 'dirs' as a fallback, or only use
+ * 'dirs' for loading. Default is to use 'dirs' as a fallback. */
+ int dir_load;
+ /* A stack of directories from which ENGINEs could be loaded */
+ STACK *dirs;
};
/* This is the "ex_data" index we obtain and reserve for use with our context
* structure. */
static int dynamic_ex_data_idx = -1;
+static void int_free_str(void *s) { OPENSSL_free(s); }
/* Because our ex_data element may or may not get allocated depending on whether
* a "first-use" occurs before the ENGINE is freed, we have a memory leak
* 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,
OPENSSL_free((void*)ctx->DYNAMIC_LIBNAME);
if(ctx->engine_id)
OPENSSL_free((void*)ctx->engine_id);
+ if(ctx->dirs)
+ sk_pop_free(ctx->dirs, int_free_str);
OPENSSL_free(ctx);
}
}
@@ -175,7 +189,7 @@ static int dynamic_set_data_ctx(ENGINE *e, dynamic_data_ctx **ctx)
c = OPENSSL_malloc(sizeof(dynamic_data_ctx));
if(!c)
{
- ENGINEerr(ENGINE_F_SET_DATA_CTX,ERR_R_MALLOC_FAILURE);
+ ENGINEerr(ENGINE_F_DYNAMIC_SET_DATA_CTX,ERR_R_MALLOC_FAILURE);
return 0;
}
memset(c, 0, sizeof(dynamic_data_ctx));
@@ -188,6 +202,14 @@ static int dynamic_set_data_ctx(ENGINE *e, dynamic_data_ctx **ctx)
c->list_add_value = 0;
c->DYNAMIC_F1 = "v_check";
c->DYNAMIC_F2 = "bind_engine";
+ c->dir_load = 1;
+ c->dirs = sk_new_null();
+ if(!c->dirs)
+ {
+ ENGINEerr(ENGINE_F_DYNAMIC_SET_DATA_CTX,ERR_R_MALLOC_FAILURE);
+ OPENSSL_free(c);
+ return 0;
+ }
CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
if((*ctx = (dynamic_data_ctx *)ENGINE_get_ex_data(e,
dynamic_ex_data_idx)) == NULL)
@@ -290,7 +312,7 @@ static int dynamic_finish(ENGINE *e)
return 0;
}
-static int dynamic_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)())
+static int dynamic_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
{
dynamic_data_ctx *ctx = dynamic_get_data_ctx(e);
int initialised;
@@ -346,6 +368,34 @@ static int dynamic_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)())
return 1;
case DYNAMIC_CMD_LOAD:
return dynamic_load(e, ctx);
+ case DYNAMIC_CMD_DIR_LOAD:
+ if((i < 0) || (i > 2))
+ {
+ ENGINEerr(ENGINE_F_DYNAMIC_CTRL,
+ ENGINE_R_INVALID_ARGUMENT);
+ return 0;
+ }
+ ctx->dir_load = (int)i;
+ return 1;
+ case DYNAMIC_CMD_DIR_ADD:
+ /* a NULL 'p' or a string of zero-length is the same thing */
+ if(!p || (strlen((const char *)p) < 1))
+ {
+ ENGINEerr(ENGINE_F_DYNAMIC_CTRL,
+ ENGINE_R_INVALID_ARGUMENT);
+ return 0;
+ }
+ {
+ char *tmp_str = BUF_strdup(p);
+ if(!tmp_str)
+ {
+ ENGINEerr(ENGINE_F_DYNAMIC_CTRL,
+ ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ sk_insert(ctx->dirs, tmp_str, -1);
+ }
+ return 1;
default:
break;
}
@@ -353,16 +403,53 @@ static int dynamic_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)())
return 0;
}
+static int int_load(dynamic_data_ctx *ctx)
+ {
+ int num, loop;
+ /* Unless told not to, try a direct load */
+ if((ctx->dir_load != 2) && (DSO_load(ctx->dynamic_dso,
+ ctx->DYNAMIC_LIBNAME, NULL, 0)) != NULL)
+ return 1;
+ /* If we're not allowed to use 'dirs' or we have none, fail */
+ if(!ctx->dir_load || ((num = sk_num(ctx->dirs)) < 1))
+ return 0;
+ for(loop = 0; loop < num; loop++)
+ {
+ const char *s = sk_value(ctx->dirs, loop);
+ char *merge = DSO_merge(ctx->dynamic_dso, ctx->DYNAMIC_LIBNAME, s);
+ if(!merge)
+ return 0;
+ if(DSO_load(ctx->dynamic_dso, merge, NULL, 0))
+ {
+ /* Found what we're looking for */
+ OPENSSL_free(merge);
+ return 1;
+ }
+ OPENSSL_free(merge);
+ }
+ return 0;
+ }
+
static int dynamic_load(ENGINE *e, dynamic_data_ctx *ctx)
{
ENGINE cpy;
dynamic_fns fns;
- if(!ctx->DYNAMIC_LIBNAME || ((ctx->dynamic_dso = DSO_load(NULL,
- ctx->DYNAMIC_LIBNAME, NULL, 0)) == NULL))
+ if(!ctx->dynamic_dso)
+ ctx->dynamic_dso = DSO_new();
+ if(!ctx->DYNAMIC_LIBNAME)
+ {
+ if(!ctx->engine_id)
+ return 0;
+ ctx->DYNAMIC_LIBNAME =
+ DSO_convert_filename(ctx->dynamic_dso, ctx->engine_id);
+ }
+ if(!int_load(ctx))
{
ENGINEerr(ENGINE_F_DYNAMIC_LOAD,
ENGINE_R_DSO_NOT_FOUND);
+ DSO_free(ctx->dynamic_dso);
+ ctx->dynamic_dso = NULL;
return 0;
}
/* 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)
* engine.h, much of this would be simplified if each area of code
* provided its own "summary" structure of all related callbacks. It
* would also increase opaqueness. */
+ fns.static_state = ENGINE_get_static_state();
fns.err_fns = ERR_get_implementation();
fns.ex_data_fns = CRYPTO_get_ex_data_implementation();
CRYPTO_get_mem_functions(&fns.mem_fns.malloc_cb,
OpenPOWER on IntegriCloud