diff options
Diffstat (limited to 'src/charon/config')
-rw-r--r-- | src/charon/config/child_cfg.c | 67 | ||||
-rw-r--r-- | src/charon/config/child_cfg.h | 15 | ||||
-rw-r--r-- | src/charon/config/ike_cfg.c | 31 | ||||
-rw-r--r-- | src/charon/config/ike_cfg.h | 11 | ||||
-rw-r--r-- | src/charon/config/proposal.c | 78 | ||||
-rw-r--r-- | src/charon/config/proposal.h | 10 |
6 files changed, 129 insertions, 83 deletions
diff --git a/src/charon/config/child_cfg.c b/src/charon/config/child_cfg.c index 2f5376753..440f7710b 100644 --- a/src/charon/config/child_cfg.c +++ b/src/charon/config/child_cfg.c @@ -120,9 +120,26 @@ static void add_proposal(private_child_cfg_t *this, proposal_t *proposal) } /** + * strip out DH groups from a proposal + */ +static void strip_dh_from_proposal(proposal_t *proposal) +{ + iterator_t *iterator; + algorithm_t *algo; + + iterator = proposal->create_algorithm_iterator(proposal, DIFFIE_HELLMAN_GROUP); + while (iterator->iterate(iterator, (void**)&algo)) + { + iterator->remove(iterator); + free(algo); + } + iterator->destroy(iterator); +} + +/** * Implementation of child_cfg_t.get_proposals */ -static linked_list_t* get_proposals(private_child_cfg_t *this) +static linked_list_t* get_proposals(private_child_cfg_t *this, bool strip_dh) { iterator_t *iterator; proposal_t *current; @@ -132,6 +149,10 @@ static linked_list_t* get_proposals(private_child_cfg_t *this) while (iterator->iterate(iterator, (void**)¤t)) { current = current->clone(current); + if (strip_dh) + { + strip_dh_from_proposal(current); + } proposals->insert_last(proposals, current); } iterator->destroy(iterator); @@ -142,7 +163,8 @@ static linked_list_t* get_proposals(private_child_cfg_t *this) /** * Implementation of child_cfg_t.get_name */ -static proposal_t* select_proposal(private_child_cfg_t*this, linked_list_t *proposals) +static proposal_t* select_proposal(private_child_cfg_t*this, + linked_list_t *proposals, bool strip_dh) { iterator_t *stored_iter, *supplied_iter; proposal_t *stored, *supplied, *selected = NULL; @@ -156,7 +178,18 @@ static proposal_t* select_proposal(private_child_cfg_t*this, linked_list_t *prop supplied_iter->reset(supplied_iter); while (supplied_iter->iterate(supplied_iter, (void**)&supplied)) { - selected = stored->select(stored, supplied); + if (strip_dh) + { + /* remove DH groups on a copy */ + stored = stored->clone(stored); + strip_dh_from_proposal(stored); + selected = stored->select(stored, supplied); + stored->destroy(stored); + } + else + { + selected = stored->select(stored, supplied); + } if (selected) { break; @@ -329,6 +362,29 @@ static mode_t get_mode(private_child_cfg_t *this) } /** + * Implementation of child_cfg_t.get_dh_group. + */ +static diffie_hellman_group_t get_dh_group(private_child_cfg_t *this) +{ + iterator_t *iterator; + proposal_t *proposal; + algorithm_t *algo; + diffie_hellman_group_t dh_group = MODP_NONE; + + iterator = this->proposals->create_iterator(this->proposals, TRUE); + while (iterator->iterate(iterator, (void**)&proposal)) + { + if (proposal->get_algorithm(proposal, DIFFIE_HELLMAN_GROUP, &algo)) + { + dh_group = algo->algorithm; + break; + } + } + iterator->destroy(iterator); + return dh_group; +} + +/** * Implementation of child_cfg_t.get_name */ static void get_ref(private_child_cfg_t *this) @@ -369,12 +425,13 @@ child_cfg_t *child_cfg_create(char *name, u_int32_t lifetime, this->public.add_traffic_selector = (void (*)(child_cfg_t*,bool,traffic_selector_t*))add_traffic_selector; this->public.get_traffic_selectors = (linked_list_t*(*)(child_cfg_t*,bool,linked_list_t*,host_t*))get_traffic_selectors; this->public.add_proposal = (void (*) (child_cfg_t*,proposal_t*))add_proposal; - this->public.get_proposals = (linked_list_t* (*) (child_cfg_t*))get_proposals; - this->public.select_proposal = (proposal_t* (*) (child_cfg_t*,linked_list_t*))select_proposal; + this->public.get_proposals = (linked_list_t* (*) (child_cfg_t*,bool))get_proposals; + this->public.select_proposal = (proposal_t* (*) (child_cfg_t*,linked_list_t*,bool))select_proposal; this->public.get_updown = (char* (*) (child_cfg_t*))get_updown; this->public.get_hostaccess = (bool (*) (child_cfg_t*))get_hostaccess; this->public.get_mode = (mode_t (*) (child_cfg_t *))get_mode; this->public.get_lifetime = (u_int32_t (*) (child_cfg_t *,bool))get_lifetime; + this->public.get_dh_group = (diffie_hellman_group_t(*)(child_cfg_t*)) get_dh_group; this->public.get_ref = (void (*) (child_cfg_t*))get_ref; this->public.destroy = (void (*) (child_cfg_t*))destroy; diff --git a/src/charon/config/child_cfg.h b/src/charon/config/child_cfg.h index 6b2299089..e1a6553b4 100644 --- a/src/charon/config/child_cfg.h +++ b/src/charon/config/child_cfg.h @@ -96,9 +96,10 @@ struct child_cfg_t { * Resulting list and all of its proposals must be freed after use. * * @param this calling object + * @param strip_dh TRUE strip out diffie hellman groups * @return list of proposals */ - linked_list_t* (*get_proposals)(child_cfg_t *this); + linked_list_t* (*get_proposals)(child_cfg_t *this, bool strip_dh); /** * @brief Select a proposal from a supplied list. @@ -107,9 +108,11 @@ struct child_cfg_t { * * @param this calling object * @param proposals list from from wich proposals are selected + * @param strip_dh TRUE strip out diffie hellman groups * @return selected proposal, or NULL if nothing matches */ - proposal_t* (*select_proposal)(child_cfg_t*this, linked_list_t *proposals); + proposal_t* (*select_proposal)(child_cfg_t*this, linked_list_t *proposals, + bool strip_dh); /** * @brief Add a traffic selector to the config. @@ -189,6 +192,14 @@ struct child_cfg_t { mode_t (*get_mode) (child_cfg_t *this); /** + * @brief Get the DH group to use for CHILD_SA setup. + * + * @param this calling object + * @return dh group to use + */ + diffie_hellman_group_t (*get_dh_group)(child_cfg_t *this); + + /** * @brief Get a new reference. * * Get a new reference to this child_cfg by increasing diff --git a/src/charon/config/ike_cfg.c b/src/charon/config/ike_cfg.c index 61e62115d..35f46a6b7 100644 --- a/src/charon/config/ike_cfg.c +++ b/src/charon/config/ike_cfg.c @@ -176,36 +176,6 @@ static diffie_hellman_group_t get_dh_group(private_ike_cfg_t *this) } /** - * Implementation of ike_cfg_t.check_dh_group. - */ -static bool check_dh_group(private_ike_cfg_t *this, - diffie_hellman_group_t dh_group) -{ - iterator_t *prop_iter, *alg_iter; - proposal_t *proposal; - algorithm_t *algo; - - prop_iter = this->proposals->create_iterator(this->proposals, TRUE); - while (prop_iter->iterate(prop_iter, (void**)&proposal)) - { - alg_iter = proposal->create_algorithm_iterator(proposal, - DIFFIE_HELLMAN_GROUP); - while (alg_iter->iterate(alg_iter, (void**)&algo)) - { - if (algo->algorithm == dh_group) - { - prop_iter->destroy(prop_iter); - alg_iter->destroy(alg_iter); - return TRUE; - } - } - alg_iter->destroy(alg_iter); - } - prop_iter->destroy(prop_iter); - return FALSE; -} - -/** * Implementation of ike_cfg_t.get_ref. */ static void get_ref(private_ike_cfg_t *this) @@ -243,7 +213,6 @@ ike_cfg_t *ike_cfg_create(bool certreq, host_t *my_host, host_t *other_host) this->public.get_proposals = (linked_list_t*(*)(ike_cfg_t*))get_proposals; this->public.select_proposal = (proposal_t*(*)(ike_cfg_t*,linked_list_t*))select_proposal; this->public.get_dh_group = (diffie_hellman_group_t(*)(ike_cfg_t*)) get_dh_group; - this->public.check_dh_group = (bool(*)(ike_cfg_t*,diffie_hellman_group_t)) check_dh_group; this->public.get_ref = (void(*)(ike_cfg_t*))get_ref; this->public.destroy = (void(*)(ike_cfg_t*))destroy; diff --git a/src/charon/config/ike_cfg.h b/src/charon/config/ike_cfg.h index ccea0a527..bcdc90d9e 100644 --- a/src/charon/config/ike_cfg.h +++ b/src/charon/config/ike_cfg.h @@ -110,17 +110,6 @@ struct ike_cfg_t { diffie_hellman_group_t (*get_dh_group)(ike_cfg_t *this); /** - * @brief Check if a suggested DH group is acceptable. - * - * If we guess a wrong DH group for IKE_SA_INIT, the other - * peer will send us a offer. But is this acceptable for us? - * - * @param this calling object - * @return TRUE if group acceptable - */ - bool (*check_dh_group) (ike_cfg_t *this, diffie_hellman_group_t dh_group); - - /** * @brief Get a new reference to this ike_cfg. * * Get a new reference to this ike_cfg by increasing diff --git a/src/charon/config/proposal.c b/src/charon/config/proposal.c index dcab8cbdd..fe113b1d8 100644 --- a/src/charon/config/proposal.c +++ b/src/charon/config/proposal.c @@ -144,39 +144,6 @@ static void add_algorithm(private_proposal_t *this, transform_type_t type, u_int } /** - * Implements proposal_t.get_algorithm. - */ -static bool get_algorithm(private_proposal_t *this, transform_type_t type, algorithm_t** algo) -{ - linked_list_t *list; - switch (type) - { - case ENCRYPTION_ALGORITHM: - list = this->encryption_algos; - break; - case INTEGRITY_ALGORITHM: - list = this->integrity_algos; - break; - case PSEUDO_RANDOM_FUNCTION: - list = this->prf_algos; - break; - case DIFFIE_HELLMAN_GROUP: - list = this->dh_groups; - break; - case EXTENDED_SEQUENCE_NUMBERS: - list = this->esns; - break; - default: - return FALSE; - } - if (list->get_first(list, (void**)algo) != SUCCESS) - { - return FALSE; - } - return TRUE; -} - -/** * Implements proposal_t.create_algorithm_iterator. */ static iterator_t *create_algorithm_iterator(private_proposal_t *this, transform_type_t type) @@ -200,6 +167,50 @@ static iterator_t *create_algorithm_iterator(private_proposal_t *this, transform } /** + * Implements proposal_t.get_algorithm. + */ +static bool get_algorithm(private_proposal_t *this, transform_type_t type, algorithm_t** algo) +{ + iterator_t *iterator = create_algorithm_iterator(this, type); + if (iterator->iterate(iterator, (void**)algo)) + { + iterator->destroy(iterator); + return TRUE; + } + iterator->destroy(iterator); + return FALSE; +} + +/** + * Implements proposal_t.has_dh_group + */ +static bool has_dh_group(private_proposal_t *this, diffie_hellman_group_t group) +{ + algorithm_t *current; + iterator_t *iterator; + bool result = FALSE; + + iterator = this->dh_groups->create_iterator(this->dh_groups, TRUE); + if (iterator->get_count(iterator)) + { + while (iterator->iterate(iterator, (void**)¤t)) + { + if (current->algorithm == group) + { + result = TRUE; + break; + } + } + } + else if (group == MODP_NONE) + { + result = TRUE; + } + iterator->destroy(iterator); + return result; +} + +/** * Find a matching alg/keysize in two linked lists */ static bool select_algo(linked_list_t *first, linked_list_t *second, bool *add, u_int16_t *alg, size_t *key_size) @@ -530,6 +541,7 @@ proposal_t *proposal_create(protocol_id_t protocol) this->public.add_algorithm = (void (*)(proposal_t*,transform_type_t,u_int16_t,size_t))add_algorithm; this->public.create_algorithm_iterator = (iterator_t* (*)(proposal_t*,transform_type_t))create_algorithm_iterator; this->public.get_algorithm = (bool (*)(proposal_t*,transform_type_t,algorithm_t**))get_algorithm; + this->public.has_dh_group = (bool (*)(proposal_t*,diffie_hellman_group_t))has_dh_group; this->public.select = (proposal_t* (*)(proposal_t*,proposal_t*))select_proposal; this->public.get_protocol = (protocol_id_t(*)(proposal_t*))get_protocol; this->public.set_spi = (void(*)(proposal_t*,u_int64_t))set_spi; diff --git a/src/charon/config/proposal.h b/src/charon/config/proposal.h index 4bee08e28..379550f44 100644 --- a/src/charon/config/proposal.h +++ b/src/charon/config/proposal.h @@ -164,7 +164,6 @@ struct proposal_t { * @brief Get the algorithm for a type to use. * * If there are multiple algorithms, only the first is returned. - * Result is still owned by proposal, do not modify! * * @param this calling object * @param type kind of algorithm @@ -172,6 +171,15 @@ struct proposal_t { * @return TRUE if algorithm of this kind available */ bool (*get_algorithm) (proposal_t *this, transform_type_t type, algorithm_t** algo); + + /** + * @brief Check if the proposal has a specific DH group. + * + * @param this calling object + * @param group group to check for + * @return TRUE if algorithm included + */ + bool (*has_dh_group) (proposal_t *this, diffie_hellman_group_t group); /** * @brief Compare two proposal, and select a matching subset. |