#include "key_exchange.h"
+#include <collections/hashtable.h>
+#include <threading/mutex.h>
+
ENUM_BEGIN(key_exchange_method_names, KE_NONE, MODP_1024_BIT,
"KE_NONE",
"MODP_768",
},
};
+/**
+ * Proposal tokens for additional key exchanges.
+ */
+static hashtable_t *tokens;
+
+/**
+ * Mutex to safely access cached tokens.
+ */
+static mutex_t *mutex;
+
+/**
+ * Destroy an allocated proposal token.
+ */
+static void token_destroy(proposal_token_t *this)
+{
+ free(this->name);
+ free(this);
+}
+
+/**
+ * Parse ke<1-7>_<method> for additional key exchange methods.
+ */
+static proposal_token_t *additional_key_exchange_parser(const char *algname)
+{
+ proposal_token_t *token;
+ const proposal_token_t *base;
+ u_int num;
+ char prefix[3], alg[256];
+
+ if (!algname || sscanf(algname, "%2s%1u_%255s", &prefix, &num, alg) != 3 ||
+ !strcaseeq(prefix, "ke"))
+ {
+ return NULL;
+ }
+ mutex->lock(mutex);
+ token = tokens->get(tokens, algname);
+ if (token || num < 1 || num > 7)
+ {
+ goto done;
+ }
+ base = lib->proposal->get_token(lib->proposal, alg);
+ if (!base || base->type != KEY_EXCHANGE_METHOD)
+ {
+ goto done;
+ }
+ INIT(token,
+ .name = strdup(algname),
+ .type = ADDITIONAL_KEY_EXCHANGE_1 + num - 1,
+ .algorithm = base->algorithm,
+ .keysize = base->keysize,
+ );
+ tokens->put(tokens, token->name, token);
+
+done:
+ mutex->unlock(mutex);
+ return token;
+}
+
/*
* Described in header
*/
-void diffie_hellman_init()
+void key_exchange_init()
{
int i;
dh_params[i].public.exp_len = dh_params[i].public.prime.len;
}
}
+
+ mutex = mutex_create(MUTEX_TYPE_RECURSIVE);
+ tokens = hashtable_create(hashtable_hash_str, hashtable_equals_str, 4);
+ lib->proposal->register_algname_parser(lib->proposal,
+ additional_key_exchange_parser);
+}
+
+/*
+ * Described in header
+ */
+void key_exchange_deinit()
+{
+ tokens->destroy_function(tokens, (void*)token_destroy);
+ mutex->destroy(mutex);
}
/*