Implemented IKEv1 hash payload
authorMartin Willi <martin@revosec.ch>
Thu, 17 Nov 2011 14:00:04 +0000 (15:00 +0100)
committerMartin Willi <martin@revosec.ch>
Tue, 20 Mar 2012 16:30:42 +0000 (17:30 +0100)
src/libcharon/Makefile.am
src/libcharon/encoding/generator.c
src/libcharon/encoding/parser.c
src/libcharon/encoding/payloads/encodings.c
src/libcharon/encoding/payloads/encodings.h
src/libcharon/encoding/payloads/hash_payload.c [new file with mode: 0644]
src/libcharon/encoding/payloads/hash_payload.h [new file with mode: 0644]

index a3b7225..7de82e3 100644 (file)
@@ -38,6 +38,7 @@ encoding/payloads/transform_substructure.c encoding/payloads/transform_substruct
 encoding/payloads/ts_payload.c encoding/payloads/ts_payload.h \
 encoding/payloads/unknown_payload.c encoding/payloads/unknown_payload.h \
 encoding/payloads/vendor_id_payload.c encoding/payloads/vendor_id_payload.h \
+encoding/payloads/hash_payload.c encoding/payloads/hash_payload.h \
 kernel/kernel_handler.c kernel/kernel_handler.h \
 network/receiver.c network/receiver.h network/sender.c network/sender.h \
 network/packet.c network/packet.h network/socket.c network/socket.h \
