implemented and tested functionality to create sa_payload from
[strongswan.git] / Source / charon / encoding / payloads / proposal_substructure.c
index b16fb9a..05b375e 100644 (file)
@@ -1,9 +1,7 @@
 /**
  * @file proposal_substructure.h
  * 
- * @brief Declaration of the class proposal_substructure_t. 
- * 
- * An object of this type represents an IKEv2 PROPOSAL Substructure and contains transforms.
+ * @brief Implementation of proposal_substructure_t.
  * 
  */
 
 typedef struct private_proposal_substructure_t private_proposal_substructure_t;
 
 /**
- * Private data of an proposal_substructure_t' Object
+ * Private data of an proposal_substructure_t object.
  * 
  */
 struct private_proposal_substructure_t {
        /**
-        * public proposal_substructure_t interface
+        * Public proposal_substructure_t interface.
         */
        proposal_substructure_t public;
        
        /**
-        * next payload type
+        * Next payload type.
         */
        u_int8_t  next_payload;
 
-       
        /**
-        * Length of this payload
+        * Length of this payload.
         */
        u_int16_t proposal_length;
        
-       
        /**
-        * Proposal number
+        * Proposal number.
         */
        u_int8_t         proposal_number;
        
        /**
-        * Protocol ID
+        * Protocol ID.
         */
        u_int8_t protocol_id;
 
        /**
-        * SPI size of the following SPI
+        * SPI size of the following SPI.
         */
        u_int8_t  spi_size;
 
        /**
-        * Number of transforms
+        * Number of transforms.
         */
        u_int8_t  transforms_count;
        
        /**
-        * SPI is stored as chunk
+        * SPI is stored as chunk.
         */
        chunk_t spi;
        
        /**
-        * Transforms are stored in a linked_list_t
+        * Transforms are stored in a linked_list_t.
         */
        linked_list_t * transforms;
        
@@ -91,14 +87,12 @@ struct private_proposal_substructure_t {
         * @brief Computes the length of this substructure.
         *
         * @param this  calling private_proposal_substructure_t object
-        * @return              
-        *                              SUCCESS in any case
         */
-       status_t (*compute_length) (private_proposal_substructure_t *this);
+       void (*compute_length) (private_proposal_substructure_t *this);
 };
 
 /**
- * Encoding rules to parse or generate a Proposal substructure
+ * Encoding rules to parse or generate a Proposal substructure.
  * 
  * The defined offsets are the positions in a object of type 
  * private_proposal_substructure_t.
@@ -143,12 +137,14 @@ encoding_rule_t proposal_substructure_encodings[] = {
 */
 
 /**
- * Implements payload_t's verify function.
- * See #payload_s.verify for description.
+ * Implementation of payload_t.verify.
  */
 static status_t verify(private_proposal_substructure_t *this)
 {
-       if ((this->next_payload != NO_PAYLOAD) && (this->next_payload != PROPOSAL_SUBSTRUCTURE))
+       status_t status = SUCCESS;
+       iterator_t *iterator;
+       
+       if ((this->next_payload != NO_PAYLOAD) && (this->next_payload != 2))
        {
                /* must be 0 or 2 */
                return FAILED;
@@ -164,26 +160,39 @@ static status_t verify(private_proposal_substructure_t *this)
                /* reserved are not supported */
                return FAILED;
        }
+       
+       iterator = this->transforms->create_iterator(this->transforms,TRUE);
+       
+       while(iterator->has_next(iterator))
+       {
+               payload_t *current_transform;
+               iterator->current(iterator,(void **)&current_transform);
+
+               status = current_transform->verify(current_transform);
+               if (status != SUCCESS)
+               {
+                       break;
+               }
+       }
+       
+       iterator->destroy(iterator);
+
 
        /* proposal number is checked in SA payload */  
-       return SUCCESS;
+       return status;
 }
 
 /**
- * Implements payload_t's get_encoding_rules function.
- * See #payload_s.get_encoding_rules for description.
+ * Implementation of payload_t.get_encoding_rules.
  */
-static status_t get_encoding_rules(private_proposal_substructure_t *this, encoding_rule_t **rules, size_t *rule_count)
+static void get_encoding_rules(private_proposal_substructure_t *this, encoding_rule_t **rules, size_t *rule_count)
 {
        *rules = proposal_substructure_encodings;
        *rule_count = sizeof(proposal_substructure_encodings) / sizeof(encoding_rule_t);
-       
-       return SUCCESS;
 }
 
 /**
- * Implements payload_t's get_type function.
- * See #payload_s.get_type for description.
+ * Implementation of payload_t.get_type.
  */
 static payload_type_t get_type(private_proposal_substructure_t *this)
 {
@@ -191,8 +200,7 @@ static payload_type_t get_type(private_proposal_substructure_t *this)
 }
 
 /**
- * Implements payload_t's get_next_type function.
- * See #payload_s.get_next_type for description.
+ * Implementation of payload_t.get_next_type.
  */
 static payload_type_t get_next_type(private_proposal_substructure_t *this)
 {
@@ -200,17 +208,14 @@ static payload_type_t get_next_type(private_proposal_substructure_t *this)
 }
 
 /**
- * Implements payload_t's set_next_type function.
- * See #payload_s.set_next_type for description.
+ * Implementation of payload_t.set_next_type.
  */
-static status_t set_next_type(private_proposal_substructure_t *this,payload_type_t type)
+static void set_next_type(private_proposal_substructure_t *this,payload_type_t type)
 {
-       return SUCCESS;
 }
 
 /**
- * Implements payload_t's get_length function.
- * See #payload_s.get_length for description.
+ * Implementation of payload_t.get_length.
  */
 static size_t get_length(private_proposal_substructure_t *this)
 {
@@ -218,19 +223,17 @@ static size_t get_length(private_proposal_substructure_t *this)
 }
 
 /**
- * Implements proposal_substructure_t's create_transform_substructure_iterator function.
- * See #proposal_substructure_s.create_transform_substructure_iterator for description.
+ * Implementation of proposal_substructure_t.create_transform_substructure_iterator.
  */
-static status_t create_transform_substructure_iterator (private_proposal_substructure_t *this,iterator_t **iterator,bool forward)
+static iterator_t *create_transform_substructure_iterator (private_proposal_substructure_t *this,bool forward)
 {
-       return (this->transforms->create_iterator(this->transforms,iterator,forward));
+       return (this->transforms->create_iterator(this->transforms,forward));
 }
 
 /**
- * Implements proposal_substructure_t's add_transform_substructure function.
- * See #proposal_substructure_s.add_transform_substructure for description.
+ * Implementation of proposal_substructure_t.add_transform_substructure.
  */
-static status_t add_transform_substructure (private_proposal_substructure_t *this,transform_substructure_t *transform)
+static void add_transform_substructure (private_proposal_substructure_t *this,transform_substructure_t *transform)
 {
        status_t status;
        if (this->transforms->get_count(this->transforms) > 0)
@@ -243,24 +246,29 @@ static status_t add_transform_substructure (private_proposal_substructure_t *thi
        }
        transform->set_is_last_transform(transform,TRUE);
        
-       status = this->transforms->insert_last(this->transforms,(void *) transform);
+       this->transforms->insert_last(this->transforms,(void *) transform);
        this->compute_length(this);
-       return status;
 }
 
 /**
- * Implements proposal_substructure_t's set_proposal_number function.
- * See #proposal_substructure_s.set_proposal_number for description.
+ * Implementation of proposal_substructure_t.proposal_substructure_t.
+ */
+static void set_is_last_proposal (private_proposal_substructure_t *this, bool is_last)
+{
+       this->next_payload = (is_last) ? 0: PROPOSAL_TYPE_VALUE;
+}
+
+
+/**
+ * Implementation of proposal_substructure_t.set_proposal_number.
  */
-static status_t set_proposal_number(private_proposal_substructure_t *this,u_int8_t proposal_number)
+static void set_proposal_number(private_proposal_substructure_t *this,u_int8_t proposal_number)
 {
        this->proposal_number = proposal_number;
-       return SUCCESS;
 }
 
 /**
- * Implements proposal_substructure_t's get_proposal_number function.
- * See #proposal_substructure_s.get_proposal_number for description.
+ * Implementation of proposal_substructure_t.get_proposal_number.
  */
 static u_int8_t get_proposal_number (private_proposal_substructure_t *this)
 {
@@ -268,30 +276,25 @@ static u_int8_t get_proposal_number (private_proposal_substructure_t *this)
 }
 
 /**
- * Implements proposal_substructure_t's set_protocol_id function.
- * See #proposal_substructure_s.set_protocol_id for description.
+ * Implementation of proposal_substructure_t.set_protocol_id.
  */
-static status_t set_protocol_id(private_proposal_substructure_t *this,u_int8_t protocol_id)
+static void set_protocol_id(private_proposal_substructure_t *this,u_int8_t protocol_id)
 {
        this->protocol_id = protocol_id;
-       return SUCCESS;
 }
 
 /**
- * Implements proposal_substructure_t's get_protocol_id function.
- * See #proposal_substructure_s.get_protocol_id for description.
+ * Implementation of proposal_substructure_t.get_protocol_id.
  */
 static u_int8_t get_protocol_id (private_proposal_substructure_t *this)
 {
        return (this->protocol_id);
 }
 
-
 /**
- * Implements proposal_substructure_t's set_spi function.
- * See #proposal_substructure_s.set_spi for description.
+ * Implementation of proposal_substructure_t.set_spi.
  */
-static status_t set_spi (private_proposal_substructure_t *this, chunk_t spi)
+static void set_spi (private_proposal_substructure_t *this, chunk_t spi)
 {
        /* first delete already set spi value */
        if (this->spi.ptr != NULL)
@@ -303,20 +306,13 @@ static status_t set_spi (private_proposal_substructure_t *this, chunk_t spi)
        }
        
        this->spi.ptr = allocator_clone_bytes(spi.ptr,spi.len);
-       if (this->spi.ptr == NULL)
-       {
-               return OUT_OF_RES;
-       }
        this->spi.len = spi.len;
        this->spi_size = spi.len;
        this->compute_length(this);
-
-       return SUCCESS;
 }
 
 /**
- * Implements proposal_substructure_t's get_spi function.
- * See #proposal_substructure_s.get_spi for description.
+ * Implementation of proposal_substructure_t.get_spi.
  */
 static chunk_t get_spi (private_proposal_substructure_t *this)
 {
@@ -327,6 +323,9 @@ static chunk_t get_spi (private_proposal_substructure_t *this)
        return spi;
 }
 
