gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r30518 - gnunet/src/mesh


From: gnunet
Subject: [GNUnet-SVN] r30518 - gnunet/src/mesh
Date: Tue, 5 Nov 2013 12:15:11 +0100

Author: bartpolot
Date: 2013-11-05 12:15:11 +0100 (Tue, 05 Nov 2013)
New Revision: 30518

Modified:
   gnunet/src/mesh/gnunet-service-mesh_connection.c
   gnunet/src/mesh/gnunet-service-mesh_connection.h
   gnunet/src/mesh/gnunet-service-mesh_peer.c
   gnunet/src/mesh/gnunet-service-mesh_tunnel.c
   gnunet/src/mesh/gnunet-service-mesh_tunnel.h
   gnunet/src/mesh/mesh_protocol_enc.h
Log:
- change key exchange messages to own encapsulation


Modified: gnunet/src/mesh/gnunet-service-mesh_connection.c
===================================================================
--- gnunet/src/mesh/gnunet-service-mesh_connection.c    2013-11-05 11:15:09 UTC 
(rev 30517)
+++ gnunet/src/mesh/gnunet-service-mesh_connection.c    2013-11-05 11:15:11 UTC 
(rev 30518)
@@ -1463,7 +1463,94 @@
   return GNUNET_OK;
 }
 
