[hipl-commit] [tiny] Rev 3731: Split-up UPDATE packet handling into multiple functions.

  • From: Tim Just <tim.just@xxxxxxxxxxxxxx>
  • To: hipl-commit@xxxxxxxxxxxxx
  • Date: Sat, 27 Mar 2010 15:40:39 +0200

Committer: Tim Just <tim.just@xxxxxxxxxxxxxx>
Date: 27/03/2010 at 15:40:38
Revision: 3731
Revision-id: tim.just@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Branch nick: tiny

Log:
  Split-up UPDATE packet handling into multiple functions.
  
  Now the packet check is done before any action is taken. In the previous
  revision the state was changed without any security check!

Modified:
  M  modules/update/hipd/update.c

=== modified file 'modules/update/hipd/update.c'
--- modules/update/hipd/update.c        2010-03-25 14:01:45 +0000
+++ modules/update/hipd/update.c        2010-03-27 13:39:18 +0000
@@ -584,39 +584,6 @@
 }
 
 /**
- * verify HMAC and signature from an UPDATE message
- *
- * @param msg the message to verify
- * @param entry the related host association
- * @return zero on success or negative on failure
- */
-static int hip_check_hmac_and_signature(hip_common_t *msg, hip_ha_t *entry)
-{
-    int err = 0;
-
-    /** @todo Check these references again because these checks are done
-     * separately for ACKs and SEQs */
-
-    /* RFC 5201 Section 6.12.1. Handling a SEQ Parameter in a Received
-     *  UPDATE Message:
-     * 3. The system MUST verify the HMAC in the UPDATE packet. If
-     * the verification fails, the packet MUST be dropped. */
-    HIP_IFEL(hip_verify_packet_hmac(msg, &entry->hip_hmac_in), -1,
-             "HMAC validation on UPDATE failed.\n");
-
-    /* RFC 5201 Section 6.12.1. Handling a SEQ Parameter in a Received
-     *  UPDATE Message:
-     * 4. The system MAY verify the SIGNATURE in the UPDATE packet.
-     * If the verification fails, the packet SHOULD be dropped and an error
-     * message logged. */
-    HIP_IFEL(entry->verify(entry->peer_pub_key, msg), -1,
-             "Verification of UPDATE signature failed.\n");
-
-out_err:
-    return err;
-}
-
-/**
  * process a LOCATOR paramter
  *
  * @param ha the related host association
@@ -851,7 +818,79 @@
 }
 
 /**
- * Process any UPDATE packet
+ * hip_update_check_packet
+ *
+ * Check a received UPDATE packet.
+ *
+ * @param packet_type The packet type of the control message (RFC 5201, 5.3.)
+ * @param ha_state The host association state (RFC 5201, 4.4.1.)
+ * @param *packet_ctx Pointer to the packet context, containing all
+ *                    information for the packet handling
+ *                    (received message, source and destination address, the
+ *                    ports and the corresponding entry from the host
+ *                    association database).
+ *
+ * @return zero on success, non-negative on error.
+ */
+static int hip_update_check_packet(const uint8_t packet_type,
+                                   const uint32_t ha_state,
+                                   struct hip_packet_context *ctx)
+{
+    int err = 0;
+    unsigned int has_esp_info = 0;
+    struct hip_esp_info *esp_info = NULL;
+
+    /** @todo Check these references again because these checks are done
+     * separately for ACKs and SEQs
+     */
+
+    /* RFC 5201 Section 6.12.1. Handling a SEQ Parameter in a Received
+     *  UPDATE Message:
+     * 3. The system MUST verify the HMAC in the UPDATE packet. If
+     * the verification fails, the packet MUST be dropped.
+     */
+    HIP_IFEL(hip_verify_packet_hmac(ctx->input_msg,
+                                    &ctx->hadb_entry->hip_hmac_in),
+             -1,
+             "HMAC validation on UPDATE failed.\n");
+
+    /* RFC 5201 Section 6.12.1. Handling a SEQ Parameter in a Received
+     *  UPDATE Message:
+     * 4. The system MAY verify the SIGNATURE in the UPDATE packet.
+     * If the verification fails, the packet SHOULD be dropped and an error
+     * message logged.
+     */
+    HIP_IFEL(ctx->hadb_entry->verify(ctx->hadb_entry->peer_pub_key,
+                                     ctx->input_msg),
+             -1,
+             "Verification of UPDATE signature failed.\n");
+
+    esp_info = hip_get_param(ctx->input_msg, HIP_PARAM_ESP_INFO);
+    if (esp_info != NULL) {
+        HIP_DEBUG("ESP INFO parameter found with new SPI %u.\n",
+                  ntohl(esp_info->new_spi));
+        has_esp_info = 1;
+
+        if (esp_info->new_spi != esp_info->old_spi) {
+            HIP_DEBUG("New SPI != Old SPI -> Please notice that "
+                      "rekeying case is not implemented yet.");
+        }
+        /** @todo Further ESP_INFO handling
+         * Done in hip_handle_esp_info() before
+         */
+    }
+
+out_err:
+    if (err) {
+        ctx->error = err;
+    }
+    return err;
+}
+
+/**
+ * hip_update_handle_packet
+ *
+ * Process an received and checked UPDATE packet.
  *
  * @param received_update_packet the received UPDATE packet
  * @param src_addr the source address of the received UPDATE packet
@@ -861,17 +900,15 @@
  *              the tunnel is absent)
  * @return zero on success or negative on failure
  */
