- cleaned code of generator_t class
authorJan Hutter <jhutter@hsr.ch>
Mon, 5 Dec 2005 13:06:24 +0000 (13:06 -0000)
committerJan Hutter <jhutter@hsr.ch>
Mon, 5 Dec 2005 13:06:24 +0000 (13:06 -0000)
Source/charon/encoding/generator.c
Source/charon/encoding/payloads/certreq_payload.c [new file with mode: 0644]
Source/charon/encoding/payloads/certreq_payload.h [new file with mode: 0644]
Source/charon/testcases/testcases.c

index 1eb2869..ee34219 100644 (file)
@@ -734,95 +734,56 @@ static void generate_payload (private_generator_t *this,payload_t *payload)
                                break;
                        }
                        case KEY_EXCHANGE_DATA:
                                break;
                        }
                        case KEY_EXCHANGE_DATA:
-                       {
-                               /* the Key Exchange Data value is generated from chunk */
-                               this->generate_from_chunk(this,rules[i].offset);
-
-                               u_int32_t payload_length_position_offset = this->last_payload_length_position_offset;
-                               /* Length of KE_PAYLOAD is calculated */
-                               u_int16_t length_of_ke_payload = KE_PAYLOAD_HEADER_LENGTH + ((chunk_t *)(this->data_struct + rules[i].offset))->len;
-
-                               u_int16_t int16_val = htons(length_of_ke_payload);                      
-                               this->write_bytes_to_buffer_at_offset(this,&int16_val,sizeof(u_int16_t),payload_length_position_offset);
-                               break;
-                       }
                        case NOTIFICATION_DATA:
                        case NOTIFICATION_DATA:
-                       {
-                               /* the Notification Data value is generated from chunk */
-                               this->generate_from_chunk(this,rules[i].offset);
-                               
-                               u_int32_t payload_length_position_offset = this->last_payload_length_position_offset;
-                               /* Length of Notification PAYLOAD is calculated */
-                               u_int16_t length_of_notify_payload = NOTIFY_PAYLOAD_HEADER_LENGTH + ((chunk_t *)(this->data_struct + rules[i].offset))->len;
-                               length_of_notify_payload += this->last_spi_size;
-                               u_int16_t int16_val = htons(length_of_notify_payload);
-
-                               this->write_bytes_to_buffer_at_offset(this,&int16_val,sizeof(u_int16_t),payload_length_position_offset);
-                               break;
-                       }               
                        case NONCE_DATA:
                        case NONCE_DATA:
-                       {
-                               /* the Nonce Data value is generated from chunk */
-                               this->generate_from_chunk(this, rules[i].offset);
-                               
-                               u_int32_t payload_length_position_offset = this->last_payload_length_position_offset;
-                               /* Length of nonce PAYLOAD is calculated */
-                               u_int16_t length_of_nonce_payload = NONCE_PAYLOAD_HEADER_LENGTH + ((chunk_t *)(this->data_struct + rules[i].offset))->len;
-                               u_int16_t int16_val = htons(length_of_nonce_payload);
-
-                               this->write_bytes_to_buffer_at_offset(this,&int16_val,sizeof(u_int16_t),payload_length_position_offset);
-                               break;
-                       }
                        case ID_DATA:
                        case ID_DATA:
-                       {
-                               /* the ID Data value is generated from chunk */
-                               this->generate_from_chunk(this, rules[i].offset);
-                               
-                               u_int32_t payload_length_position_offset = this->last_payload_length_position_offset;
-                               /* Length of nonce PAYLOAD is calculated */
-                               u_int16_t length_of_id_payload = ID_PAYLOAD_HEADER_LENGTH + ((chunk_t *)(this->data_struct + rules[i].offset))->len;
-                               u_int16_t int16_val = htons(length_of_id_payload);
-
-                               this->write_bytes_to_buffer_at_offset(this,&int16_val,sizeof(u_int16_t),payload_length_position_offset);
-                               break;
-                       }
                        case AUTH_DATA:
                        case AUTH_DATA:
