aboutsummaryrefslogtreecommitdiffstats
path: root/Source/charon/payloads/sa_payload.c
diff options
context:
space:
mode:
Diffstat (limited to 'Source/charon/payloads/sa_payload.c')
-rw-r--r--Source/charon/payloads/sa_payload.c80
1 files changed, 79 insertions, 1 deletions
diff --git a/Source/charon/payloads/sa_payload.c b/Source/charon/payloads/sa_payload.c
index 9d4f95401..f5f2c958f 100644
--- a/Source/charon/payloads/sa_payload.c
+++ b/Source/charon/payloads/sa_payload.c
@@ -102,6 +102,80 @@ encoding_rule_t sa_payload_encodings[] = {
{ PROPOSALS, offsetof(private_sa_payload_t, proposals) }
};
+/*
+ 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ ! Next Payload !C! RESERVED ! Payload Length !
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ ! !
+ ~ <Proposals> ~
+ ! !
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+*/
+
+/**
+ * Implements payload_t's verify function.
+ * See #payload_s.verify for description.
+ */
+static status_t verify(private_sa_payload_t *this)
+{
+ int proposal_number = 1;
+ status_t status;
+ linked_list_iterator_t *iterator;
+ bool first = TRUE;
+
+ if (this->critical)
+ {
+ /* critical bit set! */
+ return FAILED;
+ }
+
+ /* check proposal numbering */
+ status = this->proposals->create_iterator(this->proposals,&iterator,TRUE);
+ if (status != SUCCESS)
+ {
+ return status;
+ }
+
+ while(iterator->has_next(iterator))
+ {
+ proposal_substructure_t *current_proposal;
+ status = iterator->current(iterator,(void **)&current_proposal);
+ {
+ break;
+ }
+ if (current_proposal->get_proposal_number(current_proposal) > proposal_number)
+ {
+ if (first)
+ {
+ /* first number must be 1 */
+ status = FAILED;
+ break;
+ }
+
+ if (current_proposal->get_proposal_number(current_proposal) != (proposal_number + 1))
+ {
+ /* must be only one more then previous proposal */
+ status = FAILED;
+ break;
+ }
+ }
+ else if (current_proposal->get_proposal_number(current_proposal) < proposal_number)
+ {
+ iterator->destroy(iterator);
+ /* must not be smaller then proceeding one */
+ status = FAILED;
+ break;
+ }
+ first = FALSE;
+ }
+
+ iterator->destroy(iterator);
+ return status;
+}
+
+
/**
* Implements payload_t's and sa_payload_t's destroy function.
* See #payload_s.destroy or sa_payload_s.destroy for description.
@@ -234,12 +308,16 @@ sa_payload_t *sa_payload_create()
return NULL;
}
+ /* public interface */
+ this->public.payload_interface.verify = (status_t (*) (payload_t *))verify;
this->public.payload_interface.get_encoding_rules = (status_t (*) (payload_t *, encoding_rule_t **, size_t *) ) get_encoding_rules;
this->public.payload_interface.get_length = (size_t (*) (payload_t *)) get_length;
this->public.payload_interface.get_next_type = (payload_type_t (*) (payload_t *)) get_next_type;
this->public.payload_interface.set_next_type = (status_t (*) (payload_t *,payload_type_t)) set_next_type;
this->public.payload_interface.get_type = (payload_type_t (*) (payload_t *)) get_type;
this->public.payload_interface.destroy = (status_t (*) (payload_t *))destroy;
+
+ /* public functions */
this->public.create_proposal_substructure_iterator = (status_t (*) (sa_payload_t *,linked_list_iterator_t **,bool)) create_proposal_substructure_iterator;
this->public.add_proposal_substructure = (status_t (*) (sa_payload_t *,proposal_substructure_t *)) add_proposal_substructure;
this->public.destroy = (status_t (*) (sa_payload_t *)) destroy;
@@ -248,7 +326,7 @@ sa_payload_t *sa_payload_create()
this->compute_length = compute_length;
/* set default values of the fields */
- this->critical = SA_PAYLOAD_CRITICAL_FLAG;
+ this->critical = 1;//SA_PAYLOAD_CRITICAL_FLAG;
this->next_payload = NO_PAYLOAD;
this->payload_length = SA_PAYLOAD_HEADER_LENGTH;