summaryrefslogtreecommitdiffstats
path: root/crypto/engine/eng_list.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/engine/eng_list.c')
-rw-r--r--crypto/engine/eng_list.c87
1 files changed, 87 insertions, 0 deletions
diff --git a/crypto/engine/eng_list.c b/crypto/engine/eng_list.c
index 1352fb7c96..4f9eb99d15 100644
--- a/crypto/engine/eng_list.c
+++ b/crypto/engine/eng_list.c
@@ -25,6 +25,12 @@ static ENGINE *engine_list_head = NULL;
static ENGINE *engine_list_tail = NULL;
/*
+ * The linked list of currently loaded dynamic engines.
+ */
+static ENGINE *engine_dyn_list_head = NULL;
+static ENGINE *engine_dyn_list_tail = NULL;
+
+/*
* This cleanup function is only needed internally. If it should be called,
* we register it with the "engine_cleanup_int()" stack to be called during
* cleanup.
@@ -126,6 +132,85 @@ static int engine_list_remove(ENGINE *e)
return 1;
}
+/* Add engine to dynamic engine list. */
+int engine_add_dynamic_id(ENGINE *e, ENGINE_DYNAMIC_ID dynamic_id,
+ int not_locked)
+{
+ int result = 0;
+ ENGINE *iterator = NULL;
+
+ if (e == NULL)
+ return 0;
+
+ if (e->dynamic_id == NULL && dynamic_id == NULL)
+ return 0;
+
+ if (not_locked && !CRYPTO_THREAD_write_lock(global_engine_lock))
+ return 0;
+
+ if (dynamic_id != NULL) {
+ iterator = engine_dyn_list_head;
+ while (iterator != NULL) {
+ if (iterator->dynamic_id == dynamic_id)
+ goto err;
+ iterator = iterator->next;
+ }
+ if (e->dynamic_id != NULL)
+ goto err;
+ e->dynamic_id = dynamic_id;
+ }
+
+ if (engine_dyn_list_head == NULL) {
+ /* We are adding to an empty list. */
+ if (engine_dyn_list_tail != NULL)
+ goto err;
+ engine_dyn_list_head = e;
+ e->prev_dyn = NULL;
+ } else {
+ /* We are adding to the tail of an existing list. */
+ if (engine_dyn_list_tail == NULL
+ || engine_dyn_list_tail->next_dyn != NULL)
+ goto err;
+ engine_dyn_list_tail->next_dyn = e;
+ e->prev_dyn = engine_dyn_list_tail;
+ }
+
+ engine_dyn_list_tail = e;
+ e->next_dyn = NULL;
+ result = 1;
+
+ err:
+ if (not_locked)
+ CRYPTO_THREAD_unlock(global_engine_lock);
+ return result;
+}
+
+/* Remove engine from dynamic engine list. */
+void engine_remove_dynamic_id(ENGINE *e, int not_locked)
+{
+ if (e == NULL || e->dynamic_id == NULL)
+ return;
+
+ if (not_locked && !CRYPTO_THREAD_write_lock(global_engine_lock))
+ return;
+
+ e->dynamic_id = NULL;
+
+ /* un-link e from the chain. */
+ if (e->next_dyn != NULL)
+ e->next_dyn->prev_dyn = e->prev_dyn;
+ if (e->prev_dyn != NULL)
+ e->prev_dyn->next_dyn = e->next_dyn;
+ /* Correct our head/tail if necessary. */
+ if (engine_dyn_list_head == e)
+ engine_dyn_list_head = e->next_dyn;
+ if (engine_dyn_list_tail == e)
+ engine_dyn_list_tail = e->prev_dyn;
+
+ if (not_locked)
+ CRYPTO_THREAD_unlock(global_engine_lock);
+}
+
/* Get the first/last "ENGINE" type available. */
ENGINE *ENGINE_get_first(void)
{
@@ -272,6 +357,8 @@ static void engine_cpy(ENGINE *dest, const ENGINE *src)
dest->load_pubkey = src->load_pubkey;
dest->cmd_defns = src->cmd_defns;
dest->flags = src->flags;
+ dest->dynamic_id = src->dynamic_id;
+ engine_add_dynamic_id(dest, NULL, 0);
}
ENGINE *ENGINE_by_id(const char *id)