index 5f1a5e8..9cb1cdc 100644 (file)
@@ -452,6 +452,7 @@ METHOD(generator_t, generate_payload, void,
                        case KEY_EXCHANGE_DATA_V1:
                        case NOTIFICATION_DATA:
                        case NONCE_DATA:
+                       case HASH_DATA:
                        case ID_DATA:
                        case AUTH_DATA:
                        case CERT_DATA:
index 719c942..77923e7 100644 (file)
@@ -534,6 +534,7 @@ METHOD(parser_t, parse_payload, status_t,
                        }
                        /* chunks */
                        case NONCE_DATA:
+                       case HASH_DATA:
                        case ID_DATA:
                        case AUTH_DATA:
                        case CERT_DATA:
index 5828470..303ccca 100644 (file)
@@ -49,6 +49,7 @@ ENUM(encoding_type_names, U_INT_4, ENCRYPTED_DATA,
        "TS_TYPE",
        "ADDRESS",
        "NONCE_DATA",
+       "HASH_DATA",
        "ID_DATA",
        "AUTH_DATA",
        "CERT_DATA",
index 0e9a44e..d035522 100644 (file)
@@ -405,6 +405,16 @@ enum encoding_type_t {
        NONCE_DATA,
 
        /**
+        * Representating a Hash Data field.
+        *
+        * When generating the content of the chunkt pointing to
+        * is written.
+        *
+        * When parsing (Payload Length - 4) bytes are read and written into the chunk pointing to.
+        */
+       HASH_DATA,
+
+       /**
         * Representating a ID Data field.
         *
         * When generating the content of the chunkt pointing to
diff --git a/src/libcharon/encoding/payloads/hash_payload.c b/src/libcharon/encoding/payloads/hash_payload.c
new file mode 100644 (file)
index 0000000..ff968ee
--- /dev/null
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2011 Martin Willi
+ * Copyright (C) 2011 revosec AG
+ *
+ * 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 <stddef.h>
+
+#include "hash_payload.h"
+
+#include <encoding/payloads/encodings.h>
+
+typedef struct private_hash_payload_t private_hash_payload_t;
+
+/**
+ * Private data of an hash_payload_t object.
+ */
+struct private_hash_payload_t {
+
+       /**
+        * Public hash_payload_t interface.
+        */
+       hash_payload_t public;
+
+       /**
+        * Next payload type.
+        */
+       u_int8_t next_payload;
+
+       /**
+        * Reserved byte
+        */
+       u_int8_t reserved;
+
+       /**
+        * Length of this payload.
+        */
+       u_int16_t payload_length;
+
+       /**
+        * The contained hash value.
+        */
+       chunk_t hash;
+};
+
+/**
+ * Encoding rules for an IKEv1 hash payload
+ */
+static encoding_rule_t encodings[] = {
+       /* 1 Byte next payload type, stored in the field next_payload */
+       { U_INT_8,                      offsetof(private_hash_payload_t, next_payload)          },
+       { RESERVED_BYTE,        offsetof(private_hash_payload_t, reserved)                      },
+       /* Length of the whole payload*/
+       { PAYLOAD_LENGTH,       offsetof(private_hash_payload_t, payload_length)        },
+       /* Hash Data is from variable size */
+       { HASH_DATA,            offsetof(private_hash_payload_t, hash)                          },
+};
+
+/*
+                           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  !    RESERVED   !         Payload Length        !
+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+      !                                                               !
+      ~                       Hash Data                               ~
+      !                                                               !
+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+*/
+
+METHOD(payload_t, verify, status_t,
+       private_hash_payload_t *this)
+{
+       return SUCCESS;
+}
+
+METHOD(payload_t, get_encoding_rules, int,
+       private_hash_payload_t *this, encoding_rule_t **rules)
+{
+       *rules = encodings;
+       return countof(encodings);
+}
+
+METHOD(payload_t, get_header_length, int,
+       private_hash_payload_t *this)
+{
+       return 4;
+}
+
+METHOD(payload_t, get_type, payload_type_t,
+       private_hash_payload_t *this)
+{
+       return HASH_V1;
+}
+
+METHOD(payload_t, get_next_type, payload_type_t,
+       private_hash_payload_t *this)
+{
+       return this->next_payload;
+}
+
+METHOD(payload_t, set_next_type, void,
+       private_hash_payload_t *this, payload_type_t type)
+{
+       this->next_payload = type;
+}
+
+METHOD(payload_t, get_length, size_t,
+       private_hash_payload_t *this)
+{
+       return this->payload_length;
+}
+
+METHOD(hash_payload_t, set_hash, void,
+        private_hash_payload_t *this, chunk_t hash)
+{
+       free(this->hash.ptr);
+       this->hash = chunk_clone(hash);
+       this->payload_length = get_header_length(this) + hash.len;
+}
+
+METHOD(hash_payload_t, get_hash, chunk_t,
+       private_hash_payload_t *this)
+{
+       return this->hash;
+}
+
+METHOD2(payload_t, hash_payload_t, destroy, void,
+       private_hash_payload_t *this)
+{
+       free(this->hash.ptr);
+       free(this);
+}
+
+/*
+ * Described in header
+ */
+hash_payload_t *hash_payload_create(payload_type_t type)
+{
+       private_hash_payload_t *this;
+
+       INIT(this,
+               .public = {
+                       .payload_interface = {
+                               .verify = _verify,
+                               .get_encoding_rules = _get_encoding_rules,
+                               .get_header_length = _get_header_length,
+                               .get_length = _get_length,
+                               .get_next_type = _get_next_type,
+                               .set_next_type = _set_next_type,
+                               .get_type = _get_type,
+                               .destroy = _destroy,
+                       },
+                       .set_hash = _set_hash,
+                       .get_hash = _get_hash,
+                       .destroy = _destroy,
+               },
+               .next_payload = NO_PAYLOAD,
+               .payload_length = get_header_length(this),
+       );
+       return &this->public;
+}
diff --git a/src/libcharon/encoding/payloads/hash_payload.h b/src/libcharon/encoding/payloads/hash_payload.h
new file mode 100644 (file)
index 0000000..9f4b6e5
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2011 Martin Willi
+ * Copyright (C) 2011 revosec AG
+ *
+ * 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.
+ */
+
+/**
+ * @defgroup hash_payload hash_payload
+ * @{ @ingroup payloads
+ */
+
+#ifndef HASH_PAYLOAD_H_
+#define HASH_PAYLOAD_H_
+
+typedef struct hash_payload_t hash_payload_t;
+
+#include <library.h>
+#include <encoding/payloads/payload.h>
+
+/**
+ * Object representing an IKEv1 hash payload.
+ */
+struct hash_payload_t {
+
+       /**
+        * The payload_t interface.
+        */
+       payload_t payload_interface;
+
+       /**
+        * Set the hash value.
+        *
+        * @param hash                  chunk containing the hash, will be cloned
+        */
+       void (*set_hash) (hash_payload_t *this, chunk_t hash);
+
+       /**
+        * Get the hash value.
+        *
+        * @return                              chunkt to internal hash data
+        */
+       chunk_t (*get_hash) (hash_payload_t *this);
+
+       /**
+        * Destroys an hash_payload_t object.
+        */
+       void (*destroy) (hash_payload_t *this);
+};
+
+/**
+ * Creates an empty hash_payload_t object.
+ *
+ * @return                     hash_payload_t object
+ */
+hash_payload_t *hash_payload_create();
+
+#endif /** HASH_PAYLOAD_H_ @}*/