From: Tobias Brunner Date: Mon, 4 Nov 2019 16:27:20 +0000 (+0100) Subject: key-exchange: Add dynamic parser for additional key exchange methods X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=291fb36a43973293b43b98967e77cc8a4d793c6a;p=thirdparty%2Fstrongswan.git key-exchange: Add dynamic parser for additional key exchange methods --- diff --git a/src/libstrongswan/crypto/key_exchange.c b/src/libstrongswan/crypto/key_exchange.c index 5b01139897..b3fb9641fe 100644 --- a/src/libstrongswan/crypto/key_exchange.c +++ b/src/libstrongswan/crypto/key_exchange.c @@ -18,6 +18,9 @@ #include "key_exchange.h" +#include +#include + 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>_ 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); } /* diff --git a/src/libstrongswan/crypto/key_exchange.h b/src/libstrongswan/crypto/key_exchange.h index 73bf61f06e..4aa4e264b2 100644 --- a/src/libstrongswan/crypto/key_exchange.h +++ b/src/libstrongswan/crypto/key_exchange.h @@ -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. diff --git a/src/libstrongswan/library.c b/src/libstrongswan/library.c index f2ece6ca98..27c939540e 100644 --- a/src/libstrongswan/library.c +++ b/src/libstrongswan/library.c @@ -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); @@ -434,7 +436,7 @@ bool library_init(char *settings, const char *namespace) #endif /* INTEGRITY_TEST */ } - diffie_hellman_init(); + key_exchange_init(); return !this->init_failed; }