+/**
+ * Generic handler for mesh network encrypted traffic.
+ *
+ * @param peer Peer identity this notification is about.
+ * @param msg Encrypted message.
+ *
+ * @return GNUNET_OK to keep the connection open,
+ *         GNUNET_SYSERR to close it (signal serious error)
+ */
+static int
+handle_mesh_kx (const struct GNUNET_PeerIdentity *peer,
+                const struct GNUNET_MESH_KX *msg)
+{
+  struct MeshConnection *c;
+  struct MeshPeer *neighbor;
+  GNUNET_PEER_Id peer_id;
+  size_t size;
+  uint16_t type;
+  int fwd;
 
+  /* Check size */
+  size = ntohs (msg->header.size);
+  if (size <
+      sizeof (struct GNUNET_MESH_Encrypted) +
+      sizeof (struct GNUNET_MessageHeader))
+  {
+    GNUNET_break_op (0);
+    return GNUNET_OK;
+  }
+  type = ntohs (msg->header.type);
+  LOG (GNUNET_ERROR_TYPE_DEBUG, "\n\n");
+  LOG (GNUNET_ERROR_TYPE_DEBUG, "got a %s message from %s\n",
+              GNUNET_MESH_DEBUG_M2S (type), GNUNET_i2s (peer));
+
+  /* Check connection */
+  c = connection_get (&msg->cid);
+  if (NULL == c)
+  {
+    GNUNET_STATISTICS_update (stats, "# unknown connection", 1, GNUNET_NO);
+    LOG (GNUNET_ERROR_TYPE_DEBUG, "WARNING connection unknown\n");
+    return GNUNET_OK;
+  }
+
+  /* Check if origin is as expected */
+  neighbor = get_prev_hop (c);
+  peer_id = GNUNET_PEER_search (peer);
+  if (peer_id == GMP_get_short_id (neighbor))
+  {
+    fwd = GNUNET_YES;
+  }
+  else
+  {
+    neighbor = get_next_hop (c);
+    if (peer_id == GMP_get_short_id (neighbor))
+    {
+      fwd = GNUNET_NO;
+    }
+    else
+    {
+      /* Unexpected peer sending traffic on a connection. */
+      GNUNET_break_op (0);
+      return GNUNET_OK;
+    }
+  }
+
+  if (GMC_is_terminal (c, fwd))
+  {
+    LOG (GNUNET_ERROR_TYPE_DEBUG, "  message for us!\n");
+    GNUNET_STATISTICS_update (stats, "# messages received", 1, GNUNET_NO);
+    if (NULL == c->t)
+    {
+      GNUNET_break (0);
+      return GNUNET_OK;
+    }
+    GMT_handle_kx (c->t, &msg[1].header);
+    return GNUNET_OK;
+  }
+
+  /* Message not for us: forward to next hop */
+  LOG (GNUNET_ERROR_TYPE_DEBUG, "  not for us, retransmitting...\n");
+  GNUNET_STATISTICS_update (stats, "# messages forwarded", 1, GNUNET_NO);
+
+  GMC_send_prebuilt_message (&msg->header, c, fwd);
+
+  return GNUNET_OK;
+}
+
+
 /**
  * Core handler for encrypted mesh network traffic (channel mgmt, data).
  *
@@ -1484,6 +1571,25 @@
 
 
 /**
+ * Core handler for key exchange traffic (ephemeral key, ping, pong).
+ *
+ * @param cls Closure (unused).
+ * @param message Message received.
+ * @param peer Peer who sent the message.
+ *
+ * @return GNUNET_OK to keep the connection open,
+ *         GNUNET_SYSERR to close it (signal serious error)
+ */
+int
+GMC_handle_kx (void *cls, const struct GNUNET_PeerIdentity *peer,
+               const struct GNUNET_MessageHeader *message)
+{
+  return handle_mesh_kx (peer,
+                         (struct GNUNET_MESH_KX *) message);
+}
+
+
+/**
  * Core handler for mesh network traffic point-to-point acks.
  *
  * @param cls closure

Modified: gnunet/src/mesh/gnunet-service-mesh_connection.h
===================================================================
--- gnunet/src/mesh/gnunet-service-mesh_connection.h    2013-11-05 11:15:09 UTC 
(rev 30517)
+++ gnunet/src/mesh/gnunet-service-mesh_connection.h    2013-11-05 11:15:11 UTC 
(rev 30518)
@@ -150,6 +150,20 @@
                       const struct GNUNET_MessageHeader *message);
 
 /**
+ * Core handler for key exchange traffic (ephemeral key, ping, pong).
+ *
+ * @param cls Closure (unused).
+ * @param message Message received.
+ * @param peer Peer who sent the message.
+ *
+ * @return GNUNET_OK to keep the connection open,
+ *         GNUNET_SYSERR to close it (signal serious error)
+ */
+int
+GMC_handle_kx (void *cls, const struct GNUNET_PeerIdentity *peer,
+               const struct GNUNET_MessageHeader *message);
+
+/**
  * Core handler for mesh network traffic point-to-point acks.
  *
  * @param cls closure

Modified: gnunet/src/mesh/gnunet-service-mesh_peer.c
===================================================================
--- gnunet/src/mesh/gnunet-service-mesh_peer.c  2013-11-05 11:15:09 UTC (rev 
30517)
+++ gnunet/src/mesh/gnunet-service-mesh_peer.c  2013-11-05 11:15:11 UTC (rev 
30518)
@@ -327,6 +327,7 @@
   {&GMC_handle_poll, GNUNET_MESSAGE_TYPE_MESH_POLL,
     sizeof (struct GNUNET_MESH_Poll)},
   {&GMC_handle_encrypted, GNUNET_MESSAGE_TYPE_MESH_ENCRYPTED, 0},
+  {&GMC_handle_kx, GNUNET_MESSAGE_TYPE_MESH_KX, 0},
   {NULL, 0, 0}
 };
 

Modified: gnunet/src/mesh/gnunet-service-mesh_tunnel.c
===================================================================
--- gnunet/src/mesh/gnunet-service-mesh_tunnel.c        2013-11-05 11:15:09 UTC 
(rev 30517)
+++ gnunet/src/mesh/gnunet-service-mesh_tunnel.c        2013-11-05 11:15:11 UTC 
(rev 30518)
@@ -55,6 +55,23 @@
 };
 
 /**
+ * Structure used during a Key eXchange.
+ */
+struct MeshTunnelKXCtx
+{
+  /**
+   * Decryption ("their") old key, for decrypting traffic sent by the
+   * other end before the key exchange started.
+   */
+  struct GNUNET_CRYPTO_SymmetricSessionKey d_key_old;
+
+  /**
+   * Challenge to send in a ping and expect in the pong.
+   */
+  uint32_t challenge;
+};
+
+/**
  * Struct containing all information regarding a tunnel to a peer.
  */
 struct MeshTunnel3
@@ -70,24 +87,19 @@
   enum MeshTunnel3State state;
 
   /**
-   * Encryption ("our") key.
+   * Key eXchange context.
    */
-  struct GNUNET_CRYPTO_SymmetricSessionKey e_key;
+  struct MeshTunnelKXCtx *kx_ctx;
 
   /**
-   * Decryption ("their") key.
-   */
-  struct GNUNET_CRYPTO_SymmetricSessionKey d_key;
-
-  /**
    * Encryption ("our") key.
    */
-  struct GNUNET_CRYPTO_SymmetricSessionKey e_key_old;
+  struct GNUNET_CRYPTO_SymmetricSessionKey e_key;
 
   /**
    * Decryption ("their") key.
    */