+/**
+ * Implementation of proposal_substructure_t.get_info_for_transform_type.
+ */
 static status_t get_info_for_transform_type (private_proposal_substructure_t *this,transform_type_t type, u_int16_t *transform_id, u_int16_t *key_length)
 {
        iterator_t *iterator;
@@ -334,11 +333,8 @@ static status_t get_info_for_transform_type (private_proposal_substructure_t *th
        u_int16_t found_transform_id;
        u_int16_t found_key_length;
 
-       status = this->transforms->create_iterator(this->transforms,&iterator,TRUE);
-       if (status != SUCCESS)
-       {
-               return status;
-       }
+       iterator = this->transforms->create_iterator(this->transforms,TRUE);
+
        while (iterator->has_next(iterator))
        {
                transform_substructure_t *current_transform;
@@ -359,24 +355,18 @@ static status_t get_info_for_transform_type (private_proposal_substructure_t *th
                }               
        }
        iterator->destroy(iterator);
-       return FAILED;
+       return NOT_FOUND;
 }
 
 /**
- * Implements private_proposal_substructure_t's compute_length function.
- * See #private_proposal_substructure_s.compute_length for description.
+ * Implementation of private_proposal_substructure_t.compute_length.
  */
-static status_t compute_length (private_proposal_substructure_t *this)
+static void compute_length (private_proposal_substructure_t *this)
 {
        iterator_t *iterator;
-       status_t status;
        size_t transforms_count = 0;
        size_t length = PROPOSAL_SUBSTRUCTURE_HEADER_LENGTH;
-       status = this->transforms->create_iterator(this->transforms,&iterator,TRUE);
-       if (status != SUCCESS)
-       {
-               return length;
-       }
+       iterator = this->transforms->create_iterator(this->transforms,TRUE);
        while (iterator->has_next(iterator))
        {
                payload_t * current_transform;
@@ -390,18 +380,31 @@ static status_t compute_length (private_proposal_substructure_t *this)
        this->transforms_count= transforms_count;
        this->proposal_length = length; 
 
-       return SUCCESS;
 }
 
 /**
- * Implements proposal_substructure_t's clone function.
- * See #proposal_substructure_s.clone for description.
+ * Implementation of proposal_substructure_t.get_transform_count.
+ */
+static size_t get_transform_count (private_proposal_substructure_t *this)
+{
+       return this->transforms->get_count(this->transforms);
+}
+
+/**
+ * Implementation of proposal_substructure_t.get_spi_size.
+ */
+static size_t get_spi_size (private_proposal_substructure_t *this)
+{
+       return  this->spi.len;
+}
+
+/**
+ * Implementation of proposal_substructure_t.clone.
  */
-static status_t clone(private_proposal_substructure_t *this, private_proposal_substructure_t **clone)
+static private_proposal_substructure_t* clone(private_proposal_substructure_t *this)
 {
        private_proposal_substructure_t * new_clone;
        iterator_t *transforms;
-       status_t status;
        
        new_clone = (private_proposal_substructure_t *) proposal_substructure_create();
        
@@ -412,55 +415,26 @@ static status_t clone(private_proposal_substructure_t *this, private_proposal_su
        if (this->spi.ptr != NULL)
        {
                new_clone->spi.ptr = allocator_clone_bytes(this->spi.ptr,this->spi.len);
-               if (new_clone->spi.ptr == NULL)
-               {
-                       new_clone->public.destroy(&(new_clone->public));
-                       return OUT_OF_RES;
-               }
                new_clone->spi.len = this->spi.len;
        }
 
-       status = this->transforms->create_iterator(this->transforms,&transforms,FALSE);
-       if (status != SUCCESS)
-       {
-               new_clone->public.destroy(&(new_clone->public));
-               return status;
-       }
+       transforms = this->transforms->create_iterator(this->transforms,FALSE);
 
        while (transforms->has_next(transforms))
        {
                transform_substructure_t *current_transform;
                transform_substructure_t *current_transform_clone;
-               status = transforms->current(transforms,(void **) &current_transform);
-               if (status != SUCCESS)
-               {
-                       transforms->destroy(transforms);
-                       new_clone->public.destroy(&(new_clone->public));
-                       return status;
-               }
-               status = current_transform->clone(current_transform,&current_transform_clone);
-               if (status != SUCCESS)
-               {
-                       transforms->destroy(transforms);
-                       new_clone->public.destroy(&(new_clone->public));
-                       return status;
-               }
+
+               transforms->current(transforms,(void **) &current_transform);
+
+               current_transform_clone = current_transform->clone(current_transform);
                
-               status = new_clone->public.add_transform_substructure(&(new_clone->public),current_transform_clone);
-               if (status != SUCCESS)
-               {
-                       transforms->destroy(transforms);
-                       current_transform_clone->destroy(current_transform_clone);
-                       new_clone->public.destroy(&(new_clone->public));
-                       return status;
-               }                               
+               new_clone->public.add_transform_substructure(&(new_clone->public),current_transform_clone);
        }
        
        transforms->destroy(transforms);        
        
-       *clone = new_clone;     
-       
-       return SUCCESS;
+       return new_clone;       
 }
 
 /**
@@ -492,37 +466,37 @@ static status_t destroy(private_proposal_substructure_t *this)
 }
 
 /*
- * Described in header
+ * Described in header.
  */
 proposal_substructure_t *proposal_substructure_create()
 {
        private_proposal_substructure_t *this = allocator_alloc_thing(private_proposal_substructure_t);
-       if (this == NULL)
-       {
-               return NULL;    
-       }       
 
        /* interface functions */       
        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_encoding_rules = (void (*) (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.set_next_type = (void (*) (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;
+       this->public.payload_interface.destroy = (void (*) (payload_t *))destroy;
        
        /* public functions */
-       this->public.create_transform_substructure_iterator = (status_t (*) (proposal_substructure_t *,iterator_t **,bool)) create_transform_substructure_iterator;
-       this->public.add_transform_substructure = (status_t (*) (proposal_substructure_t *,transform_substructure_t *)) add_transform_substructure;
-       this->public.set_proposal_number = (status_t (*) (proposal_substructure_t *,u_int8_t))set_proposal_number;
+       this->public.create_transform_substructure_iterator = (iterator_t* (*) (proposal_substructure_t *,bool)) create_transform_substructure_iterator;
+       this->public.add_transform_substructure = (void (*) (proposal_substructure_t *,transform_substructure_t *)) add_transform_substructure;
+       this->public.set_proposal_number = (void (*) (proposal_substructure_t *,u_int8_t))set_proposal_number;
        this->public.get_proposal_number = (u_int8_t (*) (proposal_substructure_t *)) get_proposal_number;
-       this->public.set_protocol_id = (status_t (*) (proposal_substructure_t *,u_int8_t))set_protocol_id;
+       this->public.set_protocol_id = (void (*) (proposal_substructure_t *,u_int8_t))set_protocol_id;
        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_spi = (status_t (*) (proposal_substructure_t *,chunk_t))set_spi;
+       this->public.set_is_last_proposal = (void (*) (proposal_substructure_t *,bool)) set_is_last_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.clone = (status_t (*) (proposal_substructure_t *, proposal_substructure_t **)) clone;
-       this->public.destroy = (status_t (*) (proposal_substructure_t *)) destroy;
+       this->public.get_transform_count = (size_t (*) (proposal_substructure_t *)) get_transform_count;
+       this->public.get_spi_size = (size_t (*) (proposal_substructure_t *)) get_spi_size;      
+       this->public.clone = (proposal_substructure_t * (*) (proposal_substructure_t *)) clone;
+       this->public.destroy = (void (*) (proposal_substructure_t *)) destroy;
        
        
        /* private functions */
@@ -539,11 +513,6 @@ proposal_substructure_t *proposal_substructure_create()
        this->spi.len = 0;
 
        this->transforms = linked_list_create();
-       
-       if (this->transforms == NULL)
-       {
-               allocator_free(this);
-               return NULL;
-       }
+
        return (&(this->public));
 }