aboutsummaryrefslogtreecommitdiffstats
path: root/src/charon/encoding/payloads
diff options
context:
space:
mode:
Diffstat (limited to 'src/charon/encoding/payloads')
-rw-r--r--src/charon/encoding/payloads/notify_payload.c76
-rw-r--r--src/charon/encoding/payloads/notify_payload.h37
-rw-r--r--src/charon/encoding/payloads/proposal_substructure.c59
-rw-r--r--src/charon/encoding/payloads/proposal_substructure.h25
-rw-r--r--src/charon/encoding/payloads/sa_payload.c64
5 files changed, 147 insertions, 114 deletions
diff --git a/src/charon/encoding/payloads/notify_payload.c b/src/charon/encoding/payloads/notify_payload.c
index a4062cf42..a09e33778 100644
--- a/src/charon/encoding/payloads/notify_payload.c
+++ b/src/charon/encoding/payloads/notify_payload.c
@@ -173,12 +173,25 @@ encoding_rule_t notify_payload_encodings[] = {
*/
static status_t verify(private_notify_payload_t *this)
{
- if (this->protocol_id > 3)
+ switch (this->protocol_id)
{
- /* reserved for future use */
- return FAILED;
+ case PROTO_IKE:
+ if (this->spi.len != 8)
+ {
+ return FAILED;
+ }
+ break;
+ case PROTO_AH:
+ case PROTO_ESP:
+ if (this->spi.len != 4)
+ {
+ return FAILED;
+ }
+ break;
+ default:
+ return FAILED;
}
-
+
/* TODO: Check all kinds of notify */
if (this->notify_message_type == INVALID_KE_PAYLOAD)
@@ -265,9 +278,7 @@ static void compute_length (private_notify_payload_t *this)
{
length += this->spi.len;
}
-
this->payload_length = length;
-
}
/**
@@ -289,7 +300,7 @@ static void set_protocol_id(private_notify_payload_t *this, u_int8_t protocol_id
/**
* Implementation of notify_payload_t.get_notify_message_type.
*/
-static u_int16_t get_notify_message_type(private_notify_payload_t *this)
+static notify_message_type_t get_notify_message_type(private_notify_payload_t *this)
{
return this->notify_message_type;
}
@@ -305,32 +316,42 @@ static void set_notify_message_type(private_notify_payload_t *this, u_int16_t no
/**
* Implementation of notify_payload_t.get_spi.
*/
-static chunk_t get_spi(private_notify_payload_t *this)
+static u_int64_t get_spi(private_notify_payload_t *this)
{
- return (this->spi);
+ switch (this->protocol_id)
+ {
+ case PROTO_IKE:
+ return *((u_int64_t*)this->spi.ptr);
+ case PROTO_AH:
+ case PROTO_ESP:
+ return *((u_int32_t*)this->spi.ptr);
+ default:
+ return 0;
+ }
}
/**
* Implementation of notify_payload_t.set_spi.
*/
-static void set_spi(private_notify_payload_t *this, chunk_t spi)
+static void set_spi(private_notify_payload_t *this, u_int64_t spi)
{
- /* destroy existing data first */
- if (this->spi.ptr != NULL)
+ chunk_free(&this->spi);
+ switch (this->protocol_id)
{
- /* free existing value */
- free(this->spi.ptr);
- this->spi.ptr = NULL;
- this->spi.len = 0;
-
+ case PROTO_IKE:
+ this->spi = chunk_alloc(8);
+ *((u_int64_t*)this->spi.ptr) = spi;
+ break;
+ case PROTO_AH:
+ case PROTO_ESP:
+ this->spi = chunk_alloc(4);
+ *((u_int32_t*)this->spi.ptr) = spi;
+ break;
+ default:
+ break;
}
-
- this->spi.ptr = clalloc(spi.ptr,spi.len);
-
- this->spi.len = spi.len;
- this->spi_size = spi.len;
+ this->spi_size = this->spi.len;
this->compute_length(this);
-
}
/**
@@ -376,7 +397,6 @@ static status_t destroy(private_notify_payload_t *this)
{
free(this->spi.ptr);
}
-
free(this);
return SUCCESS;
}
@@ -400,10 +420,10 @@ notify_payload_t *notify_payload_create()
/* public functions */
this->public.get_protocol_id = (u_int8_t (*) (notify_payload_t *)) get_protocol_id;
this->public.set_protocol_id = (void (*) (notify_payload_t *,u_int8_t)) set_protocol_id;
- this->public.get_notify_message_type = (u_int16_t (*) (notify_payload_t *)) get_notify_message_type;
- this->public.set_notify_message_type = (void (*) (notify_payload_t *,u_int16_t)) set_notify_message_type;
- this->public.get_spi = (chunk_t (*) (notify_payload_t *)) get_spi;
- this->public.set_spi = (void (*) (notify_payload_t *,chunk_t)) set_spi;
+ this->public.get_notify_message_type = (notify_message_type_t (*) (notify_payload_t *)) get_notify_message_type;
+ this->public.set_notify_message_type = (void (*) (notify_payload_t *,notify_message_type_t)) set_notify_message_type;
+ this->public.get_spi = (u_int64_t (*) (notify_payload_t *)) get_spi;
+ this->public.set_spi = (void (*) (notify_payload_t *,u_int64_t)) set_spi;
this->public.get_notification_data = (chunk_t (*) (notify_payload_t *)) get_notification_data;
this->public.set_notification_data = (void (*) (notify_payload_t *,chunk_t)) set_notification_data;
this->public.destroy = (void (*) (notify_payload_t *)) destroy;
diff --git a/src/charon/encoding/payloads/notify_payload.h b/src/charon/encoding/payloads/notify_payload.h
index ab86a6d53..ef425f314 100644
--- a/src/charon/encoding/payloads/notify_payload.h
+++ b/src/charon/encoding/payloads/notify_payload.h
@@ -64,7 +64,8 @@ enum notify_message_type_t {
INVALID_SELECTORS = 39,
INITIAL_CONTACT = 16384,
- SET_WINDOW_SIZE = 16385
+ SET_WINDOW_SIZE = 16385,
+ REKEY_SA = 16393,
};
/**
@@ -107,46 +108,42 @@ struct notify_payload_t {
/**
* @brief Sets the protocol id of this payload.
*
- * @param this calling notify_payload_t object
- * @param protocol_id protocol id to set
+ * @param this calling notify_payload_t object
+ * @param protocol_id protocol id to set
*/
void (*set_protocol_id) (notify_payload_t *this, u_int8_t protocol_id);
/**
* @brief Gets the notify message type of this payload.
*
- * @param this calling notify_payload_t object
- * @return notify message type of this payload
+ * @param this calling notify_payload_t object
+ * @return notify message type of this payload
*/
- u_int16_t (*get_notify_message_type) (notify_payload_t *this);
+ notify_message_type_t (*get_notify_message_type) (notify_payload_t *this);
/**
* @brief Sets notify message type of this payload.
*
- * @param this calling notify_payload_t object
- * @param notify_message_type notify message type to set
+ * @param this calling notify_payload_t object
+ * @param type notify message type to set
*/
- void (*set_notify_message_type) (notify_payload_t *this, u_int16_t notify_message_type);
+ void (*set_notify_message_type) (notify_payload_t *this, notify_message_type_t type);
/**
* @brief Returns the currently set spi of this payload.
- *
- * @warning Returned data are not copied.
- *
+ *
* @param this calling notify_payload_t object
- * @return chunk_t pointing to the value
+ * @return SPI value
*/
- chunk_t (*get_spi) (notify_payload_t *this);
+ u_int64_t (*get_spi) (notify_payload_t *this);
/**
* @brief Sets the spi of this payload.
- *
- * @warning Value is getting copied.
*
- * @param this calling notify_payload_t object
- * @param spi chunk_t pointing to the value to set
+ * @param this calling notify_payload_t object
+ * @param spi SPI value
*/
- void (*set_spi) (notify_payload_t *this, chunk_t spi);
+ void (*set_spi) (notify_payload_t *this, u_int64_t spi);
/**
* @brief Returns the currently set notification data of payload.
@@ -163,7 +160,7 @@ struct notify_payload_t {
*
* @warning Value is getting copied.
*
- * @param this calling notify_payload_t object
+ * @param this calling notify_payload_t object
* @param notification_data chunk_t pointing to the value to set
*/
void (*set_notification_data) (notify_payload_t *this, chunk_t notification_data);
diff --git a/src/charon/encoding/payloads/proposal_substructure.c b/src/charon/encoding/payloads/proposal_substructure.c
index cb3c695b2..f72fbb1c2 100644
--- a/src/charon/encoding/payloads/proposal_substructure.c
+++ b/src/charon/encoding/payloads/proposal_substructure.c
@@ -61,7 +61,7 @@ struct private_proposal_substructure_t {
/**
* Proposal number.
*/
- u_int8_t proposal_number;
+ u_int8_t proposal_number;
/**
* Protocol ID.
@@ -404,14 +404,17 @@ static size_t get_spi_size (private_proposal_substructure_t *this)
}
/**
- * Implementation of proposal_substructure_t.add_to_proposal.
+ * Implementation of proposal_substructure_t.get_proposal.
*/
-void add_to_proposal(private_proposal_substructure_t *this, proposal_t *proposal)
+proposal_t* get_proposal(private_proposal_substructure_t *this)
{
- iterator_t *iterator = this->transforms->create_iterator(this->transforms, TRUE);
- u_int32_t spi;
+ iterator_t *iterator;
+ proposal_t *proposal;
+ u_int64_t spi;
+ proposal = proposal_create(this->protocol_id);
+ iterator = this->transforms->create_iterator(this->transforms, TRUE);
while (iterator->has_next(iterator))
{
transform_substructure_t *transform;
@@ -425,13 +428,24 @@ void add_to_proposal(private_proposal_substructure_t *this, proposal_t *proposal
transform_id = transform->get_transform_id(transform);
transform->get_key_length(transform, &key_length);
- proposal->add_algorithm(proposal, this->protocol_id, transform_type, transform_id, key_length);
+ proposal->add_algorithm(proposal, transform_type, transform_id, key_length);
}
iterator->destroy(iterator);
- spi = *((u_int32_t*)this->spi.ptr);
+ switch (this->spi.len)
+ {
+ case 4:
+ spi = *((u_int32_t*)this->spi.ptr);
+ break;
+ case 8:
+ spi = *((u_int64_t*)this->spi.ptr);
+ break;
+ default:
+ spi = 0;
+ }
+ proposal->set_spi(proposal, spi);
- proposal->set_spi(proposal, this->protocol_id, spi);
+ return proposal;
}
/**
@@ -527,7 +541,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_proposal = (void (*) (proposal_substructure_t*,proposal_t*))add_to_proposal;
+ this->public.get_proposal = (proposal_t* (*) (proposal_substructure_t*))get_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;
@@ -556,7 +570,7 @@ proposal_substructure_t *proposal_substructure_create()
/*
* Described in header.
*/
-proposal_substructure_t *proposal_substructure_create_from_proposal(proposal_t *proposal, protocol_id_t proto)
+proposal_substructure_t *proposal_substructure_create_from_proposal(proposal_t *proposal)
{
private_proposal_substructure_t *this = (private_proposal_substructure_t*)proposal_substructure_create();
iterator_t *iterator;
@@ -564,7 +578,7 @@ proposal_substructure_t *proposal_substructure_create_from_proposal(proposal_t *
transform_substructure_t *transform;
/* encryption algorithm is only availble in ESP */
- iterator = proposal->create_algorithm_iterator(proposal, proto, ENCRYPTION_ALGORITHM);
+ iterator = proposal->create_algorithm_iterator(proposal, ENCRYPTION_ALGORITHM);
while (iterator->has_next(iterator))
{
iterator->current(iterator, (void**)&algo);
@@ -574,7 +588,7 @@ proposal_substructure_t *proposal_substructure_create_from_proposal(proposal_t *
iterator->destroy(iterator);
/* integrity algorithms */
- iterator = proposal->create_algorithm_iterator(proposal, proto, INTEGRITY_ALGORITHM);
+ iterator = proposal->create_algorithm_iterator(proposal, INTEGRITY_ALGORITHM);
while (iterator->has_next(iterator))
{
algorithm_t *algo;
@@ -585,7 +599,7 @@ proposal_substructure_t *proposal_substructure_create_from_proposal(proposal_t *
iterator->destroy(iterator);
/* prf algorithms */
- iterator = proposal->create_algorithm_iterator(proposal, proto, PSEUDO_RANDOM_FUNCTION);
+ iterator = proposal->create_algorithm_iterator(proposal, PSEUDO_RANDOM_FUNCTION);
while (iterator->has_next(iterator))
{
algorithm_t *algo;
@@ -596,7 +610,7 @@ proposal_substructure_t *proposal_substructure_create_from_proposal(proposal_t *
iterator->destroy(iterator);
/* dh groups */
- iterator = proposal->create_algorithm_iterator(proposal, proto, DIFFIE_HELLMAN_GROUP);
+ iterator = proposal->create_algorithm_iterator(proposal, DIFFIE_HELLMAN_GROUP);
while (iterator->has_next(iterator))
{
algorithm_t *algo;
@@ -607,7 +621,7 @@ proposal_substructure_t *proposal_substructure_create_from_proposal(proposal_t *
iterator->destroy(iterator);
/* extended sequence numbers */
- iterator = proposal->create_algorithm_iterator(proposal, proto, EXTENDED_SEQUENCE_NUMBERS);
+ iterator = proposal->create_algorithm_iterator(proposal, EXTENDED_SEQUENCE_NUMBERS);
while (iterator->has_next(iterator))
{
algorithm_t *algo;
@@ -618,12 +632,19 @@ proposal_substructure_t *proposal_substructure_create_from_proposal(proposal_t *
iterator->destroy(iterator);
/* take over general infos */
- this->spi_size = proto == PROTO_IKE ? 8 : 4;
+ this->spi_size = proposal->get_protocol(proposal) == PROTO_IKE ? 8 : 4;
this->spi.len = this->spi_size;
this->spi.ptr = malloc(this->spi_size);
- *((u_int32_t*)this->spi.ptr) = proposal->get_spi(proposal, proto);
- this->proposal_number = proposal->get_number(proposal);
- this->protocol_id = proto;
+ if (this->spi_size == 8)
+ {
+ *((u_int64_t*)this->spi.ptr) = proposal->get_spi(proposal);
+ }
+ else
+ {
+ *((u_int32_t*)this->spi.ptr) = proposal->get_spi(proposal);
+ }
+ this->proposal_number = 0;
+ this->protocol_id = proposal->get_protocol(proposal);
return &(this->public);
}
diff --git a/src/charon/encoding/payloads/proposal_substructure.h b/src/charon/encoding/payloads/proposal_substructure.h
index a59f9532f..5b935f0cd 100644
--- a/src/charon/encoding/payloads/proposal_substructure.h
+++ b/src/charon/encoding/payloads/proposal_substructure.h
@@ -174,16 +174,12 @@ struct proposal_substructure_t {
void (*set_spi) (proposal_substructure_t *this, chunk_t spi);
/**
- * @brief Add this proposal_substructure to a proposal.
- *
- * Since a proposal_t may contain the data of multiple
- * proposal_sbustructure_t's, it may be necessary to call
- * the function multiple times with the same proposal.
+ * @brief Get a proposal_t from the propsal_substructure_t.
*
* @param this calling proposal_substructure_t object
- * @param proposal proposal where the data should be added
+ * @return proposal_t
*/
- void (*add_to_proposal) (proposal_substructure_t *this, proposal_t *proposal);
+ proposal_t * (*get_proposal) (proposal_substructure_t *this);
/**
* @brief Clones an proposal_substructure_t object.
@@ -211,21 +207,14 @@ struct proposal_substructure_t {
proposal_substructure_t *proposal_substructure_create(void);
/**
- * @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
- * data for proto, NULL is returned. Call twice, once with AH, once
- * with ESP, with the same proposal to build the two substructures
- * for it.
- *
+ * @brief Creates a proposal_substructure_t from a proposal_t.
+ *
* @param proposal proposal to build a substruct out of it
- * @param proto for which protocol the substructure should be built
- * @return proposal_substructure_t object, or NULL
+ * @return proposal_substructure_t object
*
* @ingroup payloads
*/
-proposal_substructure_t *proposal_substructure_create_from_proposal(proposal_t *proposal, protocol_id_t proto);
+proposal_substructure_t *proposal_substructure_create_from_proposal(proposal_t *proposal);
#endif /*PROPOSAL_SUBSTRUCTURE_H_*/
diff --git a/src/charon/encoding/payloads/sa_payload.c b/src/charon/encoding/payloads/sa_payload.c
index 345264b4d..a54e406a3 100644
--- a/src/charon/encoding/payloads/sa_payload.c
+++ b/src/charon/encoding/payloads/sa_payload.c
@@ -232,18 +232,20 @@ static iterator_t *create_proposal_substructure_iterator (private_sa_payload_t *
/**
* Implementation of sa_payload_t.add_proposal_substructure.
*/
-static void add_proposal_substructure (private_sa_payload_t *this,proposal_substructure_t *proposal)
+static void add_proposal_substructure(private_sa_payload_t *this,proposal_substructure_t *proposal)
{
status_t status;
- if (this->proposals->get_count(this->proposals) > 0)
+ u_int proposal_count = this->proposals->get_count(this->proposals);
+
+ if (proposal_count > 0)
{
proposal_substructure_t *last_proposal;
status = this->proposals->get_last(this->proposals,(void **) &last_proposal);
/* last transform is now not anymore last one */
- last_proposal->set_is_last_proposal(last_proposal,FALSE);
+ last_proposal->set_is_last_proposal(last_proposal, FALSE);
}
- proposal->set_is_last_proposal(proposal,TRUE);
-
+ proposal->set_is_last_proposal(proposal, TRUE);
+ proposal->set_proposal_number(proposal, proposal_count + 1);
this->proposals->insert_last(this->proposals,(void *) proposal);
this->compute_length(this);
}
@@ -254,19 +256,9 @@ static void add_proposal_substructure (private_sa_payload_t *this,proposal_subst
static void add_proposal(private_sa_payload_t *this, proposal_t *proposal)
{
proposal_substructure_t *substructure;
- protocol_id_t proto[2];
- u_int i;
- /* build the substructures for every protocol */
- proposal->get_protocols(proposal, proto);
- for (i = 0; i<2; i++)
- {
- if (proto[i] != PROTO_NONE)
- {
- substructure = proposal_substructure_create_from_proposal(proposal, proto[i]);
- add_proposal_substructure(this, substructure);
- }
- }
+ substructure = proposal_substructure_create_from_proposal(proposal);
+ add_proposal_substructure(this, substructure);
}
/**
@@ -274,30 +266,44 @@ static void add_proposal(private_sa_payload_t *this, proposal_t *proposal)
*/
static linked_list_t *get_proposals(private_sa_payload_t *this)
{
- int proposal_struct_number = 0;
+ int struct_number = 0;
+ int ignore_struct_number = 0;
iterator_t *iterator;
- 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 proposal */
- iterator = this->proposals->create_iterator(this->proposals,TRUE);
+ /* we do not support proposals split up to two proposal substructures, as
+ * AH+ESP bundles are not supported in RFC4301 anymore.
+ * To handle such structures safely, we just skip proposals with multiple
+ * protocols.
+ */
+ iterator = this->proposals->create_iterator(this->proposals, TRUE);
while (iterator->has_next(iterator))
{
+ proposal_t *proposal;
proposal_substructure_t *proposal_struct;
- iterator->current(iterator,(void **)&(proposal_struct));
- if (proposal_struct->get_proposal_number(proposal_struct) > proposal_struct_number)
+ iterator->current(iterator, (void **)&proposal_struct);
+ /* check if a proposal has a single protocol */
+ if (proposal_struct->get_proposal_number(proposal_struct) == struct_number)
+ {
+ if (ignore_struct_number < struct_number)
+ {
+ /* remova an already added, if first of series */
+ proposal_list->remove_last(proposal_list, (void**)proposal);
+ proposal->destroy(proposal);
+ ignore_struct_number = struct_number;
+ }
+ continue;
+ }
+ struct_number++;
+ proposal = proposal_struct->get_proposal(proposal_struct);
+ if (proposal)
{
- /* 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 = 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_proposal(proposal_struct, proposal);
}
iterator->destroy(iterator);
return proposal_list;
@@ -354,7 +360,7 @@ sa_payload_t *sa_payload_create()
this->payload_length = SA_PAYLOAD_HEADER_LENGTH;
this->proposals = linked_list_create();
- return (&(this->public));
+ return &this->public;
}
/*