diff options
Diffstat (limited to 'Source')
-rw-r--r-- | Source/charon/encoding/message.c | 9 | ||||
-rw-r--r-- | Source/charon/encoding/message.h | 9 | ||||
-rw-r--r-- | Source/charon/encoding/payloads/auth_payload.c | 9 | ||||
-rw-r--r-- | Source/charon/encoding/payloads/auth_payload.h | 10 | ||||
-rw-r--r-- | Source/charon/encoding/payloads/id_payload.c | 13 | ||||
-rw-r--r-- | Source/charon/encoding/payloads/id_payload.h | 12 | ||||
-rw-r--r-- | Source/charon/sa/authenticator.c | 59 | ||||
-rw-r--r-- | Source/charon/sa/authenticator.h | 9 | ||||
-rw-r--r-- | Source/charon/sa/ike_sa.c | 27 | ||||
-rw-r--r-- | Source/charon/sa/ike_sa.h | 23 | ||||
-rw-r--r-- | Source/charon/sa/states/ike_auth_requested.c | 48 | ||||
-rw-r--r-- | Source/charon/sa/states/ike_auth_requested.h | 2 | ||||
-rw-r--r-- | Source/charon/sa/states/ike_sa_init_requested.c | 79 | ||||
-rw-r--r-- | Source/charon/sa/states/ike_sa_init_requested.h | 2 | ||||
-rw-r--r-- | Source/charon/sa/states/ike_sa_init_responded.c | 96 | ||||
-rw-r--r-- | Source/charon/sa/states/ike_sa_init_responded.h | 2 | ||||
-rw-r--r-- | Source/charon/sa/states/initiator_init.c | 11 | ||||
-rw-r--r-- | Source/charon/sa/states/responder_init.c | 13 | ||||
-rw-r--r-- | Source/charon/testcases/parser_test.c | 4 |
19 files changed, 303 insertions, 134 deletions
diff --git a/Source/charon/encoding/message.c b/Source/charon/encoding/message.c index 7fea8aea3..996f8fb87 100644 --- a/Source/charon/encoding/message.c +++ b/Source/charon/encoding/message.c @@ -640,6 +640,14 @@ static packet_t *get_packet (private_message_t *this) } /** + * Implementation of message_t.get_packet_data. + */ +static chunk_t get_packet_data (private_message_t *this) +{ + return allocator_clone_chunk(this->packet->data); +} + +/** * Implementation of message_t.parse_header. */ static status_t parse_header(private_message_t *this) @@ -1163,6 +1171,7 @@ message_t *message_create_from_packet(packet_t *packet) this->public.parse_body = (status_t (*) (message_t *,crypter_t*,signer_t*)) parse_body; this->public.verify = (status_t (*) (message_t*)) verify; this->public.get_packet = (packet_t * (*) (message_t*)) get_packet; + this->public.get_packet_data = (chunk_t (*) (message_t *this)) get_packet_data; this->public.destroy = (void(*)(message_t*))destroy; /* private values */ diff --git a/Source/charon/encoding/message.h b/Source/charon/encoding/message.h index dfbb10da9..e3be83653 100644 --- a/Source/charon/encoding/message.h +++ b/Source/charon/encoding/message.h @@ -290,6 +290,15 @@ struct message_t { packet_t * (*get_packet) (message_t *this); /** + * Returns a clone of the internal stored packet_t data. + * + * @param this message_t object + * @return clone of the internal stored packet_t data. + */ + chunk_t (*get_packet_data) (message_t *this); + + + /** * @brief Destroys a message and all including objects. * * @param this message_t object diff --git a/Source/charon/encoding/payloads/auth_payload.c b/Source/charon/encoding/payloads/auth_payload.c index 1070826c2..e9dad81b4 100644 --- a/Source/charon/encoding/payloads/auth_payload.c +++ b/Source/charon/encoding/payloads/auth_payload.c @@ -215,6 +215,14 @@ static void set_data (private_auth_payload_t *this, chunk_t data) */ static chunk_t get_data (private_auth_payload_t *this) { + return (this->auth_data); +} + +/** + * Implementation of auth_payload_t.get_data_clone. + */ +static chunk_t get_data_clone (private_auth_payload_t *this) +{ chunk_t cloned_data; if (this->auth_data.ptr == NULL) { @@ -259,6 +267,7 @@ auth_payload_t *auth_payload_create() this->public.set_auth_method = (void (*) (auth_payload_t *,auth_method_t)) set_auth_method; this->public.get_auth_method = (auth_method_t (*) (auth_payload_t *)) get_auth_method; this->public.set_data = (void (*) (auth_payload_t *,chunk_t)) set_data; + this->public.get_data_clone = (chunk_t (*) (auth_payload_t *)) get_data_clone; this->public.get_data = (chunk_t (*) (auth_payload_t *)) get_data; /* private variables */ diff --git a/Source/charon/encoding/payloads/auth_payload.h b/Source/charon/encoding/payloads/auth_payload.h index 3a2d4459d..2613288fe 100644 --- a/Source/charon/encoding/payloads/auth_payload.h +++ b/Source/charon/encoding/payloads/auth_payload.h @@ -115,6 +115,16 @@ struct auth_payload_t { * @param this calling auth_payload_t object * @return AUTH data as chunk_t */ + chunk_t (*get_data_clone) (auth_payload_t *this); + + /** + * @brief Get the AUTH data. + * + * Returned data are NOT copied + * + * @param this calling auth_payload_t object + * @return AUTH data as chunk_t + */ chunk_t (*get_data) (auth_payload_t *this); /** diff --git a/Source/charon/encoding/payloads/id_payload.c b/Source/charon/encoding/payloads/id_payload.c index 285791279..9560d4f87 100644 --- a/Source/charon/encoding/payloads/id_payload.c +++ b/Source/charon/encoding/payloads/id_payload.c @@ -214,11 +214,20 @@ static void set_data (private_id_payload_t *this, chunk_t data) this->payload_length = ID_PAYLOAD_HEADER_LENGTH + this->id_data.len; } + /** - * Implementation of id_payload_t.get_data. + * Implementation of id_payload_t.get_data_clone. */ static chunk_t get_data (private_id_payload_t *this) { + return (this->id_data); +} + +/** + * Implementation of id_payload_t.get_data_clone. + */ +static chunk_t get_data_clone (private_id_payload_t *this) +{ chunk_t cloned_data; if (this->id_data.ptr == NULL) { @@ -288,6 +297,8 @@ id_payload_t *id_payload_create(bool is_initiator) this->public.get_id_type = (id_type_t (*) (id_payload_t *)) get_id_type; this->public.set_data = (void (*) (id_payload_t *,chunk_t)) set_data; this->public.get_data = (chunk_t (*) (id_payload_t *)) get_data; + this->public.get_data_clone = (chunk_t (*) (id_payload_t *)) get_data_clone; + this->public.get_initiator = (bool (*) (id_payload_t *)) get_initiator; this->public.set_initiator = (void (*) (id_payload_t *,bool)) set_initiator; this->public.get_identification = (identification_t * (*) (id_payload_t *this)) get_identification; diff --git a/Source/charon/encoding/payloads/id_payload.h b/Source/charon/encoding/payloads/id_payload.h index 7348f2668..c3951135b 100644 --- a/Source/charon/encoding/payloads/id_payload.h +++ b/Source/charon/encoding/payloads/id_payload.h @@ -87,9 +87,19 @@ struct id_payload_t { * @param this calling id_payload_t object * @return ID data as chunk_t */ - chunk_t (*get_data) (id_payload_t *this); + chunk_t (*get_data_clone) (id_payload_t *this); /** + * @brief Get the ID data. + * + * Returned data are NOT copied. + * + * @param this calling id_payload_t object + * @return ID data as chunk_t + */ + chunk_t (*get_data) (id_payload_t *this); + + /** * @brief Creates an identification object of this id payload. * * Returned object has to get destroyed by the caller. diff --git a/Source/charon/sa/authenticator.c b/Source/charon/sa/authenticator.c index 6ab1b00ee..978106b1f 100644 --- a/Source/charon/sa/authenticator.c +++ b/Source/charon/sa/authenticator.c @@ -51,7 +51,7 @@ struct private_authenticator_t { /** * TODO */ - chunk_t (*allocate_octets) (private_authenticator_t *this,chunk_t last_message, chunk_t other_nonce,identification_t *my_id); + chunk_t (*allocate_octets) (private_authenticator_t *this,chunk_t last_message, chunk_t other_nonce,id_payload_t *my_id); chunk_t (*allocate_auth_data_with_preshared_secret) (private_authenticator_t *this,chunk_t octets,chunk_t preshared_secret); }; @@ -59,16 +59,16 @@ struct private_authenticator_t { /** * Implementation of authenticator_t.private_authenticator_t. */ -static chunk_t allocate_octets(private_authenticator_t *this,chunk_t last_message, chunk_t other_nonce,identification_t *my_id) +static chunk_t allocate_octets(private_authenticator_t *this,chunk_t last_message, chunk_t other_nonce,id_payload_t *my_id) { - chunk_t id_chunk = my_id->get_encoding(my_id); + chunk_t id_chunk = my_id->get_data(my_id); u_int8_t id_with_header[4 + id_chunk.len]; chunk_t id_with_header_chunk; chunk_t octets; u_int8_t *current_pos; prf_t *prf; - id_with_header[0] = my_id->get_type(my_id); + id_with_header[0] = my_id->get_id_type(my_id); id_with_header[1] = 0x00; id_with_header[2] = 0x00; id_with_header[3] = 0x00; @@ -91,7 +91,7 @@ static chunk_t allocate_octets(private_authenticator_t *this,chunk_t last_messag current_pos += other_nonce.len; prf->get_bytes(prf,id_with_header_chunk,current_pos); - this->logger->log_chunk(this->logger,RAW | MORE, "Octets (Mesage + Nonce + prf(Sk_px,Idx)",&octets); + this->logger->log_chunk(this->logger,RAW | MOST, "Octets (Mesage + Nonce + prf(Sk_px,Idx)",&octets); return octets; } @@ -120,25 +120,25 @@ static chunk_t allocate_auth_data_with_preshared_secret (private_authenticator_t /** - * Implementation of authenticator_t.verify_authentication. + * Implementation of authenticator_t.private_authenticator_t. */ -static status_t verify_authentication (private_authenticator_t *this,auth_method_t auth_method, chunk_t auth_data, chunk_t last_message, chunk_t other_nonce,identification_t *my_id,bool *verified) + +static status_t verify_auth_data (private_authenticator_t *this,auth_payload_t *auth_payload, chunk_t last_received_packet,chunk_t my_nonce,id_payload_t *other_id_payload,bool *verified) { - switch(auth_method) + switch(auth_payload->get_auth_method(auth_payload)) { case SHARED_KEY_MESSAGE_INTEGRITY_CODE: { - chunk_t preshared_secret; + chunk_t auth_data = auth_payload->get_data(auth_payload); preshared_secret.ptr = "secret"; preshared_secret.len = strlen(preshared_secret.ptr); - chunk_t octets = this->allocate_octets(this,last_message, other_nonce,my_id); + chunk_t octets = this->allocate_octets(this,last_received_packet,my_nonce,other_id_payload); chunk_t my_auth_data = this->allocate_auth_data_with_preshared_secret(this,octets,preshared_secret); - - allocator_free_chunk(&octets); - + allocator_free_chunk(&octets); + if (auth_data.len != my_auth_data.len) { *verified = FALSE; @@ -164,33 +164,40 @@ static status_t verify_authentication (private_authenticator_t *this,auth_method } /** - * Implementation of authenticator_t.allocate_auth_data. + * Implementation of authenticator_t.compute_auth_data. */ -static status_t allocate_auth_data (private_authenticator_t *this,auth_method_t auth_method,chunk_t last_message, chunk_t other_nonce,identification_t *my_id,chunk_t *auth_data) +static status_t compute_auth_data (private_authenticator_t *this,auth_payload_t **auth_payload, chunk_t last_sent_packet,chunk_t other_nonce,id_payload_t *my_id_payload) { - switch(auth_method) + +/* switch(auth_method) { case SHARED_KEY_MESSAGE_INTEGRITY_CODE: - { + {*/ + chunk_t preshared_secret; preshared_secret.ptr = "secret"; preshared_secret.len = strlen(preshared_secret.ptr); - chunk_t octets = this->allocate_octets(this,last_message, other_nonce,my_id); - chunk_t my_auth_data = allocate_auth_data_with_preshared_secret(this,octets,preshared_secret); - + chunk_t octets = this->allocate_octets(this,last_sent_packet,other_nonce,my_id_payload); + chunk_t auth_data = this->allocate_auth_data_with_preshared_secret(this,octets,preshared_secret); + + allocator_free_chunk(&octets); + + *auth_payload = auth_payload_create(); + (*auth_payload)->set_auth_method((*auth_payload),SHARED_KEY_MESSAGE_INTEGRITY_CODE); + (*auth_payload)->set_data((*auth_payload),auth_data); + + allocator_free_chunk(&auth_data); allocator_free_chunk(&octets); - - *auth_data = my_auth_data; return SUCCESS; - } +/* } default: { return NOT_SUPPORTED; } - } + }*/ } /** @@ -210,8 +217,8 @@ authenticator_t *authenticator_create(protected_ike_sa_t *ike_sa) /* Public functions */ this->public.destroy = (void(*)(authenticator_t*))destroy; - this->public.verify_authentication = (status_t (*) (authenticator_t *,auth_method_t , chunk_t , chunk_t , chunk_t ,identification_t *,bool *) )verify_authentication; - this->public.allocate_auth_data = (status_t (*) (authenticator_t *,auth_method_t ,chunk_t , chunk_t ,identification_t *,chunk_t *)) allocate_auth_data; + this->public.verify_auth_data = (status_t (*) (authenticator_t *,auth_payload_t *, chunk_t ,chunk_t ,id_payload_t *,bool *)) verify_auth_data; + this->public.compute_auth_data = (status_t (*) (authenticator_t *,auth_payload_t **, chunk_t ,chunk_t ,id_payload_t *)) compute_auth_data; /* private functions */ this->allocate_octets = allocate_octets; diff --git a/Source/charon/sa/authenticator.h b/Source/charon/sa/authenticator.h index 3978cf1e9..06cb96d2d 100644 --- a/Source/charon/sa/authenticator.h +++ b/Source/charon/sa/authenticator.h @@ -27,7 +27,8 @@ #include <types.h> #include <encoding/payloads/auth_payload.h> -#include <utils/identification.h> +#include <encoding/payloads/id_payload.h> +#include <network/packet.h> #include <sa/ike_sa.h> @@ -51,7 +52,7 @@ struct authenticator_t { * @return * - NOT_SUPPORTED if auth_method is not supported */ - status_t (*verify_authentication) (authenticator_t *this,auth_method_t auth_method, chunk_t auth_data, chunk_t last_message, chunk_t other_nonce,identification_t *my_id,bool *verified); + status_t (*verify_auth_data) (authenticator_t *this,auth_payload_t *auth_payload, chunk_t last_received_packet,chunk_t my_nonce,id_payload_t *other_id_payload,bool *verified); /** * @brief Verifying of given authentication data. @@ -61,9 +62,7 @@ struct authenticator_t { * @return * - NOT_SUPPORTED if auth_method is not supported */ - status_t (*allocate_auth_data) (authenticator_t *this,auth_method_t auth_method,chunk_t last_message, chunk_t other_nonce,identification_t *my_id,chunk_t *auth_data); - - + status_t (*compute_auth_data) (authenticator_t *this,auth_payload_t **auth_payload, chunk_t last_sent_packet,chunk_t other_nonce,id_payload_t *my_id_payload); /** * @brief Destroys a authenticator_t object. * diff --git a/Source/charon/sa/ike_sa.c b/Source/charon/sa/ike_sa.c index 05f317ff8..1c18e3c74 100644 --- a/Source/charon/sa/ike_sa.c +++ b/Source/charon/sa/ike_sa.c @@ -784,20 +784,19 @@ static void set_last_replied_message_id (private_ike_sa_t *this,u_int32_t messag } /** - * Implementation of protected_ike_sa_t.get_last_sent_message_data. + * Implementation of protected_ike_sa_t.get_last_responded_message. */ -static chunk_t get_last_sent_message_data (private_ike_sa_t *this) +static message_t * get_last_responded_message (private_ike_sa_t *this) { - chunk_t last_sent_message_data = CHUNK_INITIALIZER; - packet_t *packet; - - if (this->last_requested_message != NULL) - { - packet = this->last_requested_message->get_packet(this->last_requested_message); - last_sent_message_data = packet->data; - } - - return last_sent_message_data; + return this->last_responded_message; +} + +/** + * Implementation of protected_ike_sa_t.get_last_requested_message. + */ +static message_t * get_last_requested_message (private_ike_sa_t *this) +{ + return this->last_requested_message; } /** @@ -960,7 +959,9 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id) this->protected.get_crypter_responder = (crypter_t *(*) (protected_ike_sa_t *)) get_crypter_responder; this->protected.get_signer_responder = (signer_t *(*) (protected_ike_sa_t *)) get_signer_responder; this->protected.reset_message_buffers = (void (*) (protected_ike_sa_t *)) reset_message_buffers; - this->protected.get_last_sent_message_data = (chunk_t (*) (protected_ike_sa_t *this)) get_last_sent_message_data; + this->protected.get_last_responded_message = (message_t * (*) (protected_ike_sa_t *this)) get_last_responded_message; + this->protected.get_last_requested_message = (message_t * (*) (protected_ike_sa_t *this)) get_last_requested_message; + this->protected.set_last_replied_message_id = (void (*) (protected_ike_sa_t *,u_int32_t)) set_last_replied_message_id; /* private functions */ diff --git a/Source/charon/sa/ike_sa.h b/Source/charon/sa/ike_sa.h index c561b99b1..9402bf1d2 100644 --- a/Source/charon/sa/ike_sa.h +++ b/Source/charon/sa/ike_sa.h @@ -329,16 +329,27 @@ struct protected_ike_sa_t { prf_t *(*get_prf) (protected_ike_sa_t *this); /** - * Gets the data of last sent message. - * - * Data are not getting cloned. - * + * Gets the last responded message. + * * @param this calling object - * @return chunk_t pointing to data + * @return + * - last received as message_t object + * - NULL if no last request available */ - chunk_t (*get_last_sent_message_data) (protected_ike_sa_t *this); + message_t *(*get_last_responded_message) (protected_ike_sa_t *this); /** + * Gets the last requested message. + * + * @param this calling object + * @return + * - last sent as message_t object + * - NULL if no last request available + */ + message_t *(*get_last_requested_message) (protected_ike_sa_t *this); + + + /** * Gets the Shared key SK_pr. * * Returned value is not cloned! diff --git a/Source/charon/sa/states/ike_auth_requested.c b/Source/charon/sa/states/ike_auth_requested.c index cfbd986fe..33c050e41 100644 --- a/Source/charon/sa/states/ike_auth_requested.c +++ b/Source/charon/sa/states/ike_auth_requested.c @@ -60,6 +60,16 @@ struct private_ike_auth_requested_t { * Received nonce from responder */ chunk_t received_nonce; + + /** + * Sent nonce in IKE_SA_INIT request. + */ + chunk_t sent_nonce; + + /** + * IKE_SA_INIT-Request in binary form. + */ + chunk_t ike_sa_init_reply_data; /** * Logger used to log data @@ -336,26 +346,28 @@ static status_t process_sa_payload(private_ike_auth_requested_t *this, sa_payloa */ static status_t process_auth_payload(private_ike_auth_requested_t *this, auth_payload_t *auth_payload, id_payload_t *other_id_payload) { - - chunk_t received_auth_data = auth_payload->get_data(auth_payload); - chunk_t last_message_data = this->ike_sa->get_last_sent_message_data(this->ike_sa); - bool verified; - identification_t *identification; authenticator_t *authenticator; - - identification = other_id_payload->get_identification(other_id_payload); - + status_t status; + bool verified; + /* TODO VERIFY auth here */ authenticator = authenticator_create(this->ike_sa); - authenticator->verify_authentication(authenticator,auth_payload->get_auth_method(auth_payload),received_auth_data,last_message_data,this->received_nonce,identification,&verified); - + status = authenticator->verify_auth_data(authenticator,auth_payload,this->ike_sa_init_reply_data,this->sent_nonce,other_id_payload,&verified); authenticator->destroy(authenticator); - - allocator_free_chunk(&received_auth_data); - - - /* TODO VERIFY auth here */ + if (status != SUCCESS) + { + this->logger->log(this->logger, ERROR, "Could not verify AUTH data. Error status: %s",mapping_find(status_m,status)); + return FAILED; + } + + if (!verified) + { + this->logger->log(this->logger, ERROR | MORE, "AUTH data could not be verified"); + return FAILED; + } + + this->logger->log(this->logger, CONTROL | MORE, "AUTH data verified"); return SUCCESS; } @@ -415,13 +427,15 @@ static ike_sa_state_t get_state(private_ike_auth_requested_t *this) static void destroy(private_ike_auth_requested_t *this) { allocator_free_chunk(&(this->received_nonce)); + allocator_free_chunk(&(this->sent_nonce)); + allocator_free_chunk(&(this->ike_sa_init_reply_data)); allocator_free(this); } /* * Described in header. */ -ike_auth_requested_t *ike_auth_requested_create(protected_ike_sa_t *ike_sa, chunk_t received_nonce) +ike_auth_requested_t *ike_auth_requested_create(protected_ike_sa_t *ike_sa,chunk_t sent_nonce,chunk_t received_nonce,chunk_t ike_sa_init_reply_data) { private_ike_auth_requested_t *this = allocator_alloc_thing(private_ike_auth_requested_t); @@ -440,6 +454,8 @@ ike_auth_requested_t *ike_auth_requested_create(protected_ike_sa_t *ike_sa, chun /* private data */ this->ike_sa = ike_sa; this->received_nonce = received_nonce; + this->sent_nonce = sent_nonce; + this->ike_sa_init_reply_data = ike_sa_init_reply_data; this->logger = this->ike_sa->get_logger(this->ike_sa); return &(this->public); diff --git a/Source/charon/sa/states/ike_auth_requested.h b/Source/charon/sa/states/ike_auth_requested.h index 5f1e04217..c4caaca18 100644 --- a/Source/charon/sa/states/ike_auth_requested.h +++ b/Source/charon/sa/states/ike_auth_requested.h @@ -55,6 +55,6 @@ struct ike_auth_requested_t { * * @ingroup states */ -ike_auth_requested_t *ike_auth_requested_create(protected_ike_sa_t *ike_sa, chunk_t received_nonce); +ike_auth_requested_t *ike_auth_requested_create(protected_ike_sa_t *ike_sa,chunk_t sent_nonce,chunk_t received_nonce,chunk_t ike_sa_init_repy_data); #endif /*IKE_AUTH_REQUESTED_H_*/ diff --git a/Source/charon/sa/states/ike_sa_init_requested.c b/Source/charon/sa/states/ike_sa_init_requested.c index 68e34a5c0..1013eaedc 100644 --- a/Source/charon/sa/states/ike_sa_init_requested.c +++ b/Source/charon/sa/states/ike_sa_init_requested.c @@ -34,6 +34,7 @@ #include <transforms/diffie_hellman.h> #include <sa/states/ike_auth_requested.h> #include <sa/states/initiator_init.h> +#include <sa/authenticator.h> typedef struct private_ike_sa_init_requested_t private_ike_sa_init_requested_t; @@ -74,6 +75,11 @@ struct private_ike_sa_init_requested_t { chunk_t received_nonce; /** + * Packet data of ike_sa_init request + */ + chunk_t ike_sa_init_request_data; + + /** * DH group priority used to get dh_group_number from configuration manager. * * Currently unused but usable if informational messages of unsupported dh group number are processed. @@ -92,8 +98,11 @@ struct private_ike_sa_init_requested_t { * * @param this calling object * @param message the created message will be stored at this location + * @return + * - SUCCESS + * - FAILED */ - void (*build_ike_auth_request) (private_ike_sa_init_requested_t *this, message_t **message); + status_t (*build_ike_auth_request) (private_ike_sa_init_requested_t *this, message_t **message); /** * Builds the id payload for this state. @@ -110,8 +119,11 @@ struct private_ike_sa_init_requested_t { * @param this calling object * @param payload The generated payload object of type auth_payload_t is * stored at this location. + * @return + * - SUCCESS + * - FAILED */ - void (*build_auth_payload) (private_ike_sa_init_requested_t *this, payload_t **payload); + status_t (*build_auth_payload) (private_ike_sa_init_requested_t *this, payload_t **payload,id_payload_t *my_id_payload); /** * Builds the SA payload for this state. @@ -156,6 +168,7 @@ struct private_ike_sa_init_requested_t { static status_t process_message(private_ike_sa_init_requested_t *this, message_t *ike_sa_init_reply) { ike_auth_requested_t *next_state; + chunk_t ike_sa_init_reply_data; exchange_type_t exchange_type; init_config_t *init_config; u_int64_t responder_spi; @@ -381,8 +394,14 @@ static status_t process_message(private_ike_sa_init_requested_t *this, message_t this->ike_sa->compute_secrets(this->ike_sa,this->shared_secret,this->sent_nonce, this->received_nonce); /* build the complete IKE_AUTH request */ - this->build_ike_auth_request (this,&request); - + status = this->build_ike_auth_request (this,&request); + if (status != SUCCESS) + { + this->logger->log(this->logger, ERROR, "Could not build request message"); + return DELETE_ME; + } + + /* message can now be sent (must not be destroyed) */ status = this->ike_sa->send_request(this->ike_sa, request); if (status != SUCCESS) @@ -394,9 +413,11 @@ static status_t process_message(private_ike_sa_init_requested_t *this, message_t this->ike_sa->set_last_replied_message_id(this->ike_sa,ike_sa_init_reply->get_message_id(ike_sa_init_reply)); + ike_sa_init_reply_data = ike_sa_init_reply->get_packet_data(ike_sa_init_reply); + /* state can now be changed */ this->logger->log(this->logger, CONTROL|MOST, "Create next state object"); - next_state = ike_auth_requested_create(this->ike_sa,this->received_nonce); + next_state = ike_auth_requested_create(this->ike_sa,this->sent_nonce,this->received_nonce,ike_sa_init_reply_data); /* state can now be changed */ this->ike_sa->set_new_state(this->ike_sa,(state_t *) next_state); @@ -412,10 +433,11 @@ static status_t process_message(private_ike_sa_init_requested_t *this, message_t /** * implements private_ike_sa_init_requested_t.build_ike_auth_request */ -static void build_ike_auth_request (private_ike_sa_init_requested_t *this, message_t **request) +static status_t build_ike_auth_request (private_ike_sa_init_requested_t *this, message_t **request) { payload_t *payload; message_t *message; + status_t status; /* going to build message */ this->logger->log(this->logger, CONTROL|MOST, "Going to build empty message"); @@ -427,7 +449,14 @@ static void build_ike_auth_request (private_ike_sa_init_requested_t *this, messa message->add_payload(message, payload); /* build auth payload */ - this->build_auth_payload(this, &payload); + status = this->build_auth_payload(this, &payload,(id_payload_t *) payload); + if (status != SUCCESS) + { + this->logger->log(this->logger, ERROR, "Could not create auth payload"); + message->destroy(message); + return status; + } + this->logger->log(this->logger, CONTROL|MOST, "add AUTH payload to message"); message->add_payload(message, payload); @@ -447,6 +476,7 @@ static void build_ike_auth_request (private_ike_sa_init_requested_t *this, messa message->add_payload(message, payload); *request = message; + return SUCCESS; } /** @@ -469,19 +499,23 @@ static void build_id_payload (private_ike_sa_init_requested_t *this, payload_t * /** * Implementation of private_ike_sa_init_requested_t.build_auth_payload. */ -static void build_auth_payload (private_ike_sa_init_requested_t *this, payload_t **payload) +static status_t build_auth_payload (private_ike_sa_init_requested_t *this, payload_t **payload,id_payload_t *my_id_payload) { + authenticator_t *authenticator; auth_payload_t *auth_payload; - sa_config_t *sa_config; - - sa_config = this->ike_sa->get_sa_config(this->ike_sa); - auth_payload = auth_payload_create(); - auth_payload->set_auth_method(auth_payload,sa_config->get_auth_method(sa_config)); - /* - * TODO generate AUTH DATA - */ - + status_t status; + + authenticator = authenticator_create(this->ike_sa); + status = authenticator->compute_auth_data(authenticator,&auth_payload,this->ike_sa_init_request_data,this->received_nonce,my_id_payload); + authenticator->destroy(authenticator); + + if (status != SUCCESS) + { + return status; + } + *payload = (payload_t *) auth_payload; + return SUCCESS; } /** @@ -575,10 +609,10 @@ static void destroy_after_state_change (private_ike_sa_init_requested_t *this) this->logger->log(this->logger, CONTROL | MOST, "Destroy diffie hellman object"); this->diffie_hellman->destroy(this->diffie_hellman); - this->logger->log(this->logger, CONTROL | MOST, "Destroy sent nonce"); - allocator_free(this->sent_nonce.ptr); - this->logger->log(this->logger, CONTROL | MOST, "Destroy shared secret (secrets allready derived)"); + this->logger->log(this->logger, CONTROL | MOST, "Destroy shared secret"); allocator_free_chunk(&(this->shared_secret)); + this->logger->log(this->logger, CONTROL | MOST, "Destroy ike_sa_init_request_data"); + allocator_free_chunk(&(this->ike_sa_init_request_data)); this->logger->log(this->logger, CONTROL | MOST, "Destroy object itself"); allocator_free(this); } @@ -598,6 +632,8 @@ static void destroy(private_ike_sa_init_requested_t *this) allocator_free(this->received_nonce.ptr); this->logger->log(this->logger, CONTROL | MOST, "Destroy shared secret (secrets allready derived)"); allocator_free_chunk(&(this->shared_secret)); + this->logger->log(this->logger, CONTROL | MOST, "Destroy ike_sa_init_request_data"); + allocator_free_chunk(&(this->ike_sa_init_request_data)); this->logger->log(this->logger, CONTROL | MOST, "Destroy object itself"); allocator_free(this); } @@ -605,7 +641,7 @@ static void destroy(private_ike_sa_init_requested_t *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) +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) { private_ike_sa_init_requested_t *this = allocator_alloc_thing(private_ike_sa_init_requested_t); @@ -630,6 +666,7 @@ ike_sa_init_requested_t *ike_sa_init_requested_create(protected_ike_sa_t *ike_sa this->logger = this->ike_sa->get_logger(this->ike_sa); this->diffie_hellman = diffie_hellman; 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 01bef9357..d5de50443 100644 --- a/Source/charon/sa/states/ike_sa_init_requested.h +++ b/Source/charon/sa/states/ike_sa_init_requested.h @@ -53,6 +53,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); +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); #endif /*IKE_SA_INIT_REQUESTED_H_*/ diff --git a/Source/charon/sa/states/ike_sa_init_responded.c b/Source/charon/sa/states/ike_sa_init_responded.c index 6e7fb69c4..31d41cbf4 100644 --- a/Source/charon/sa/states/ike_sa_init_responded.c +++ b/Source/charon/sa/states/ike_sa_init_responded.c @@ -57,6 +57,21 @@ struct private_ike_sa_init_responded_t { chunk_t received_nonce; /** + * Sent nonce. + */ + chunk_t sent_nonce; + + /** + * Data of the IKE_SA_INIT response. + */ + chunk_t ike_sa_init_response_data; + + /** + * Data of the IKE_SA_INIT request. + */ + chunk_t ike_sa_init_request_data; + + /** * sa config to use */ sa_config_t *sa_config; @@ -68,9 +83,9 @@ struct private_ike_sa_init_responded_t { */ logger_t *logger; - status_t (*build_idr_payload) (private_ike_sa_init_responded_t *this, id_payload_t *request_idi, id_payload_t *request_idr, message_t *response); + status_t (*build_idr_payload) (private_ike_sa_init_responded_t *this, id_payload_t *request_idi, id_payload_t *request_idr, message_t *response,id_payload_t **response_idr); status_t (*build_sa_payload) (private_ike_sa_init_responded_t *this, sa_payload_t *request, message_t *response); - status_t (*build_auth_payload) (private_ike_sa_init_responded_t *this, auth_payload_t *request,id_payload_t *other_id_payload, message_t *response); + status_t (*build_auth_payload) (private_ike_sa_init_responded_t *this, auth_payload_t *request,id_payload_t *other_id_payload,id_payload_t *my_id_payload, message_t* response); status_t (*build_ts_payload) (private_ike_sa_init_responded_t *this, bool ts_initiator, ts_payload_t *request, message_t *response); }; @@ -84,7 +99,7 @@ static status_t process_message(private_ike_sa_init_responded_t *this, message_t crypter_t *crypter; iterator_t *payloads; exchange_type_t exchange_type; - id_payload_t *idi_request, *idr_request = NULL; + id_payload_t *idi_request, *idr_request = NULL,*idr_response; auth_payload_t *auth_request; sa_payload_t *sa_request; ts_payload_t *tsi_request, *tsr_request; @@ -182,7 +197,7 @@ static status_t process_message(private_ike_sa_init_responded_t *this, message_t /* add payloads to it */ - status = this->build_idr_payload(this, idi_request, idr_request, response); + status = this->build_idr_payload(this, idi_request, idr_request, response,&idr_response); if (status != SUCCESS) { this->logger->log(this->logger, ERROR, "Building idr payload failed"); @@ -196,7 +211,7 @@ static status_t process_message(private_ike_sa_init_responded_t *this, message_t response->destroy(response); return status; } - status = this->build_auth_payload(this, auth_request,idi_request, response); + status = this->build_auth_payload(this, auth_request,idi_request, idr_response,response); if (status != SUCCESS) { this->logger->log(this->logger, ERROR, "Building auth payload failed"); @@ -240,7 +255,7 @@ static status_t process_message(private_ike_sa_init_responded_t *this, message_t /** * Implements private_ike_sa_init_responded_t.build_idr_payload */ -static status_t build_idr_payload(private_ike_sa_init_responded_t *this, id_payload_t *request_idi, id_payload_t *request_idr, message_t *response) +static status_t build_idr_payload(private_ike_sa_init_responded_t *this, id_payload_t *request_idi, id_payload_t *request_idr, message_t *response,id_payload_t **response_idr) { identification_t *other_id, *my_id = NULL; init_config_t *init_config; @@ -280,7 +295,7 @@ static status_t build_idr_payload(private_ike_sa_init_responded_t *this, id_payl /* build response */ idr_response = id_payload_create_from_identification(FALSE, my_id); response->add_payload(response, (payload_t*)idr_response); - + *response_idr = idr_response; return SUCCESS; } @@ -331,37 +346,41 @@ static status_t build_sa_payload(private_ike_sa_init_responded_t *this, sa_paylo /** * Implements private_ike_sa_init_responded_t.build_auth_payload */ -static status_t build_auth_payload(private_ike_sa_init_responded_t *this, auth_payload_t *request,id_payload_t *other_id_payload, message_t *response) +static status_t build_auth_payload(private_ike_sa_init_responded_t *this, auth_payload_t *auth_request,id_payload_t *other_id_payload,id_payload_t *my_id_payload, message_t* response) { - auth_payload_t *dummy; - u_int8_t data[] = {0x01,0x03,0x01,0x03,0x01,0x03,0x01,0x03,0x01,0x03,0x01,0x03,0x01,0x03,0x01,0x03}; - chunk_t auth_data; - auth_data.ptr = data; - auth_data.len = sizeof(data); authenticator_t *authenticator; - chunk_t received_auth_data = request->get_data(request); - chunk_t last_message_data = this->ike_sa->get_last_sent_message_data(this->ike_sa); - bool verified; - identification_t *identification; - - identification = other_id_payload->get_identification(other_id_payload); + auth_payload_t *auth_reply; + status_t status; + bool verified; - /* TODO VERIFY auth here */ authenticator = authenticator_create(this->ike_sa); - authenticator->verify_authentication(authenticator,request->get_auth_method(request),received_auth_data,last_message_data,this->received_nonce,identification,&verified); - + + status = authenticator->verify_auth_data(authenticator,auth_request, this->ike_sa_init_request_data,this->sent_nonce,other_id_payload,&verified); + + if (status != SUCCESS) + { + this->logger->log(this->logger, ERROR, "Verification of AUTH payload returned status %s",mapping_find(status_m,status)); + authenticator->destroy(authenticator); + return status; + } + if (!verified) + { + this->logger->log(this->logger, ERROR, "Verification of AUTH failed."); + authenticator->destroy(authenticator); + return FAILED; + } + + status = authenticator->compute_auth_data(authenticator,&auth_reply, this->ike_sa_init_response_data,this->received_nonce,my_id_payload); authenticator->destroy(authenticator); - - allocator_free_chunk(&received_auth_data); - - dummy = auth_payload_create(); - dummy->set_data(dummy, auth_data); - dummy->set_auth_method(dummy, RSA_DIGITAL_SIGNATURE); - - /* TODO replace dummy */ - - response->add_payload(response, (payload_t *)dummy); + if (status != SUCCESS) + { + this->logger->log(this->logger, ERROR, "Could not compute AUTH payload."); + return FAILED; + + } + + response->add_payload(response, (payload_t *)auth_reply); return SUCCESS; } @@ -427,14 +446,22 @@ static void destroy(private_ike_sa_init_responded_t *this) { this->logger->log(this->logger, CONTROL | MORE, "Going to destroy ike_sa_init_responded_t state object"); + this->logger->log(this->logger, CONTROL | MOST, "Destroy received nonce"); allocator_free_chunk(&(this->received_nonce)); + this->logger->log(this->logger, CONTROL | MOST, "Destroy sent nonce"); + allocator_free_chunk(&(this->sent_nonce)); + this->logger->log(this->logger, CONTROL | MOST, "Destroy IKE_SA_INIT response octets"); + allocator_free_chunk(&(this->ike_sa_init_response_data)); + this->logger->log(this->logger, CONTROL | MOST, "Destroy IKE_SA_INIT request octets"); + allocator_free_chunk(&(this->ike_sa_init_request_data)); + allocator_free(this); } /* * Described in header. */ -ike_sa_init_responded_t *ike_sa_init_responded_create(protected_ike_sa_t *ike_sa, chunk_t received_nonce) +ike_sa_init_responded_t *ike_sa_init_responded_create(protected_ike_sa_t *ike_sa, chunk_t received_nonce, chunk_t sent_nonce,chunk_t ike_sa_init_request_data, chunk_t ike_sa_init_response_data) { private_ike_sa_init_responded_t *this = allocator_alloc_thing(private_ike_sa_init_responded_t); @@ -452,6 +479,9 @@ ike_sa_init_responded_t *ike_sa_init_responded_create(protected_ike_sa_t *ike_sa /* private data */ this->ike_sa = ike_sa; this->received_nonce = received_nonce; + this->sent_nonce = sent_nonce; + this->ike_sa_init_response_data = ike_sa_init_response_data; + this->ike_sa_init_request_data = ike_sa_init_request_data; this->logger = this->ike_sa->get_logger(this->ike_sa); return &(this->public); diff --git a/Source/charon/sa/states/ike_sa_init_responded.h b/Source/charon/sa/states/ike_sa_init_responded.h index fdcc055c7..6dd634288 100644 --- a/Source/charon/sa/states/ike_sa_init_responded.h +++ b/Source/charon/sa/states/ike_sa_init_responded.h @@ -54,6 +54,6 @@ struct ike_sa_init_responded_t { * * @ingroup states */ -ike_sa_init_responded_t *ike_sa_init_responded_create(protected_ike_sa_t *ike_sa, chunk_t received_nonce); +ike_sa_init_responded_t *ike_sa_init_responded_create(protected_ike_sa_t *ike_sa, chunk_t received_nonce,chunk_t sent_nonce,chunk_t ike_sa_init_request_data,chunk_t ike_sa_init_response_data); #endif /*IKE_SA_INIT_RESPONDED_H_*/ diff --git a/Source/charon/sa/states/initiator_init.c b/Source/charon/sa/states/initiator_init.c index 59a6a2e2a..e0a6092ed 100644 --- a/Source/charon/sa/states/initiator_init.c +++ b/Source/charon/sa/states/initiator_init.c @@ -134,6 +134,7 @@ 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; + this->logger->log(this->logger, CONTROL, "Initializing connection %s",name); @@ -177,11 +178,13 @@ static status_t initiate_connection (private_initiator_init_t *this, char *name) status_t retry_initiate_connection (private_initiator_init_t *this, int dh_group_priority) { ike_sa_init_requested_t *next_state; + chunk_t ike_sa_init_request_data; init_config_t *init_config; randomizer_t *randomizer; + ike_sa_id_t *ike_sa_id; message_t *message; status_t status; - ike_sa_id_t *ike_sa_id; + this->dh_group_priority = dh_group_priority; @@ -218,10 +221,14 @@ status_t retry_initiate_connection (private_initiator_init_t *this, int dh_group message->destroy(message); return DELETE_ME; } + + message = this->ike_sa->get_last_requested_message(this->ike_sa); + + ike_sa_init_request_data = message->get_packet_data(message); /* state can now be changed */ this->logger->log(this->logger, CONTROL|MOST, "Create next state object"); - next_state = ike_sa_init_requested_create(this->ike_sa, this->dh_group_priority, this->diffie_hellman, this->sent_nonce); + 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); /* state can now be changed */ this->ike_sa->set_new_state(this->ike_sa,(state_t *) next_state); diff --git a/Source/charon/sa/states/responder_init.c b/Source/charon/sa/states/responder_init.c index 72e11e392..e112f421a 100644 --- a/Source/charon/sa/states/responder_init.c +++ b/Source/charon/sa/states/responder_init.c @@ -155,6 +155,8 @@ struct private_responder_init_t { static status_t process_message(private_responder_init_t *this, message_t *message) { ike_sa_init_responded_t *next_state; + chunk_t ike_sa_init_response_data; + chunk_t ike_sa_init_request_data; exchange_type_t exchange_type; host_t *source, *destination; init_config_t *init_config; @@ -166,6 +168,7 @@ static status_t process_message(private_responder_init_t *this, message_t *messa host_t *my_host; status_t status; + exchange_type = message->get_exchange_type(message); if (exchange_type != IKE_SA_INIT) { @@ -357,12 +360,14 @@ static status_t process_message(private_responder_init_t *this, message_t *messa return DELETE_ME; } - - /* state can now be changed */ this->logger->log(this->logger, CONTROL|MOST, "Create next state object"); - next_state = ike_sa_init_responded_create(this->ike_sa, this->received_nonce); + response = this->ike_sa->get_last_responded_message(this->ike_sa); + ike_sa_init_response_data = response->get_packet_data(response); + ike_sa_init_request_data = message->get_packet_data(message); + + next_state = ike_sa_init_responded_create(this->ike_sa, this->received_nonce, this->sent_nonce,ike_sa_init_request_data,ike_sa_init_response_data); /* state can now be changed */ this->ike_sa->set_new_state(this->ike_sa, (state_t *) next_state); @@ -534,8 +539,6 @@ static void destroy_after_state_change (private_responder_init_t *this) this->diffie_hellman->destroy(this->diffie_hellman); } - this->logger->log(this->logger, CONTROL | MOST, "Destroy sent nonce"); - allocator_free_chunk(&(this->sent_nonce)); this->logger->log(this->logger, CONTROL | MOST, "Destroy object"); allocator_free(this); } diff --git a/Source/charon/testcases/parser_test.c b/Source/charon/testcases/parser_test.c index 81e26d9b5..2815c63a8 100644 --- a/Source/charon/testcases/parser_test.c +++ b/Source/charon/testcases/parser_test.c @@ -471,7 +471,7 @@ void test_parser_with_id_payload(tester_t *tester) { return; } - result = id_payload->get_data(id_payload); + result = id_payload->get_data_clone(id_payload); tester->assert_true(tester,(id_payload->get_initiator(id_payload) == TRUE), "is IDi payload"); tester->assert_true(tester,(id_payload->get_id_type(id_payload) == ID_IPV6_ADDR), "is ID_IPV6_ADDR ID type"); tester->assert_true(tester,(result.len == 12), "parsed data lenght"); @@ -597,7 +597,7 @@ void test_parser_with_auth_payload(tester_t *tester) { return; } - result = auth_payload->get_data(auth_payload); + result = auth_payload->get_data_clone(auth_payload); tester->assert_true(tester,(auth_payload->get_auth_method(auth_payload) == DSS_DIGITAL_SIGNATURE), "is DSS_DIGITAL_SIGNATURE method"); tester->assert_true(tester,(result.len == 12), "parsed data lenght"); tester->assert_false(tester,(memcmp(auth_bytes + 8, result.ptr, result.len)), "parsed nonce data"); |