-static int hip_handle_update(const uint8_t packet_type,
-                             const uint32_t ha_state,
-                             struct hip_packet_context *ctx)
+static int hip_update_handle_packet(const uint8_t packet_type,
+                                    const uint32_t ha_state,
+                                    struct hip_packet_context *ctx)
 {
     int err = 0, same_seq = 0;
     unsigned int ack_peer_update_id         = 0;
     unsigned int seq_update_id              = 0;
-    unsigned int has_esp_info               = 0;
     struct hip_seq *seq                     = NULL;
     struct hip_ack *ack                     = NULL;
-    struct hip_esp_info *esp_info           = NULL;
     struct hip_locator *locator             = NULL;
     struct hip_echo_request *echo_request   = NULL;
     struct hip_echo_response *echo_response = NULL;
@@ -943,12 +980,14 @@
         HIP_DEBUG("SEQ parameter found with  Update ID %u.\n",
                   seq_update_id);
 
-        /// @todo 15.9.2009: Handle retransmission case
+        /**
+         *  @todo 15.9.2009: Handle retransmission case
+         */
 
         if (localstate->update_id_in != 0 &&
             (seq_update_id < localstate->update_id_in ||
              seq_update_id > localstate->update_id_in + 
update_id_window_size)) {
-            // RFC 5201 6.12.1 part 1:
+            /* RFC 5201 6.12.1 part 1: */
             HIP_DEBUG("Update ID (%u) in the SEQ parameter is not "
                       "in the window of the previous Update ID (%u). "
                       "Dropping the packet.\n",
@@ -964,7 +1003,6 @@
          * UPDATE are then processed.  The system MUST record the Update ID
          * in the received SEQ parameter, for replay protection.
          */
-
         if (localstate->update_id_in != 0 &&
             localstate->update_id_in == seq_update_id) {
             same_seq = 1;
@@ -974,57 +1012,40 @@
         _HIP_DEBUG("Stored peer's incoming UPDATE ID %u\n", ha->update_id_in);
     }
 
-    /* RFC 5201 Section 6.12.1 3th and 4th steps or
-     *          Section 6.12.2 2nd and 3th steps */
-    HIP_IFE(hip_check_hmac_and_signature(ctx->input_msg, ctx->hadb_entry), -1);
-
-    esp_info = hip_get_param(ctx->input_msg, HIP_PARAM_ESP_INFO);
-    if (esp_info != NULL) {
-        HIP_DEBUG("ESP INFO parameter found with new SPI %u.\n",
-                  ntohl(esp_info->new_spi));
-        has_esp_info = 1;
-
-        if (esp_info->new_spi != esp_info->old_spi) {
-            HIP_DEBUG("New SPI != Old SPI -> Please notice that "
-                      "rekeying case is not implemented yet.");
-        }
-        /// @todo Further ESP_INFO handling
-        // Done in hip_handle_esp_info() before
-    }
-
    /* set local UDP port just in case the original communications
       changed from raw to UDP or vice versa */
     ctx->hadb_entry->local_udp_port = ctx->msg_ports->dst_port;
     /* @todo: a workaround for bug id 944 */
     ctx->hadb_entry->peer_udp_port = ctx->msg_ports->src_port;
 
-    /* RFC 5206: End-Host Mobility and Multihoming. */
-    // 3.2.1. Mobility with a Single SA Pair (No Rekeying)
-    locator           = hip_get_param(ctx->input_msg, HIP_PARAM_LOCATOR);
-    echo_request      = hip_get_param(ctx->input_msg, 
HIP_PARAM_ECHO_REQUEST_SIGN);
-    echo_response     = hip_get_param(ctx->input_msg, 
HIP_PARAM_ECHO_RESPONSE_SIGN);
-
-    if (locator != NULL) {
-        hip_handle_first_update_packet(ctx->input_msg,
-                                       ctx->hadb_entry,
-                                       ctx->src_addr);
-
+    /* RFC 5206: End-Host Mobility and Multihoming.
+     * 3.2.1. Mobility with a Single SA Pair (No Rekeying)
+     */
+    locator       = hip_get_param(ctx->input_msg, HIP_PARAM_LOCATOR);
+    echo_request  = hip_get_param(ctx->input_msg, HIP_PARAM_ECHO_REQUEST_SIGN);
+    echo_response = hip_get_param(ctx->input_msg, 
HIP_PARAM_ECHO_RESPONSE_SIGN);
+
+    if (locator) {
+        err = hip_handle_first_update_packet(ctx->input_msg,
+                                             ctx->hadb_entry,
+                                             ctx->src_addr);
         goto out_err;
-    } else if (echo_request != NULL)   {
-        // Ignore the ECHO REQUESTS with the same SEQ after processing
-        // the first one.
+    } else if (echo_request) {
+        /* Ignore the ECHO REQUESTS with the same SEQ after processing the 
first
+         * one.
+         */
         if (same_seq) {
             goto out_err;
         }
-
-        // We handle ECHO_REQUEST by sending an update packet
-        // with reversed source and destination address.
+        /* We handle ECHO_REQUEST by sending an update packet with reversed
+         * source and destination address.
+         */
         hip_handle_second_update_packet(ctx->input_msg,
                                         ctx->hadb_entry,
                                         ctx->dst_addr,
                                         ctx->src_addr);
         goto out_err;
-    } else if (echo_response != NULL)   {
+    } else if (echo_response) {
         hip_handle_third_update_packet(ctx->hadb_entry,
                                        ctx->dst_addr,
                                        ctx->src_addr);
@@ -1059,13 +1080,23 @@
 
     HIP_IFEL(hip_register_handle_function(HIP_UPDATE,
                                           HIP_STATE_ESTABLISHED,
-                                          &hip_handle_update,
-                                          0),
-             -1, "Error on registering UPDATE handle function.\n");
-    HIP_IFEL(hip_register_handle_function(HIP_UPDATE,
-                                          HIP_STATE_R2_SENT,
-                                          &hip_handle_update,
-                                          0),
+                                          &hip_update_check_packet,
+                                          20000),
+             -1, "Error on registering UPDATE handle function.\n");
+    HIP_IFEL(hip_register_handle_function(HIP_UPDATE,
+                                          HIP_STATE_ESTABLISHED,
+                                          &hip_update_handle_packet,
+                                          30000),
+             -1, "Error on registering UPDATE handle function.\n");
+    HIP_IFEL(hip_register_handle_function(HIP_UPDATE,
+                                          HIP_STATE_R2_SENT,
+                                          &hip_update_check_packet,
+                                          20000),
+             -1, "Error on registering UPDATE handle function.\n");
+    HIP_IFEL(hip_register_handle_function(HIP_UPDATE,
+                                          HIP_STATE_R2_SENT,
+                                          &hip_update_handle_packet,
+                                          30000),
              -1, "Error on registering UPDATE handle function.\n");
 
     HIP_IFEL(hip_register_maint_function(&hip_update_maintenance, 40000),

Other related posts:

  • » [hipl-commit] [tiny] Rev 3731: Split-up UPDATE packet handling into multiple functions. - Tim Just