[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;
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r30518 - gnunet/src/mesh,
gnunet <=