-                       {
-                               /* the AUTH Data value is generated from chunk */
-                               this->generate_from_chunk(this, rules[i].offset);
-                               
-                               u_int32_t payload_length_position_offset = this->last_payload_length_position_offset;
-                               /* Length of nonce PAYLOAD is calculated */
-                               u_int16_t length_of_auth_payload = AUTH_PAYLOAD_HEADER_LENGTH + ((chunk_t *)(this->data_struct + rules[i].offset))->len;
-                               u_int16_t int16_val = htons(length_of_auth_payload);
-
-                               this->write_bytes_to_buffer_at_offset(this,&int16_val,sizeof(u_int16_t),payload_length_position_offset);
-                               break;
-                       }
                        case CERT_DATA:
                        case CERT_DATA:
+                       case CERTREQ_DATA:
                        {
                        {
-                               /* the CERT Data value is generated from chunk */
-                               this->generate_from_chunk(this, rules[i].offset);
+                               u_int32_t payload_length_position_offset;
+                               u_int16_t length_of_payload;
+                               u_int16_t header_length = 0;
+                               u_int16_t length_in_network_order;
+
+                               switch(rules[i].type)
+                               {
+                                       case KEY_EXCHANGE_DATA:
+                                               header_length = KE_PAYLOAD_HEADER_LENGTH;
+                                               break;
+                                       case NOTIFICATION_DATA:
+                                               header_length = NOTIFY_PAYLOAD_HEADER_LENGTH + this->last_spi_size ;
+                                               break;
+                                       case NONCE_DATA:
+                                               header_length = NONCE_PAYLOAD_HEADER_LENGTH;
+                                               break;
+                                       case ID_DATA:
+                                               header_length = ID_PAYLOAD_HEADER_LENGTH;
+                                               break;
+                                       case AUTH_DATA:
+                                               header_length = AUTH_PAYLOAD_HEADER_LENGTH;
+                                               break;
+                                       case CERT_DATA:
+                                               header_length = CERT_PAYLOAD_HEADER_LENGTH;
+                                               break;
+                                       case CERTREQ_DATA:
+                                               header_length = CERTREQ_PAYLOAD_HEADER_LENGTH;
+                                               break;
+                                       default:
+                                               break;
+                               }
                                
                                
-                               u_int32_t payload_length_position_offset = this->last_payload_length_position_offset;
-                               /* Length of PAYLOAD is calculated */
-                               u_int16_t length_of_cert_payload = CERT_PAYLOAD_HEADER_LENGTH + ((chunk_t *)(this->data_struct + rules[i].offset))->len;
-                               u_int16_t int16_val = htons(length_of_cert_payload);
+                               /* the data value is generated from chunk */
+                               this->generate_from_chunk(this,rules[i].offset);
 
 
-                               this->write_bytes_to_buffer_at_offset(this,&int16_val,sizeof(u_int16_t),payload_length_position_offset);
-                               break;
-                       }
-                       case CERTREQ_DATA:
-                       {
-                               /* the CERTREQ Data value is generated from chunk */
-                               this->generate_from_chunk(this, rules[i].offset);
+                               payload_length_position_offset = this->last_payload_length_position_offset;
                                
                                
-                               u_int32_t payload_length_position_offset = this->last_payload_length_position_offset;
-                               /* Length of PAYLOAD is calculated */
-                               u_int16_t length_of_certreq_payload = CERTREQ_PAYLOAD_HEADER_LENGTH + ((chunk_t *)(this->data_struct + rules[i].offset))->len;
-                               u_int16_t int16_val = htons(length_of_certreq_payload);
+                               
+                               /* Length of payload is calculated */
+                               length_of_payload = header_length + ((chunk_t *)(this->data_struct + rules[i].offset))->len;
 
 
-                               this->write_bytes_to_buffer_at_offset(this,&int16_val,sizeof(u_int16_t),payload_length_position_offset);
+                               length_in_network_order = htons(length_of_payload);                     
+                               this->write_bytes_to_buffer_at_offset(this,&length_in_network_order,sizeof(u_int16_t),payload_length_position_offset);
                                break;
                        }
                        case PROPOSALS:
                                break;
                        }
                        case PROPOSALS:
diff --git a/Source/charon/encoding/payloads/certreq_payload.c b/Source/charon/encoding/payloads/certreq_payload.c
new file mode 100644 (file)
index 0000000..8058ff0
--- /dev/null
@@ -0,0 +1,264 @@
+/**
+ * @file certreq_payload.c
+ * 
+ * @brief Implementation of certreq_payload_t.
+ * 
+ */
+
+/*
+ * Copyright (C) 2005 Jan Hutter, Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#include "certreq_payload.h"
+
+#include <utils/allocator.h>
+
+
+typedef struct private_certreq_payload_t private_certreq_payload_t;
+
+/**
+ * Private data of an certreq_payload_t object.
+ * 
+ */
+struct private_certreq_payload_t {
+       /**
+        * Public certreq_payload_t interface.
+        */
+       certreq_payload_t public;
+       
+       /**
+        * Next payload type.
+        */
+       u_int8_t  next_payload;
+
+       /**
+        * Critical flag.
+        */
+       bool critical;
+       
+       /**
+        * Length of this payload.
+        */
+       u_int16_t payload_length;
+       
+       /**
+        * Encoding of the CERT Data.
+        */
+       u_int8_t cert_encoding;
+       
+       /**
+        * The contained certreq data value.
+        */
+       chunk_t certreq_data;
+};
+
+/**
+ * Encoding rules to parse or generate a CERTREQ payload
+ * 
+ * The defined offsets are the positions in a object of type 
+ * private_certreq_payload_t.
+ * 
+ */
+encoding_rule_t certreq_payload_encodings[] = {
+       /* 1 Byte next payload type, stored in the field next_payload */
+       { U_INT_8,                      offsetof(private_certreq_payload_t, next_payload)       },
+       /* the critical bit */
+       { FLAG,                         offsetof(private_certreq_payload_t, critical)           },
+       /* 7 Bit reserved bits, nowhere stored */
+       { RESERVED_BIT, 0                                                                                                               },
+       { RESERVED_BIT, 0                                                                                                               },
+       { RESERVED_BIT, 0                                                                                                               },
+       { RESERVED_BIT, 0                                                                                                               },
+       { RESERVED_BIT, 0                                                                                                               },
+       { RESERVED_BIT, 0                                                                                                               },
+       { RESERVED_BIT, 0                                                                                                               },
+       /* Length of the whole payload*/
+       { PAYLOAD_LENGTH,       offsetof(private_certreq_payload_t, payload_length)},
+       /* 1 Byte CERTREQ type*/
+       { U_INT_8,                      offsetof(private_certreq_payload_t, cert_encoding)},
+       /* some certreq data bytes, length is defined in PAYLOAD_LENGTH */
+       { CERTREQ_DATA,                 offsetof(private_certreq_payload_t, certreq_data)}
+};
+
+/*
+                           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        !
+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+      ! Cert Encoding !                                               !
+      +-+-+-+-+-+-+-+-+                                               !
+      ~                    Certification Authority                    ~
+      !                                                               !
+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+*/
+
+/**
+ * Implementation of payload_t.verify.
+ */
+static status_t verify(private_certreq_payload_t *this)
+{
+       if (this->critical)
+       {
+               /* critical bit is set! */
+               return FAILED;
+       }
+       if ((this->cert_encoding == 0) ||
+               ((this->cert_encoding >= 14) && (this->cert_encoding <= 200)))
+       {
+               /* reserved IDs */
+               return FAILED;
+       }
+       return SUCCESS;
+}
+
+/**
+ * Implementation of certreq_payload_t.get_encoding_rules.
+ */
+static void get_encoding_rules(private_certreq_payload_t *this, encoding_rule_t **rules, size_t *rule_count)
+{
+       *rules = certreq_payload_encodings;
+       *rule_count = sizeof(certreq_payload_encodings) / sizeof(encoding_rule_t);
+}
+
+/**
+ * Implementation of payload_t.get_type.
+ */
+static payload_type_t get_payload_type(private_certreq_payload_t *this)
+{
+       return CERTIFICATE_REQUEST;
+}
+
+/**
+ * Implementation of payload_t.get_next_type.
+ */
+static payload_type_t get_next_type(private_certreq_payload_t *this)
+{
+       return (this->next_payload);
+}
+
+/**
+ * Implementation of payload_t.set_next_type.
+ */
+static void set_next_type(private_certreq_payload_t *this,payload_type_t type)
+{
+       this->next_payload = type;
+}
+
+/**
+ * Implementation of payload_t.get_length.
+ */
+static size_t get_length(private_certreq_payload_t *this)
+{
+       return this->payload_length;
+}
+
+/**
+ * Implementation of certreq_payload_t.set_cert_encoding.
+ */
+static void set_cert_encoding (private_certreq_payload_t *this, cert_encoding_t encoding)
+{
+       this->cert_encoding = encoding;
+}
+
+/**
+ * Implementation of certreq_payload_t.get_cert_encoding.
+ */
+static cert_encoding_t get_cert_encoding (private_certreq_payload_t *this)
+{
+       return (this->cert_encoding);
+}
+
+/**
+ * Implementation of certreq_payload_t.set_data.
+ */
+static void set_data (private_certreq_payload_t *this, chunk_t data)
+{
+       if (this->certreq_data.ptr != NULL)
+       {
+               allocator_free_chunk(&(this->certreq_data));
+       }
+       this->certreq_data.ptr = allocator_clone_bytes(data.ptr,data.len);
+       this->certreq_data.len = data.len;
+       this->payload_length = CERTREQ_PAYLOAD_HEADER_LENGTH + this->certreq_data.len;
+}
+
+/**
+ * Implementation of certreq_payload_t.get_data.
+ */
+static chunk_t get_data (private_certreq_payload_t *this)
+{
+       return (this->certreq_data);
+}
+
+/**
+ * Implementation of certreq_payload_t.get_data_clone.
+ */
+static chunk_t get_data_clone (private_certreq_payload_t *this)
+{
+       chunk_t cloned_data;
+       if (this->certreq_data.ptr == NULL)
+       {
+               return (this->certreq_data);
+       }
+       cloned_data.ptr = allocator_clone_bytes(this->certreq_data.ptr,this->certreq_data.len);
+       cloned_data.len = this->certreq_data.len;
+       return cloned_data;
+}
+
+/**
+ * Implementation of payload_t.destroy and certreq_payload_t.destroy.
+ */
+static void destroy(private_certreq_payload_t *this)
+{
+       if (this->certreq_data.ptr != NULL)
+       {
+               allocator_free_chunk(&(this->certreq_data));
+       }
+       
+       allocator_free(this);   
+}
+
+/*
+ * Described in header
+ */
+certreq_payload_t *certreq_payload_create()
+{
+       private_certreq_payload_t *this = allocator_alloc_thing(private_certreq_payload_t);
+
+       /* interface functions */
+       this->public.payload_interface.verify = (status_t (*) (payload_t *))verify;
+       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 = (void (*) (payload_t *,payload_type_t)) set_next_type;
+       this->public.payload_interface.get_type = (payload_type_t (*) (payload_t *)) get_payload_type;
+       this->public.payload_interface.destroy = (void (*) (payload_t *))destroy;
+       
+       /* public functions */
+       this->public.destroy = (void (*) (certreq_payload_t *)) destroy;
+       this->public.set_cert_encoding = (void (*) (certreq_payload_t *,cert_encoding_t)) set_cert_encoding;
+       this->public.get_cert_encoding = (cert_encoding_t (*) (certreq_payload_t *)) get_cert_encoding;
+       this->public.set_data = (void (*) (certreq_payload_t *,chunk_t)) set_data;
+       this->public.get_data_clone = (chunk_t (*) (certreq_payload_t *)) get_data_clone;
+       this->public.get_data = (chunk_t (*) (certreq_payload_t *)) get_data;
+       
+       /* private variables */
+       this->critical = FALSE;
+       this->next_payload = NO_PAYLOAD;
+       this->payload_length =CERTREQ_PAYLOAD_HEADER_LENGTH;
+       this->certreq_data = CHUNK_INITIALIZER;
+
+       return (&(this->public));
+}
diff --git a/Source/charon/encoding/payloads/certreq_payload.h b/Source/charon/encoding/payloads/certreq_payload.h
new file mode 100644 (file)
index 0000000..4fbf803
--- /dev/null
@@ -0,0 +1,119 @@
+/**
+ * @file certreq_payload.h
+ * 
+ * @brief Interface of certreq_payload_t.
+ * 
+ */
+
+/*
+ * Copyright (C) 2005 Jan Hutter, Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#ifndef _CERTREQ_PAYLOAD_H_
+#define _CERTREQ_PAYLOAD_H_
+
+#include <types.h>
+#include <encoding/payloads/payload.h>
+#include <encoding/payloads/cert_payload.h>
+
+/**
+ * Length of a CERTREQ payload without the CERTREQ data in bytes.
+ * 
+ * @ingroup payloads
+ */
+#define CERTREQ_PAYLOAD_HEADER_LENGTH 5
+
+
+typedef struct certreq_payload_t certreq_payload_t;
+
+/**
+ * Object representing an IKEv2 CERTREQ payload.
+ * 
+ * The CERTREQ payload format is described in draft section 3.7.
+ * 
+ * @ingroup payloads
+ * 
+ */
+struct certreq_payload_t {
+       /**
+        * The payload_t interface.
+        */
+       payload_t payload_interface;
+
+       /**
+        * @brief Set the CERT encoding.
+        * 
+        *
+        * @param this                  calling certreq_payload_t object
+        * @param encoding              CERT encoding
+        */
+       void (*set_cert_encoding) (certreq_payload_t *this, cert_encoding_t encoding);
+       
+       /**
+        * @brief Get the CERT encoding.
+        *
+        * @param this                  calling certreq_payload_t object
+        * @return                              Encoding of the CERT 
+        */
+       cert_encoding_t (*get_cert_encoding) (certreq_payload_t *this);
+       
+       /**
+        * @brief Set the CERTREQ data.
+        * 
+        * Data are getting cloned.
+        *
+        * @param this                  calling certreq_payload_t object
+        * @param data                  CERTREQ data as chunk_t
+        */
+       void (*set_data) (certreq_payload_t *this, chunk_t data);
+       
+       /**
+        * @brief Get the CERTREQ data.
+        * 
+        * Returned data are a copy of the internal one.
+        *
+        * @param this                  calling certreq_payload_t object
+        * @return                              CERTREQ data as chunk_t
+        */
+       chunk_t (*get_data_clone) (certreq_payload_t *this);
+       
+       /**
+        * @brief Get the CERTREQ data.
+        * 
+        * Returned data are NOT copied.
+        *
+        * @param this                  calling certreq_payload_t object
+        * @return                              CERTREQ data as chunk_t
+        */
+       chunk_t (*get_data) (certreq_payload_t *this);
+       
+       /**
+        * @brief Destroys an certreq_payload_t object.
+        *
+        * @param this  certreq_payload_t object to destroy
+        */
+       void (*destroy) (certreq_payload_t *this);
+};
+
+/**
+ * @brief Creates an empty certreq_payload_t object.
+ * 
+ * @return                             created certreq_payload_t object
+ * 
+ * @ingroup payloads
+ */
+certreq_payload_t *certreq_payload_create();
+
+
+#endif //_CERTREQ_PAYLOAD_H_
index 849e8b4..011195a 100644 (file)
@@ -233,8 +233,8 @@ int main()
        tester_t *tester = tester_create(test_output, FALSE);
        
 
        tester_t *tester = tester_create(test_output, FALSE);
        
 
-//     tester->perform_tests(tester,all_tests);
-       tester->perform_test(tester,&generator_test13); 
+       tester->perform_tests(tester,all_tests);
+//     tester->perform_test(tester,&generator_test13); 
        
        
        tester->destroy(tester);
        
        
        tester->destroy(tester);