key-exchange: Add dynamic parser for additional key exchange methods

This commit is contained in:
Tobias Brunner 2019-11-04 17:27:20 +01:00
parent 95275d2fe5
commit e05d86b27a
3 changed files with 86 additions and 4 deletions

View File

@ -18,6 +18,9 @@
#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",
@ -475,10 +478,68 @@ static struct {
},
};
/**
* 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;
@ -498,6 +559,20 @@ void diffie_hellman_init()
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);
}
/*

View File

@ -178,9 +178,14 @@ struct diffie_hellman_params_t {
};
/**
* Initialize diffie hellman parameters during startup.
* Initialize DH parameters and KE token parser during startup.
*/
void diffie_hellman_init();
void key_exchange_init();
/**
* Deinitialize KE token parser during shutdown.
*/
void key_exchange_deinit();
/**
* Get the parameters associated with the specified Diffie-Hellman group.

View File

@ -161,6 +161,8 @@ void library_deinit()
/* make sure the cache is clear before unloading plugins */
lib->credmgr->flush_cache(lib->credmgr, CERT_ANY);
key_exchange_deinit();
this->public.streams->destroy(this->public.streams);
this->public.watcher->destroy(this->public.watcher);
this->public.scheduler->destroy(this->public.scheduler);
@ -436,7 +438,7 @@ bool library_init(char *settings, const char *namespace)
#endif /* INTEGRITY_TEST */
}
diffie_hellman_init();
key_exchange_init();
return !this->init_failed;
}