summaryrefslogtreecommitdiffstats
path: root/crypto/engine
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/engine')
-rw-r--r--crypto/engine/engine.h15
-rw-r--r--crypto/engine/engine_int.h2
-rw-r--r--crypto/engine/engine_list.c51
3 files changed, 65 insertions, 3 deletions
diff --git a/crypto/engine/engine.h b/crypto/engine/engine.h
index e129cde70c..258ec6ec43 100644
--- a/crypto/engine/engine.h
+++ b/crypto/engine/engine.h
@@ -108,6 +108,15 @@ typedef void DH_METHOD;
* control commands on behalf of the ENGINE using their "cmd_defns" data. */
#define ENGINE_FLAGS_MANUAL_CMD_CTRL (int)0x0002
+/* This flag is for ENGINEs who return new duplicate structures when found via
+ * "ENGINE_by_id()". When an ENGINE must store state (eg. if ENGINE_ctrl()
+ * commands are called in sequence as part of some stateful process like
+ * key-generation setup and execution), it can set this flag - then each attempt
+ * to obtain the ENGINE will result in it being copied into a new structure.
+ * Normally, ENGINEs don't declare this flag so ENGINE_by_id() just increments
+ * the existing ENGINE's structural reference count. */
+#define ENGINE_FLAGS_BY_ID_COPY (int)0x0004
+
/* ENGINEs can support their own command types, and these flags are used in
* ENGINE_CTRL_GET_CMD_FLAGS to indicate to the caller what kind of input each
* command expects. Currently only numeric and string input is supported. If a
@@ -349,6 +358,11 @@ int ENGINE_set_cmd_defns(ENGINE *e, const ENGINE_CMD_DEFN *defns);
/* Copies across all ENGINE methods and pointers. NB: This does *not* change
* reference counts however. */
int ENGINE_cpy(ENGINE *dest, const ENGINE *src);
+/* These functions (and the "get" function lower down) allow control over any
+ * per-structure ENGINE data. */
+int ENGINE_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+ CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
+int ENGINE_set_ex_data(ENGINE *e, int idx, void *arg);
/* Cleans the internal engine structure. This should only be used when the
* application is about to exit. */
void ENGINE_cleanup(void);
@@ -372,6 +386,7 @@ ENGINE_LOAD_KEY_PTR ENGINE_get_load_privkey_function(const ENGINE *e);
ENGINE_LOAD_KEY_PTR ENGINE_get_load_pubkey_function(const ENGINE *e);
const ENGINE_CMD_DEFN *ENGINE_get_cmd_defns(const ENGINE *e);
int ENGINE_get_flags(const ENGINE *e);
+void *ENGINE_get_ex_data(const ENGINE *e, int idx);
/* FUNCTIONAL functions. These functions deal with ENGINE structures
* that have (or will) be initialised for use. Broadly speaking, the
diff --git a/crypto/engine/engine_int.h b/crypto/engine/engine_int.h
index addf6b533b..d44f648559 100644
--- a/crypto/engine/engine_int.h
+++ b/crypto/engine/engine_int.h
@@ -96,6 +96,8 @@ struct engine_st
* simply to cope with (de)allocation of this structure. Hence,
* running_ref <= struct_ref at all times. */
int funct_ref;
+ /* A place to store per-key data */
+ CRYPTO_EX_DATA ex_data;
/* Used to maintain the linked-list of engines. */
struct engine_st *prev;
struct engine_st *next;
diff --git a/crypto/engine/engine_list.c b/crypto/engine/engine_list.c
index 2ca667e85d..0f6e9bb242 100644
--- a/crypto/engine/engine_list.c
+++ b/crypto/engine/engine_list.c
@@ -61,6 +61,14 @@
#include "engine_int.h"
#include <openssl/engine.h>
+/* Weird "ex_data" handling. Some have suggested there's some problems with the
+ * CRYPTO_EX_DATA code (or model), but for now I'm implementing it exactly as
+ * it's done in crypto/rsa/. That way the usage and documentation of that can be
+ * used to assist here, and any changes or fixes made there should similarly map
+ * over here quite straightforwardly. */
+static int engine_ex_data_num = 0;
+static STACK_OF(CRYPTO_EX_DATA_FUNCS) *engine_ex_data_stack = NULL;
+
/* The linked-list of pointers to engine types. engine_list_head
* incorporates an implicit structural reference but engine_list_tail
* does not - the latter is a computational niceity and only points
@@ -308,7 +316,7 @@ int ENGINE_remove(ENGINE *e)
ENGINE *ENGINE_by_id(const char *id)
{
- ENGINE *iterator = NULL;
+ ENGINE *iterator = NULL, *cp = NULL;
if(id == NULL)
{
ENGINEerr(ENGINE_F_ENGINE_BY_ID,
@@ -325,8 +333,24 @@ ENGINE *ENGINE_by_id(const char *id)
while(iterator && (strcmp(id, iterator->id) != 0))
iterator = iterator->next;
if(iterator)
- /* We need to return a structural reference */
- iterator->struct_ref++;
+ {
+ /* We need to return a structural reference. If this is
+ * a "dynamic" ENGINE type, make a duplicate - otherwise
+ * increment the existing ENGINE's reference count. */
+ if(iterator->flags & ENGINE_FLAGS_BY_ID_COPY)
+ {
+ cp = ENGINE_new();
+ if(!cp)
+ iterator = NULL;
+ else
+ {
+ ENGINE_cpy(cp, iterator);
+ iterator = cp;
+ }
+ }
+ else
+ iterator->struct_ref++;
+ }
}
CRYPTO_r_unlock(CRYPTO_LOCK_ENGINE);
if(iterator == NULL)
@@ -347,6 +371,7 @@ ENGINE *ENGINE_new(void)
}
memset(ret, 0, sizeof(ENGINE));
ret->struct_ref = 1;
+ CRYPTO_new_ex_data(engine_ex_data_stack, ret, &ret->ex_data);
return ret;
}
@@ -372,10 +397,30 @@ int ENGINE_free(ENGINE *e)
abort();
}
#endif
+ CRYPTO_free_ex_data(engine_ex_data_stack, e, &e->ex_data);
OPENSSL_free(e);
return 1;
}
+int ENGINE_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+ CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
+ {
+ engine_ex_data_num++;
+ return(CRYPTO_get_ex_new_index(engine_ex_data_num - 1,
+ &engine_ex_data_stack, argl, argp,
+ new_func, dup_func, free_func));
+ }
+
+int ENGINE_set_ex_data(ENGINE *e, int idx, void *arg)
+ {
+ return(CRYPTO_set_ex_data(&e->ex_data, idx, arg));
+ }
+
+void *ENGINE_get_ex_data(const ENGINE *e, int idx)
+ {
+ return(CRYPTO_get_ex_data(&e->ex_data, idx));
+ }
+
void ENGINE_cleanup(void)
{
ENGINE *iterator = engine_list_head;