-  struct GNUNET_CRYPTO_SymmetricSessionKey d_key_old;
+  struct GNUNET_CRYPTO_SymmetricSessionKey d_key;
 
   /**
    * Task to start the rekey process.
@@ -196,7 +208,7 @@
 /**
  * Cached message used to perform a key exchange.
  */
-static struct GNUNET_MESH_KX kx_msg;
+static struct GNUNET_MESH_KX_Ephemeral kx_msg;
 
 /**
  * Task to generate a new ephemeral key.
@@ -243,7 +255,50 @@
   }
 }
 
+
+
 /**
+ * Encrypt data with the tunnel key.
+ *
+ * @param t Tunnel whose key to use.
+ * @param dst Destination for the encrypted data.
+ * @param src Source of the plaintext.
+ * @param size Size of the plaintext.
+ * @param iv Initialization Vector to use.
+ */
+static int
+t_encrypt (struct MeshTunnel3 *t,
+           void *dst, const void *src,
+           size_t size, uint64_t iv)
+{
+  struct GNUNET_CRYPTO_SymmetricInitializationVector siv;
+
+  GNUNET_CRYPTO_symmetric_derive_iv (&siv, &t->e_key, &iv, sizeof (uint64_t), 
NULL);
+  return GNUNET_CRYPTO_symmetric_encrypt (src, size, &t->e_key, &siv, dst);
+}
+
+
+/**
+ * Decrypt data with the tunnel key.
+ *
+ * @param t Tunnel whose key to use.
+ * @param dst Destination for the plaintext.
+ * @param src Source of the encrypted data.
+ * @param size Size of the encrypted data.
+ * @param iv Initialization Vector to use.
+ */
+static int
+t_decrypt (struct MeshTunnel3 *t,
+           void *dst, const void *src,
+           size_t size, uint64_t iv)
+{
+  struct GNUNET_CRYPTO_SymmetricInitializationVector siv;
+
+  GNUNET_CRYPTO_symmetric_derive_iv (&siv, &t->e_key, &iv, sizeof (uint64_t), 
NULL);
+  return GNUNET_CRYPTO_symmetric_decrypt (src, size, &t->d_key, &siv, dst);
+}
+
+/**
  * Pick a connection on which send the next data message.
  *
  * @param t Tunnel on which to send the message.
@@ -295,8 +350,52 @@
   GMT_send_prebuilt_message (&kx_msg.header, t, NULL, GNUNET_YES);
 }
 
+/**
+ * Send a ping message on a tunnel.
+ *
+ * @param t Tunnel on which to send the ping.
+ */
+static void
+send_ping (struct MeshTunnel3 *t)
+{
+  struct GNUNET_MESH_KX_Ping msg;
+  size_t size;
 
+  msg.header.size = htons (sizeof (msg));
+  msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_KX_PING);
+  msg.iv = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, UINT_MAX);
+  msg.target = *GMP_get_id (t->peer);
+  msg.nonce = t->kx_ctx->challenge;
+  size = sizeof (msg.target) + sizeof (msg.nonce);
+  t_encrypt (t, &msg.target, &msg.target, size, msg.iv);
+
+  /* When channel is NULL, fwd is irrelevant. */
+  GMT_send_prebuilt_message (&msg.header, t, NULL, GNUNET_YES);
+}
+
+
 /**
+ * Send a pong message on a tunnel.
+ *
+ * @param t Tunnel on which to send the pong.
+ * @param challenge Value sent in the ping that we have to send back.
+ */
+static void
+send_pong (struct MeshTunnel3 *t, uint32_t challenge)
+{
+  struct GNUNET_MESH_KX_Pong msg;
+
+  msg.header.size = htons (sizeof (msg));
+  msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_KX_PONG);
+  msg.iv = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, UINT_MAX);
+  msg.nonce = htonl (challenge);
+
+  /* When channel is NULL, fwd is irrelevant. */
+  GMT_send_prebuilt_message (&msg.header, t, NULL, GNUNET_YES);
+}
+
+
+/**
  * Initiate a rekey with the remote peer.
  *
  * @param cls Closure (tunnel).
@@ -312,7 +411,12 @@
   if (0 != (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason))
     return;
 
+  t->kx_ctx = GNUNET_new (struct MeshTunnelKXCtx);
+  t->kx_ctx->challenge = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE,
+                                                   UINT32_MAX);
+  t->kx_ctx->d_key_old = t->d_key;
   send_ephemeral (t);
+  send_ping (t);
   t->rekey_task = GNUNET_SCHEDULER_add_delayed (REKEY_WAIT, &rekey_tunnel, t);
 }
 
@@ -384,49 +488,12 @@
 
 
 /**
- * Encrypt data with the tunnel key.
+ * Demultiplex data per channel and call appropriate channel handler.
  *
- * @param t Tunnel whose key to use.
- * @param dst Destination for the encrypted data.
- * @param src Source of the plaintext.
- * @param size Size of the plaintext.
- * @param iv Initialization Vector to use.
- * @param fwd Is this a fwd message?
+ * @param t Tunnel on which the data came.
+ * @param msg Data message.
+ * @param fwd Is this FWD data? (root -> dest)
  */
