aboutsummaryrefslogtreecommitdiffstats
path: root/src/charon/config
diff options
context:
space:
mode:
Diffstat (limited to 'src/charon/config')
-rw-r--r--src/charon/config/child_cfg.c67
-rw-r--r--src/charon/config/child_cfg.h15
-rw-r--r--src/charon/config/ike_cfg.c31
-rw-r--r--src/charon/config/ike_cfg.h11
-rw-r--r--src/charon/config/proposal.c78
-rw-r--r--src/charon/config/proposal.h10
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**)&current))
{
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**)&current))
+ {
+ 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.