aboutsummaryrefslogtreecommitdiff
path: root/src/mesh/gnunet-service-mesh_tunnel.c
diff options
context:
space:
mode:
authorBart Polot <bart@net.in.tum.de>2013-11-05 12:32:20 +0000
committerBart Polot <bart@net.in.tum.de>2013-11-05 12:32:20 +0000
commite01f4bbf85a92eb6e5c12cdf5b978f9485032bdf (patch)
tree28f9c0c8c423f316dc24cee4a5a6d7db0de12837 /src/mesh/gnunet-service-mesh_tunnel.c
parent4049b02df580a3009fb397382028e52f59a664e7 (diff)
downloadgnunet-e01f4bbf85a92eb6e5c12cdf5b978f9485032bdf.tar.gz
gnunet-e01f4bbf85a92eb6e5c12cdf5b978f9485032bdf.zip
- refactoring, extra checks
Diffstat (limited to 'src/mesh/gnunet-service-mesh_tunnel.c')
-rw-r--r--src/mesh/gnunet-service-mesh_tunnel.c157
1 files changed, 123 insertions, 34 deletions
diff --git a/src/mesh/gnunet-service-mesh_tunnel.c b/src/mesh/gnunet-service-mesh_tunnel.c
index e8b2739c6..d8f35d6e1 100644
--- a/src/mesh/gnunet-service-mesh_tunnel.c
+++ b/src/mesh/gnunet-service-mesh_tunnel.c
@@ -256,6 +256,59 @@ GMT_state2s (enum MeshTunnel3State s)
256} 256}
257 257
258 258
259/**
260 * Fill ephemeral key message purpose size.
261 *
262 * @return Size of the part of the ephemeral key message that must be signed.
263 */
264size_t
265ephemeral_purpose_size (void)
266{
267 return sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) +
268 sizeof (struct GNUNET_TIME_AbsoluteNBO) +
269 sizeof (struct GNUNET_TIME_AbsoluteNBO) +
270 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey) +
271 sizeof (struct GNUNET_PeerIdentity);
272}
273
274
275/**
276 * Check that a ephemeral key message s well formed and correctly signed.
277 *
278 * @param t Tunnel on which the message came.
279 * @param msg The ephemeral key message.
280 *
281 * @return \GNUNET_OK if message is fine, \GNUNET_SYSERR otherwise.
282 */
283int
284check_ephemeral (struct MeshTunnel3 *t,
285 const struct GNUNET_MESH_KX_Ephemeral *msg)
286{
287 /* Check message size */
288 if (ntohs (msg->header.size) != sizeof (struct GNUNET_MESH_KX_Ephemeral))
289 return GNUNET_SYSERR;
290
291 /* Check signature size */
292 if (ntohl (msg->purpose.size) != ephemeral_purpose_size ())
293 return GNUNET_SYSERR;
294
295 /* Check origin */
296 if (0 != memcmp (&msg->origin_identity,
297 GMP_get_id (t->peer),
298 sizeof (struct GNUNET_PeerIdentity)))
299 return GNUNET_SYSERR;
300
301 /* Check signature */
302 if (GNUNET_OK !=
303 GNUNET_CRYPTO_eddsa_verify (GNUNET_SIGNATURE_PURPOSE_MESH_KX,
304 &msg->purpose,
305 &msg->signature,
306 &msg->origin_identity.public_key))
307 return GNUNET_SYSERR;
308
309 return GNUNET_OK;
310}
311
259 312
260/** 313/**
261 * Encrypt data with the tunnel key. 314 * Encrypt data with the tunnel key.
@@ -298,6 +351,51 @@ t_decrypt (struct MeshTunnel3 *t,
298 return GNUNET_CRYPTO_symmetric_decrypt (src, size, &t->d_key, &siv, dst); 351 return GNUNET_CRYPTO_symmetric_decrypt (src, size, &t->d_key, &siv, dst);
299} 352}
300 353
354
355/**
356 * Create key material by doing ECDH on the local and remote ephemeral keys.
357 *
358 * @param key_material Where to store the key material.
359 * @param ephemeral_key Peer's public ephemeral key.
360 */
361void
362derive_key_material (struct GNUNET_HashCode *key_material,
363 const struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral_key)
364{
365 if (GNUNET_OK !=
366 GNUNET_CRYPTO_ecc_ecdh (my_ephemeral_key,
367 ephemeral_key,
368 key_material))
369 {
370 GNUNET_break (0);
371 }
372}
373
374/**
375 * Create a symmetic key from the identities of both ends and the key material
376 * from ECDH.
377 *
378 * @param key Destination for the generated key.
379 * @param sender ID of the peer that will encrypt with @c key.
380 * @param receiver ID of the peer that will decrypt with @c key.
381 * @param key_material Hash created with ECDH with the ephemeral keys.
382 */
383void
384derive_symmertic (struct GNUNET_CRYPTO_SymmetricSessionKey *key,
385 const struct GNUNET_PeerIdentity *sender,
386 const struct GNUNET_PeerIdentity *receiver,
387 const struct GNUNET_HashCode *key_material)
388{
389 const char salt[] = "MESH kx salt";
390
391 GNUNET_CRYPTO_kdf (key, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
392 salt, sizeof (salt),
393 key_material, sizeof (struct GNUNET_HashCode),
394 sender, sizeof (struct GNUNET_PeerIdentity),
395 receiver, sizeof (struct GNUNET_PeerIdentity),
396 NULL);
397}
398
301/** 399/**
302 * Pick a connection on which send the next data message. 400 * Pick a connection on which send the next data message.
303 * 401 *
@@ -658,10 +756,20 @@ handle_ch_destroy (struct MeshTunnel3 *t,
658 * @param msg Key eXchange message. 756 * @param msg Key eXchange message.
659 */ 757 */
660static void 758static void
661handle_kx (struct MeshTunnel3 *t, 759handle_ephemeral (struct MeshTunnel3 *t,
662 const struct GNUNET_MESH_KX *msg) 760 const struct GNUNET_MESH_KX_Ephemeral *msg)
663{ 761{
762 struct GNUNET_HashCode key_material;
763 LOG (GNUNET_ERROR_TYPE_DEBUG, " ephemeral key message\n");
664 764
765 if (GNUNET_OK != check_ephemeral (t, msg))
766 {
767 GNUNET_break_op (0);
768 return;
769 }
770 derive_key_material (&key_material, &msg->ephemeral_key);
771 derive_symmertic (&t->e_key, &my_full_id, GMP_get_id (t->peer), &key_material);
772 derive_symmertic (&t->d_key, GMP_get_id (t->peer), &my_full_id, &key_material);
665} 773}
666 774
667 775
@@ -805,7 +913,7 @@ GMT_handle_encrypted (struct MeshTunnel3 *t,
805 * Demultiplex an encapsulated KX message by message type. 913 * Demultiplex an encapsulated KX message by message type.
806 * 914 *
807 * @param t Tunnel on which the message came. 915 * @param t Tunnel on which the message came.
808 * @param message KX message itself. 916 * @param message Payload of KX message.
809 */ 917 */
810void 918void
811GMT_handle_kx (struct MeshTunnel3 *t, 919GMT_handle_kx (struct MeshTunnel3 *t,
@@ -814,10 +922,11 @@ GMT_handle_kx (struct MeshTunnel3 *t,
814 uint16_t type; 922 uint16_t type;
815 923
816 type = ntohs (message->type); 924 type = ntohs (message->type);
925 LOG (GNUNET_ERROR_TYPE_DEBUG, "kx message received\n", type);
817 switch (type) 926 switch (type)
818 { 927 {
819 case GNUNET_MESSAGE_TYPE_MESH_KX: 928 case GNUNET_MESSAGE_TYPE_MESH_KX:
820 handle_kx (t, (struct GNUNET_MESH_KX *) message); 929 handle_ephemeral (t, (struct GNUNET_MESH_KX_Ephemeral *) message);
821 break; 930 break;
822 931
823 case GNUNET_MESSAGE_TYPE_MESH_KX_PING: 932 case GNUNET_MESSAGE_TYPE_MESH_KX_PING:
@@ -929,11 +1038,7 @@ GMT_init (const struct GNUNET_CONFIGURATION_Handle *c,
929 kx_msg.header.size = htons (sizeof (kx_msg)); 1038 kx_msg.header.size = htons (sizeof (kx_msg));
930 kx_msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_KX); 1039 kx_msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_KX);
931 kx_msg.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_MESH_KX); 1040 kx_msg.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_MESH_KX);
932 kx_msg.purpose.size = htonl (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) + 1041 kx_msg.purpose.size = htonl (ephemeral_purpose_size ());
933 sizeof (struct GNUNET_TIME_AbsoluteNBO) +
934 sizeof (struct GNUNET_TIME_AbsoluteNBO) +
935 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey) +
936 sizeof (struct GNUNET_PeerIdentity));
937 kx_msg.origin_identity = my_full_id; 1042 kx_msg.origin_identity = my_full_id;
938 rekey_task = GNUNET_SCHEDULER_add_now (&rekey, NULL); 1043 rekey_task = GNUNET_SCHEDULER_add_now (&rekey, NULL);
939 1044
@@ -969,31 +1074,15 @@ GMT_new (struct MeshPeer *destination)
969 t = GNUNET_new (struct MeshTunnel3); 1074 t = GNUNET_new (struct MeshTunnel3);
970 t->next_chid = 0; 1075 t->next_chid = 0;
971 t->peer = destination; 1076 t->peer = destination;
972// if (GNUNET_OK != 1077
973// GNUNET_CONTAINER_multihashmap_put (tunnels, tid, t, 1078 if (GNUNET_OK !=
974// GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) 1079 GNUNET_CONTAINER_multipeermap_put (tunnels, GMP_get_id (destination), t,
975// { 1080 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
976// GNUNET_break (0); 1081 {
977// tunnel_destroy (t); 1082 GNUNET_break (0);
978// return NULL; 1083 GNUNET_free (t);
979// } 1084 return NULL;
980 1085 }
981// char salt[] = "salt";
982// GNUNET_CRYPTO_kdf (&t->e_key, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
983// salt, sizeof (salt),
984// &t->e_key, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
985// &my_full_id, sizeof (struct GNUNET_PeerIdentity),
986// GNUNET_PEER_resolve2 (t->peer->id), sizeof (struct GNUNET_PeerIdentity),
987// NULL);
988// GNUNET_CRYPTO_kdf (&t->d_key, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
989// salt, sizeof (salt),
990// &t->d_key, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
991// GNUNET_PEER_resolve2 (t->peer->id), sizeof (struct GNUNET_PeerIdentity),
992// &my_full_id, sizeof (struct GNUNET_PeerIdentity),
993// NULL);
994
995 GNUNET_CONTAINER_multipeermap_put (tunnels, GMP_get_id (destination), t,
996 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
997 return t; 1086 return t;
998} 1087}
999 1088