-static int
-t_encrypt (struct MeshTunnel3 *t,
-           void *dst, const void *src,
-           size_t size, uint64_t iv, int fwd)
-{
-  struct GNUNET_CRYPTO_SymmetricInitializationVector siv;
-
-  GNUNET_CRYPTO_symmetric_derive_iv (&siv, &t->e_key, &iv, sizeof (uint64_t), 
NULL);
-  return GNUNET_CRYPTO_symmetric_encrypt (src, size, &t->e_key, &siv, dst);
-}
-
-
-/**
- * Decrypt data with the tunnel key.
- *
- * @param t Tunnel whose key to use.
- * @param dst Destination for the plaintext.
- * @param src Source of the encrypted data.
- * @param size Size of the encrypted data.
- * @param iv Initialization Vector to use.
- * @param fwd Is this a fwd message?
- */
-static int
-t_decrypt (struct MeshTunnel3 *t,
-             void *dst, const void *src,
-             size_t size, uint64_t iv, int fwd)
-{
-  struct GNUNET_CRYPTO_SymmetricInitializationVector siv;
-
-  GNUNET_CRYPTO_symmetric_derive_iv (&siv, &t->e_key, &iv, sizeof (uint64_t), 
NULL);
-  return GNUNET_CRYPTO_symmetric_decrypt (src, size, &t->d_key, &siv, dst);
-}
-
-
 void
 handle_data (struct MeshTunnel3 *t,
              const struct GNUNET_MESH_Data *msg,
@@ -585,6 +652,64 @@
 
 
 /**
+ * The peer's ephemeral key has changed: update the symmetrical keys.
+ *
+ * @param t Tunnel this message came on.
+ * @param msg Key eXchange message.
+ */
+static void
+handle_kx (struct MeshTunnel3 *t,
+               const struct GNUNET_MESH_KX *msg)
+{
+
+}
+
+
+/**
+ * Peer wants to check our symmetrical keys by sending an encrypted challenge.
+ * Answer with by retransmitting the challenge with the "opposite" key.
+ *
+ * @param t Tunnel this message came on.
+ * @param msg Key eXchange Ping message.
+ */
+static void
+handle_ping (struct MeshTunnel3 *t,
+                 const struct GNUNET_MESH_KX_Ping *msg)
+{
+  uint32_t challenge;
+
+  challenge = ntohl (msg->nonce);
+  send_pong (t, challenge);
+}
+
+
+/**
+ * Peer has answer to our challenge.
+ * If answer is successful, consider the key exchange finished and clean
+ * up all related state.
+ *
+ * @param t Tunnel this message came on.
+ * @param msg Key eXchange Pong message.
+ */
+static void
+handle_pong (struct MeshTunnel3 *t,
+                 const struct GNUNET_MESH_KX_Pong *msg)
+{
+  if (GNUNET_SCHEDULER_NO_TASK != t->rekey_task)
+  {
+    GNUNET_SCHEDULER_cancel (t->rekey_task);
+    t->rekey_task = GNUNET_SCHEDULER_NO_TASK;
+//     t->e_key_old = 0;
+//     t->d_key_old = 0;
+  }
+  else
+  {
+    GNUNET_break (0);
+  }
+}
+
+
+/**
  * Demultiplex by message type and call appropriate handler for a message
  * towards a channel of a local tunnel.
  *
@@ -650,10 +775,8 @@
 GMT_send_kx (struct MeshTunnel3 *t)
 {
   
-
 }
 
-
 /**
  * Decrypt and demultiplex by message type. Call appropriate handler
  * for every message.
@@ -674,7 +797,7 @@
   struct GNUNET_MessageHeader *msgh;
   unsigned int off;
 
-  decrypted_size = t_decrypt (t, cbuf, &msg[1], payload_size, msg->iv, fwd);
+  decrypted_size = t_decrypt (t, cbuf, &msg[1], payload_size, msg->iv);
   off = 0;
   while (off < decrypted_size)
   {
@@ -686,6 +809,41 @@
 
 
 /**
+ * Demultiplex an encapsulated KX message by message type.
+ *
+ * @param t Tunnel on which the message came.
+ * @param message KX message itself.
+ */
+void
+GMT_handle_kx (struct MeshTunnel3 *t,
+               const struct GNUNET_MessageHeader *message)
+{
+  uint16_t type;
+
+  type = ntohs (message->type);
+  switch (type)
+  {
+    case GNUNET_MESSAGE_TYPE_MESH_KX:
+      handle_kx (t, (struct GNUNET_MESH_KX *) message);
+      break;
+
+    case GNUNET_MESSAGE_TYPE_MESH_KX_PING:
+      handle_ping (t, (struct GNUNET_MESH_KX_Ping *) message);
+      break;
+
+    case GNUNET_MESSAGE_TYPE_MESH_KX_PONG:
+      handle_pong (t, (struct GNUNET_MESH_KX_Pong *) message);
+      break;
+
+    default:
+      GNUNET_break_op (0);
+      LOG (GNUNET_ERROR_TYPE_DEBUG, "kx message not known (%u)\n", type);
+  }
+}
+
+
+
+/**
  * Cache a message to be sent once tunnel is online.
  *
  * @param t Tunnel to hold the message.
@@ -1418,7 +1576,7 @@
   msg = (struct GNUNET_MESH_Encrypted *) cbuf;
   msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_ENCRYPTED);
   msg->iv = GNUNET_htonll (iv);
-  encrypted_size = t_encrypt (t, &msg[1], message, size, iv, fwd);
+  encrypted_size = t_encrypt (t, &msg[1], message, size, iv);
   msg->header.size = htons (sizeof (struct GNUNET_MESH_Encrypted) + 
encrypted_size);
   c = tunnel_get_connection (t, fwd);
   if (NULL == c)

Modified: gnunet/src/mesh/gnunet-service-mesh_tunnel.h
===================================================================
--- gnunet/src/mesh/gnunet-service-mesh_tunnel.h        2013-11-05 11:15:09 UTC 
(rev 30517)
+++ gnunet/src/mesh/gnunet-service-mesh_tunnel.h        2013-11-05 11:15:11 UTC 
(rev 30518)
@@ -213,6 +213,16 @@
                       int fwd);
 
 /**
+ * Demultiplex an encapsulated KX message by message type.
+ *
+ * @param t Tunnel on which the message came.
+ * @param message KX message itself.
+ */
+void
+GMT_handle_kx (struct MeshTunnel3 *t,
+               const struct GNUNET_MessageHeader *message);
+
+/**
  * Cache a message to be sent once tunnel is online.
  *
  * @param t Tunnel to hold the message.

Modified: gnunet/src/mesh/mesh_protocol_enc.h
===================================================================
--- gnunet/src/mesh/mesh_protocol_enc.h 2013-11-05 11:15:09 UTC (rev 30517)
+++ gnunet/src/mesh/mesh_protocol_enc.h 2013-11-05 11:15:11 UTC (rev 30518)
@@ -98,16 +98,40 @@
 
 
 /**
+ * Message for encapsulation of a Key eXchange message in a connection.
+ */
+struct GNUNET_MESH_KX
+{
+    /**
+     * Type: GNUNET_MESSAGE_TYPE_MESH_KX.
+     */
+  struct GNUNET_MessageHeader header;
+
+    /**
+     * Always 0.
+     */
+  uint32_t reserved GNUNET_PACKED;
+
+    /**
+     * ID of the connection.
+     */
+  struct GNUNET_HashCode cid;
+
+  /* Specific KX message follows. */
+};
+
+
+/**
  * Message transmitted with the signed ephemeral key of a peer.  The
  * session key is then derived from the two ephemeral keys (ECDHE).
  *
  * As far as possible, same as CORE's EphemeralKeyMessage.
  */
-struct GNUNET_MESH_KX
+struct GNUNET_MESH_KX_Ephemeral
 {
 
   /**
-   * Message type is GNUNET_MESSAGE_TYPE_MESH_KX.
+   * Message type is GNUNET_MESSAGE_TYPE_MESH_KX_EPHEMERAL.
    */
   struct GNUNET_MessageHeader header;
 
@@ -214,7 +238,7 @@
 struct GNUNET_MESH_Encrypted
 {
   /**
-   * Type: GNUNET_MESSAGE_TYPE_MESH_{FWD,BCK}
+   * Type: GNUNET_MESSAGE_TYPE_MESH_ENCRYPTED
    */
   struct GNUNET_MessageHeader header;
 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]