diff options
Diffstat (limited to 'src/libcharon/config/proposal.c')
-rw-r--r-- | src/libcharon/config/proposal.c | 91 |
1 files changed, 49 insertions, 42 deletions
diff --git a/src/libcharon/config/proposal.c b/src/libcharon/config/proposal.c index 43b467f46..4803c7be2 100644 --- a/src/libcharon/config/proposal.c +++ b/src/libcharon/config/proposal.c @@ -19,7 +19,7 @@ #include "proposal.h" #include <daemon.h> -#include <utils/linked_list.h> +#include <collections/linked_list.h> #include <utils/identification.h> #include <crypto/transform.h> @@ -232,14 +232,21 @@ METHOD(proposal_t, has_dh_group, bool, } METHOD(proposal_t, strip_dh, void, - private_proposal_t *this) + private_proposal_t *this, diffie_hellman_group_t keep) { + enumerator_t *enumerator; algorithm_t *alg; - while (this->dh_groups->remove_last(this->dh_groups, (void**)&alg) == SUCCESS) + enumerator = this->dh_groups->create_enumerator(this->dh_groups); + while (enumerator->enumerate(enumerator, (void**)&alg)) { - free(alg); + if (alg->algorithm != keep) + { + this->dh_groups->remove_at(this->dh_groups, enumerator); + free(alg); + } } + enumerator->destroy(enumerator); } /** @@ -515,6 +522,23 @@ METHOD(proposal_t, clone_, proposal_t*, } /** + * Map integrity algorithms to the PRF functions using the same algorithm. + */ +static const struct { + integrity_algorithm_t integ; + pseudo_random_function_t prf; +} integ_prf_map[] = { + {AUTH_HMAC_SHA1_96, PRF_HMAC_SHA1 }, + {AUTH_HMAC_SHA2_256_128, PRF_HMAC_SHA2_256 }, + {AUTH_HMAC_SHA2_384_192, PRF_HMAC_SHA2_384 }, + {AUTH_HMAC_SHA2_512_256, PRF_HMAC_SHA2_512 }, + {AUTH_HMAC_MD5_96, PRF_HMAC_MD5 }, + {AUTH_AES_XCBC_96, PRF_AES128_XCBC }, + {AUTH_CAMELLIA_XCBC_96, PRF_CAMELLIA128_XCBC }, + {AUTH_AES_CMAC_96, PRF_AES128_CMAC }, +}; + +/** * Checks the proposal read from a string. */ static void check_proposal(private_proposal_t *this) @@ -522,6 +546,27 @@ static void check_proposal(private_proposal_t *this) enumerator_t *e; algorithm_t *alg; bool all_aead = TRUE; + int i; + + if (this->protocol == PROTO_IKE && + this->prf_algos->get_count(this->prf_algos) == 0) + { /* No explicit PRF found. We assume the same algorithm as used + * for integrity checking */ + e = this->integrity_algos->create_enumerator(this->integrity_algos); + while (e->enumerate(e, &alg)) + { + for (i = 0; i < countof(integ_prf_map); i++) + { + if (alg->algorithm == integ_prf_map[i].integ) + { + add_algorithm(this, PSEUDO_RANDOM_FUNCTION, + integ_prf_map[i].prf, 0); + break; + } + } + } + e->destroy(e); + } e = this->encryption_algos->create_enumerator(this->encryption_algos); while (e->enumerate(e, &alg)) @@ -572,44 +617,6 @@ static bool add_string_algo(private_proposal_t *this, const char *alg) add_algorithm(this, token->type, token->algorithm, token->keysize); - if (this->protocol == PROTO_IKE && token->type == INTEGRITY_ALGORITHM) - { - pseudo_random_function_t prf; - - switch (token->algorithm) - { - case AUTH_HMAC_SHA1_96: - prf = PRF_HMAC_SHA1; - break; - case AUTH_HMAC_SHA2_256_128: - prf = PRF_HMAC_SHA2_256; - break; - case AUTH_HMAC_SHA2_384_192: - prf = PRF_HMAC_SHA2_384; - break; - case AUTH_HMAC_SHA2_512_256: - prf = PRF_HMAC_SHA2_512; - break; - case AUTH_HMAC_MD5_96: - prf = PRF_HMAC_MD5; - break; - case AUTH_AES_XCBC_96: - prf = PRF_AES128_XCBC; - break; - case AUTH_CAMELLIA_XCBC_96: - prf = PRF_CAMELLIA128_XCBC; - break; - case AUTH_AES_CMAC_96: - prf = PRF_AES128_CMAC; - break; - default: - prf = PRF_UNDEFINED; - } - if (prf != PRF_UNDEFINED) - { - add_algorithm(this, PSEUDO_RANDOM_FUNCTION, prf, 0); - } - } return TRUE; } |