$(BUILD_DIR)traffic_selector.o : $(CONFIG_DIR)traffic_selector.c $(CONFIG_DIR)traffic_selector.h
$(CC) $(CFLAGS) -c -o $@ $<
-OBJS+= $(BUILD_DIR)child_proposal.o
-$(BUILD_DIR)child_proposal.o : $(CONFIG_DIR)child_proposal.c $(CONFIG_DIR)child_proposal.h
+OBJS+= $(BUILD_DIR)proposal.o
+$(BUILD_DIR)proposal.o : $(CONFIG_DIR)proposal.c $(CONFIG_DIR)proposal.h
$(CC) $(CFLAGS) -c -o $@ $<
static void load_default_config (private_configuration_manager_t *this)
{
init_config_t *init_config_a, *init_config_b;
- ike_proposal_t proposals;
- child_proposal_t *child_proposal;
+ proposal_t *proposal;
sa_config_t *sa_config_a, *sa_config_b;
traffic_selector_t *ts;
init_config_a = init_config_create("0.0.0.0","192.168.0.3",IKEV2_UDP_PORT,IKEV2_UDP_PORT);
init_config_b = init_config_create("0.0.0.0","192.168.0.2",IKEV2_UDP_PORT,IKEV2_UDP_PORT);
- ts = traffic_selector_create_from_string(1, TS_IPV4_ADDR_RANGE, "0.0.0.0", 0, "255.255.255.255", 65535);
-
- proposals.encryption_algorithm = ENCR_AES_CBC;
- proposals.encryption_algorithm_key_length = 16;
- proposals.integrity_algorithm = AUTH_HMAC_MD5_96;
- proposals.integrity_algorithm_key_length = 16;
- proposals.pseudo_random_function = PRF_HMAC_MD5;
- proposals.pseudo_random_function_key_length = 16;
- proposals.diffie_hellman_group = MODP_1024_BIT;
-
- init_config_a->add_proposal(init_config_a,1,proposals);
- init_config_b->add_proposal(init_config_b,1,proposals);
-
+ /* IKE proposals for alice */
+ proposal = proposal_create(1);
+ proposal->add_algorithm(proposal, IKE, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 16);
+ POS;
+ proposal->add_algorithm(proposal, IKE, INTEGRITY_ALGORITHM, AUTH_HMAC_MD5_96, 16);
+ POS;
+ proposal->add_algorithm(proposal, IKE, PSEUDO_RANDOM_FUNCTION, PRF_HMAC_MD5, 16);
+ proposal->add_algorithm(proposal, IKE, DIFFIE_HELLMAN_GROUP, MODP_1024_BIT, 0);
+ proposal->add_algorithm(proposal, IKE, DIFFIE_HELLMAN_GROUP, MODP_2048_BIT, 0);
+ init_config_a->add_proposal(init_config_a, proposal);
+
+ /* IKE proposals for bob */
+ proposal = proposal_create(1);
+ proposal->add_algorithm(proposal, IKE, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 16);
+ proposal->add_algorithm(proposal, IKE, INTEGRITY_ALGORITHM, AUTH_HMAC_MD5_96, 16);
+ proposal->add_algorithm(proposal, IKE, PSEUDO_RANDOM_FUNCTION, PRF_HMAC_MD5, 16);
+ proposal->add_algorithm(proposal, IKE, DIFFIE_HELLMAN_GROUP, MODP_2048_BIT, 0);
+ init_config_b->add_proposal(init_config_b, proposal);
+
sa_config_a = sa_config_create(ID_IPV4_ADDR, "192.168.0.2",
ID_IPV4_ADDR, "192.168.0.3",
RSA_DIGITAL_SIGNATURE,
ID_IPV4_ADDR, "192.168.0.2",
RSA_DIGITAL_SIGNATURE,
30000);
-
+
+ /* traffic selectors */
+ ts = traffic_selector_create_from_string(1, TS_IPV4_ADDR_RANGE, "0.0.0.0", 0, "255.255.255.255", 65535);
sa_config_a->add_traffic_selector_initiator(sa_config_a,ts);
sa_config_a->add_traffic_selector_responder(sa_config_a,ts);
-
sa_config_b->add_traffic_selector_initiator(sa_config_b,ts);
sa_config_b->add_traffic_selector_responder(sa_config_b,ts);
-
ts->destroy(ts);
/* child proposal for alice */
- child_proposal = child_proposal_create(1);
+ proposal = proposal_create(1);
- child_proposal->add_algorithm(child_proposal, AH, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA1_96, 20);
- child_proposal->add_algorithm(child_proposal, AH, INTEGRITY_ALGORITHM, AUTH_HMAC_MD5_96, 20);
- child_proposal->add_algorithm(child_proposal, AH, DIFFIE_HELLMAN_GROUP, MODP_1024_BIT, 0);
- child_proposal->add_algorithm(child_proposal, AH, DIFFIE_HELLMAN_GROUP, MODP_2048_BIT, 0);
- child_proposal->add_algorithm(child_proposal, AH, EXTENDED_SEQUENCE_NUMBERS, NO_EXT_SEQ_NUMBERS, 0);
+ proposal->add_algorithm(proposal, AH, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA1_96, 20);
+ proposal->add_algorithm(proposal, AH, INTEGRITY_ALGORITHM, AUTH_HMAC_MD5_96, 20);
+ proposal->add_algorithm(proposal, AH, DIFFIE_HELLMAN_GROUP, MODP_1024_BIT, 0);
+ proposal->add_algorithm(proposal, AH, DIFFIE_HELLMAN_GROUP, MODP_2048_BIT, 0);
+ proposal->add_algorithm(proposal, AH, EXTENDED_SEQUENCE_NUMBERS, NO_EXT_SEQ_NUMBERS, 0);
- child_proposal->add_algorithm(child_proposal, ESP, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 16);
- child_proposal->add_algorithm(child_proposal, ESP, ENCRYPTION_ALGORITHM, ENCR_3DES, 32);
- child_proposal->add_algorithm(child_proposal, ESP, INTEGRITY_ALGORITHM, AUTH_HMAC_MD5_96, 20);
- child_proposal->add_algorithm(child_proposal, ESP, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA1_96, 20);
- child_proposal->add_algorithm(child_proposal, ESP, DIFFIE_HELLMAN_GROUP, MODP_1024_BIT, 0);
- child_proposal->add_algorithm(child_proposal, ESP, EXTENDED_SEQUENCE_NUMBERS, NO_EXT_SEQ_NUMBERS, 0);
+ proposal->add_algorithm(proposal, ESP, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 16);
+ proposal->add_algorithm(proposal, ESP, ENCRYPTION_ALGORITHM, ENCR_3DES, 32);
+ proposal->add_algorithm(proposal, ESP, INTEGRITY_ALGORITHM, AUTH_HMAC_MD5_96, 20);
+ proposal->add_algorithm(proposal, ESP, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA1_96, 20);
+ proposal->add_algorithm(proposal, ESP, DIFFIE_HELLMAN_GROUP, MODP_1024_BIT, 0);
+ proposal->add_algorithm(proposal, ESP, EXTENDED_SEQUENCE_NUMBERS, NO_EXT_SEQ_NUMBERS, 0);
- sa_config_a->add_proposal(sa_config_a, child_proposal);
+ sa_config_a->add_proposal(sa_config_a, proposal);
/* child proposal for bob */
- child_proposal = child_proposal_create(1);
+ proposal = proposal_create(1);
- child_proposal->add_algorithm(child_proposal, AH, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA1_96, 20);
- child_proposal->add_algorithm(child_proposal, AH, DIFFIE_HELLMAN_GROUP, MODP_1024_BIT, 0);
- child_proposal->add_algorithm(child_proposal, AH, EXTENDED_SEQUENCE_NUMBERS, NO_EXT_SEQ_NUMBERS, 0);
+ proposal->add_algorithm(proposal, AH, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA1_96, 20);
+ proposal->add_algorithm(proposal, AH, DIFFIE_HELLMAN_GROUP, MODP_1024_BIT, 0);
+ proposal->add_algorithm(proposal, AH, EXTENDED_SEQUENCE_NUMBERS, NO_EXT_SEQ_NUMBERS, 0);
- child_proposal->add_algorithm(child_proposal, ESP, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 16);
- child_proposal->add_algorithm(child_proposal, ESP, INTEGRITY_ALGORITHM, AUTH_HMAC_MD5_96, 20);
- child_proposal->add_algorithm(child_proposal, ESP, DIFFIE_HELLMAN_GROUP, MODP_1024_BIT, 0);
- child_proposal->add_algorithm(child_proposal, ESP, EXTENDED_SEQUENCE_NUMBERS, NO_EXT_SEQ_NUMBERS, 0);
+ proposal->add_algorithm(proposal, ESP, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 16);
+ proposal->add_algorithm(proposal, ESP, INTEGRITY_ALGORITHM, AUTH_HMAC_MD5_96, 20);
+ proposal->add_algorithm(proposal, ESP, DIFFIE_HELLMAN_GROUP, MODP_1024_BIT, 0);
+ proposal->add_algorithm(proposal, ESP, EXTENDED_SEQUENCE_NUMBERS, NO_EXT_SEQ_NUMBERS, 0);
- sa_config_b->add_proposal(sa_config_b, child_proposal);
+ sa_config_b->add_proposal(sa_config_b, proposal);
}
/**
- * Implementation of init_config_t.get_dh_group_number.
+ * Implementation of init_config_t.get_proposals.
*/
-static diffie_hellman_group_t get_dh_group_number (private_init_config_t *this,size_t priority)
+static linked_list_t* get_proposals (private_init_config_t *this)
{
- ike_proposal_t *ike_proposal;
-
- if ((this->proposals->get_count(this->proposals) == 0) || (this->proposals->get_count(this->proposals) < priority))
- {
- return MODP_UNDEFINED;
- }
-
- this->proposals->get_at_position(this->proposals,(priority -1),(void **) &ike_proposal);
-
- return (ike_proposal->diffie_hellman_group);
+ return this->proposals;
}
-
+
/**
- * Implementation of init_config_t.get_proposals.
+ * Implementation of init_config_t.select_proposal.
*/
-static size_t get_proposals (private_init_config_t *this,ike_proposal_t **proposals)
+static proposal_t *select_proposal(private_init_config_t *this, linked_list_t *proposals)
{
- iterator_t *iterator;
- ike_proposal_t *current_proposal;
- int i = 0;
- ike_proposal_t *proposal_array;
+ iterator_t *stored_iter, *supplied_iter;
+ proposal_t *stored, *supplied, *selected;
- proposal_array = allocator_alloc(this->proposals->get_count(this->proposals) * sizeof(ike_proposal_t));
-
- iterator = this->proposals->create_iterator(this->proposals,TRUE);
+ stored_iter = this->proposals->create_iterator(this->proposals, TRUE);
+ supplied_iter = proposals->create_iterator(proposals, TRUE);
- while (iterator->has_next(iterator))
+ /* compare all stored proposals with all supplied. Stored ones are preferred. */
+ while (stored_iter->has_next(stored_iter))
{
- iterator->current(iterator,(void **) ¤t_proposal);
- proposal_array[i] = (*current_proposal);
- i++;
+ supplied_iter->reset(supplied_iter);
+ stored_iter->current(stored_iter, (void**)&stored);
+
+ while (supplied_iter->has_next(supplied_iter))
+ {
+ supplied_iter->current(supplied_iter, (void**)&supplied);
+ selected = stored->select(stored, supplied);
+ if (selected)
+ {
+ /* they match, return */
+ stored_iter->destroy(stored_iter);
+ supplied_iter->destroy(supplied_iter);
+ return selected;
+ }
+ }
}
- iterator->destroy(iterator);
- *proposals = proposal_array;
- return this->proposals->get_count(this->proposals);
-}
+ /* no proposal match :-(, will result in a NO_PROPOSAL_CHOSEN... */
+ stored_iter->destroy(stored_iter);
+ supplied_iter->destroy(supplied_iter);
+ return NULL;
+}
+
/**
- * Implementation of init_config_t.select_proposal.
+ * Implementation of init_config_t.add_proposal.
*/
-static status_t select_proposal (private_init_config_t *this, ike_proposal_t *proposals, size_t proposal_count, ike_proposal_t *selected_proposal)
+static void add_proposal (private_init_config_t *this, proposal_t *proposal)
{
- iterator_t * my_iterator;
- int i;
- ike_proposal_t *my_current_proposal;
-
- my_iterator = this->proposals->create_iterator(this->proposals,TRUE);
+ this->proposals->insert_last(this->proposals, proposal);
+}
+/**
+ * Implementation of init_config_t.get_dh_group.
+ */
+static diffie_hellman_group_t get_dh_group(private_init_config_t *this)
+{
+ iterator_t *iterator;
+ proposal_t *proposal;
+ algorithm_t *algo;
- for (i = 0; i < proposal_count; i++)
+ iterator = this->proposals->create_iterator(this->proposals, TRUE);
+ while (iterator->has_next(iterator))
{
- my_iterator->reset(my_iterator);
- while (my_iterator->has_next(my_iterator))
+ iterator->current(iterator, (void**)&proposal);
+ proposal->get_algorithm(proposal, IKE, DIFFIE_HELLMAN_GROUP, &algo);
+ if (algo)
{
- my_iterator->current(my_iterator,(void **) &my_current_proposal);
-
- /* memcmp doesn't work here */
- if ((proposals[i].encryption_algorithm == my_current_proposal->encryption_algorithm) &&
- (proposals[i].encryption_algorithm_key_length == my_current_proposal->encryption_algorithm_key_length) &&
- (proposals[i].integrity_algorithm == my_current_proposal->integrity_algorithm) &&
- (proposals[i].integrity_algorithm_key_length == my_current_proposal->integrity_algorithm_key_length) &&
- (proposals[i].pseudo_random_function == my_current_proposal->pseudo_random_function) &&
- (proposals[i].pseudo_random_function_key_length == my_current_proposal->pseudo_random_function_key_length) &&
- (proposals[i].diffie_hellman_group == my_current_proposal->diffie_hellman_group))
- {
- /* found a matching proposal */
- *selected_proposal = *my_current_proposal;
- my_iterator->destroy(my_iterator);
- return SUCCESS;
- }
-
- }
+ iterator->destroy(iterator);
+ return algo->algorithm;
+ }
}
-
- my_iterator->destroy(my_iterator);
- return NOT_FOUND;
+ iterator->destroy(iterator);
+ return MODP_UNDEFINED;
}
/**
- * Implementation of init_config_t.destroy.
+ * Implementation of init_config_t.check_dh_group.
*/
-static void add_proposal (private_init_config_t *this,size_t priority, ike_proposal_t proposal)
+static bool check_dh_group(private_init_config_t *this, diffie_hellman_group_t dh_group)
{
- ike_proposal_t * new_proposal = allocator_alloc(sizeof(ike_proposal_t));
- status_t status;
-
- *new_proposal = proposal;
-
+ iterator_t *prop_iter, *alg_iter;
+ proposal_t *proposal;
+ algorithm_t *algo;
- if (priority > this->proposals->get_count(this->proposals))
+ prop_iter = this->proposals->create_iterator(this->proposals, TRUE);
+ while (prop_iter->has_next(prop_iter))
{
- this->proposals->insert_last(this->proposals,new_proposal);
- return;
+ prop_iter->current(prop_iter, (void**)&proposal);
+ alg_iter = proposal->create_algorithm_iterator(proposal, IKE, DIFFIE_HELLMAN_GROUP);
+ while (alg_iter->has_next(alg_iter))
+ {
+ alg_iter->current(alg_iter, (void**)&algo);
+ if (algo->algorithm == dh_group)
+ {
+ prop_iter->destroy(prop_iter);
+ alg_iter->destroy(alg_iter);
+ return TRUE;
+ }
+ }
}
-
- status = this->proposals->insert_at_position(this->proposals,(priority - 1),new_proposal);
-
+ prop_iter->destroy(prop_iter);
+ alg_iter->destroy(alg_iter);
+ return FALSE;
}
/**
*/
static void destroy (private_init_config_t *this)
{
- ike_proposal_t *proposal;
+ proposal_t *proposal;
- while (this->proposals->get_count(this->proposals) > 0)
+ while (this->proposals->remove_last(this->proposals, (void**)&proposal) == SUCCESS)
{
- this->proposals->remove_first(this->proposals,(void **) &proposal);
- allocator_free(proposal);
+ proposal->destroy(proposal);
}
this->proposals->destroy(this->proposals);
this->public.get_other_host = (host_t*(*)(init_config_t*))get_other_host;
this->public.get_my_host_clone = (host_t*(*)(init_config_t*))get_my_host_clone;
this->public.get_other_host_clone = (host_t*(*)(init_config_t*))get_other_host_clone;
- this->public.get_dh_group_number = (diffie_hellman_group_t (*)(init_config_t*,size_t))get_dh_group_number;
- this->public.get_proposals = (size_t(*)(init_config_t*,ike_proposal_t**))get_proposals;
- this->public.select_proposal = (status_t(*)(init_config_t*,ike_proposal_t*,size_t,ike_proposal_t*))select_proposal;
- this->public.add_proposal = (void(*)(init_config_t*, size_t, ike_proposal_t)) add_proposal;
+ this->public.get_proposals = (linked_list_t*(*)(init_config_t*))get_proposals;
+ this->public.select_proposal = (proposal_t*(*)(init_config_t*,linked_list_t*))select_proposal;
+ this->public.add_proposal = (void(*)(init_config_t*, proposal_t*)) add_proposal;
+ this->public.get_dh_group = (diffie_hellman_group_t(*)(init_config_t*)) get_dh_group;
+ this->public.check_dh_group = (bool(*)(init_config_t*,diffie_hellman_group_t)) check_dh_group;
this->public.destroy = (void(*)(init_config_t*))destroy;
/* private variables */
#include <types.h>
#include <network/host.h>
-#include <utils/iterator.h>
+#include <utils/linked_list.h>
+#include <config/proposal.h>
#include <transforms/crypters/crypter.h>
#include <transforms/prfs/prf.h>
#include <transforms/signers/signer.h>
#include <transforms/diffie_hellman.h>
-typedef struct ike_proposal_t ike_proposal_t;
-
-/**
- * @brief Represents a Proposal used in IKE_SA_INIT phase.
- *
- * @todo Currently the amount of tranforms with same type in a IKE proposal is limited to 1.
- * Support of more transforms with same type has to be added.
- *
- * @ingroup config
- */
-struct ike_proposal_t {
- /**
- * Encryption algorithm.
- */
- encryption_algorithm_t encryption_algorithm;
-
- /**
- * Key length of encryption algorithm in bytes.
- */
- u_int16_t encryption_algorithm_key_length;
-
- /**
- * Integrity algorithm.
- */
- integrity_algorithm_t integrity_algorithm;
-
- /**
- * Key length of integrity algorithm.
- */
- u_int16_t integrity_algorithm_key_length;
-
- /**
- * Pseudo random function (prf).
- */
- pseudo_random_function_t pseudo_random_function;
-
- /**
- * Key length of prf.
- */
- u_int16_t pseudo_random_function_key_length;
-
- /**
- * Diffie hellman group.
- */
- diffie_hellman_group_t diffie_hellman_group;
-};
-
typedef struct init_config_t init_config_t;
* @param this calling object
* @return host information as host_t object
*/
- host_t * (*get_my_host) (init_config_t *this);
+ host_t *(*get_my_host) (init_config_t *this);
/**
* @brief Get other host information as host_t object.
* @param this calling object
* @return host information as host_t object
*/
- host_t * (*get_other_host) (init_config_t *this);
+ host_t *(*get_other_host) (init_config_t *this);
/**
* @brief Get my host information as host_t object.
* @param this calling object
* @return host information as host_t object
*/
- host_t * (*get_my_host_clone) (init_config_t *this);
+ host_t *(*get_my_host_clone) (init_config_t *this);
/**
* @brief Get other host information as host_t object.
* @param this calling object
* @return host information as host_t object
*/
- host_t * (*get_other_host_clone) (init_config_t *this);
+ host_t *(*get_other_host_clone) (init_config_t *this);
/**
- * @brief Get the diffie hellman group to use as initiator with given priority.
+ * @brief Returns a list of all supported proposals.
*
- * @param this calling object
- * @param priority priority of dh group number (starting at 1)
- * @return diffie hellman group number for given priority or
- * MODP_UNDEFINED for not supported priorities
- */
- diffie_hellman_group_t (*get_dh_group_number) (init_config_t *this,size_t priority);
-
- /**
- * @brief Returns a list of all supported ike_proposals of type ike_proposal_t *.
- *
- * Returned array of ike_proposal_t has to get destroyed by the caller.
+ * Returned list is still owned by init_config and MUST NOT
+ * modified or destroyed.
*
* @param this calling object
- * @param proposals first proposal in a array
- * @return number of proposals in array
+ * @return list containing all the proposals
*/
- size_t (*get_proposals) (init_config_t *this,ike_proposal_t **proposals);
+ linked_list_t *(*get_proposals) (init_config_t *this);
/**
- * @brief Adds a proposal with given priority to the current stored proposals.
+ * @brief Adds a proposal to the list..
*
- * If allready a proposal with given priority is stored the other one is
- * moved one priority back. If priority is higher then all other stored
- * proposals, it is inserted as last one.
+ * The first added proposal has the highest priority, the last
+ * added the lowest.
*
* @param this calling object
* @param priority priority of adding proposal
* @param proposal proposal to add
*/
- void (*add_proposal) (init_config_t *this,size_t priority, ike_proposal_t proposal);
+ void (*add_proposal) (init_config_t *this, proposal_t *proposal);
/**
* @brief Select a proposed from suggested proposals.
*
+ * Returned proposal must be destroyed after usage.
+ *
+ * @param this calling object
+ * @param proposals list of proposals to select from
+ * @return selected proposal, or NULL if none matches.
+ */
+ proposal_t *(*select_proposal) (init_config_t *this, linked_list_t *proposals);
+
+ /**
+ * @brief Get the DH group to use for connection initialization.
+ *
+ * @param this calling object
+ * @return dh group to use for initialization
+ */
+ diffie_hellman_group_t (*get_dh_group) (init_config_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
- * @param suggested_proposals first proposal in a array
- * @param proposal_count number of suggested proposals in array
- * @param selected_proposal the ike_proposal_t pointing to is set
- * @return
- * - SUCCESS if a proposal was selected
- * - NOT_FOUND if none of suggested proposals is supported
+ * @return dh group to use for initialization
*/
- status_t (*select_proposal) (init_config_t *this, ike_proposal_t *proposals, size_t proposal_count, ike_proposal_t *selected_proposal);
+ bool (*check_dh_group) (init_config_t *this, diffie_hellman_group_t dh_group);
/**
* @brief Destroys a init_config_t object.
*
* @ingroup config
*/
-init_config_t * init_config_create(char * my_ip, char *other_ip, u_int16_t my_port, u_int16_t other_port);
+init_config_t * init_config_create(char *my_ip, char *other_ip, u_int16_t my_port, u_int16_t other_port);
#endif //_INIT_CONFIG_H_
/**
- * @file child_proposal.c
+ * @file proposal.c
*
- * @brief Implementation of child_proposal_t.
+ * @brief Implementation of proposal_t.
*
*/
* for more details.
*/
-#include "child_proposal.h"
+#include "proposal.h"
#include <utils/linked_list.h>
#include <utils/allocator.h>
};
-typedef struct private_child_proposal_t private_child_proposal_t;
+typedef struct private_proposal_t private_proposal_t;
/**
- * Private data of an child_proposal_t object
+ * Private data of an proposal_t object
*/
-struct private_child_proposal_t {
+struct private_proposal_t {
/**
* Public part
*/
- child_proposal_t public;
+ proposal_t public;
/**
* number of this proposal, as used in the payload
/**
* Look up a protocol_proposal, or create one if necessary...
*/
-static protocol_proposal_t *get_protocol_proposal(private_child_proposal_t *this, protocol_id_t proto, bool create)
+static protocol_proposal_t *get_protocol_proposal(private_proposal_t *this, protocol_id_t proto, bool create)
{
protocol_proposal_t *proto_proposal = NULL, *current_proto_proposal;;
iterator_t *iterator;
}
/**
- * Implements child_proposal_t.add_algorithm
+ * Implements proposal_t.add_algorithm
*/
-static void add_algorithm(private_child_proposal_t *this, protocol_id_t proto, transform_type_t type, u_int16_t algo, size_t key_size)
+static void add_algorithm(private_proposal_t *this, protocol_id_t proto, transform_type_t type, u_int16_t algo, size_t key_size)
{
protocol_proposal_t *proto_proposal = get_protocol_proposal(this, proto, TRUE);
}
/**
- * Implements child_proposal_t.get_algorithm.
+ * Implements proposal_t.get_algorithm.
*/
-static bool get_algorithm(private_child_proposal_t *this, protocol_id_t proto, transform_type_t type, algorithm_t** algo)
+static bool get_algorithm(private_proposal_t *this, protocol_id_t proto, transform_type_t type, algorithm_t** algo)
{
linked_list_t * list;
protocol_proposal_t *proto_proposal = get_protocol_proposal(this, proto, FALSE);
}
/**
- * Implements child_proposal_t.create_algorithm_iterator.
+ * Implements proposal_t.create_algorithm_iterator.
*/
-static iterator_t *create_algorithm_iterator(private_child_proposal_t *this, protocol_id_t proto, transform_type_t type)
+static iterator_t *create_algorithm_iterator(private_proposal_t *this, protocol_id_t proto, transform_type_t type)
{
protocol_proposal_t *proto_proposal = get_protocol_proposal(this, proto, FALSE);
if (proto_proposal == NULL)
}
/**
- * Implements child_proposal_t.select.
+ * Implements proposal_t.select.
*/
-static child_proposal_t *select_proposal(private_child_proposal_t *this, private_child_proposal_t *other)
+static proposal_t *select_proposal(private_proposal_t *this, private_proposal_t *other)
{
- child_proposal_t *selected;
+ proposal_t *selected;
u_int16_t algo;
size_t key_size;
iterator_t *iterator;
return NULL;
}
- selected = child_proposal_create(this->number);
+ selected = proposal_create(this->number);
/* iterate over supplied proposals */
iterator = other->protocol_proposals->create_iterator(other->protocol_proposals, TRUE);
}
/**
- * Implements child_proposal_t.get_number.
+ * Implements proposal_t.get_number.
*/
-static u_int8_t get_number(private_child_proposal_t *this)
+static u_int8_t get_number(private_proposal_t *this)
{
return this->number;
}
/**
- * Implements child_proposal_t.get_protocols.
+ * Implements proposal_t.get_protocols.
*/
-static void get_protocols(private_child_proposal_t *this, protocol_id_t ids[2])
+static void get_protocols(private_proposal_t *this, protocol_id_t ids[2])
{
iterator_t *iterator = this->protocol_proposals->create_iterator(this->protocol_proposals, TRUE);
u_int i = 0;
}
/**
- * Implements child_proposal_t.set_spi.
+ * Implements proposal_t.set_spi.
*/
-static void set_spi(private_child_proposal_t *this, protocol_id_t proto, u_int64_t spi)
+static void set_spi(private_proposal_t *this, protocol_id_t proto, u_int64_t spi)
{
protocol_proposal_t *proto_proposal = get_protocol_proposal(this, proto, FALSE);
if (proto_proposal)
}
/**
- * Implements child_proposal_t.get_spi.
+ * Implements proposal_t.get_spi.
*/
-static u_int64_t get_spi(private_child_proposal_t *this, protocol_id_t proto)
+static u_int64_t get_spi(private_proposal_t *this, protocol_id_t proto)
{
protocol_proposal_t *proto_proposal = get_protocol_proposal(this, proto, FALSE);
if (proto_proposal)
}
/**
- * Implements child_proposal_t.destroy.
+ * Implements proposal_t.destroy.
*/
-static void destroy(private_child_proposal_t *this)
+static void destroy(private_proposal_t *this)
{
while(this->protocol_proposals->get_count(this->protocol_proposals) > 0)
{
/*
* Describtion in header-file
*/
-child_proposal_t *child_proposal_create(u_int8_t number)
+proposal_t *proposal_create(u_int8_t number)
{
- private_child_proposal_t *this = allocator_alloc_thing(private_child_proposal_t);
+ private_proposal_t *this = allocator_alloc_thing(private_proposal_t);
- this->public.add_algorithm = (void (*)(child_proposal_t*,protocol_id_t,transform_type_t,u_int16_t,size_t))add_algorithm;
- this->public.create_algorithm_iterator = (iterator_t* (*)(child_proposal_t*,protocol_id_t,transform_type_t))create_algorithm_iterator;
- this->public.get_algorithm = (bool (*)(child_proposal_t*,protocol_id_t,transform_type_t,algorithm_t**))get_algorithm;
- this->public.select = (child_proposal_t* (*)(child_proposal_t*,child_proposal_t*))select_proposal;
- this->public.get_number = (u_int8_t (*)(child_proposal_t*))get_number;
- this->public.get_protocols = (void(*)(child_proposal_t *this, protocol_id_t ids[2]))get_protocols;
- this->public.set_spi = (void(*)(child_proposal_t*,protocol_id_t,u_int64_t spi))set_spi;
- this->public.get_spi = (u_int64_t(*)(child_proposal_t*,protocol_id_t))get_spi;
- this->public.destroy = (void(*)(child_proposal_t*))destroy;
+ this->public.add_algorithm = (void (*)(proposal_t*,protocol_id_t,transform_type_t,u_int16_t,size_t))add_algorithm;
+ this->public.create_algorithm_iterator = (iterator_t* (*)(proposal_t*,protocol_id_t,transform_type_t))create_algorithm_iterator;
+ this->public.get_algorithm = (bool (*)(proposal_t*,protocol_id_t,transform_type_t,algorithm_t**))get_algorithm;
+ this->public.select = (proposal_t* (*)(proposal_t*,proposal_t*))select_proposal;
+ this->public.get_number = (u_int8_t (*)(proposal_t*))get_number;
+ this->public.get_protocols = (void(*)(proposal_t *this, protocol_id_t ids[2]))get_protocols;
+ this->public.set_spi = (void(*)(proposal_t*,protocol_id_t,u_int64_t spi))set_spi;
+ this->public.get_spi = (u_int64_t(*)(proposal_t*,protocol_id_t))get_spi;
+ this->public.destroy = (void(*)(proposal_t*))destroy;
/* init private members*/
this->number = number;
/**
- * @file child_proposal.h
+ * @file proposal.h
*
- * @brief Interface of child_proposal_t.
+ * @brief Interface of proposal_t.
*
*/
* for more details.
*/
-#ifndef _CHILD_PROPOSAL_H_
-#define _CHILD_PROPOSAL_H_
+#ifndef _PROPOSAL_H_
+#define _PROPOSAL_H_
#include <types.h>
#include <utils/identification.h>
u_int16_t key_size;
};
-typedef struct child_proposal_t child_proposal_t;
+typedef struct proposal_t proposal_t;
/**
* @brief Stores a proposal for a child SA.
*
- * A child_proposal may contain more than one algorithm
+ * A proposal may contain more than one algorithm
* of the same kind. ONE of them can be selected.
*
* @warning This class is NOT thread-save!
*
* @b Constructors:
- * - child_proposal_create()
+ * - proposal_create()
*
* @ingroup config
*/
-struct child_proposal_t {
+struct proposal_t {
/**
* @brief Add an algorithm to the proposal.
* @param alg identifier for algorithm
* @param key_size key size to use
*/
- void (*add_algorithm) (child_proposal_t *this, protocol_id_t proto, transform_type_t type, u_int16_t alg, size_t key_size);
+ void (*add_algorithm) (proposal_t *this, protocol_id_t proto, transform_type_t type, u_int16_t alg, size_t key_size);
/**
* @brief Get an iterator over algorithms for a specifc protocol/algo type.
* @param type kind of algorithm
* @return iterator over algorithms
*/
- iterator_t *(*create_algorithm_iterator) (child_proposal_t *this, protocol_id_t proto, transform_type_t type);
+ iterator_t *(*create_algorithm_iterator) (proposal_t *this, protocol_id_t proto, transform_type_t type);
/**
* @brief Get the algorithm for a type to use.
*
* If there are multiple algorithms, only the first is returned.
- * Result is still owned by child_proposal, do not modify!
+ * Result is still owned by proposal, do not modify!
*
* @param this calling object
* @param proto desired protocol
* @param[out] algo pointer which receives algorithm and key size
* @return TRUE if algorithm of this kind available
*/
- bool (*get_algorithm) (child_proposal_t *this, protocol_id_t proto, transform_type_t type, algorithm_t** algo);
+ bool (*get_algorithm) (proposal_t *this, protocol_id_t proto, transform_type_t type, algorithm_t** algo);
/**
* @brief Compare two proposal, and select a matching subset.
* - selected proposal, if possible
* - NULL, if proposals don't match
*/
- child_proposal_t *(*select) (child_proposal_t *this, child_proposal_t *other);
+ proposal_t *(*select) (proposal_t *this, proposal_t *other);
/**
* @brief Get the number set on construction.
* @param this calling object
* @return number
*/
- u_int8_t (*get_number) (child_proposal_t *this);
+ u_int8_t (*get_number) (proposal_t *this);
/**
* @brief Get the protocol ids in the proposals.
* @param this calling object
* @param ids array of protocol ids,
*/
- void (*get_protocols) (child_proposal_t *this, protocol_id_t ids[2]);
+ void (*get_protocols) (proposal_t *this, protocol_id_t ids[2]);
/**
* @brief Get the spi for a specific protocol.
* @param proto AH/ESP
* @return spi for proto
*/
- u_int64_t (*get_spi) (child_proposal_t *this, protocol_id_t proto);
+ u_int64_t (*get_spi) (proposal_t *this, protocol_id_t proto);
/**
* @brief Set the spi for a specific protocol.
* @param proto AH/ESP
* @param spi spi to set for proto
*/
- void (*set_spi) (child_proposal_t *this, protocol_id_t proto, u_int64_t spi);
+ void (*set_spi) (proposal_t *this, protocol_id_t proto, u_int64_t spi);
/**
* @brief Destroys the proposal object.
*
* @param this calling object
*/
- void (*destroy) (child_proposal_t *this);
+ void (*destroy) (proposal_t *this);
};
/**
* @brief Create a child proposal for AH and/or ESP.
*
* @param number number of the proposal, as in the payload
- * @return child_proposal_t object
+ * @return proposal_t object
*
* @ingroup config
*/
-child_proposal_t *child_proposal_create(u_int8_t number);
+proposal_t *proposal_create(u_int8_t number);
-#endif //_CHILD_PROPOSAL_H_
+#endif //_PROPOSAL_H_
/**
* Implementation of sa_config_t.select_proposal
*/
-static child_proposal_t *select_proposal(private_sa_config_t *this, linked_list_t *proposals)
+static proposal_t *select_proposal(private_sa_config_t *this, linked_list_t *proposals)
{
iterator_t *stored_iter, *supplied_iter;
- child_proposal_t *stored, *supplied, *selected;
+ proposal_t *stored, *supplied, *selected;
stored_iter = this->proposals->create_iterator(this->proposals, TRUE);
supplied_iter = proposals->create_iterator(proposals, TRUE);
/**
* Implementation of sa_config_t.add_proposal
*/
-static void add_proposal(private_sa_config_t *this, child_proposal_t *proposal)
+static void add_proposal(private_sa_config_t *this, proposal_t *proposal)
{
this->proposals->insert_last(this->proposals, (void*)proposal);
}
*/
static status_t destroy(private_sa_config_t *this)
{
- child_proposal_t *proposal;
+ proposal_t *proposal;
traffic_selector_t *traffic_selector;
this->public.get_traffic_selectors_responder = (size_t(*)(sa_config_t*,traffic_selector_t**[]))get_traffic_selectors_responder;
this->public.select_traffic_selectors_responder = (size_t(*)(sa_config_t*,traffic_selector_t*[],size_t,traffic_selector_t**[]))select_traffic_selectors_responder;
this->public.get_proposals = (linked_list_t*(*)(sa_config_t*))get_proposals;
- this->public.select_proposal = (child_proposal_t*(*)(sa_config_t*,linked_list_t*))select_proposal;
+ this->public.select_proposal = (proposal_t*(*)(sa_config_t*,linked_list_t*))select_proposal;
this->public.add_traffic_selector_initiator = (void(*)(sa_config_t*,traffic_selector_t*))add_traffic_selector_initiator;
this->public.add_traffic_selector_responder = (void(*)(sa_config_t*,traffic_selector_t*))add_traffic_selector_responder;
- this->public.add_proposal = (void(*)(sa_config_t*,child_proposal_t*))add_proposal;
+ this->public.add_proposal = (void(*)(sa_config_t*,proposal_t*))add_proposal;
this->public.destroy = (void(*)(sa_config_t*))destroy;
/* apply init values */
#include <transforms/signers/signer.h>
#include <transforms/diffie_hellman.h>
#include <config/traffic_selector.h>
-#include <config/child_proposal.h>
+#include <config/proposal.h>
* @param proposals list from from wich proposals are selected
* @return selected proposal, or NULL if nothing matches
*/
- child_proposal_t *(*select_proposal) (sa_config_t *this, linked_list_t *proposals);
+ proposal_t *(*select_proposal) (sa_config_t *this, linked_list_t *proposals);
/**
* @brief Add a traffic selector to the list for initiator.
* @param this calling object
* @param proposal proposal to add
*/
- void (*add_proposal) (sa_config_t *this, child_proposal_t *proposal);
+ void (*add_proposal) (sa_config_t *this, proposal_t *proposal);
/**
* @brief Destroys the config object
/**
* A send_queue_t instance.
*/
-
send_queue_t *send_queue;
/**
return FAILED;
}
- /* notify message types and data is not getting checked in here */
+ /* TODO: Check all kinds of notify */
+ if (this->notify_message_type == INVALID_KE_PAYLOAD)
+ {
+ /* check notification data */
+ diffie_hellman_group_t dh_group;
+ if (this->notification_data.len != 2)
+ {
+ return FAILED;
+ }
+ dh_group = ntohs(*((u_int16_t*)this->notification_data.ptr));
+ if (dh_group < MODP_1024_BIT || dh_group > MODP_8192_BIT)
+ {
+ return FAILED;
+ }
+ }
return SUCCESS;
}
}
/**
- * Implementation of proposal_substructure_t.add_to_child_proposal.
+ * Implementation of proposal_substructure_t.add_to_proposal.
*/
-void add_to_child_proposal(private_proposal_substructure_t *this, child_proposal_t *proposal)
+void add_to_proposal(private_proposal_substructure_t *this, proposal_t *proposal)
{
iterator_t *iterator = this->transforms->create_iterator(this->transforms, TRUE);
this->public.get_protocol_id = (u_int8_t (*) (proposal_substructure_t *)) get_protocol_id;
this->public.get_info_for_transform_type = (status_t (*) (proposal_substructure_t *,transform_type_t,u_int16_t *, u_int16_t *))get_info_for_transform_type;
this->public.set_is_last_proposal = (void (*) (proposal_substructure_t *,bool)) set_is_last_proposal;
- this->public.add_to_child_proposal = (void (*) (proposal_substructure_t*,child_proposal_t*))add_to_child_proposal;
+ this->public.add_to_proposal = (void (*) (proposal_substructure_t*,proposal_t*))add_to_proposal;
this->public.set_spi = (void (*) (proposal_substructure_t *,chunk_t))set_spi;
this->public.get_spi = (chunk_t (*) (proposal_substructure_t *)) get_spi;
this->public.get_transform_count = (size_t (*) (proposal_substructure_t *)) get_transform_count;
/*
* Described in header.
*/
-proposal_substructure_t *proposal_substructure_create_from_child_proposal(child_proposal_t *proposal, protocol_id_t proto)
+proposal_substructure_t *proposal_substructure_create_from_proposal(proposal_t *proposal, protocol_id_t proto)
{
private_proposal_substructure_t *this = (private_proposal_substructure_t*)proposal_substructure_create();
iterator_t *iterator;
#include <types.h>
#include <encoding/payloads/payload.h>
#include <encoding/payloads/transform_substructure.h>
-#include <config/child_proposal.h>
+#include <config/proposal.h>
#include <utils/linked_list.h>
*/
void (*set_spi) (proposal_substructure_t *this, chunk_t spi);
- void (*add_to_child_proposal) (proposal_substructure_t *this, child_proposal_t *proposal);
+ void (*add_to_proposal) (proposal_substructure_t *this, proposal_t *proposal);
/**
* @brief Clones an proposal_substructure_t object.
proposal_substructure_t *proposal_substructure_create();
/**
- * @brief Creates a proposal substructure from a child_proposal.
+ * @brief Creates a proposal substructure from a proposal.
*
* Since a child proposal may contain data for both AH and ESP,
* the protocol must be specified. If the proposal does not contain
*
* @ingroup payloads
*/
-proposal_substructure_t *proposal_substructure_create_from_child_proposal(child_proposal_t *proposal, protocol_id_t proto);
+proposal_substructure_t *proposal_substructure_create_from_proposal(proposal_t *proposal, protocol_id_t proto);
#endif /*PROPOSAL_SUBSTRUCTURE_H_*/
}
/**
- * Implementation of sa_payload_t.add_child_proposal.
+ * Implementation of sa_payload_t.add_proposal.
*/
-static void add_child_proposal(private_sa_payload_t *this, child_proposal_t *proposal)
+static void add_proposal(private_sa_payload_t *this, proposal_t *proposal)
{
proposal_substructure_t *substructure;
protocol_id_t proto[2];
{
if (proto[i] != UNDEFINED_PROTOCOL_ID)
{
- substructure = proposal_substructure_create_from_child_proposal(proposal, proto[i]);
+ substructure = proposal_substructure_create_from_proposal(proposal, proto[i]);
add_proposal_substructure(this, substructure);
}
}
}
-
/**
- * Implementation of sa_payload_t.get_ike_proposals.
+ * Implementation of sa_payload_t.get_proposals.
*/
-static status_t get_ike_proposals (private_sa_payload_t *this,ike_proposal_t ** proposals, size_t *proposal_count)
-{
- int found_ike_proposals = 0;
- int current_proposal_number = 0;
- iterator_t *iterator;
- ike_proposal_t *tmp_proposals;
-
- iterator = this->proposals->create_iterator(this->proposals,TRUE);
-
- /* first find out the number of ike proposals and check their number of transforms and
- * if the SPI is empty!*/
- while (iterator->has_next(iterator))
- {
- proposal_substructure_t *current_proposal;
- iterator->current(iterator,(void **)&(current_proposal));
- if (current_proposal->get_protocol_id(current_proposal) == IKE)
- {
- /* a ike proposal consists of an empty spi*/
- if (current_proposal->get_spi_size(current_proposal) != 0)
- {
- iterator->destroy(iterator);
- return FAILED;
- }
-
- found_ike_proposals++;
- }
- }
- iterator->reset(iterator);
-
- if (found_ike_proposals == 0)
- {
- iterator->destroy(iterator);
- return NOT_FOUND;
- }
-
- /* allocate memory to hold each proposal as ike_proposal_t */
-
- tmp_proposals = allocator_alloc(found_ike_proposals * sizeof(ike_proposal_t));
-
- /* create from each proposal_substructure a ike_proposal_t data area*/
- while (iterator->has_next(iterator))
- {
- proposal_substructure_t *current_proposal;
- iterator->current(iterator,(void **)&(current_proposal));
- if (current_proposal->get_protocol_id(current_proposal) == IKE)
- {
- bool encryption_algorithm_found = FALSE;
- bool integrity_algorithm_found = FALSE;
- bool pseudo_random_function_found = FALSE;
- bool diffie_hellman_group_found = FALSE;
- status_t status;
- iterator_t *transforms;
-
- transforms = current_proposal->create_transform_substructure_iterator(current_proposal,TRUE);
- while (transforms->has_next(transforms))
- {
- transform_substructure_t *current_transform;
- transforms->current(transforms,(void **)&(current_transform));
-
- switch (current_transform->get_transform_type(current_transform))
- {
- case ENCRYPTION_ALGORITHM:
- {
- tmp_proposals[current_proposal_number].encryption_algorithm = current_transform->get_transform_id(current_transform);
- status = current_transform->get_key_length(current_transform,&(tmp_proposals[current_proposal_number].encryption_algorithm_key_length));
- if (status == SUCCESS)
- {
- encryption_algorithm_found = TRUE;
- }
- break;
- }
- case INTEGRITY_ALGORITHM:
- {
- tmp_proposals[current_proposal_number].integrity_algorithm = current_transform->get_transform_id(current_transform);
- status = current_transform->get_key_length(current_transform,&(tmp_proposals[current_proposal_number].integrity_algorithm_key_length));
- if (status == SUCCESS)
- {
- integrity_algorithm_found = TRUE;
- }
- break;
- }
- case PSEUDO_RANDOM_FUNCTION:
- {
- tmp_proposals[current_proposal_number].pseudo_random_function = current_transform->get_transform_id(current_transform);
- status = current_transform->get_key_length(current_transform,&(tmp_proposals[current_proposal_number].pseudo_random_function_key_length));
- if (status == SUCCESS)
- {
- pseudo_random_function_found = TRUE;
- }
- break;
- }
- case DIFFIE_HELLMAN_GROUP:
- {
- tmp_proposals[current_proposal_number].diffie_hellman_group = current_transform->get_transform_id(current_transform);
- diffie_hellman_group_found = TRUE;
- break;
- }
- default:
- {
- /* not a transform of an ike proposal. Break here */
- break;
- }
- }
-
- }
-
- transforms->destroy(transforms);
-
- if ((!encryption_algorithm_found) ||
- (!integrity_algorithm_found) ||
- (!pseudo_random_function_found) ||
- (!diffie_hellman_group_found))
- {
- /* one of needed transforms could not be found */
- iterator->reset(iterator);
- allocator_free(tmp_proposals);
- return FAILED;
- }
-
- current_proposal_number++;
- }
- }
-
- iterator->destroy(iterator);
-
- *proposals = tmp_proposals;
- *proposal_count = found_ike_proposals;
-
- return SUCCESS;
-}
-
-/**
- * Implementation of sa_payload_t.get_child_proposals.
- */
-static linked_list_t *get_child_proposals(private_sa_payload_t *this)
+static linked_list_t *get_proposals(private_sa_payload_t *this)
{
int proposal_struct_number = 0;
iterator_t *iterator;
- child_proposal_t *proposal;
+ proposal_t *proposal;
linked_list_t *proposal_list;
/* this list will hold our proposals */
proposal_list = linked_list_create();
- /* iterate over structures, one OR MORE structures will result in a child_proposal */
+ /* iterate over structures, one OR MORE structures will result in a proposal */
iterator = this->proposals->create_iterator(this->proposals,TRUE);
while (iterator->has_next(iterator))
{
{
/* here starts a new proposal, create a new one and add it to the list */
proposal_struct_number = proposal_struct->get_proposal_number(proposal_struct);
- proposal = child_proposal_create(proposal_struct_number);
+ proposal = proposal_create(proposal_struct_number);
proposal_list->insert_last(proposal_list, proposal);
}
/* proposal_substructure_t does the dirty work and builds up the proposal */
- proposal_struct->add_to_child_proposal(proposal_struct, proposal);
+ proposal_struct->add_to_proposal(proposal_struct, proposal);
}
iterator->destroy(iterator);
return proposal_list;
/* public functions */
this->public.create_proposal_substructure_iterator = (iterator_t* (*) (sa_payload_t *,bool)) create_proposal_substructure_iterator;
this->public.add_proposal_substructure = (void (*) (sa_payload_t *,proposal_substructure_t *)) add_proposal_substructure;
- this->public.get_ike_proposals = (status_t (*) (sa_payload_t *, ike_proposal_t **, size_t *)) get_ike_proposals;
- this->public.get_child_proposals = (linked_list_t* (*) (sa_payload_t *)) get_child_proposals;
+ this->public.get_proposals = (linked_list_t* (*) (sa_payload_t *)) get_proposals;
this->public.destroy = (void (*) (sa_payload_t *)) destroy;
/* private functions */
/*
* Described in header.
*/
-sa_payload_t *sa_payload_create_from_ike_proposals(ike_proposal_t *proposals, size_t proposal_count)
-{
- int i;
- sa_payload_t *sa_payload= sa_payload_create();
-
- for (i = 0; i < proposal_count; i++)
- {
- proposal_substructure_t *proposal_substructure;
- transform_substructure_t *encryption_algorithm;
- transform_substructure_t *integrity_algorithm;
- transform_substructure_t *pseudo_random_function;
- transform_substructure_t *diffie_hellman_group;
-
- /* create proposal substructure */
- proposal_substructure = proposal_substructure_create();
- proposal_substructure->set_protocol_id(proposal_substructure,IKE);
- proposal_substructure->set_proposal_number(proposal_substructure,(i + 1));
-
-
- /* create transform substructures to hold each specific transform for an ike proposal */
- encryption_algorithm = transform_substructure_create_type(ENCRYPTION_ALGORITHM,proposals[i].encryption_algorithm,proposals[i].encryption_algorithm_key_length);
- proposal_substructure->add_transform_substructure(proposal_substructure,encryption_algorithm);
-
- pseudo_random_function = transform_substructure_create_type(PSEUDO_RANDOM_FUNCTION,proposals[i].pseudo_random_function,proposals[i].pseudo_random_function_key_length);
- proposal_substructure->add_transform_substructure(proposal_substructure,pseudo_random_function);
-
- integrity_algorithm = transform_substructure_create_type(INTEGRITY_ALGORITHM,proposals[i].integrity_algorithm,proposals[i].integrity_algorithm_key_length);
- proposal_substructure->add_transform_substructure(proposal_substructure,integrity_algorithm);
-
- diffie_hellman_group = transform_substructure_create_type(DIFFIE_HELLMAN_GROUP,proposals[i].diffie_hellman_group,0);
- proposal_substructure->add_transform_substructure(proposal_substructure,diffie_hellman_group);
-
- /* add proposal to sa payload */
- sa_payload->add_proposal_substructure(sa_payload,proposal_substructure);
- }
-
- return sa_payload;
-}
-
-/*
- * Described in header.
- */
-sa_payload_t *sa_payload_create_from_child_proposal_list(linked_list_t *proposals)
+sa_payload_t *sa_payload_create_from_proposal_list(linked_list_t *proposals)
{
iterator_t *iterator;
- child_proposal_t *proposal;
+ proposal_t *proposal;
sa_payload_t *sa_payload = sa_payload_create();
/* add every payload from the list */
while (iterator->has_next(iterator))
{
iterator->current(iterator, (void**)&proposal);
- add_child_proposal((private_sa_payload_t*)sa_payload, proposal);
+ add_proposal((private_sa_payload_t*)sa_payload, proposal);
}
iterator->destroy(iterator);
/*
* Described in header.
*/
-sa_payload_t *sa_payload_create_from_child_proposal(child_proposal_t *proposal)
+sa_payload_t *sa_payload_create_from_proposal(proposal_t *proposal)
{
sa_payload_t *sa_payload = sa_payload_create();
- add_child_proposal((private_sa_payload_t*)sa_payload, proposal);
+ add_proposal((private_sa_payload_t*)sa_payload, proposal);
return sa_payload;
}
* @b Constructors:
* - sa_payload_create()
* - sa_payload_create_from_ike_proposals()
- * - sa_payload_create_from_child_proposal()
+ * - sa_payload_create_from_proposal()
*
- * @todo Add support of algorithms without specified keylength in get_child_proposals and get_ike_proposals.
+ * @todo Add support of algorithms without specified keylength in get_proposals and get_ike_proposals.
*
* @ingroup payloads
*/
* @param proposal proposal_substructure_t object to add
*/
void (*add_proposal_substructure) (sa_payload_t *this,proposal_substructure_t *proposal);
-
- /**
- * @brief Creates an array of ike_proposal_t's in this SA payload.
- *
- * An IKE proposal consist of transform of type ENCRYPTION_ALGORITHM,
- * PSEUDO_RANDOM_FUNCTION, INTEGRITY_ALGORITHM and DIFFIE_HELLMAN_GROUP
- *
- * @param proposals the pointer to the first entry of ike_proposal_t's is set
- * @param proposal_count the number of found proposals is written at this location
- * @return
- * - SUCCESS if an IKE proposal could be found
- * - NOT_FOUND if no IKE proposal could be found
- * - FAILED if a proposal does not contain all needed transforms
- * for a IKE_PROPOSAL
- */
- status_t (*get_ike_proposals) (sa_payload_t *this, ike_proposal_t **proposals, size_t *proposal_count);
-
+
/**
- * @brief Creates an array of child_proposal_t's in this SA payload.
+ * @brief Gets the proposals in this payload as a list.
*
- * @return a list containing child_proposal_t s
+ * @return a list containing proposal_t s
*/
- linked_list_t *(*get_child_proposals) (sa_payload_t *this);
+ linked_list_t *(*get_proposals) (sa_payload_t *this);
/**
* @brief Add a child proposal (AH/ESP) to the payload.
*
* @param proposal child proposal to add to the payload
*/
- void (*add_child_proposal) (sa_payload_t *this, child_proposal_t *proposal);
+ void (*add_proposal) (sa_payload_t *this, proposal_t *proposal);
/**
* @brief Destroys an sa_payload_t object.
sa_payload_t *sa_payload_create();
/**
- * @brief Creates a sa_payload_t object from array of ike_proposal_t's.
+ * @brief Creates a sa_payload_t object from a list of proposals.
*
- * @return created sa_payload_t object
- * @param proposals pointer to first proposal in array of type ike_proposal_t
- * @param proposal_count number of ike_proposal_t's in array
+ * @param proposals list of proposals to build the payload from
* @return sa_payload_t object
*
* @ingroup payloads
*/
-sa_payload_t *sa_payload_create_from_ike_proposals(ike_proposal_t *proposals, size_t proposal_count);
+sa_payload_t *sa_payload_create_from_proposal_list(linked_list_t *proposals);
-sa_payload_t *sa_payload_create_from_child_proposal_list(linked_list_t *proposals);
-
-sa_payload_t *sa_payload_create_from_child_proposal(child_proposal_t *proposal);
+/**
+ * @brief Creates a sa_payload_t object from a single proposal.
+ *
+ * This is only for convenience. Use sa_payload_create_from_proposal_list
+ * if you want to add more than one proposal.
+ *
+ * @param proposal proposal from which the payload should be built.
+ * @return sa_payload_t object
+ *
+ * @ingroup payloads
+ */
+sa_payload_t *sa_payload_create_from_proposal(proposal_t *proposal);
#endif /*SA_PAYLOAD_H_*/
#include <transforms/signers/signer.h>
#include <transforms/prfs/prf.h>
#include <transforms/crypters/crypter.h>
-#include <config/child_proposal.h>
+#include <config/proposal.h>
/**
id_payload_t *my_id,
bool initiator)
{
+ prf_t *prf;
chunk_t id_chunk = my_id->get_data(my_id);
u_int8_t id_with_header[4 + id_chunk.len];
/*
if (initiator)
{
- this->prf->set_key(this->prf,this->ike_sa->get_key_pi(this->ike_sa));
+ prf = this->ike_sa->get_prf_auth_i(this->ike_sa);
}
else
{
- this->prf->set_key(this->prf,this->ike_sa->get_key_pr(this->ike_sa));
+ prf = this->ike_sa->get_prf_auth_r(this->ike_sa);
}
-
/* 4 bytes are id type and reserved fields of id payload */
- octets.len = last_message.len + other_nonce.len + this->prf->get_block_size(this->prf);
+ octets.len = last_message.len + other_nonce.len + prf->get_block_size(prf);
octets.ptr = allocator_alloc(octets.len);
current_pos = octets.ptr;
memcpy(current_pos,last_message.ptr,last_message.len);
current_pos += last_message.len;
memcpy(current_pos,other_nonce.ptr,other_nonce.len);
current_pos += other_nonce.len;
- this->prf->get_bytes(this->prf,id_with_header_chunk,current_pos);
+ prf->get_bytes(prf, id_with_header_chunk, current_pos);
this->logger->log_chunk(this->logger,RAW | LEVEL2, "Octets (Mesage + Nonce + prf(Sk_px,Idx)",&octets);
return octets;
/*
* Described in header.
*/
-child_sa_t * child_sa_create(child_proposal_t *proposal, prf_plus_t *prf_plus)
+child_sa_t * child_sa_create(proposal_t *proposal, prf_plus_t *prf_plus)
{
private_child_sa_t *this = allocator_alloc_thing(private_child_sa_t);
u_int i;
* @return child_sa_t object
* @ingroup sa
*/
-child_sa_t * child_sa_create(child_proposal_t *proposal, prf_plus_t *prf_plus);
+child_sa_t * child_sa_create(proposal_t *proposal, prf_plus_t *prf_plus);
#endif /*_CHILD_SA_H_*/
* Protected part of a ike_sa_t object.
*/
protected_ike_sa_t protected;
-
- /**
- * Resends the last sent reply.
- *
- * @param this calling object
- */
- status_t (*resend_last_reply) (private_ike_sa_t *this);
-
- /* private values */
/**
* Identifier for the current IKE_SA.
/**
* Crypter object for initiator.
- *
- * Gets set in states:
- * - IKE_SA_INIT_REQUESTED
- * - RESPONDER_INIT
- *
- * Available in states:
- * - IKE_SA_INIT_RESPONDED
- * - IKE_AUTH_REQUESTED
- * -IKE_SA_ESTABLISHED
*/
crypter_t *crypter_initiator;
/**
* Crypter object for responder.
- *
- * Gets set in states:
- * - IKE_SA_INIT_REQUESTED
- * - RESPONDER_INIT
- *
- * Available in states:
- * - IKE_SA_INIT_RESPONDED
- * - IKE_AUTH_REQUESTED
- * -IKE_SA_ESTABLISHED
*/
crypter_t *crypter_responder;
/**
* Signer object for initiator.
- *
- * Gets set in states:
- * - IKE_SA_INIT_REQUESTED
- * - RESPONDER_INIT
- *
- * Available in states:
- * - IKE_SA_INIT_RESPONDED
- * - IKE_AUTH_REQUESTED
- * -IKE_SA_ESTABLISHED
*/
signer_t *signer_initiator;
/**
* Signer object for responder.
- *
- * Gets set in states:
- * - IKE_SA_INIT_REQUESTED
- * - RESPONDER_INIT
- *
- * Available in states:
- * - IKE_SA_INIT_RESPONDED
- * - IKE_AUTH_REQUESTED
- * -IKE_SA_ESTABLISHED
*/
signer_t *signer_responder;
/**
- * Prf function.
- *
- * Gets set in states:
- * - IKE_SA_INIT_REQUESTED
- * - RESPONDER_INIT
- *
- * Available in states:
- * - IKE_SA_INIT_RESPONDED
- * - IKE_AUTH_REQUESTED
- * -IKE_SA_ESTABLISHED
+ * Multi purpose prf, set key, use it, forget it
*/
prf_t *prf;
/**
* Prf function for derivating keymat child SAs
- *
- * Gets set in states:
- * - IKE_SA_INIT_REQUESTED
- * - RESPONDER_INIT
- *
- * Available in states:
- * - IKE_SA_INIT_RESPONDED
- * - IKE_AUTH_REQUESTED
- * -IKE_SA_ESTABLISHED
*/
prf_t *child_prf;
/**
- * Shared secrets which have to be stored.
- *
- * Are getting set in states:
- * - IKE_SA_INIT_REQUESTED
- * - RESPONDER_INIT
- *
- * Available in states:
- * - IKE_SA_INIT_RESPONDED
- * - IKE_AUTH_REQUESTED
- * -IKE_SA_ESTABLISHED
+ * PRF, with key set to pi_key, used for authentication
*/
- struct {
- /**
- * Key for generating auth payload (initiator)
- */
- chunk_t pi_key;
-
- /**
- * Key for generating auth payload (responder)
- */
- chunk_t pr_key;
+ prf_t *prf_auth_i;
- } secrets;
+ /**
+ * PRF, with key set to pr_key, used for authentication
+ */
+ prf_t *prf_auth_r;
/**
* Next message id to receive.
* A logger for this IKE_SA.
*/
logger_t *logger;
+
+ /**
+ * Resends the last sent reply.
+ *
+ * @param this calling object
+ */
+ status_t (*resend_last_reply) (private_ike_sa_t *this);
};
/**
return this->ike_sa_id;
}
-/**
- * Implementation of protected_ike_sa_t.compute_secrets.
- */
-static void compute_secrets(private_ike_sa_t *this,
- chunk_t dh_shared_secret,
- chunk_t initiator_nonce,
- chunk_t responder_nonce)
-{
- u_int8_t d_buffer[this->child_prf->get_block_size(this->child_prf)];
- chunk_t d_key = {ptr: d_buffer, len: sizeof(d_buffer)};
- u_int8_t ei_buffer[this->crypter_initiator->get_block_size(this->crypter_initiator)];
- chunk_t ei_key = {ptr: ei_buffer, len: sizeof(ei_buffer)};
- u_int8_t er_buffer[this->crypter_responder->get_block_size(this->crypter_responder)];
- chunk_t er_key = {ptr: er_buffer, len: sizeof(er_buffer)};
- u_int8_t ai_buffer[this->signer_initiator->get_key_size(this->signer_initiator)];
- chunk_t ai_key = {ptr: ai_buffer, len: sizeof(ai_buffer)};
- u_int8_t ar_buffer[this->signer_responder->get_key_size(this->signer_responder)];
- chunk_t ar_key = {ptr: ar_buffer, len: sizeof(ar_buffer)};
- u_int8_t concatenated_nonces_buffer[initiator_nonce.len + responder_nonce.len];
- chunk_t concatenated_nonces = {ptr: concatenated_nonces_buffer, len : sizeof(concatenated_nonces_buffer)};
- u_int8_t skeyseed_buffer[this->prf->get_block_size(this->prf)];
- chunk_t skeyseed = {ptr: skeyseed_buffer, len: sizeof(skeyseed_buffer)};
- u_int64_t initiator_spi;
- u_int64_t responder_spi;
- chunk_t prf_plus_seed;
- prf_plus_t *prf_plus;
-
- /* first is initiator */
- memcpy(concatenated_nonces.ptr,initiator_nonce.ptr,initiator_nonce.len);
- /* second is responder */
- memcpy(concatenated_nonces.ptr + initiator_nonce.len,responder_nonce.ptr,responder_nonce.len);
-
- this->logger->log_chunk(this->logger, RAW | LEVEL2, "Nonce data", &concatenated_nonces);
-
- /* Status of set_key is not checked */
- this->prf->set_key(this->prf,concatenated_nonces);
-
- this->prf->get_bytes(this->prf,dh_shared_secret,skeyseed_buffer);
-
- prf_plus_seed.len = (initiator_nonce.len + responder_nonce.len + 16);
- prf_plus_seed.ptr = allocator_alloc(prf_plus_seed.len);
-
- /* first is initiator */
- memcpy(prf_plus_seed.ptr,initiator_nonce.ptr,initiator_nonce.len);
- /* second is responder */
- memcpy(prf_plus_seed.ptr + initiator_nonce.len,responder_nonce.ptr,responder_nonce.len);
- /* third is initiator spi */
- initiator_spi = this->ike_sa_id->get_initiator_spi(this->ike_sa_id);
- memcpy(prf_plus_seed.ptr + initiator_nonce.len + responder_nonce.len,&initiator_spi,8);
- /* fourth is responder spi */
- responder_spi = this->ike_sa_id->get_responder_spi(this->ike_sa_id);
- memcpy(prf_plus_seed.ptr + initiator_nonce.len + responder_nonce.len + 8,&responder_spi,8);
-
- this->logger->log_chunk(this->logger, PRIVATE | LEVEL1, "Keyseed", &skeyseed);
- this->logger->log_chunk(this->logger, PRIVATE | LEVEL1, "PRF+ Seed", &prf_plus_seed);
-
- this->logger->log(this->logger, CONTROL | LEVEL2, "Set new key of prf object");
- this->prf->set_key(this->prf,skeyseed);
-
- this->logger->log(this->logger, CONTROL | LEVEL2, "Create new prf+ object");
- prf_plus = prf_plus_create(this->prf, prf_plus_seed);
- allocator_free_chunk(&prf_plus_seed);
-
-
- prf_plus->get_bytes(prf_plus,d_key.len,d_buffer);
- this->logger->log_chunk(this->logger, PRIVATE, "Sk_d secret", &(d_key));
- this->child_prf->set_key(this->child_prf, d_key);
-
- prf_plus->get_bytes(prf_plus,ai_key.len,ai_buffer);
- this->logger->log_chunk(this->logger, PRIVATE, "Sk_ai secret", &(ai_key));
- this->signer_initiator->set_key(this->signer_initiator,ai_key);
-
- prf_plus->get_bytes(prf_plus,ar_key.len,ar_buffer);
- this->logger->log_chunk(this->logger, PRIVATE, "Sk_ar secret", &(ar_key));
- this->signer_responder->set_key(this->signer_responder,ar_key);
-
- prf_plus->get_bytes(prf_plus,ei_key.len,ei_buffer);
- this->logger->log_chunk(this->logger, PRIVATE, "Sk_ei secret", &(ei_key));
- this->crypter_initiator->set_key(this->crypter_initiator,ei_key);
-
- prf_plus->get_bytes(prf_plus,er_key.len,er_buffer);
- this->logger->log_chunk(this->logger, PRIVATE, "Sk_er secret", &(er_key));
- this->crypter_responder->set_key(this->crypter_responder,er_key);
-
- prf_plus->allocate_bytes(prf_plus,
- this->crypter_responder->get_block_size(this->crypter_responder),
- &(this->secrets.pi_key));
- this->logger->log_chunk(this->logger, PRIVATE, "Sk_pi secret", &(this->secrets.pi_key));
-
- prf_plus->allocate_bytes(prf_plus,
- this->crypter_responder->get_block_size(this->crypter_responder),
- &(this->secrets.pr_key));
- this->logger->log_chunk(this->logger, PRIVATE, "Sk_pr secret", &(this->secrets.pr_key));
-
- prf_plus->destroy(prf_plus);
-}
-
/**
* Implementation of private_ike_sa_t.resend_last_reply.
*/
}
/**
- * Implementation of protected_ike_sa_t.get_key_pr.
+ * Implementation of protected_ike_sa_t.get_prf_auth_i.
*/
-static chunk_t get_key_pr (private_ike_sa_t *this)
+static prf_t *get_prf_auth_i (private_ike_sa_t *this)
{
- return this->secrets.pr_key;
+ return this->prf_auth_i;
}
-
/**
- * Implementation of protected_ike_sa_t.get_key_pi.
+ * Implementation of protected_ike_sa_t.get_prf_auth_r.
*/
-static chunk_t get_key_pi (private_ike_sa_t *this)
+static prf_t *get_prf_auth_r (private_ike_sa_t *this)
{
- return this->secrets.pi_key;
+ return this->prf_auth_r;
}
+
/**
- * Implementation of protected_ike_sa_t.set_prf.
+ * Implementation of protected_ike_sa_t.build_transforms.
*/
-static status_t create_transforms_from_proposal (private_ike_sa_t *this,ike_proposal_t *proposal)
+static status_t build_transforms(private_ike_sa_t *this, proposal_t *proposal, diffie_hellman_t *dh, chunk_t nonce_i, chunk_t nonce_r)
{
- this->logger->log(this->logger, CONTROL|LEVEL2, "Going to create transform objects for proposal");
-
- this->logger->log(this->logger, CONTROL|LEVEL2, "Encryption algorithm: %s with keylength %d",
- mapping_find(encryption_algorithm_m,proposal->encryption_algorithm),
- proposal->encryption_algorithm_key_length);
- this->logger->log(this->logger, CONTROL|LEVEL2, "Integrity algorithm: %s with keylength %d",
- mapping_find(integrity_algorithm_m,proposal->integrity_algorithm),
- proposal->integrity_algorithm_key_length);
- this->logger->log(this->logger, CONTROL|LEVEL2, "PRF: %s with keylength %d",
- mapping_find(pseudo_random_function_m,proposal->pseudo_random_function),
- proposal->pseudo_random_function_key_length);
+ chunk_t nonces, nonces_spis, skeyseed, key, secret;
+ u_int64_t spi_i, spi_r;
+ prf_plus_t *prf_plus;
+ algorithm_t *algo;
+ size_t key_size;
+ /*
+ * Build the PRF+ instance for deriving keys
+ */
if (this->prf != NULL)
{
this->prf->destroy(this->prf);
}
- this->prf = prf_create(proposal->pseudo_random_function);
- if (this->prf == NULL)
+ proposal->get_algorithm(proposal, IKE, PSEUDO_RANDOM_FUNCTION, &algo);
+ if (algo == NULL)
{
- this->logger->log(this->logger, ERROR|LEVEL1, "PRF %s not supported!",
- mapping_find(pseudo_random_function_m,proposal->pseudo_random_function));
+ this->logger->log(this->logger, ERROR|LEVEL2, "No PRF algoithm selected!?");
return FAILED;
}
- this->child_prf = prf_create(proposal->pseudo_random_function);
- if (this->child_prf == NULL)
+ this->prf = prf_create(algo->algorithm);
+ if (this->prf == NULL)
{
- this->logger->log(this->logger, ERROR|LEVEL1, "PRF %s not supported!",
- mapping_find(pseudo_random_function_m,proposal->pseudo_random_function));
+ this->logger->log(this->logger, ERROR|LEVEL1,
+ "PSEUDO_RANDOM_FUNCTION %s not supported!",
+ mapping_find(pseudo_random_function_m, algo->algorithm));
return FAILED;
}
- if (this->crypter_initiator != NULL)
+ /* concatenate nonces = nonce_i | nonce_r */
+ nonces = allocator_alloc_as_chunk(nonce_i.len + nonce_r.len);
+ memcpy(nonces.ptr, nonce_i.ptr, nonce_i.len);
+ memcpy(nonces.ptr + nonce_i.len, nonce_r.ptr, nonce_r.len);
+
+ /* concatenate prf_seed = nonce_i | nonce_r | spi_i | spi_r */
+ nonces_spis = allocator_alloc_as_chunk(nonces.len + 16);
+ memcpy(nonces_spis.ptr, nonces.ptr, nonces.len);
+ spi_i = this->ike_sa_id->get_initiator_spi(this->ike_sa_id);
+ spi_r = this->ike_sa_id->get_responder_spi(this->ike_sa_id);
+ memcpy(nonces_spis.ptr + nonces.len, &spi_i, 8);
+ memcpy(nonces_spis.ptr + nonces.len + 8, &spi_r, 8);
+
+ /* SKEYSEED = prf(Ni | Nr, g^ir) */
+ dh->get_shared_secret(dh, &secret);
+ this->logger->log_chunk(this->logger, PRIVATE, "Shared Diffie Hellman secret", &secret);
+ this->prf->set_key(this->prf, nonces);
+ this->prf->allocate_bytes(this->prf, secret, &skeyseed);
+ this->logger->log_chunk(this->logger, PRIVATE | LEVEL1, "SKEYSEED", &skeyseed);
+ allocator_free_chunk(&secret);
+
+ /* prf+ (SKEYSEED, Ni | Nr | SPIi | SPIr )
+ * = SK_d | SK_ai | SK_ar | SK_ei | SK_er | SK_pi | SK_pr
+ *
+ * we use the prf directly for prf+
+ */
+ this->prf->set_key(this->prf, skeyseed);
+ prf_plus = prf_plus_create(this->prf, nonces_spis);
+
+ /* clean up unused stuff */
+ allocator_free_chunk(&nonces);
+ allocator_free_chunk(&nonces_spis);
+ allocator_free_chunk(&skeyseed);
+
+
+ /*
+ * We now can derive all of our key. We build the transforms
+ * directly.
+ */
+
+
+ /* SK_d used for prf+ to derive keys for child SAs */
+ this->child_prf = prf_create(algo->algorithm);
+ key_size = this->child_prf->get_key_size(this->child_prf);
+ prf_plus->allocate_bytes(prf_plus, key_size, &key);
+ this->logger->log_chunk(this->logger, PRIVATE, "Sk_d secret", &key);
+ this->child_prf->set_key(this->child_prf, key);
+ allocator_free_chunk(&key);
+
+
+ /* SK_ai/SK_ar used for integrity protection */
+ proposal->get_algorithm(proposal, IKE, INTEGRITY_ALGORITHM, &algo);
+ if (algo == NULL)
{
- this->crypter_initiator->destroy(this->crypter_initiator);
+ this->logger->log(this->logger, ERROR|LEVEL2, "No integrity algoithm selected?!");
+ return FAILED;
}
- this->crypter_initiator = crypter_create(proposal->encryption_algorithm,
- proposal->encryption_algorithm_key_length);
- if (this->crypter_initiator == NULL)
+ if (this->signer_initiator != NULL)
+ {
+ this->signer_initiator->destroy(this->signer_initiator);
+ }
+ if (this->signer_responder != NULL)
{
- this->logger->log(this->logger, ERROR|LEVEL1, "Encryption algorithm %s not supported!",
- mapping_find(encryption_algorithm_m,proposal->encryption_algorithm));
+ this->signer_responder->destroy(this->signer_responder);
+ }
+
+ this->signer_initiator = signer_create(algo->algorithm);
+ this->signer_responder = signer_create(algo->algorithm);
+ if (this->signer_initiator == NULL || this->signer_responder == NULL)
+ {
+ this->logger->log(this->logger, ERROR|LEVEL1,
+ "INTEGRITY_ALGORITHM %s not supported!",
+ mapping_find(integrity_algorithm_m,algo->algorithm));
return FAILED;
}
+ key_size = this->signer_initiator->get_key_size(this->signer_initiator);
+
+ prf_plus->allocate_bytes(prf_plus, key_size, &key);
+ this->logger->log_chunk(this->logger, PRIVATE, "Sk_ai secret", &key);
+ this->signer_initiator->set_key(this->signer_initiator, key);
+ allocator_free_chunk(&key);
+ prf_plus->allocate_bytes(prf_plus, key_size, &key);
+ this->logger->log_chunk(this->logger, PRIVATE, "Sk_ar secret", &key);
+ this->signer_responder->set_key(this->signer_responder, key);
+ allocator_free_chunk(&key);
+
+
+ /* SK_ei/SK_er used for encryption */
+ proposal->get_algorithm(proposal, IKE, ENCRYPTION_ALGORITHM, &algo);
+ if (algo == NULL)
+ {
+ this->logger->log(this->logger, ERROR|LEVEL2, "No encryption algoithm selected!?");
+ return FAILED;
+ }
+ if (this->crypter_initiator != NULL)
+ {
+ this->crypter_initiator->destroy(this->crypter_initiator);
+ }
if (this->crypter_responder != NULL)
{
this->crypter_responder->destroy(this->crypter_responder);
}
- this->crypter_responder = crypter_create(proposal->encryption_algorithm,
- proposal->encryption_algorithm_key_length);
- /* check must not be done again */
- if (this->signer_initiator != NULL)
+ this->crypter_initiator = crypter_create(algo->algorithm, algo->key_size);
+ this->crypter_responder = crypter_create(algo->algorithm, algo->key_size);
+ if (this->crypter_initiator == NULL || this->crypter_responder == NULL)
{
- this->signer_initiator->destroy(this->signer_initiator);
- }
- this->signer_initiator = signer_create(proposal->integrity_algorithm);
- if (this->signer_initiator == NULL)
- {
- this->logger->log(this->logger, ERROR|LEVEL1, "Integrity algorithm %s not supported!",
- mapping_find(integrity_algorithm_m,proposal->integrity_algorithm));
+ this->logger->log(this->logger, ERROR|LEVEL1,
+ "ENCRYPTION_ALGORITHM %s (key size %d) not supported!",
+ mapping_find(encryption_algorithm_m, algo->algorithm),
+ algo->key_size);
return FAILED;
}
+ key_size = this->crypter_initiator->get_key_size(this->crypter_initiator);
- if (this->signer_responder != NULL)
+ prf_plus->allocate_bytes(prf_plus, key_size, &key);
+ this->logger->log_chunk(this->logger, PRIVATE, "Sk_ei secret", &key);
+ this->crypter_initiator->set_key(this->crypter_initiator, key);
+ allocator_free_chunk(&key);
+
+ prf_plus->allocate_bytes(prf_plus, key_size, &key);
+ this->logger->log_chunk(this->logger, PRIVATE, "Sk_er secret", &key);
+ this->crypter_responder->set_key(this->crypter_responder, key);
+ allocator_free_chunk(&key);
+
+ /* SK_pi/SK_pr used for authentication */
+ proposal->get_algorithm(proposal, IKE, PSEUDO_RANDOM_FUNCTION, &algo);
+ if (this->prf_auth_i != NULL)
{
- this->signer_responder->destroy(this->signer_responder);
+ this->prf_auth_i->destroy(this->prf_auth_i);
}
- this->signer_responder = signer_create(proposal->integrity_algorithm);
-
+ if (this->prf_auth_r != NULL)
+ {
+ this->prf_auth_r->destroy(this->prf_auth_r);
+ }
+
+ this->prf_auth_i = prf_create(algo->algorithm);
+ this->prf_auth_r = prf_create(algo->algorithm);
+
+ key_size = this->prf_auth_i->get_key_size(this->prf_auth_i);
+ prf_plus->allocate_bytes(prf_plus, key_size, &key);
+ this->logger->log_chunk(this->logger, PRIVATE, "Sk_pi secret", &key);
+ this->prf_auth_i->set_key(this->prf_auth_i, key);
+ allocator_free_chunk(&key);
+
+ prf_plus->allocate_bytes(prf_plus, key_size, &key);
+ this->logger->log_chunk(this->logger, PRIVATE, "Sk_pr secret", &key);
+ this->prf_auth_r->set_key(this->prf_auth_r, key);
+ allocator_free_chunk(&key);
+
+ /* all done, prf_plus not needed anymore */
+ prf_plus->destroy(prf_plus);
+
return SUCCESS;
}
/* destroy child sa */
}
this->child_sas->destroy(this->child_sas);
-
- this->logger->log(this->logger, CONTROL | LEVEL3, "Destroy secrets");
- allocator_free(this->secrets.pi_key.ptr);
- allocator_free(this->secrets.pr_key.ptr);
if (this->crypter_initiator != NULL)
{
this->logger->log(this->logger, CONTROL | LEVEL3, "Destroy child_prf object");
this->child_prf->destroy(this->child_prf);
}
+ if (this->prf_auth_i != NULL)
+ {
+ this->prf_auth_i->destroy(this->prf_auth_i);
+ }
+ if (this->prf_auth_r != NULL)
+ {
+ this->prf_auth_r->destroy(this->prf_auth_r);
+ }
/* destroy ike_sa_id */
this->logger->log(this->logger, CONTROL | LEVEL3, "Destroy ike_sa_id object");
/* protected functions */
this->protected.build_message = (void (*) (protected_ike_sa_t *, exchange_type_t , bool , message_t **)) build_message;
- this->protected.compute_secrets = (void (*) (protected_ike_sa_t *,chunk_t ,chunk_t , chunk_t )) compute_secrets;
this->protected.get_prf = (prf_t *(*) (protected_ike_sa_t *)) get_prf;
- this->protected.get_child_prf = (prf_t *(*) (protected_ike_sa_t *)) get_child_prf;
- this->protected.get_key_pr = (chunk_t (*) (protected_ike_sa_t *)) get_key_pr;
- this->protected.get_key_pi = (chunk_t (*) (protected_ike_sa_t *)) get_key_pi;
+ this->protected.get_child_prf = (prf_t *(*) (protected_ike_sa_t *)) get_child_prf;
+ this->protected.get_prf_auth_i = (prf_t *(*) (protected_ike_sa_t *)) get_prf_auth_i;
+ this->protected.get_prf_auth_r = (prf_t *(*) (protected_ike_sa_t *)) get_prf_auth_r;
this->protected.get_logger = (logger_t *(*) (protected_ike_sa_t *)) get_logger;
this->protected.set_init_config = (void (*) (protected_ike_sa_t *,init_config_t *)) set_init_config;
this->protected.get_init_config = (init_config_t *(*) (protected_ike_sa_t *)) get_init_config;
this->protected.send_request = (status_t (*) (protected_ike_sa_t *,message_t *)) send_request;
this->protected.send_response = (status_t (*) (protected_ike_sa_t *,message_t *)) send_response;
this->protected.send_notify = (void (*)(protected_ike_sa_t*,exchange_type_t,notify_message_type_t,chunk_t)) send_notify;
- this->protected.create_transforms_from_proposal = (status_t (*) (protected_ike_sa_t *,ike_proposal_t *)) create_transforms_from_proposal;
+ this->protected.build_transforms = (status_t (*) (protected_ike_sa_t *,proposal_t*,diffie_hellman_t*,chunk_t,chunk_t)) build_transforms;
this->protected.set_new_state = (void (*) (protected_ike_sa_t *,state_t *)) set_new_state;
this->protected.get_crypter_initiator = (crypter_t *(*) (protected_ike_sa_t *)) get_crypter_initiator;
this->protected.get_signer_initiator = (signer_t *(*) (protected_ike_sa_t *)) get_signer_initiator;
this->message_id_out = 0;
this->message_id_in = 0;
this->last_replied_message_id = -1;
- this->secrets.pi_key = CHUNK_INITIALIZER;
- this->secrets.pr_key = CHUNK_INITIALIZER;
this->crypter_initiator = NULL;
this->crypter_responder = NULL;
this->signer_initiator = NULL;
this->signer_responder = NULL;
this->prf = NULL;
+ this->prf_auth_i = NULL;
+ this->prf_auth_r = NULL;
this->child_prf = NULL;
this->init_config = NULL;
this->sa_config = NULL;
* @param message new message is stored at this location
*/
void (*build_message) (protected_ike_sa_t *this, exchange_type_t type, bool request, message_t **message);
-
- /**
- * @brief Compute the shared secrets needed for encryption, signing, etc.
- *
- * Preconditions:
- * - Call of function protected_ike_sa_t.create_transforms_from_proposal
- *
- * @param this calling object
- * @param dh_shared_secret shared secret of diffie hellman exchange
- * @param initiator_nonce nonce of initiator
- * @param responder_nonce nonce of responder
- */
- void (*compute_secrets) (protected_ike_sa_t *this,
- chunk_t dh_shared_secret,
- chunk_t initiator_nonce,
- chunk_t responder_nonce);
/**
* @brief Get the internal stored logger_t object for given ike_sa_t object.
void (*set_other_host) (protected_ike_sa_t *this,host_t *other_host);
/**
- * @brief Create all needed transform objects for this IKE_SA using
- * the informations stored in a ike_proposal_t object.
+ * @brief Derive all keys and create the transforms for IKE communication.
*
+ * Keys are derived using the diffie hellman secret, nonces and internal
+ * stored SPIs.
* Allready existing objects get destroyed.
*
* @param this calling object
- * @param proposal proposal used to get informations for transform
- * objects (algorithms, key lengths, etc.)
+ * @param proposal proposal which contains algorithms to use
+ * @param dh diffie hellman object with shared secret
+ * @param nonce_i initiators nonce
+ * @param nonce_r responders nonce
*/
- status_t (*create_transforms_from_proposal) (protected_ike_sa_t *this,ike_proposal_t * proposal);
+ status_t (*build_transforms) (protected_ike_sa_t *this, proposal_t* proposal,
+ diffie_hellman_t *dh, chunk_t nonce_i, chunk_t nonce_r);
/**
* @brief Send the next request message.
signer_t *(*get_signer_responder) (protected_ike_sa_t *this);
/**
- * @brief Get the internal stored prf_t object.
+ * @brief Get the multi purpose prf.
*
* @param this calling object
* @return pointer to prf_t object
*/
prf_t *(*get_child_prf) (protected_ike_sa_t *this);
+ /**
+ * @brief Get the prf used for authentication of initiator.
+ *
+ * @param this calling object
+ * @return pointer to prf_t object
+ */
+ prf_t *(*get_prf_auth_i) (protected_ike_sa_t *this);
+
+ /**
+ * @brief Get the prf used for authentication of responder.
+ *
+ * @param this calling object
+ * @return pointer to prf_t object
+ */
+ prf_t *(*get_prf_auth_r) (protected_ike_sa_t *this);
+
/**
* @brief Get the last responded message.
*
*/
message_t *(*get_last_requested_message) (protected_ike_sa_t *this);
- /**
- * @brief Get the Shared key SK_pr.
- *
- * Returned value is not cloned!
- *
- * @param this calling object
- * @return SK_pr key
- */
- chunk_t (*get_key_pr) (protected_ike_sa_t *this);
-
- /**
- * @brief Get the Shared key SK_pi.
- *
- * Returned value is not cloned!
- *
- * @param this calling object
- * @return SK_pi key
- */
- chunk_t (*get_key_pi) (protected_ike_sa_t *this);
-
/**
* @brief Resets message counters and does destroy stored received and sent messages.
*
*/
static status_t process_sa_payload(private_ike_auth_requested_t *this, sa_payload_t *sa_payload)
{
- child_proposal_t *proposal, *proposal_tmp;
+ proposal_t *proposal, *proposal_tmp;
linked_list_t *proposal_list;
child_sa_t *child_sa;
chunk_t seed;
prf_plus_t *prf_plus;
/* get his selected proposal */
- proposal_list = sa_payload->get_child_proposals(sa_payload);
+ proposal_list = sa_payload->get_proposals(sa_payload);
/* check count of proposals */
if (proposal_list->get_count(proposal_list) == 0)
{
chunk_t received_nonce;
/**
- * Packet data of ike_sa_init request
+ * Selected proposal
*/
- chunk_t ike_sa_init_request_data;
+ proposal_t *proposal;
/**
- * DH group priority used to get dh_group_number from configuration manager.
- *
- * Is passed to the next state object of type INITATOR_INIT if the selected group number
- * is not the same as in the peers selected proposal.
+ * Packet data of ike_sa_init request
*/
- u_int16_t dh_group_priority;
+ chunk_t ike_sa_init_request_data;
/**
* Assigned logger
{
return status;
}
-
+
+ /* derive all the keys used in the IKE_SA */
+ status = this->ike_sa->build_transforms(this->ike_sa, this->proposal, this->diffie_hellman, this->sent_nonce, this->received_nonce);
+ if (status != SUCCESS)
+ {
+ this->logger->log(this->logger, AUDIT, "Transform objects could not be created from selected proposal. Deleting IKE_SA");
+ return DELETE_ME;
+ }
+
/* build empty message */
this->ike_sa->build_message(this->ike_sa, IKE_AUTH, TRUE, &request);
*/
status_t process_sa_payload (private_ike_sa_init_requested_t *this, sa_payload_t *sa_payload)
{
- ike_proposal_t selected_proposal;
- ike_proposal_t *ike_proposals;
+ proposal_t *proposal;
+ linked_list_t *proposal_list;
init_config_t *init_config;
- size_t proposal_count;
- status_t status;
init_config = this->ike_sa->get_init_config(this->ike_sa);
- /* get the list of selected proposals */
- status = sa_payload->get_ike_proposals (sa_payload, &ike_proposals,&proposal_count);
- if (status != SUCCESS)
+ /* get the list of selected proposals, the peer has to select only one proposal */
+ proposal_list = sa_payload->get_proposals (sa_payload);
+ if (proposal_list->get_count(proposal_list) != 1)
{
- this->logger->log(this->logger, AUDIT, "IKE_SA_INIT response did not contain any proposals. Deleting IKE_SA");
- return DELETE_ME;
+ this->logger->log(this->logger, AUDIT, "IKE_SA_INIT response did not contain a single proposal. Deleting IKE_SA");
+ while (proposal_list->remove_last(proposal_list, (void**)&proposal) == SUCCESS)
+ {
+ proposal->destroy(proposal);
+ }
+ proposal_list->destroy(proposal_list);
+ return DELETE_ME;
}
- /* the peer has to select only one proposal */
- if (proposal_count != 1)
+
+ /* we have to re-check if the others selection is valid */
+ this->proposal = init_config->select_proposal(init_config, proposal_list);
+ while (proposal_list->remove_last(proposal_list, (void**)&proposal) == SUCCESS)
{
- this->logger->log(this->logger, AUDIT, "IKE_SA_INIT response contained more than one proposal. Deleting IKE_SA");
- allocator_free(ike_proposals);
- return DELETE_ME;
+ proposal->destroy(proposal);
}
+ proposal_list->destroy(proposal_list);
- /* now let the configuration-manager check the selected proposals*/
- this->logger->log(this->logger, CONTROL | LEVEL2, "Check selected proposal");
- status = init_config->select_proposal (init_config,ike_proposals,1,&selected_proposal);
- allocator_free(ike_proposals);
- if (status != SUCCESS)
+ if (this->proposal == NULL)
{
this->logger->log(this->logger, AUDIT, "IKE_SA_INIT response contained selected proposal we did not offer. Deleting IKE_SA");
return DELETE_ME;
}
-
- status = this->ike_sa->create_transforms_from_proposal(this->ike_sa,&selected_proposal);
- if (status != SUCCESS)
- {
- this->logger->log(this->logger, AUDIT, "Transform objects could not be created from selected proposal. Deleting IKE_SA");
- return DELETE_ME;
- }
+
return SUCCESS;
}
* Implementation of private_ike_sa_init_requested_t.process_ke_payload.
*/
status_t process_ke_payload (private_ike_sa_init_requested_t *this, ke_payload_t *ke_payload)
-{
- chunk_t shared_secret;
- status_t status;
-
+{
this->diffie_hellman->set_other_public_value(this->diffie_hellman, ke_payload->get_key_exchange_data(ke_payload));
- /* store shared secret
- * status of dh object does not have to get checked cause other key is set
- */
- this->logger->log(this->logger, CONTROL | LEVEL2, "Retrieve shared secret and store it");
- status = this->diffie_hellman->get_shared_secret(this->diffie_hellman, &shared_secret);
- this->logger->log_chunk(this->logger, PRIVATE, "Shared secret", &shared_secret);
-
- this->logger->log(this->logger, CONTROL | LEVEL2, "Going to derive all secrets from shared secret");
- this->ike_sa->compute_secrets(this->ike_sa,shared_secret,this->sent_nonce, this->received_nonce);
-
- allocator_free_chunk(&(shared_secret));
-
return SUCCESS;
}
/* get proposals form config, add to payload */
sa_config = this->ike_sa->get_sa_config(this->ike_sa);
proposal_list = sa_config->get_proposals(sa_config);
- sa_payload = sa_payload_create_from_child_proposal_list(proposal_list);
+ sa_payload = sa_payload_create_from_proposal_list(proposal_list);
/* TODO child sa stuff */
case INVALID_KE_PAYLOAD:
{
initiator_init_t *initiator_init_state;
- u_int16_t new_dh_group_priority;
+ chunk_t notify_data;
+ diffie_hellman_group_t dh_group;
+ init_config_t *init_config;
+
+ notify_data = notify_payload->get_notification_data(notify_payload);
+ dh_group = ntohs(*((u_int16_t*)notify_data.ptr));
+
+ this->logger->log(this->logger, ERROR|LEVEL1, "Peer wouldn't accept DH group, it requested %s!",
+ mapping_find(diffie_hellman_group_m, dh_group));
+ /* check if we can accept this dh group */
+ init_config = this->ike_sa->get_init_config(this->ike_sa);
+ if (!init_config->check_dh_group(init_config, dh_group))
+ {
+ this->logger->log(this->logger, AUDIT,
+ "Peer does only accept DH group %s, which we do not accept! Aborting",
+ mapping_find(diffie_hellman_group_m, dh_group));
+ return DELETE_ME;
+ }
- this->logger->log(this->logger, ERROR|LEVEL1, "Selected DH group is not the one in the proposal selected by the responder!");
/* Going to change state back to initiator_init_t */
this->logger->log(this->logger, CONTROL|LEVEL2, "Create next state object");
initiator_init_state = initiator_init_create(this->ike_sa);
this->logger->log(this->logger, CONTROL|LEVEL2, "Destroy old sate object");
this->logger->log(this->logger, CONTROL|LEVEL2, "Going to retry initialization of connection");
- new_dh_group_priority = this->dh_group_priority + 1;
this->public.state_interface.destroy(&(this->public.state_interface));
- if (initiator_init_state->retry_initiate_connection (initiator_init_state,new_dh_group_priority) != SUCCESS)
+ if (initiator_init_state->retry_initiate_connection (initiator_init_state, dh_group) != SUCCESS)
{
return DELETE_ME;
}
return FAILED;
-
}
default:
{
}
}
-
/**
* Implementation of state_t.get_state.
*/
*/
static void destroy_after_state_change (private_ike_sa_init_requested_t *this)
{
- this->logger->log(this->logger, CONTROL | LEVEL3, "Going to destroy state of type ike_sa_init_requested_t after state change.");
-
- this->logger->log(this->logger, CONTROL | LEVEL3, "Destroy diffie hellman object");
this->diffie_hellman->destroy(this->diffie_hellman);
- this->logger->log(this->logger, CONTROL | LEVEL3, "Destroy ike_sa_init_request_data");
allocator_free_chunk(&(this->ike_sa_init_request_data));
- this->logger->log(this->logger, CONTROL | LEVEL3, "Destroy object itself");
- allocator_free(this);
+ if (this->proposal)
+ {
+ this->proposal->destroy(this->proposal);
+ }
+ allocator_free(this);
}
/**
*/
static void destroy(private_ike_sa_init_requested_t *this)
{
- this->logger->log(this->logger, CONTROL | LEVEL3, "Going to destroy state of type ike_sa_init_requested_t");
-
- this->logger->log(this->logger, CONTROL | LEVEL3, "Destroy diffie hellman object");
this->diffie_hellman->destroy(this->diffie_hellman);
- this->logger->log(this->logger, CONTROL | LEVEL3, "Destroy sent nonce");
allocator_free(this->sent_nonce.ptr);
- this->logger->log(this->logger, CONTROL | LEVEL3, "Destroy received nonce");
allocator_free(this->received_nonce.ptr);
- this->logger->log(this->logger, CONTROL | LEVEL3, "Destroy ike_sa_init_request_data");
allocator_free_chunk(&(this->ike_sa_init_request_data));
- this->logger->log(this->logger, CONTROL | LEVEL3, "Destroy object itself");
+ if (this->proposal)
+ {
+ this->proposal->destroy(this->proposal);
+ }
allocator_free(this);
}
/*
* Described in header.
*/
-ike_sa_init_requested_t *ike_sa_init_requested_create(protected_ike_sa_t *ike_sa, u_int16_t dh_group_priority, diffie_hellman_t *diffie_hellman, chunk_t sent_nonce,chunk_t ike_sa_init_request_data)
+ike_sa_init_requested_t *ike_sa_init_requested_create(protected_ike_sa_t *ike_sa, diffie_hellman_t *diffie_hellman, chunk_t sent_nonce,chunk_t ike_sa_init_request_data)
{
private_ike_sa_init_requested_t *this = allocator_alloc_thing(private_ike_sa_init_requested_t);
this->received_nonce = CHUNK_INITIALIZER;
this->logger = this->ike_sa->get_logger(this->ike_sa);
this->diffie_hellman = diffie_hellman;
+ this->proposal = NULL;
this->sent_nonce = sent_nonce;
this->ike_sa_init_request_data = ike_sa_init_request_data;
- this->dh_group_priority = dh_group_priority;
return &(this->public);
}
* Constructor of class ike_sa_init_requested_t.
*
* @param ike_sa assigned ike_sa
- * @param dh_group_priority the last used priority number to get the DH group for request
* @param diffie_hellman diffie_hellman object use to retrieve shared secret
* @param sent_nonce Sent nonce value
* @param ike_sa_init_request_data the binary representation of the IKE_SA_INIT request message
* @ingroup states
*/
ike_sa_init_requested_t *ike_sa_init_requested_create(protected_ike_sa_t *ike_sa,
- u_int16_t dh_group_priority,
diffie_hellman_t *diffie_hellman,
chunk_t sent_nonce,
chunk_t ike_sa_init_request_data);
*/
static status_t build_sa_payload(private_ike_sa_init_responded_t *this, sa_payload_t *request, message_t *response)
{
- child_proposal_t *proposal, *proposal_tmp;
+ proposal_t *proposal, *proposal_tmp;
linked_list_t *proposal_list;
sa_payload_t *sa_response;
child_sa_t *child_sa;
/* TODO: child sa stuff */
/* get proposals from request */
- proposal_list = request->get_child_proposals(request);
+ proposal_list = request->get_proposals(request);
if (proposal_list->get_count(proposal_list) == 0)
{
/* if the other side did not offer any proposals, we do not create child sa's */
}
/* create payload with selected propsal */
- sa_response = sa_payload_create_from_child_proposal(proposal);
+ sa_response = sa_payload_create_from_proposal(proposal);
response->add_payload(response, (payload_t*)sa_response);
/* install child SAs for AH and esp */
*/
diffie_hellman_t *diffie_hellman;
- /**
- * DH group number.
- */
- u_int16_t dh_group_number;
-
- /**
- * DH group priority used to get dh_group_number from configuration manager.
- * This priority is passed to the next state of type IKE_SA_INIT_REQUESTED.
- */
- u_int16_t dh_group_priority;
-
/**
* Sent nonce.
* This nonce is passed to the next state of type IKE_SA_INIT_REQUESTED.
init_config_t *init_config;
sa_config_t *sa_config;
status_t status;
-
+ diffie_hellman_group_t dh_group;
this->logger->log(this->logger, CONTROL, "Initializing connection %s",name);
+ /* get configs */
status = charon->configuration_manager->get_init_config_for_name(charon->configuration_manager,name,&init_config);
if (status != SUCCESS)
{
this->logger->log(this->logger, ERROR | LEVEL1, "Could not retrieve INIT configuration informations for %s",name);
return DELETE_ME;
}
-
this->ike_sa->set_init_config(this->ike_sa,init_config);
-
status = charon->configuration_manager->get_sa_config_for_name(charon->configuration_manager,name,&sa_config);
-
if (status != SUCCESS)
- {
+ {
this->logger->log(this->logger, ERROR | LEVEL1, "Could not retrieve SA configuration informations for %s",name);
return DELETE_ME;
}
-
this->ike_sa->set_sa_config(this->ike_sa,sa_config);
/* host informations are read from configuration */
this->ike_sa->set_other_host(this->ike_sa,init_config->get_other_host_clone(init_config));
this->ike_sa->set_my_host(this->ike_sa,init_config->get_my_host_clone(init_config));
- this->dh_group_number = init_config->get_dh_group_number(init_config,this->dh_group_priority);
- if (this->dh_group_number == MODP_UNDEFINED)
- {
- this->logger->log(this->logger, AUDIT, "Could not find a matching diffie hellman group after %d. try. Aborting.",
- this->dh_group_priority);
- return DELETE_ME;
- }
+ /* we must guess now a DH group. For that we choose our most preferred group */
+ dh_group = init_config->get_dh_group(init_config);
/* next step is done in retry_initiate_connection */
- return this->public.retry_initiate_connection(&(this->public),this->dh_group_priority);
+ return this->public.retry_initiate_connection(&(this->public), dh_group);
}
/**
* Implementation of initiator_init_t.retry_initiate_connection.
*/
-status_t retry_initiate_connection (private_initiator_init_t *this, int dh_group_priority)
+status_t retry_initiate_connection (private_initiator_init_t *this, diffie_hellman_group_t dh_group)
{
ike_sa_init_requested_t *next_state;
chunk_t ike_sa_init_request_data;
ike_sa_id_t *ike_sa_id;
message_t *message;
status_t status;
-
- this->dh_group_priority = dh_group_priority;
-
- init_config = this->ike_sa->get_init_config(this->ike_sa);
-
- ike_sa_id = this->ike_sa->public.get_id(&(this->ike_sa->public));
- ike_sa_id->set_responder_spi(ike_sa_id,0);
-
- this->dh_group_number = init_config->get_dh_group_number(init_config,dh_group_priority);
- if (this->dh_group_number == MODP_UNDEFINED)
+ if (dh_group == MODP_UNDEFINED)
{
- this->logger->log(this->logger, AUDIT, "Could not find a matching diffie hellman group after %d. try. Aborting.",
- this->dh_group_priority);
+ this->logger->log(this->logger, AUDIT, "No DH group acceptable for initialization, Aborting");
+ message->destroy(message);
return DELETE_ME;
}
- this->diffie_hellman = diffie_hellman_create(this->dh_group_number);
+ init_config = this->ike_sa->get_init_config(this->ike_sa);
+ this->diffie_hellman = diffie_hellman_create(dh_group);
+ ike_sa_id = this->ike_sa->public.get_id(&(this->ike_sa->public));
+ ike_sa_id->set_responder_spi(ike_sa_id,0);
/* going to build message */
this->logger->log(this->logger, CONTROL|LEVEL2, "Going to build message");
/* state can now be changed */
this->logger->log(this->logger, CONTROL|LEVEL2, "Create next state object");
- next_state = ike_sa_init_requested_create(this->ike_sa, this->dh_group_priority, this->diffie_hellman, this->sent_nonce,ike_sa_init_request_data);
+ next_state = ike_sa_init_requested_create(this->ike_sa, this->diffie_hellman, this->sent_nonce,ike_sa_init_request_data);
this->ike_sa->set_new_state(this->ike_sa,(state_t *) next_state);
this->logger->log(this->logger, CONTROL|LEVEL2, "Destroy old sate object");
static void build_sa_payload(private_initiator_init_t *this, message_t *request)
{
sa_payload_t* sa_payload;
- size_t proposal_count;
- ike_proposal_t *proposals;
+ linked_list_t *proposal_list;
init_config_t *init_config;
this->logger->log(this->logger, CONTROL|LEVEL1, "Building SA payload");
init_config = this->ike_sa->get_init_config(this->ike_sa);
- proposal_count = init_config->get_proposals(init_config,&proposals);
+ proposal_list = init_config->get_proposals(init_config);
- sa_payload = sa_payload_create_from_ike_proposals(proposals,proposal_count);
-
- allocator_free(proposals);
+ sa_payload = sa_payload_create_from_proposal_list(proposal_list);
this->logger->log(this->logger, CONTROL|LEVEL2, "Add SA payload to message");
request->add_payload(request, (payload_t *) sa_payload);
{
ke_payload_t *ke_payload;
chunk_t key_data;
+ diffie_hellman_group_t dh_group;
this->logger->log(this->logger, CONTROL|LEVEL1, "Building KE payload");
this->diffie_hellman->get_my_public_value(this->diffie_hellman,&key_data);
+ dh_group = this->diffie_hellman->get_dh_group(this->diffie_hellman);
ke_payload = ke_payload_create();
- ke_payload->set_dh_group_number(ke_payload, this->dh_group_number);
+ ke_payload->set_dh_group_number(ke_payload, dh_group);
ke_payload->set_key_exchange_data(ke_payload, key_data);
allocator_free_chunk(&key_data);
/* private data */
this->ike_sa = ike_sa;
- this->dh_group_priority = 1;
this->logger = this->ike_sa->get_logger(this->ike_sa);
this->sent_nonce = CHUNK_INITIALIZER;
this->diffie_hellman = NULL;
*/
chunk_t received_nonce;
+ /**
+ * Selected proposal
+ */
+ proposal_t *proposal;
+
/**
* Logger used to log data .
*
nonce_payload_t *nonce_request = NULL;
host_t *source, *destination;
init_config_t *init_config;
- chunk_t shared_secret;
iterator_t *payloads;
message_t *response;
status_t status;
{
response->destroy(response);
return status;
- }
+ }
- /* store shared secret */
- this->logger->log(this->logger, CONTROL | LEVEL2, "Retrieve shared secret and store it");
- status = this->diffie_hellman->get_shared_secret(this->diffie_hellman, &shared_secret);
- this->logger->log_chunk(this->logger, PRIVATE, "Shared Diffie Hellman secret", &shared_secret);
-
- this->ike_sa->compute_secrets(this->ike_sa,shared_secret,this->received_nonce, this->sent_nonce);
-
- /* not used anymore */
- allocator_free_chunk(&shared_secret);
+ /* derive all the keys used in the IKE_SA */
+ status = this->ike_sa->build_transforms(this->ike_sa, this->proposal, this->diffie_hellman, this->received_nonce, this->sent_nonce);
+ if (status != SUCCESS)
+ {
+ this->logger->log(this->logger, AUDIT, "Transform objects could not be created from selected proposal. Deleting IKE_SA");
+ return DELETE_ME;
+ }
/* message can now be sent (must not be destroyed) */
status = this->ike_sa->send_response(this->ike_sa, response);
*/
static status_t build_sa_payload(private_responder_init_t *this,sa_payload_t *sa_request, message_t *response)
{
- ike_proposal_t selected_proposal;
- ike_proposal_t *ike_proposals;
+ proposal_t *proposal;
+ linked_list_t *proposal_list;
init_config_t *init_config;
sa_payload_t* sa_payload;
- size_t proposal_count;
- status_t status;
+ algorithm_t *algo;
init_config = this->ike_sa->get_init_config(this->ike_sa);
this->logger->log(this->logger, CONTROL | LEVEL2, "Process received SA payload");
+
/* get the list of suggested proposals */
- status = sa_request->get_ike_proposals (sa_request, &ike_proposals,&proposal_count);
- if (status != SUCCESS)
+ proposal_list = sa_request->get_proposals (sa_request);
+
+ /* select proposal */
+ this->proposal = init_config->select_proposal(init_config, proposal_list);
+ while(proposal_list->remove_last(proposal_list, (void**)&proposal) == SUCCESS)
{
- this->logger->log(this->logger, AUDIT, "IKE_SA_INIT request did not contain any proposals. Deleting IKE_SA");
- this->ike_sa->send_notify(this->ike_sa, IKE_SA_INIT, NO_PROPOSAL_CHOSEN, CHUNK_INITIALIZER);
- return DELETE_ME;
+ proposal->destroy(proposal);
}
-
- status = init_config->select_proposal(init_config, ike_proposals,proposal_count,&(selected_proposal));
- allocator_free(ike_proposals);
- if (status != SUCCESS)
+ proposal_list->destroy(proposal_list);
+ if (this->proposal == NULL)
{
this->logger->log(this->logger, AUDIT, "IKE_SA_INIT request did not contain any acceptable proposals. Deleting IKE_SA");
this->ike_sa->send_notify(this->ike_sa, IKE_SA_INIT, NO_PROPOSAL_CHOSEN, CHUNK_INITIALIZER);
return DELETE_ME;
}
-
- this->dh_group_number = selected_proposal.diffie_hellman_group;
-
- status = this->ike_sa->create_transforms_from_proposal(this->ike_sa,&(selected_proposal));
- if (status != SUCCESS)
- {
- this->logger->log(this->logger, AUDIT, "Transform objects could not be created from selected proposal. Deleting IKE_SA");
- return DELETE_ME;
- }
+ /* get selected DH group to force policy, this is very restrictive!? */
+ this->proposal->get_algorithm(this->proposal, IKE, DIFFIE_HELLMAN_GROUP, &algo);
+ this->dh_group_number = algo->algorithm;
this->logger->log(this->logger, CONTROL | LEVEL2, "SA Payload processed");
this->logger->log(this->logger, CONTROL|LEVEL2, "Building SA payload");
- sa_payload = sa_payload_create_from_ike_proposals(&(selected_proposal),1);
+ sa_payload = sa_payload_create_from_proposal(this->proposal);
this->logger->log(this->logger, CONTROL|LEVEL2, "add SA payload to message");
response->add_payload(response,(payload_t *) sa_payload);
this->logger->log(this->logger, AUDIT, "No diffie hellman group to select. Deleting IKE_SA");
return DELETE_ME;
}
+
if (this->dh_group_number != group)
{
u_int16_t accepted_group;
this->logger->log(this->logger, CONTROL | LEVEL2, "Destroy diffie_hellman_t hellman object");
this->diffie_hellman->destroy(this->diffie_hellman);
}
+ if (this->proposal)
+ {
+ this->proposal->destroy(this->proposal);
+ }
this->logger->log(this->logger, CONTROL | LEVEL2, "Destroy object");
allocator_free(this);
}
this->logger->log(this->logger, CONTROL | LEVEL2, "Destroy diffie_hellman_t object");
this->diffie_hellman->destroy(this->diffie_hellman);
}
+ if (this->proposal)
+ {
+ this->proposal->destroy(this->proposal);
+ }
this->logger->log(this->logger, CONTROL | LEVEL2, "Destroy object");
allocator_free(this);
this->received_nonce = CHUNK_INITIALIZER;
this->dh_group_number = MODP_UNDEFINED;
this->diffie_hellman = NULL;
+ this->proposal = NULL;
return &(this->public);
}
$(BUILD_DIR)sa_config_test.o : $(TESTCASES_DIR)sa_config_test.c $(TESTCASES_DIR)sa_config_test.h
$(CC) $(CFLAGS) -c -o $@ $<
-TEST_OBJS+= $(BUILD_DIR)child_proposal_test.o
-$(BUILD_DIR)child_proposal_test.o : $(TESTCASES_DIR)child_proposal_test.c $(TESTCASES_DIR)child_proposal_test.h
+TEST_OBJS+= $(BUILD_DIR)proposal_test.o
+$(BUILD_DIR)proposal_test.o : $(TESTCASES_DIR)proposal_test.c $(TESTCASES_DIR)proposal_test.h
$(CC) $(CFLAGS) -c -o $@ $<
TEST_OBJS+= $(BUILD_DIR)rsa_test.o
generator_t *generator;
transform_attribute_t *attribute1, *attribute2, *attribute3;
transform_substructure_t *transform1, *transform2;
- proposal_substructure_t *proposal1, *proposal2;
- ike_proposal_t *ike_proposals;
+ proposal_substructure_t *proposal_str1, *proposal_str2;
linked_list_t *list;
- child_proposal_t *child_proposal1, *child_proposal2;
- size_t ike_proposal_count;
+ proposal_t *proposal1, *proposal2;
sa_payload_t *sa_payload;
ike_header_t *ike_header;
logger->log(logger,CONTROL,"transforms created");
/* create proposal 1 */
- proposal1 = proposal_substructure_create();
+ proposal_str1 = proposal_substructure_create();
tester->assert_true(tester,(proposal1 != NULL), "proposal create check");
stringval = "ABCDEFGH";
data.ptr = (void *) stringval;
data.len = 8;
- proposal1->add_transform_substructure(proposal1,transform1);
- proposal1->add_transform_substructure(proposal1,transform2);
- proposal1->set_spi(proposal1,data);
- proposal1->set_proposal_number(proposal1,7);
- proposal1->set_protocol_id(proposal1,4);
+ proposal_str1->add_transform_substructure(proposal_str1,transform1);
+ proposal_str1->add_transform_substructure(proposal_str1,transform2);
+ proposal_str1->set_spi(proposal_str1,data);
+ proposal_str1->set_proposal_number(proposal_str1,7);
+ proposal_str1->set_protocol_id(proposal_str1,4);
/* create proposal 2 */
- proposal2 = proposal_substructure_create();
- tester->assert_true(tester,(proposal2 != NULL), "proposal create check");
- proposal2->set_proposal_number(proposal2,7);
- proposal2->set_protocol_id(proposal2,5);
+ proposal_str2 = proposal_substructure_create();
+ tester->assert_true(tester,(proposal_str2 != NULL), "proposal create check");
+ proposal_str2->set_proposal_number(proposal_str2,7);
+ proposal_str2->set_protocol_id(proposal_str2,5);
/* create sa_payload */
sa_payload = sa_payload_create();
- sa_payload->add_proposal_substructure(sa_payload,proposal1);
- sa_payload->add_proposal_substructure(sa_payload,proposal2);
+ sa_payload->add_proposal_substructure(sa_payload,proposal_str1);
+ sa_payload->add_proposal_substructure(sa_payload,proposal_str2);
ike_header = ike_header_create();
ike_header->set_initiator_spi(ike_header,0x22000054231234LL);
tester->assert_true(tester,(generator != NULL), "generator create check");
- ike_proposal_count = 2;
- ike_proposals = allocator_alloc(ike_proposal_count * (sizeof(ike_proposal_t)));
+ proposal1 = proposal_create(1);
+ proposal1->add_algorithm(proposal1, IKE, ENCRYPTION_ALGORITHM, 1, 20);
+ proposal1->add_algorithm(proposal1, IKE, PSEUDO_RANDOM_FUNCTION, 2, 22);
+ proposal1->add_algorithm(proposal1, IKE, INTEGRITY_ALGORITHM, 3, 24);
+ proposal1->add_algorithm(proposal1, IKE, DIFFIE_HELLMAN_GROUP, 4, 0);
- ike_proposals[0].encryption_algorithm = 1;
- ike_proposals[0].encryption_algorithm_key_length = 20;
- ike_proposals[0].pseudo_random_function = 2;
- ike_proposals[0].pseudo_random_function_key_length = 22;
- ike_proposals[0].integrity_algorithm = 3;
- ike_proposals[0].integrity_algorithm_key_length = 24;
- ike_proposals[0].diffie_hellman_group = 4;
+ proposal2 = proposal_create(2);
+ proposal2->add_algorithm(proposal2, IKE, ENCRYPTION_ALGORITHM, 5, 26);
+ proposal2->add_algorithm(proposal2, IKE, PSEUDO_RANDOM_FUNCTION, 6, 28);
+ proposal2->add_algorithm(proposal2, IKE, INTEGRITY_ALGORITHM, 7, 30);
+ proposal2->add_algorithm(proposal2, IKE, DIFFIE_HELLMAN_GROUP, 8, 0);
- ike_proposals[1].encryption_algorithm = 5;
- ike_proposals[1].encryption_algorithm_key_length = 26;
- ike_proposals[1].pseudo_random_function = 6;
- ike_proposals[1].pseudo_random_function_key_length = 28;
- ike_proposals[1].integrity_algorithm = 7;
- ike_proposals[1].integrity_algorithm_key_length = 30;
- ike_proposals[1].diffie_hellman_group = 8;
-
- sa_payload = sa_payload_create_from_ike_proposals(ike_proposals,ike_proposal_count);
+ list = linked_list_create();
+ list->insert_last(list, (void*)proposal1);
+ list->insert_last(list, (void*)proposal2);
+ sa_payload = sa_payload_create_from_proposal_list(list);
tester->assert_true(tester,(sa_payload != NULL), "sa_payload create check");
generator->generate_payload(generator,(payload_t *)sa_payload);
tester->assert_true(tester,(memcmp(expected_generation2,generated_data.ptr,sizeof(expected_generation2)) == 0), "compare generated data");
sa_payload->destroy(sa_payload);
- allocator_free(ike_proposals);
+ list->destroy(list);
+ proposal1->destroy(proposal1);
+ proposal2->destroy(proposal2);
allocator_free_chunk(&generated_data);
generator->destroy(generator);
tester->assert_true(tester,(generator != NULL), "generator create check");
- child_proposal1 = child_proposal_create(1);
+ proposal1 = proposal_create(1);
- child_proposal1->add_algorithm(child_proposal1, AH, INTEGRITY_ALGORITHM, AUTH_HMAC_MD5_96, 20);
- child_proposal1->add_algorithm(child_proposal1, AH, DIFFIE_HELLMAN_GROUP, MODP_2048_BIT, 0);
- child_proposal1->add_algorithm(child_proposal1, AH, EXTENDED_SEQUENCE_NUMBERS, EXT_SEQ_NUMBERS, 0);
- child_proposal1->set_spi(child_proposal1, AH, 0x01010101l);
+ proposal1->add_algorithm(proposal1, AH, INTEGRITY_ALGORITHM, AUTH_HMAC_MD5_96, 20);
+ proposal1->add_algorithm(proposal1, AH, DIFFIE_HELLMAN_GROUP, MODP_2048_BIT, 0);
+ proposal1->add_algorithm(proposal1, AH, EXTENDED_SEQUENCE_NUMBERS, EXT_SEQ_NUMBERS, 0);
+ proposal1->set_spi(proposal1, AH, 0x01010101l);
- child_proposal1->add_algorithm(child_proposal1, ESP, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 20);
- child_proposal1->add_algorithm(child_proposal1, ESP, DIFFIE_HELLMAN_GROUP, MODP_1024_BIT, 0);
- child_proposal1->set_spi(child_proposal1, ESP, 0x02020202);
+ proposal1->add_algorithm(proposal1, ESP, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 20);
+ proposal1->add_algorithm(proposal1, ESP, DIFFIE_HELLMAN_GROUP, MODP_1024_BIT, 0);
+ proposal1->set_spi(proposal1, ESP, 0x02020202);
- child_proposal2->add_algorithm(child_proposal2, AH, INTEGRITY_ALGORITHM, AUTH_HMAC_MD5_96, 20);
- child_proposal2->add_algorithm(child_proposal2, AH, DIFFIE_HELLMAN_GROUP, MODP_2048_BIT, 0);
- child_proposal2->add_algorithm(child_proposal2, AH, EXTENDED_SEQUENCE_NUMBERS, EXT_SEQ_NUMBERS, 0);
- child_proposal2->set_spi(child_proposal2, AH, 0x01010101);
+ proposal2->add_algorithm(proposal2, AH, INTEGRITY_ALGORITHM, AUTH_HMAC_MD5_96, 20);
+ proposal2->add_algorithm(proposal2, AH, DIFFIE_HELLMAN_GROUP, MODP_2048_BIT, 0);
+ proposal2->add_algorithm(proposal2, AH, EXTENDED_SEQUENCE_NUMBERS, EXT_SEQ_NUMBERS, 0);
+ proposal2->set_spi(proposal2, AH, 0x01010101);
- child_proposal2->add_algorithm(child_proposal2, ESP, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 32);
- child_proposal2->add_algorithm(child_proposal2, ESP, INTEGRITY_ALGORITHM, AUTH_HMAC_MD5_96, 20);
- child_proposal2->add_algorithm(child_proposal2, ESP, DIFFIE_HELLMAN_GROUP, MODP_1024_BIT, 0);
- child_proposal2->set_spi(child_proposal2, ESP, 0x02020202);
+ proposal2->add_algorithm(proposal2, ESP, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 32);
+ proposal2->add_algorithm(proposal2, ESP, INTEGRITY_ALGORITHM, AUTH_HMAC_MD5_96, 20);
+ proposal2->add_algorithm(proposal2, ESP, DIFFIE_HELLMAN_GROUP, MODP_1024_BIT, 0);
+ proposal2->set_spi(proposal2, ESP, 0x02020202);
- list->insert_last(list, (void*)child_proposal1);
- list->insert_last(list, (void*)child_proposal2);
+ list->insert_last(list, (void*)proposal1);
+ list->insert_last(list, (void*)proposal2);
- sa_payload = sa_payload_create_from_child_proposal_list(list);
+ sa_payload = sa_payload_create_from_proposal_list(list);
tester->assert_true(tester,(sa_payload != NULL), "sa_payload create check");
generator->generate_payload(generator,(payload_t *)sa_payload);
tester->assert_true(tester,(memcmp(expected_generation3,generated_data.ptr,sizeof(expected_generation3)) == 0), "compare generated data");
sa_payload->destroy(sa_payload);
- child_proposal1->destroy(child_proposal1);
- child_proposal2->destroy(child_proposal2);
+ proposal1->destroy(proposal1);
+ proposal2->destroy(proposal2);
list->destroy(list);
allocator_free_chunk(&generated_data);
generator->destroy(generator);
void test_init_config(protected_tester_t *tester)
{
init_config_t *init_config = init_config_create("192.168.0.1","192.168.0.2",500,500);
- ike_proposal_t prop1, prop2, prop3, prop4, selected_one;
- ike_proposal_t *proposal_list;
- size_t proposal_count;
+ proposal_t *prop1, *prop2, *prop3, *prop4, *selected_one;
+ linked_list_t *list;
status_t status;
- prop1.encryption_algorithm = ENCR_AES_CBC;
- prop1.encryption_algorithm_key_length = 20;
- prop1.integrity_algorithm = AUTH_HMAC_SHA1_96;
- prop1.integrity_algorithm_key_length = 20;
- prop1.pseudo_random_function = PRF_HMAC_SHA1;
- prop1.pseudo_random_function_key_length = 20;
- prop1.diffie_hellman_group = MODP_2048_BIT;
+ prop1 = proposal_create(1);
+ prop1->add_algorithm(prop1, IKE, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 20);
+ prop1->add_algorithm(prop1, IKE, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA1_96, 20);
+ prop1->add_algorithm(prop1, IKE, PSEUDO_RANDOM_FUNCTION, PRF_HMAC_SHA1, 20);
+ prop1->add_algorithm(prop1, IKE, DIFFIE_HELLMAN_GROUP, MODP_2048_BIT, 0);
- prop2 = prop1;
- prop2.pseudo_random_function = PRF_HMAC_MD5;
- prop2.diffie_hellman_group = MODP_1024_BIT;
+ prop2 = proposal_create(2);
+ prop2->add_algorithm(prop2, IKE, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 20);
+ prop2->add_algorithm(prop2, IKE, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA1_96, 20);
+ prop2->add_algorithm(prop2, IKE, PSEUDO_RANDOM_FUNCTION, PRF_HMAC_MD5, 20);
+ prop2->add_algorithm(prop2, IKE, DIFFIE_HELLMAN_GROUP, MODP_1024_BIT, 0);
- prop3 = prop1;
- prop3.encryption_algorithm = ENCR_DES;
- prop3.diffie_hellman_group = MODP_768_BIT;
+ prop3 = proposal_create(3);
+ prop3->add_algorithm(prop3, IKE, ENCRYPTION_ALGORITHM, ENCR_DES, 20);
+ prop3->add_algorithm(prop3, IKE, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA1_96, 20);
+ prop3->add_algorithm(prop3, IKE, PSEUDO_RANDOM_FUNCTION, PRF_HMAC_MD5, 20);
+ prop3->add_algorithm(prop3, IKE, DIFFIE_HELLMAN_GROUP, MODP_768_BIT, 0);
- prop4 = prop1;
+ prop4 = proposal_create(4);
+ prop4->add_algorithm(prop4, IKE, ENCRYPTION_ALGORITHM, ENCR_3DES, 20);
+ prop4->add_algorithm(prop4, IKE, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA1_96, 20);
+ prop4->add_algorithm(prop4, IKE, PSEUDO_RANDOM_FUNCTION, PRF_HMAC_TIGER, 20);
+ prop4->add_algorithm(prop4, IKE, DIFFIE_HELLMAN_GROUP, MODP_768_BIT, 0);
- prop4.encryption_algorithm = ENCR_3DES;
- prop4.pseudo_random_function = PRF_HMAC_TIGER;
+ init_config->add_proposal(init_config, prop1);
+ init_config->add_proposal(init_config, prop2);
+ init_config->add_proposal(init_config, prop3);
+ init_config->add_proposal(init_config, prop4);
- init_config->add_proposal(init_config,1,prop1);
- init_config->add_proposal(init_config,1,prop2);
- init_config->add_proposal(init_config,3,prop3);
- init_config->add_proposal(init_config,2,prop4);
+ list = init_config->get_proposals(init_config);
- proposal_count = init_config->get_proposals(init_config,&proposal_list);
-
- tester->assert_true(tester,(proposal_count == 4), "proposal count check ");
-
- tester->assert_true(tester,(proposal_list[0].encryption_algorithm == ENCR_AES_CBC), "encryption algorithm check 1");
- tester->assert_true(tester,(proposal_list[0].pseudo_random_function == PRF_HMAC_MD5), "prf check 1");
+ tester->assert_true(tester,(list->get_count(list) == 4), "proposal count check ");
- tester->assert_true(tester,(proposal_list[1].encryption_algorithm == ENCR_3DES), "encryption algorithm check 2");
- tester->assert_true(tester,(proposal_list[1].pseudo_random_function == PRF_HMAC_TIGER), "prf check 2");
-
- tester->assert_true(tester,(proposal_list[2].encryption_algorithm == ENCR_AES_CBC), "encryption algorithm check 3");
- tester->assert_true(tester,(proposal_list[2].pseudo_random_function == PRF_HMAC_SHA1), "prf check 3");
-
- tester->assert_true(tester,(proposal_list[3].encryption_algorithm == ENCR_DES), "encryption algorithm check 4");
- tester->assert_true(tester,(proposal_list[3].pseudo_random_function == PRF_HMAC_SHA1), "prf check 4");
-
-
/* going to check proposals */
- status = init_config->select_proposal(init_config,proposal_list,proposal_count,&selected_one);
- tester->assert_true(tester,(status == SUCCESS), "select proposal call check 1");
-
- tester->assert_true(tester,(selected_one.encryption_algorithm == ENCR_AES_CBC), "encryption algorithm check");
- tester->assert_true(tester,(selected_one.pseudo_random_function == PRF_HMAC_MD5), "prf check");
-
- proposal_list[0].encryption_algorithm = ENCR_DES_IV32;
-
- status = init_config->select_proposal(init_config,proposal_list,proposal_count,&selected_one);
- tester->assert_true(tester,(status == SUCCESS), "select proposal call check 2");
-
- tester->assert_true(tester,(selected_one.encryption_algorithm == ENCR_3DES), "encryption algorithm check");
- tester->assert_true(tester,(selected_one.pseudo_random_function == PRF_HMAC_TIGER), "prf check");
-
- proposal_list[1].pseudo_random_function = PRF_AES128_CBC;
-
- status = init_config->select_proposal(init_config,proposal_list,proposal_count,&selected_one);
- tester->assert_true(tester,(status == SUCCESS), "select proposal call check 3");
-
- tester->assert_true(tester,(selected_one.encryption_algorithm == ENCR_AES_CBC), "encryption algorithm check");
- tester->assert_true(tester,(selected_one.pseudo_random_function == PRF_HMAC_SHA1), "prf check");
-
- proposal_list[2].pseudo_random_function = PRF_AES128_CBC;
-
- status = init_config->select_proposal(init_config,proposal_list,proposal_count,&selected_one);
- tester->assert_true(tester,(status == SUCCESS), "select proposal call check 4");
-
- tester->assert_true(tester,(selected_one.encryption_algorithm == ENCR_DES), "encryption algorithm check");
- tester->assert_true(tester,(selected_one.pseudo_random_function == PRF_HMAC_SHA1), "prf check");
-
- proposal_list[3].pseudo_random_function = PRF_AES128_CBC;
-
- status = init_config->select_proposal(init_config,proposal_list,proposal_count,&selected_one);
- tester->assert_true(tester,(status == NOT_FOUND), "select proposal call check 5");
-
- tester->assert_true(tester,(init_config->get_dh_group_number(init_config,1) == MODP_1024_BIT), "get DH group number call check 1");
- tester->assert_true(tester,(init_config->get_dh_group_number(init_config,2) == MODP_2048_BIT), "get DH group number call check 2");
- tester->assert_true(tester,(init_config->get_dh_group_number(init_config,3) == MODP_2048_BIT), "get DH group number call check 3");
- tester->assert_true(tester,(init_config->get_dh_group_number(init_config,4) == MODP_768_BIT), "get DH group number call check 4");
+ /* TODO test?*/
- allocator_free(proposal_list);
+ list->destroy(list);
init_config->destroy(init_config);
}
status_t status;
chunk_t sa_chunk, sa_chunk2, sa_chunk3;
iterator_t *proposals, *transforms, *attributes;
- ike_proposal_t *ike_proposals;
- size_t ike_proposal_count;
/* first test generic parsing functionality */
status = sa_payload->payload_interface.verify(&(sa_payload->payload_interface));
tester->assert_true(tester,(status == SUCCESS),"verify call check");
-
+ /*
status = sa_payload->get_ike_proposals (sa_payload, &ike_proposals, &ike_proposal_count);
tester->assert_true(tester,(status == SUCCESS),"get ike proposals call check");
{
allocator_free(ike_proposals);
}
+ */
sa_payload->destroy(sa_payload);
/* now test SA functionality after parsing an SA payload with child sa proposals*/
status = sa_payload->payload_interface.verify(&(sa_payload->payload_interface));
tester->assert_true(tester,(status == SUCCESS),"verify call check");
-
+/*
status = sa_payload->get_ike_proposals (sa_payload, &ike_proposals, &ike_proposal_count);
tester->assert_false(tester,(status == SUCCESS),"get ike proposals call check");
- /*
- status = sa_payload->get_child_proposals (sa_payload, &child_proposals, &child_proposal_count);
+
+ status = sa_payload->get_proposals (sa_payload, &proposals, &proposal_count);
tester->assert_true(tester,(status == SUCCESS),"get child proposals call check");
- tester->assert_true(tester,(child_proposal_count == 2),"child proposal count check");
- tester->assert_true(tester,(child_proposals[0].ah.is_set == TRUE),"is ah set check");
- tester->assert_true(tester,(child_proposals[0].ah.integrity_algorithm == AUTH_HMAC_MD5_96),"integrity_algorithm check");
- tester->assert_true(tester,(child_proposals[0].ah.integrity_algorithm_key_size == 20),"integrity_algorithm_key_size check");
- tester->assert_true(tester,(child_proposals[0].ah.diffie_hellman_group == MODP_2048_BIT),"diffie_hellman_group check");
- tester->assert_true(tester,(child_proposals[0].ah.extended_sequence_numbers == EXT_SEQ_NUMBERS),"extended_sequence_numbers check");
- tester->assert_true(tester,(child_proposals[0].ah.spi[0] == 1),"spi check");
- tester->assert_true(tester,(child_proposals[0].ah.spi[1] == 1),"spi check");
- tester->assert_true(tester,(child_proposals[0].ah.spi[2] == 1),"spi check");
- tester->assert_true(tester,(child_proposals[0].ah.spi[3] == 1),"spi check");
-
- tester->assert_true(tester,(child_proposals[0].esp.is_set == TRUE),"is ah set check");
- tester->assert_true(tester,(child_proposals[0].esp.encryption_algorithm == ENCR_AES_CBC),"integrity_algorithm check");
- tester->assert_true(tester,(child_proposals[0].esp.encryption_algorithm_key_size == 32),"integrity_algorithm_key_size check");
- tester->assert_true(tester,(child_proposals[0].esp.diffie_hellman_group == MODP_1024_BIT),"diffie_hellman_group check");
- tester->assert_true(tester,(child_proposals[0].esp.integrity_algorithm == AUTH_UNDEFINED),"integrity_algorithm check");
- tester->assert_true(tester,(child_proposals[0].esp.spi[0] == 2),"spi check");
- tester->assert_true(tester,(child_proposals[0].esp.spi[1] == 2),"spi check");
- tester->assert_true(tester,(child_proposals[0].esp.spi[2] == 2),"spi check");
- tester->assert_true(tester,(child_proposals[0].esp.spi[3] == 2),"spi check");
-
- tester->assert_true(tester,(child_proposals[1].ah.is_set == TRUE),"is ah set check");
- tester->assert_true(tester,(child_proposals[1].ah.integrity_algorithm == AUTH_HMAC_MD5_96),"integrity_algorithm check");
- tester->assert_true(tester,(child_proposals[1].ah.integrity_algorithm_key_size == 20),"integrity_algorithm_key_size check");
- tester->assert_true(tester,(child_proposals[1].ah.diffie_hellman_group == MODP_2048_BIT),"diffie_hellman_group check");
- tester->assert_true(tester,(child_proposals[1].ah.extended_sequence_numbers == EXT_SEQ_NUMBERS),"extended_sequence_numbers check");
- tester->assert_true(tester,(child_proposals[1].ah.spi[0] == 1),"spi check");
- tester->assert_true(tester,(child_proposals[1].ah.spi[1] == 1),"spi check");
- tester->assert_true(tester,(child_proposals[1].ah.spi[2] == 1),"spi check");
- tester->assert_true(tester,(child_proposals[1].ah.spi[3] == 1),"spi check");
-
- tester->assert_true(tester,(child_proposals[1].esp.is_set == TRUE),"is ah set check");
- tester->assert_true(tester,(child_proposals[1].esp.encryption_algorithm == ENCR_AES_CBC),"integrity_algorithm check");
- tester->assert_true(tester,(child_proposals[1].esp.encryption_algorithm_key_size == 32),"integrity_algorithm_key_size check");
- tester->assert_true(tester,(child_proposals[1].esp.diffie_hellman_group == MODP_1024_BIT),"diffie_hellman_group check");
- tester->assert_true(tester,(child_proposals[1].esp.integrity_algorithm == AUTH_HMAC_MD5_96),"integrity_algorithm check");
- tester->assert_true(tester,(child_proposals[1].esp.integrity_algorithm_key_size == 20),"integrity_algorithm check");
- tester->assert_true(tester,(child_proposals[1].esp.spi[0] == 2),"spi check");
- tester->assert_true(tester,(child_proposals[1].esp.spi[1] == 2),"spi check");
- tester->assert_true(tester,(child_proposals[1].esp.spi[2] == 2),"spi check");
- tester->assert_true(tester,(child_proposals[1].esp.spi[3] == 2),"spi check");
+ tester->assert_true(tester,(proposal_count == 2),"child proposal count check");
+ tester->assert_true(tester,(proposals[0].ah.is_set == TRUE),"is ah set check");
+ tester->assert_true(tester,(proposals[0].ah.integrity_algorithm == AUTH_HMAC_MD5_96),"integrity_algorithm check");
+ tester->assert_true(tester,(proposals[0].ah.integrity_algorithm_key_size == 20),"integrity_algorithm_key_size check");
+ tester->assert_true(tester,(proposals[0].ah.diffie_hellman_group == MODP_2048_BIT),"diffie_hellman_group check");
+ tester->assert_true(tester,(proposals[0].ah.extended_sequence_numbers == EXT_SEQ_NUMBERS),"extended_sequence_numbers check");
+ tester->assert_true(tester,(proposals[0].ah.spi[0] == 1),"spi check");
+ tester->assert_true(tester,(proposals[0].ah.spi[1] == 1),"spi check");
+ tester->assert_true(tester,(proposals[0].ah.spi[2] == 1),"spi check");
+ tester->assert_true(tester,(proposals[0].ah.spi[3] == 1),"spi check");
+
+ tester->assert_true(tester,(proposals[0].esp.is_set == TRUE),"is ah set check");
+ tester->assert_true(tester,(proposals[0].esp.encryption_algorithm == ENCR_AES_CBC),"integrity_algorithm check");
+ tester->assert_true(tester,(proposals[0].esp.encryption_algorithm_key_size == 32),"integrity_algorithm_key_size check");
+ tester->assert_true(tester,(proposals[0].esp.diffie_hellman_group == MODP_1024_BIT),"diffie_hellman_group check");
+ tester->assert_true(tester,(proposals[0].esp.integrity_algorithm == AUTH_UNDEFINED),"integrity_algorithm check");
+ tester->assert_true(tester,(proposals[0].esp.spi[0] == 2),"spi check");
+ tester->assert_true(tester,(proposals[0].esp.spi[1] == 2),"spi check");
+ tester->assert_true(tester,(proposals[0].esp.spi[2] == 2),"spi check");
+ tester->assert_true(tester,(proposals[0].esp.spi[3] == 2),"spi check");
+
+ tester->assert_true(tester,(proposals[1].ah.is_set == TRUE),"is ah set check");
+ tester->assert_true(tester,(proposals[1].ah.integrity_algorithm == AUTH_HMAC_MD5_96),"integrity_algorithm check");
+ tester->assert_true(tester,(proposals[1].ah.integrity_algorithm_key_size == 20),"integrity_algorithm_key_size check");
+ tester->assert_true(tester,(proposals[1].ah.diffie_hellman_group == MODP_2048_BIT),"diffie_hellman_group check");
+ tester->assert_true(tester,(proposals[1].ah.extended_sequence_numbers == EXT_SEQ_NUMBERS),"extended_sequence_numbers check");
+ tester->assert_true(tester,(proposals[1].ah.spi[0] == 1),"spi check");
+ tester->assert_true(tester,(proposals[1].ah.spi[1] == 1),"spi check");
+ tester->assert_true(tester,(proposals[1].ah.spi[2] == 1),"spi check");
+ tester->assert_true(tester,(proposals[1].ah.spi[3] == 1),"spi check");
+
+ tester->assert_true(tester,(proposals[1].esp.is_set == TRUE),"is ah set check");
+ tester->assert_true(tester,(proposals[1].esp.encryption_algorithm == ENCR_AES_CBC),"integrity_algorithm check");
+ tester->assert_true(tester,(proposals[1].esp.encryption_algorithm_key_size == 32),"integrity_algorithm_key_size check");
+ tester->assert_true(tester,(proposals[1].esp.diffie_hellman_group == MODP_1024_BIT),"diffie_hellman_group check");
+ tester->assert_true(tester,(proposals[1].esp.integrity_algorithm == AUTH_HMAC_MD5_96),"integrity_algorithm check");
+ tester->assert_true(tester,(proposals[1].esp.integrity_algorithm_key_size == 20),"integrity_algorithm check");
+ tester->assert_true(tester,(proposals[1].esp.spi[0] == 2),"spi check");
+ tester->assert_true(tester,(proposals[1].esp.spi[1] == 2),"spi check");
+ tester->assert_true(tester,(proposals[1].esp.spi[2] == 2),"spi check");
+ tester->assert_true(tester,(proposals[1].esp.spi[3] == 2),"spi check");
if (status == SUCCESS)
{
- allocator_free(child_proposals);
+ allocator_free(proposals);
}
*/
/**
- * @file child_proposal_test.c
+ * @file proposal_test.c
*
- * @brief Tests for the child_proposal_t class.
+ * @brief Tests for the proposal_t class.
*
*/
* for more details.
*/
-#include "child_proposal_test.h"
+#include "proposal_test.h"
#include <daemon.h>
-#include <config/child_proposal.h>
+#include <config/proposal.h>
#include <utils/allocator.h>
#include <utils/logger.h>
/**
* Described in header.
*/
-void test_child_proposal(protected_tester_t *tester)
+void test_proposal(protected_tester_t *tester)
{
- child_proposal_t *proposal1, *proposal2, *proposal3;
+ proposal_t *proposal1, *proposal2, *proposal3;
iterator_t *iterator;
algorithm_t *algo;
bool result;
- proposal1 = child_proposal_create(1);
+ proposal1 = proposal_create(1);
proposal1->add_algorithm(proposal1, ESP, ENCRYPTION_ALGORITHM, ENCR_3DES, 0);
proposal1->add_algorithm(proposal1, ESP, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 32);
proposal1->add_algorithm(proposal1, ESP, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 16);
proposal1->add_algorithm(proposal1, AH, DIFFIE_HELLMAN_GROUP, MODP_1024_BIT, 0);
proposal1->add_algorithm(proposal1, AH, DIFFIE_HELLMAN_GROUP, MODP_2048_BIT, 0);
- proposal2 = child_proposal_create(2);
+ proposal2 = proposal_create(2);
proposal2->add_algorithm(proposal2, ESP, ENCRYPTION_ALGORITHM, ENCR_3IDEA, 0);
proposal2->add_algorithm(proposal2, ESP, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 16);
proposal2->add_algorithm(proposal2, ESP, INTEGRITY_ALGORITHM, AUTH_HMAC_MD5_96, 20);
/**
- * @file child_proposal_test.h
+ * @file proposal_test.h
*
- * @brief Tests for the child_proposal_t class.
+ * @brief Tests for the proposal_t class.
*
*/
#include <utils/tester.h>
/**
- * @brief Test function used to test the child_proposal_t functionality.
+ * @brief Test function used to test the proposal_t functionality.
*
* @param tester associated protected_tester_t object
*
* @ingroup testcases
*/
-void test_child_proposal(protected_tester_t *tester);
+void test_proposal(protected_tester_t *tester);
#endif //CHILD_PROPOSAL_TEST_H_
{
sa_config_t *sa_config;
traffic_selector_t *ts_policy[3], *ts_request[4], *ts_reference[3], **ts_result;
- child_proposal_t *proposal1, *proposal2, *proposal3, *proposal_sel;
+ proposal_t *proposal1, *proposal2, *proposal3, *proposal_sel;
linked_list_t *proposals_list;
iterator_t *iterator;
size_t count;
*/
/* esp only prop */
- proposal1 = child_proposal_create(1);
+ proposal1 = proposal_create(1);
proposal1->add_algorithm(proposal1, ESP, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 16);
/* ah only prop */
- proposal2 = child_proposal_create(2);
+ proposal2 = proposal_create(2);
proposal2->add_algorithm(proposal2, AH, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA1_96, 20);
/* ah and esp prop */
- proposal3 = child_proposal_create(3);
+ proposal3 = proposal_create(3);
proposal3->add_algorithm(proposal3, ESP, ENCRYPTION_ALGORITHM, ENCR_3DES, 16);
proposal3->add_algorithm(proposal3, AH, INTEGRITY_ALGORITHM, AUTH_HMAC_MD5_96, 20);
proposals_list = linked_list_create();
- proposal1 = child_proposal_create(1);
+ proposal1 = proposal_create(1);
proposal1->add_algorithm(proposal1, ESP, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 32);
- proposal2 = child_proposal_create(2);
+ proposal2 = proposal_create(2);
proposal2->add_algorithm(proposal2, ESP, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 16);
proposal2->add_algorithm(proposal2, ESP, ENCRYPTION_ALGORITHM, ENCR_3DES, 16);
proposal2->add_algorithm(proposal2, ESP, ENCRYPTION_ALGORITHM, ENCR_BLOWFISH, 0);
#include <testcases/encryption_payload_test.h>
#include <testcases/init_config_test.h>
#include <testcases/sa_config_test.h>
-#include <testcases/child_proposal_test.h>
+#include <testcases/proposal_test.h>
#include <testcases/rsa_test.h>
#include <testcases/kernel_interface_test.h>
test_t encryption_payload_test = {test_encryption_payload, "encryption payload test"};
test_t init_config_test = {test_init_config, "init_config_t test"};
test_t sa_config_test = {test_sa_config, "sa_config_t test"};
-test_t child_proposal_test = {test_child_proposal, "child_proposal_t test"};
+test_t proposal_test = {test_proposal, "proposal_t test"};
test_t rsa_test = {test_rsa, "RSA private/public key test"};
test_t kernel_interface_test = {test_kernel_interface, "Kernel Interface"};
&encryption_payload_test,
&init_config_test,
&sa_config_test,
- &child_proposal_test,
+ &proposal_test,
&rsa_test,
NULL
};
tester_t *tester = tester_create(test_output, FALSE);
- //tester->perform_tests(tester,all_tests);
- tester->perform_test(tester,&kernel_interface_test);
+ tester->perform_tests(tester,all_tests);
+ //tester->perform_test(tester,&kernel_interface_test);
tester->destroy(tester);
#define AES_KS_LENGTH 120
#define AES_RC_LENGTH 29
+#define AES_BLOCK_SIZE 16
+
typedef struct private_aes_cbc_crypter_t private_aes_cbc_crypter_t;
/**
/**
* The number of cipher rounds.
*/
- u_int32_t aes_Nrnd;
-
- /**
- * The encryption key schedule.
- */
- u_int32_t aes_e_key[AES_KS_LENGTH];
- /**
- * The decryption key schedule.
- */
- u_int32_t aes_d_key[AES_KS_LENGTH];
-
- /**
- * The number of columns in the cipher state.
- */
- u_int32_t aes_Ncol;
-
- /**
- * Blocksize of this AES cypher object.
- */
- u_int32_t blocksize;
-
- /**
- * Decrypts a block.
- *
- * No memory gets allocated.
- *
- * @param this calling object
- * @param[in] in_blk block to decrypt
- * @param[out] out_blk decrypted data are written to this location
- */
- void (*decrypt_block) (const private_aes_cbc_crypter_t *this, const unsigned char in_blk[], unsigned char out_blk[]);
-
- /**
- * Encrypts a block.
- *
- * No memory gets allocated.
- *
- * @param this calling object
- * @param[in] in_blk block to encrypt
- * @param[out] out_blk encrypted data are written to this location
- */
+ u_int32_t aes_Nrnd;
+
+ /**
+ * The encryption key schedule.
+ */
+ u_int32_t aes_e_key[AES_KS_LENGTH];
+
+ /**
+ * The decryption key schedule.
+ */
+ u_int32_t aes_d_key[AES_KS_LENGTH];
+
+ /**
+ * The number of columns in the cipher state.
+ */
+ u_int32_t aes_Ncol;
+
+ /**
+ * Key size of this AES cypher object.
+ */
+ u_int32_t key_size;
+
+ /**
+ * Decrypts a block.
+ *
+ * No memory gets allocated.
+ *
+ * @param this calling object
+ * @param[in] in_blk block to decrypt
+ * @param[out] out_blk decrypted data are written to this location
+ */
+ void (*decrypt_block) (const private_aes_cbc_crypter_t *this, const unsigned char in_blk[], unsigned char out_blk[]);
+
+ /**
+ * Encrypts a block.
+ *
+ * No memory gets allocated.
+ *
+ * @param this calling object
+ * @param[in] in_blk block to encrypt
+ * @param[out] out_blk encrypted data are written to this location
+ */
void (*encrypt_block) (const private_aes_cbc_crypter_t *this, const unsigned char in_blk[], unsigned char out_blk[]);
};
*/
static size_t get_block_size (private_aes_cbc_crypter_t *this)
{
- return this->blocksize;
+ return AES_BLOCK_SIZE;
+}
+
+/**
+ * Implementation of crypter_t.get_key_size.
+ */
+static size_t get_key_size (private_aes_cbc_crypter_t *this)
+{
+ return this->key_size;
}
/**
u_int32_t *kf, *kt, rci, f = 0;
u_int8_t *in_key = key.ptr;
- if (key.len != this->blocksize)
+ if (key.len != this->key_size)
{
return INVALID_ARG;
}
/*
* Described in header
*/
-aes_cbc_crypter_t *aes_cbc_crypter_create(size_t blocksize)
+aes_cbc_crypter_t *aes_cbc_crypter_create(size_t key_size)
{
private_aes_cbc_crypter_t *this = allocator_alloc_thing(private_aes_cbc_crypter_t);
-
+
#if !defined(FIXED_TABLES)
- if(!tab_gen) { gen_tabs(); tab_gen = 1; }
+ if(!tab_gen) { gen_tabs(); tab_gen = 1; }
#endif
-
- switch(blocksize) {
- case 32: /* bytes */
- this->aes_Ncol = 8;
- this->aes_Nkey = 8;
- this->blocksize = blocksize;
- break;
- case 24: /* bytes */
- this->aes_Ncol = 6;
- this->aes_Nkey = 6;
- this->blocksize = blocksize;
- break;
- case 16: /* bytes */
- default:
- this->aes_Ncol = 4;
- this->aes_Nkey = 4;
- this->blocksize = 16;
- break;
- }
-
+
+ this->key_size = key_size;
+ switch(key_size) {
+ case 32: /* bytes */
+ this->aes_Ncol = 8;
+ this->aes_Nkey = 8;
+ break;
+ case 24: /* bytes */
+ this->aes_Ncol = 6;
+ this->aes_Nkey = 6;
+ break;
+ case 16: /* bytes */
+ this->aes_Ncol = 4;
+ this->aes_Nkey = 4;
+ break;
+ default:
+ allocator_free(this);
+ return NULL;
+ }
+
/* functions of crypter_t interface */
this->public.crypter_interface.encrypt = (status_t (*) (crypter_t *, chunk_t,chunk_t, chunk_t *)) encrypt;
this->public.crypter_interface.decrypt = (status_t (*) (crypter_t *, chunk_t , chunk_t, chunk_t *)) decrypt;
this->public.crypter_interface.get_block_size = (size_t (*) (crypter_t *)) get_block_size;
+ this->public.crypter_interface.get_key_size = (size_t (*) (crypter_t *)) get_key_size;
this->public.crypter_interface.set_key = (status_t (*) (crypter_t *,chunk_t)) set_key;
this->public.crypter_interface.destroy = (void (*) (crypter_t *)) destroy;
/**
* @brief Constructor to create aes_cbc_crypter_t objects.
*
- * If an unvalid blocksize is specified, 16 is selected.
+ * Supported key sizes are: 16, 24 or 32.
*
- * @param blocksize block size of AES crypter
- * (16, 24 or 32 are supported)
- * Default size is set to 16.
- * @return aes_cbc_crypter_t object
+ * @param key_size key size in bytes
+ * @return
+ * - aes_cbc_crypter_t object
+ * - NULL if key size not supported
*/
-aes_cbc_crypter_t *aes_cbc_crypter_create(size_t blocksize);
+aes_cbc_crypter_t *aes_cbc_crypter_create(size_t key_size);
#endif //_AES_CRYPTER_H_
/*
* Described in header.
*/
-crypter_t *crypter_create(encryption_algorithm_t encryption_algorithm,size_t blocksize)
+crypter_t *crypter_create(encryption_algorithm_t encryption_algorithm, size_t key_size)
{
switch (encryption_algorithm)
{
case ENCR_AES_CBC:
{
- return (crypter_t*)aes_cbc_crypter_create(blocksize);
+ return (crypter_t*)aes_cbc_crypter_create(key_size);
}
default:
return NULL;
* Currently only the following algorithms are implemented and therefore supported:
* - ENCR_AES_CBC
*
- * @b Constructors:
- * - crypter_create()
- * - aes_cbc_crypter_create()
- *
- * @todo Implement more enryption algorithm, especially 3DES
+ * @todo Implement more enryption algorithms, such as 3DES
*
* @ingroup crypters
*/
/**
* @brief Generic interface for symmetric encryption algorithms.
*
- * @todo Distinguish between block_size and key_size, since not all
- * algorithms use key_size == block_size (e.g. 3DES).
- *
- * @todo Add a getter which says if an algorithm uses fixed key size, needed for
- * tranform_attribute encoding.
+ * @b Constructors:
+ * - crypter_create()
*
* @ingroup crypters
*/
struct crypter_t {
/**
- * @brief Encrypt a chunk of data and allocate space for
- * the encrypted value.
+ * @brief Encrypt a chunk of data and allocate space for the encrypted value.
*
* @param this calling object
* @param data data to encrypt
status_t (*encrypt) (crypter_t *this, chunk_t data, chunk_t iv, chunk_t *encrypted);
/**
- * @brief Decrypt a chunk of data and allocate space for
- * the decrypted value.
+ * @brief Decrypt a chunk of data and allocate space for the decrypted value.
*
* @param this calling object
* @param data data to decrypt
* @return block size in bytes
*/
size_t (*get_block_size) (crypter_t *this);
+
+ /**
+ * @brief Get the key size of this crypter_t object.
+ *
+ * @param this calling object
+ * @return key size in bytes
+ */
+ size_t (*get_key_size) (crypter_t *this);
/**
* @brief Set the key for this crypter_t object.
* @param key key to set
* @return
* - SUCCESS
- * - INVALID_ARG if key size != block size
+ * - INVALID_ARG if key length invalid
*/
status_t (*set_key) (crypter_t *this, chunk_t key);
* Currently only the following algorithms are implemented and therefore supported:
* - ENCR_AES_CBC
*
+ * The key_size is ignored for algorithms with fixed key size.
+ *
* @param encryption_algorithm Algorithm to use for crypter
- * @param blocksize block size in bytes
+ * @param key_size size of the key in bytes
* @return
* - crypter_t object
- * - NULL if encryption algorithm or blocksize is not supported
+ * - NULL if encryption algorithm/key_size is not supported
*/
-crypter_t *crypter_create(encryption_algorithm_t encryption_algorithm, size_t blocksize);
+crypter_t *crypter_create(encryption_algorithm_t encryption_algorithm, size_t key_size);
#endif /*CRYPTER_H_*/
return SUCCESS;
}
+/**
+ * Implementation of diffie_hellman_t.get_dh_group.
+ */
+static diffie_hellman_group_t get_dh_group(private_diffie_hellman_t *this)
+{
+ return this->dh_group_number;
+}
+
/**
* Implementation of diffie_hellman_t.destroy.
*/
this->public.set_other_public_value = (void (*)(diffie_hellman_t *, chunk_t )) set_other_public_value;
this->public.get_other_public_value = (status_t (*)(diffie_hellman_t *, chunk_t *)) get_other_public_value;
this->public.get_my_public_value = (void (*)(diffie_hellman_t *, chunk_t *)) get_my_public_value;
+ this->public.get_dh_group = (diffie_hellman_group_t (*)(diffie_hellman_t *)) get_dh_group;
this->public.destroy = (void (*)(diffie_hellman_t *)) destroy;
/* private functions */
* @param[out] public_value public value of caller is stored at this location
*/
void (*get_my_public_value) (diffie_hellman_t *this, chunk_t *public_value);
+
+ /**
+ * @brief Get the DH group used.
+ *
+ * @param this calling diffie_hellman_t object
+ * @return DH group set in construction
+ */
+ diffie_hellman_group_t (*get_dh_group) (diffie_hellman_t *this);
/**
* @brief Destroys an diffie_hellman_t object.
return this->hmac->get_block_size(this->hmac);
}
+/**
+ * Implementation of prf_t.get_block_size.
+ */
+static size_t get_key_size(private_hmac_prf_t *this)
+{
+ /* for HMAC prfs, IKEv2 uses block size as key size */
+ return this->hmac->get_block_size(this->hmac);
+}
+
/**
* Implementation of prf_t.set_key.
*/
this->public.prf_interface.get_bytes = (void (*) (prf_t *,chunk_t,u_int8_t*))get_bytes;
this->public.prf_interface.allocate_bytes = (void (*) (prf_t*,chunk_t,chunk_t*))allocate_bytes;
this->public.prf_interface.get_block_size = (size_t (*) (prf_t*))get_block_size;
+ this->public.prf_interface.get_key_size = (size_t (*) (prf_t*))get_key_size;
this->public.prf_interface.set_key = (void (*) (prf_t *,chunk_t))set_key;
this->public.prf_interface.destroy = (void (*) (prf_t *))destroy;
*/
size_t (*get_block_size) (prf_t *this);
+ /**
+ * @brief Get the key size of this prf_t object.
+ *
+ * @param this calling object
+ * @return key size in bytes
+ */
+ size_t (*get_key_size) (prf_t *this);
+
/**
* @brief Set the key for this prf_t object.
*
*/
static size_t get_key_size (private_hmac_signer_t *this)
{
+ /* for HMAC signer, IKEv2 uses block size as key size */
return this->hmac_prf->get_block_size(this->hmac_prf);
}