From: Martin Willi Date: Tue, 14 Feb 2006 14:52:00 +0000 (-0000) Subject: - refactored ike proposal X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ce461bbd13c5ea6a94ba0b34cbb4d1be8159b67e;p=people%2Fms%2Fstrongswan.git - refactored ike proposal - uses now proposal_t, wich is also used by child proposals - ike key derivation refactored - crypter_t api has get_key_size now - some other improvements here and there --- diff --git a/Source/charon/config/Makefile.config b/Source/charon/config/Makefile.config index 7ca46d14f..7189d404b 100644 --- a/Source/charon/config/Makefile.config +++ b/Source/charon/config/Makefile.config @@ -31,6 +31,6 @@ OBJS+= $(BUILD_DIR)traffic_selector.o $(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 $@ $< diff --git a/Source/charon/config/configuration_manager.c b/Source/charon/config/configuration_manager.c index ed5c33d26..adbd0ddee 100644 --- a/Source/charon/config/configuration_manager.c +++ b/Source/charon/config/configuration_manager.c @@ -275,27 +275,32 @@ u_int8_t private_key_2[]; 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, @@ -305,46 +310,46 @@ static void load_default_config (private_configuration_manager_t *this) 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); diff --git a/Source/charon/config/init_config.c b/Source/charon/config/init_config.c index 27f669b9d..92871dd3b 100644 --- a/Source/charon/config/init_config.c +++ b/Source/charon/config/init_config.c @@ -87,108 +87,111 @@ static host_t * get_other_host_clone (private_init_config_t *this) } /** - * 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; } /** @@ -196,12 +199,11 @@ static void add_proposal (private_init_config_t *this,size_t priority, ike_propo */ 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); @@ -222,10 +224,11 @@ init_config_t * init_config_create(char * my_ip, char *other_ip, u_int16_t my_po 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 */ diff --git a/Source/charon/config/init_config.h b/Source/charon/config/init_config.h index 14ffeeee8..f63df61cf 100644 --- a/Source/charon/config/init_config.h +++ b/Source/charon/config/init_config.h @@ -25,60 +25,14 @@ #include #include -#include +#include +#include #include #include #include #include -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; @@ -100,7 +54,7 @@ struct 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. @@ -110,7 +64,7 @@ struct init_config_t { * @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. @@ -120,7 +74,7 @@ struct init_config_t { * @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. @@ -130,54 +84,60 @@ struct init_config_t { * @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. @@ -194,6 +154,6 @@ struct init_config_t { * * @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_ diff --git a/Source/charon/config/child_proposal.c b/Source/charon/config/proposal.c similarity index 82% rename from Source/charon/config/child_proposal.c rename to Source/charon/config/proposal.c index 729102ebf..528cf9808 100644 --- a/Source/charon/config/child_proposal.c +++ b/Source/charon/config/proposal.c @@ -1,7 +1,7 @@ /** - * @file child_proposal.c + * @file proposal.c * - * @brief Implementation of child_proposal_t. + * @brief Implementation of proposal_t. * */ @@ -20,7 +20,7 @@ * for more details. */ -#include "child_proposal.h" +#include "proposal.h" #include #include @@ -105,17 +105,17 @@ struct protocol_proposal_t { }; -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 @@ -131,7 +131,7 @@ struct private_child_proposal_t { /** * 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; @@ -187,9 +187,9 @@ static void add_algo(linked_list_t *list, u_int8_t algo, size_t key_size) } /** - * 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); @@ -216,9 +216,9 @@ static void add_algorithm(private_child_proposal_t *this, protocol_id_t proto, t } /** - * 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); @@ -255,9 +255,9 @@ static bool get_algorithm(private_child_proposal_t *this, protocol_id_t proto, t } /** - * 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) @@ -328,11 +328,11 @@ static bool select_algo(linked_list_t *first, linked_list_t *second, bool *add, } /** - * 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; @@ -353,7 +353,7 @@ static child_proposal_t *select_proposal(private_child_proposal_t *this, private 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); @@ -448,17 +448,17 @@ static child_proposal_t *select_proposal(private_child_proposal_t *this, private } /** - * 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; @@ -480,9 +480,9 @@ static void get_protocols(private_child_proposal_t *this, protocol_id_t ids[2]) } /** - * 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) @@ -500,9 +500,9 @@ static void set_spi(private_child_proposal_t *this, protocol_id_t proto, u_int64 } /** - * 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) @@ -535,9 +535,9 @@ static void free_algo_list(linked_list_t *list) } /** - * 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) { @@ -561,19 +561,19 @@ static void destroy(private_child_proposal_t *this) /* * 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; diff --git a/Source/charon/config/child_proposal.h b/Source/charon/config/proposal.h similarity index 81% rename from Source/charon/config/child_proposal.h rename to Source/charon/config/proposal.h index 69bd7f395..53d417bb1 100644 --- a/Source/charon/config/child_proposal.h +++ b/Source/charon/config/proposal.h @@ -1,7 +1,7 @@ /** - * @file child_proposal.h + * @file proposal.h * - * @brief Interface of child_proposal_t. + * @brief Interface of proposal_t. * */ @@ -20,8 +20,8 @@ * for more details. */ -#ifndef _CHILD_PROPOSAL_H_ -#define _CHILD_PROPOSAL_H_ +#ifndef _PROPOSAL_H_ +#define _PROPOSAL_H_ #include #include @@ -117,22 +117,22 @@ struct algorithm_t { 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. @@ -154,7 +154,7 @@ struct child_proposal_t { * @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. @@ -164,13 +164,13 @@ struct child_proposal_t { * @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 @@ -178,7 +178,7 @@ struct child_proposal_t { * @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. @@ -193,7 +193,7 @@ struct child_proposal_t { * - 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. @@ -201,7 +201,7 @@ struct child_proposal_t { * @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. @@ -212,7 +212,7 @@ struct child_proposal_t { * @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. @@ -221,7 +221,7 @@ struct child_proposal_t { * @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. @@ -230,24 +230,24 @@ struct child_proposal_t { * @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_ diff --git a/Source/charon/config/sa_config.c b/Source/charon/config/sa_config.c index ca29b0294..6e7f8ee03 100644 --- a/Source/charon/config/sa_config.c +++ b/Source/charon/config/sa_config.c @@ -216,10 +216,10 @@ static linked_list_t *get_proposals(private_sa_config_t *this) /** * 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); @@ -272,7 +272,7 @@ static void add_traffic_selector_responder(private_sa_config_t *this, traffic_se /** * 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); } @@ -282,7 +282,7 @@ static void add_proposal(private_sa_config_t *this, child_proposal_t *proposal) */ static status_t destroy(private_sa_config_t *this) { - child_proposal_t *proposal; + proposal_t *proposal; traffic_selector_t *traffic_selector; @@ -332,10 +332,10 @@ sa_config_t *sa_config_create(id_type_t my_id_type, char *my_id, id_type_t other 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 */ diff --git a/Source/charon/config/sa_config.h b/Source/charon/config/sa_config.h index fd1952864..4fd7305f6 100644 --- a/Source/charon/config/sa_config.h +++ b/Source/charon/config/sa_config.h @@ -32,7 +32,7 @@ #include #include #include -#include +#include @@ -174,7 +174,7 @@ struct sa_config_t { * @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. @@ -211,7 +211,7 @@ struct sa_config_t { * @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 diff --git a/Source/charon/daemon.h b/Source/charon/daemon.h index 4650c5cb0..343aecb25 100644 --- a/Source/charon/daemon.h +++ b/Source/charon/daemon.h @@ -97,7 +97,6 @@ struct daemon_t { /** * A send_queue_t instance. */ - send_queue_t *send_queue; /** diff --git a/Source/charon/encoding/payloads/notify_payload.c b/Source/charon/encoding/payloads/notify_payload.c index dccc9d169..ee4b44e9e 100644 --- a/Source/charon/encoding/payloads/notify_payload.c +++ b/Source/charon/encoding/payloads/notify_payload.c @@ -180,8 +180,22 @@ static status_t verify(private_notify_payload_t *this) 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; } diff --git a/Source/charon/encoding/payloads/proposal_substructure.c b/Source/charon/encoding/payloads/proposal_substructure.c index a2ba15b9e..2cf96fbb6 100644 --- a/Source/charon/encoding/payloads/proposal_substructure.c +++ b/Source/charon/encoding/payloads/proposal_substructure.c @@ -406,9 +406,9 @@ static size_t get_spi_size (private_proposal_substructure_t *this) } /** - * 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); @@ -525,7 +525,7 @@ proposal_substructure_t *proposal_substructure_create() 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; @@ -554,7 +554,7 @@ proposal_substructure_t *proposal_substructure_create() /* * 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; diff --git a/Source/charon/encoding/payloads/proposal_substructure.h b/Source/charon/encoding/payloads/proposal_substructure.h index 0247584bb..2270a525b 100644 --- a/Source/charon/encoding/payloads/proposal_substructure.h +++ b/Source/charon/encoding/payloads/proposal_substructure.h @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include @@ -173,7 +173,7 @@ struct proposal_substructure_t { */ 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. @@ -201,7 +201,7 @@ struct proposal_substructure_t { 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 @@ -215,7 +215,7 @@ proposal_substructure_t *proposal_substructure_create(); * * @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_*/ diff --git a/Source/charon/encoding/payloads/sa_payload.c b/Source/charon/encoding/payloads/sa_payload.c index 90f8698f8..3a40d41b2 100644 --- a/Source/charon/encoding/payloads/sa_payload.c +++ b/Source/charon/encoding/payloads/sa_payload.c @@ -257,9 +257,9 @@ static void add_proposal_substructure (private_sa_payload_t *this,proposal_subst } /** - * 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]; @@ -271,161 +271,26 @@ static void add_child_proposal(private_sa_payload_t *this, child_proposal_t *pro { 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)) { @@ -436,11 +301,11 @@ static linked_list_t *get_child_proposals(private_sa_payload_t *this) { /* 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; @@ -484,8 +349,7 @@ sa_payload_t *sa_payload_create() /* 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 */ @@ -503,52 +367,10 @@ sa_payload_t *sa_payload_create() /* * 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 */ @@ -556,7 +378,7 @@ sa_payload_t *sa_payload_create_from_child_proposal_list(linked_list_t *proposal 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); @@ -566,11 +388,11 @@ sa_payload_t *sa_payload_create_from_child_proposal_list(linked_list_t *proposal /* * 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; } diff --git a/Source/charon/encoding/payloads/sa_payload.h b/Source/charon/encoding/payloads/sa_payload.h index 0c54ae689..1f11d516c 100644 --- a/Source/charon/encoding/payloads/sa_payload.h +++ b/Source/charon/encoding/payloads/sa_payload.h @@ -54,9 +54,9 @@ typedef struct sa_payload_t sa_payload_t; * @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 */ @@ -91,36 +91,20 @@ struct sa_payload_t { * @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. @@ -140,19 +124,26 @@ struct sa_payload_t { 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_*/ diff --git a/Source/charon/encoding/payloads/transform_substructure.h b/Source/charon/encoding/payloads/transform_substructure.h index 79dd101d0..62def3309 100644 --- a/Source/charon/encoding/payloads/transform_substructure.h +++ b/Source/charon/encoding/payloads/transform_substructure.h @@ -32,7 +32,7 @@ #include #include #include -#include +#include /** diff --git a/Source/charon/sa/authenticator.c b/Source/charon/sa/authenticator.c index 7d40c78c2..5aaa2d983 100644 --- a/Source/charon/sa/authenticator.c +++ b/Source/charon/sa/authenticator.c @@ -116,6 +116,7 @@ static chunk_t allocate_octets(private_authenticator_t *this, 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]; /* @@ -139,23 +140,22 @@ static chunk_t allocate_octets(private_authenticator_t *this, 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; diff --git a/Source/charon/sa/child_sa.c b/Source/charon/sa/child_sa.c index c18b760f2..2c4624310 100644 --- a/Source/charon/sa/child_sa.c +++ b/Source/charon/sa/child_sa.c @@ -70,7 +70,7 @@ static void destroy(private_child_sa_t *this) /* * 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; diff --git a/Source/charon/sa/child_sa.h b/Source/charon/sa/child_sa.h index 8a7462594..bde032b74 100644 --- a/Source/charon/sa/child_sa.h +++ b/Source/charon/sa/child_sa.h @@ -67,6 +67,6 @@ struct child_sa_t { * @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_*/ diff --git a/Source/charon/sa/ike_sa.c b/Source/charon/sa/ike_sa.c index 2f403abf6..ac617faef 100644 --- a/Source/charon/sa/ike_sa.c +++ b/Source/charon/sa/ike_sa.c @@ -57,15 +57,6 @@ struct private_ike_sa_t { * 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. @@ -152,112 +143,43 @@ struct private_ike_sa_t { /** * 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. @@ -278,6 +200,13 @@ struct private_ike_sa_t { * 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); }; /** @@ -440,103 +369,6 @@ static ike_sa_id_t* get_id(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. */ @@ -680,97 +512,209 @@ static prf_t *get_child_prf (private_ike_sa_t *this) } /** - * 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; } @@ -1081,10 +1025,6 @@ static void destroy (private_ike_sa_t *this) /* 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) { @@ -1120,6 +1060,14 @@ static void destroy (private_ike_sa_t *this) 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"); @@ -1182,11 +1130,10 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id) /* 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; @@ -1200,7 +1147,7 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id) 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; @@ -1230,13 +1177,13 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id) 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; diff --git a/Source/charon/sa/ike_sa.h b/Source/charon/sa/ike_sa.h index 09101f7f5..f5591a00b 100644 --- a/Source/charon/sa/ike_sa.h +++ b/Source/charon/sa/ike_sa.h @@ -163,22 +163,6 @@ struct protected_ike_sa_t { * @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. @@ -259,16 +243,20 @@ struct protected_ike_sa_t { 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. @@ -368,7 +356,7 @@ struct protected_ike_sa_t { 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 @@ -383,6 +371,22 @@ struct protected_ike_sa_t { */ 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. * @@ -403,26 +407,6 @@ struct protected_ike_sa_t { */ 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. * diff --git a/Source/charon/sa/states/ike_auth_requested.c b/Source/charon/sa/states/ike_auth_requested.c index 60369ba28..e6559319c 100644 --- a/Source/charon/sa/states/ike_auth_requested.c +++ b/Source/charon/sa/states/ike_auth_requested.c @@ -326,14 +326,14 @@ static status_t process_idr_payload(private_ike_auth_requested_t *this, id_paylo */ 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) { diff --git a/Source/charon/sa/states/ike_sa_init_requested.c b/Source/charon/sa/states/ike_sa_init_requested.c index 7636ecbbe..327eb2d7c 100644 --- a/Source/charon/sa/states/ike_sa_init_requested.c +++ b/Source/charon/sa/states/ike_sa_init_requested.c @@ -70,17 +70,14 @@ struct private_ike_sa_init_requested_t { 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 @@ -329,7 +326,15 @@ static status_t process_message(private_ike_sa_init_requested_t *this, message_t { 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); @@ -402,45 +407,39 @@ status_t process_nonce_payload (private_ike_sa_init_requested_t *this, nonce_pay */ 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; } @@ -448,24 +447,9 @@ status_t process_sa_payload (private_ike_sa_init_requested_t *this, sa_payload_t * 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; } @@ -528,7 +512,7 @@ static status_t build_sa_payload (private_ike_sa_init_requested_t *this, message /* 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 */ @@ -625,9 +609,25 @@ static status_t process_notify_payload(private_ike_sa_init_requested_t *this, no 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); @@ -644,15 +644,13 @@ static status_t process_notify_payload(private_ike_sa_init_requested_t *this, no 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: { @@ -676,7 +674,6 @@ static status_t process_notify_payload(private_ike_sa_init_requested_t *this, no } } - /** * Implementation of state_t.get_state. */ @@ -690,14 +687,13 @@ static ike_sa_state_t get_state(private_ike_sa_init_requested_t *this) */ 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); } /** @@ -705,24 +701,21 @@ static void destroy_after_state_change (private_ike_sa_init_requested_t *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); @@ -748,9 +741,9 @@ ike_sa_init_requested_t *ike_sa_init_requested_create(protected_ike_sa_t *ike_sa 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); } diff --git a/Source/charon/sa/states/ike_sa_init_requested.h b/Source/charon/sa/states/ike_sa_init_requested.h index 7d4df6ba8..1fe0a6d1d 100644 --- a/Source/charon/sa/states/ike_sa_init_requested.h +++ b/Source/charon/sa/states/ike_sa_init_requested.h @@ -53,7 +53,6 @@ struct ike_sa_init_requested_t { * 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 @@ -62,7 +61,6 @@ struct ike_sa_init_requested_t { * @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); diff --git a/Source/charon/sa/states/ike_sa_init_responded.c b/Source/charon/sa/states/ike_sa_init_responded.c index 2c21992e6..536041d0d 100644 --- a/Source/charon/sa/states/ike_sa_init_responded.c +++ b/Source/charon/sa/states/ike_sa_init_responded.c @@ -387,7 +387,7 @@ static status_t build_idr_payload(private_ike_sa_init_responded_t *this, id_payl */ 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; @@ -397,7 +397,7 @@ static status_t build_sa_payload(private_ike_sa_init_responded_t *this, sa_paylo /* 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 */ @@ -426,7 +426,7 @@ static status_t build_sa_payload(private_ike_sa_init_responded_t *this, sa_paylo } /* 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 */ diff --git a/Source/charon/sa/states/initiator_init.c b/Source/charon/sa/states/initiator_init.c index 6ab698f89..f27dcb559 100644 --- a/Source/charon/sa/states/initiator_init.c +++ b/Source/charon/sa/states/initiator_init.c @@ -57,17 +57,6 @@ struct private_initiator_init_t { */ 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. @@ -124,49 +113,41 @@ static status_t initiate_connection (private_initiator_init_t *this, char *name) 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; @@ -174,24 +155,18 @@ status_t retry_initiate_connection (private_initiator_init_t *this, int dh_group 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"); @@ -222,7 +197,7 @@ status_t retry_initiate_connection (private_initiator_init_t *this, int dh_group /* 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"); @@ -236,19 +211,16 @@ status_t retry_initiate_connection (private_initiator_init_t *this, int dh_group 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); @@ -261,13 +233,15 @@ static void build_ke_payload(private_initiator_init_t *this, message_t *request) { 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); @@ -372,7 +346,6 @@ initiator_init_t *initiator_init_create(protected_ike_sa_t *ike_sa) /* 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; diff --git a/Source/charon/sa/states/responder_init.c b/Source/charon/sa/states/responder_init.c index 2ea5b034d..c85f12efc 100644 --- a/Source/charon/sa/states/responder_init.c +++ b/Source/charon/sa/states/responder_init.c @@ -79,6 +79,11 @@ struct private_responder_init_t { */ chunk_t received_nonce; + /** + * Selected proposal + */ + proposal_t *proposal; + /** * Logger used to log data . * @@ -153,7 +158,6 @@ static status_t process_message(private_responder_init_t *this, message_t *messa 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; @@ -275,17 +279,15 @@ static status_t process_message(private_responder_init_t *this, message_t *messa { 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); @@ -318,47 +320,40 @@ static status_t process_message(private_responder_init_t *this, message_t *messa */ 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); @@ -383,6 +378,7 @@ static status_t build_ke_payload(private_responder_init_t *this,ke_payload_t *ke 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; @@ -510,6 +506,10 @@ static void destroy(private_responder_init_t *this) 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); } @@ -527,6 +527,10 @@ static void destroy_after_state_change (private_responder_init_t *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); @@ -558,6 +562,7 @@ responder_init_t *responder_init_create(protected_ike_sa_t *ike_sa) this->received_nonce = CHUNK_INITIALIZER; this->dh_group_number = MODP_UNDEFINED; this->diffie_hellman = NULL; + this->proposal = NULL; return &(this->public); } diff --git a/Source/charon/testcases/Makefile.testcases b/Source/charon/testcases/Makefile.testcases index b338989ae..a459e3221 100644 --- a/Source/charon/testcases/Makefile.testcases +++ b/Source/charon/testcases/Makefile.testcases @@ -116,8 +116,8 @@ TEST_OBJS+= $(BUILD_DIR)sa_config_test.o $(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 diff --git a/Source/charon/testcases/generator_test.c b/Source/charon/testcases/generator_test.c index c249e82cc..e1a1dc1a6 100644 --- a/Source/charon/testcases/generator_test.c +++ b/Source/charon/testcases/generator_test.c @@ -422,11 +422,9 @@ void test_generator_with_sa_payload(protected_tester_t *tester) 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; @@ -488,30 +486,30 @@ void test_generator_with_sa_payload(protected_tester_t *tester) 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); @@ -581,26 +579,22 @@ void test_generator_with_sa_payload(protected_tester_t *tester) 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); @@ -643,7 +637,9 @@ void test_generator_with_sa_payload(protected_tester_t *tester) 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); @@ -655,32 +651,32 @@ void test_generator_with_sa_payload(protected_tester_t *tester) 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); @@ -754,8 +750,8 @@ void test_generator_with_sa_payload(protected_tester_t *tester) 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); diff --git a/Source/charon/testcases/init_config_test.c b/Source/charon/testcases/init_config_test.c index b8c985362..5e4506ab5 100644 --- a/Source/charon/testcases/init_config_test.c +++ b/Source/charon/testcases/init_config_test.c @@ -32,97 +32,48 @@ 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); } diff --git a/Source/charon/testcases/parser_test.c b/Source/charon/testcases/parser_test.c index 92493b235..5dcfc7ca3 100644 --- a/Source/charon/testcases/parser_test.c +++ b/Source/charon/testcases/parser_test.c @@ -104,8 +104,6 @@ void test_parser_with_sa_payload(protected_tester_t *tester) 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 */ @@ -242,7 +240,7 @@ void test_parser_with_sa_payload(protected_tester_t *tester) 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"); @@ -268,6 +266,7 @@ void test_parser_with_sa_payload(protected_tester_t *tester) { allocator_free(ike_proposals); } + */ sa_payload->destroy(sa_payload); /* now test SA functionality after parsing an SA payload with child sa proposals*/ @@ -347,59 +346,59 @@ void test_parser_with_sa_payload(protected_tester_t *tester) 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); } */ diff --git a/Source/charon/testcases/child_proposal_test.c b/Source/charon/testcases/proposal_test.c similarity index 91% rename from Source/charon/testcases/child_proposal_test.c rename to Source/charon/testcases/proposal_test.c index f0944df8d..7e7f2a4c5 100644 --- a/Source/charon/testcases/child_proposal_test.c +++ b/Source/charon/testcases/proposal_test.c @@ -1,7 +1,7 @@ /** - * @file child_proposal_test.c + * @file proposal_test.c * - * @brief Tests for the child_proposal_t class. + * @brief Tests for the proposal_t class. * */ @@ -20,10 +20,10 @@ * for more details. */ -#include "child_proposal_test.h" +#include "proposal_test.h" #include -#include +#include #include #include @@ -31,14 +31,14 @@ /** * 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); @@ -48,7 +48,7 @@ void test_child_proposal(protected_tester_t *tester) 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); diff --git a/Source/charon/testcases/child_proposal_test.h b/Source/charon/testcases/proposal_test.h similarity index 80% rename from Source/charon/testcases/child_proposal_test.h rename to Source/charon/testcases/proposal_test.h index 400951e78..d6d9681ac 100644 --- a/Source/charon/testcases/child_proposal_test.h +++ b/Source/charon/testcases/proposal_test.h @@ -1,7 +1,7 @@ /** - * @file child_proposal_test.h + * @file proposal_test.h * - * @brief Tests for the child_proposal_t class. + * @brief Tests for the proposal_t class. * */ @@ -27,13 +27,13 @@ #include /** - * @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_ diff --git a/Source/charon/testcases/sa_config_test.c b/Source/charon/testcases/sa_config_test.c index 8fe624eb2..2dfb1118b 100644 --- a/Source/charon/testcases/sa_config_test.c +++ b/Source/charon/testcases/sa_config_test.c @@ -37,7 +37,7 @@ void test_sa_config(protected_tester_t *tester) { 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; @@ -61,15 +61,15 @@ void test_sa_config(protected_tester_t *tester) */ /* 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); @@ -84,9 +84,9 @@ void test_sa_config(protected_tester_t *tester) 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); diff --git a/Source/charon/testcases/testcases.c b/Source/charon/testcases/testcases.c index 170ebf6e8..af539cb4f 100644 --- a/Source/charon/testcases/testcases.c +++ b/Source/charon/testcases/testcases.c @@ -58,7 +58,7 @@ #include #include #include -#include +#include #include #include @@ -123,7 +123,7 @@ test_t hmac_signer_test2 = {test_hmac_sha1_signer, "HMAC SHA1 signer test"}; 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"}; @@ -233,7 +233,7 @@ int main() &encryption_payload_test, &init_config_test, &sa_config_test, - &child_proposal_test, + &proposal_test, &rsa_test, NULL }; @@ -249,8 +249,8 @@ int main() 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); diff --git a/Source/charon/transforms/crypters/aes_cbc_crypter.c b/Source/charon/transforms/crypters/aes_cbc_crypter.c index 2768c06ee..d5d0f9a60 100644 --- a/Source/charon/transforms/crypters/aes_cbc_crypter.c +++ b/Source/charon/transforms/crypters/aes_cbc_crypter.c @@ -41,6 +41,8 @@ #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; /** @@ -63,47 +65,48 @@ struct 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[]); }; @@ -1464,7 +1467,15 @@ static status_t encrypt (private_aes_cbc_crypter_t *this, chunk_t data, chunk_t */ 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; } /** @@ -1475,7 +1486,7 @@ static status_t set_key (private_aes_cbc_crypter_t *this, chunk_t key) 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; } @@ -1574,37 +1585,38 @@ static void destroy (private_aes_cbc_crypter_t *this) /* * 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; diff --git a/Source/charon/transforms/crypters/aes_cbc_crypter.h b/Source/charon/transforms/crypters/aes_cbc_crypter.h index 360f2454d..62cd77af7 100644 --- a/Source/charon/transforms/crypters/aes_cbc_crypter.h +++ b/Source/charon/transforms/crypters/aes_cbc_crypter.h @@ -48,14 +48,14 @@ struct aes_cbc_crypter_t { /** * @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_ diff --git a/Source/charon/transforms/crypters/crypter.c b/Source/charon/transforms/crypters/crypter.c index aebb220cc..37b96304e 100644 --- a/Source/charon/transforms/crypters/crypter.c +++ b/Source/charon/transforms/crypters/crypter.c @@ -49,13 +49,13 @@ mapping_t encryption_algorithm_m[] = { /* * 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; diff --git a/Source/charon/transforms/crypters/crypter.h b/Source/charon/transforms/crypters/crypter.h index 25a27e142..7f371de8a 100644 --- a/Source/charon/transforms/crypters/crypter.h +++ b/Source/charon/transforms/crypters/crypter.h @@ -33,11 +33,7 @@ typedef enum encryption_algorithm_t encryption_algorithm_t; * 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 */ @@ -71,18 +67,14 @@ typedef struct crypter_t crypter_t; /** * @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 @@ -95,8 +87,7 @@ struct crypter_t { 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 @@ -115,6 +106,14 @@ struct crypter_t { * @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. @@ -123,7 +122,7 @@ struct crypter_t { * @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); @@ -141,12 +140,14 @@ struct crypter_t { * 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_*/ diff --git a/Source/charon/transforms/diffie_hellman.c b/Source/charon/transforms/diffie_hellman.c index 9c75237cc..88900eb61 100644 --- a/Source/charon/transforms/diffie_hellman.c +++ b/Source/charon/transforms/diffie_hellman.c @@ -530,6 +530,14 @@ static status_t get_shared_secret(private_diffie_hellman_t *this,chunk_t *secret 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. */ @@ -562,6 +570,7 @@ diffie_hellman_t *diffie_hellman_create(diffie_hellman_group_t dh_group_number) 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 */ diff --git a/Source/charon/transforms/diffie_hellman.h b/Source/charon/transforms/diffie_hellman.h index 2c0f948e1..d4f956325 100644 --- a/Source/charon/transforms/diffie_hellman.h +++ b/Source/charon/transforms/diffie_hellman.h @@ -117,6 +117,14 @@ struct diffie_hellman_t { * @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. diff --git a/Source/charon/transforms/prfs/hmac_prf.c b/Source/charon/transforms/prfs/hmac_prf.c index af307a4d0..ce4330090 100644 --- a/Source/charon/transforms/prfs/hmac_prf.c +++ b/Source/charon/transforms/prfs/hmac_prf.c @@ -67,6 +67,15 @@ static size_t get_block_size(private_hmac_prf_t *this) 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. */ @@ -94,6 +103,7 @@ hmac_prf_t *hmac_prf_create(hash_algorithm_t hash_algorithm) 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; diff --git a/Source/charon/transforms/prfs/prf.h b/Source/charon/transforms/prfs/prf.h index d96fc66ae..17b1110b2 100644 --- a/Source/charon/transforms/prfs/prf.h +++ b/Source/charon/transforms/prfs/prf.h @@ -97,6 +97,14 @@ struct prf_t { */ 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. * diff --git a/Source/charon/transforms/signers/hmac_signer.c b/Source/charon/transforms/signers/hmac_signer.c index ed17b23a6..ee029011f 100644 --- a/Source/charon/transforms/signers/hmac_signer.c +++ b/Source/charon/transforms/signers/hmac_signer.c @@ -109,6 +109,7 @@ static bool verify_signature (private_hmac_signer_t *this, chunk_t data, chunk_t */ 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); }