GNUnet 0.27.0
 
Loading...
Searching...
No Matches
gnunet-service-cadet_tunnels.c
Go to the documentation of this file.
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2013, 2017, 2018 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
33#include "gnunet_common.h"
34#include "gnunet_pils_service.h"
36#include "platform.h"
37#include "gnunet_util_lib.h"
39#include "cadet_protocol.h"
45
46
47#define LOG(level, ...) GNUNET_log_from (level, "cadet-tun", __VA_ARGS__)
48
54#define MAX_UNVERIFIED_ATTEMPTS 16
55
59#define IDLE_DESTROY_DELAY GNUNET_TIME_relative_multiply ( \
60 GNUNET_TIME_UNIT_SECONDS, 90)
61
66#define INITIAL_KX_RETRY_DELAY GNUNET_TIME_relative_multiply ( \
67 GNUNET_TIME_UNIT_MILLISECONDS, 250)
68
72#define MAX_SKIPPED_KEYS 64
73
78#define MAX_KEY_GAP 256
79
80
116
117
256
257
264typedef void
265(*CadetTunnelAxolotlCallback) (void *cls,
267
268
321
322
364
365
531
532
539int
541{
542 const struct GNUNET_PeerIdentity *my_identity;
543
546
547 if (0 > GNUNET_memcmp (my_identity, other))
548 return GNUNET_YES;
549 else if (0 < GNUNET_memcmp (my_identity, other))
550 return GNUNET_NO;
551 else
552 {
553 GNUNET_break_op (0);
554 return GNUNET_SYSERR;
555 }
556}
557
558
565static void
567{
568 struct CadetTunnel *t = ct->t;
569
571 GNUNET_CONTAINER_DLL_remove (t->connection_ready_head,
572 t->connection_ready_tail,
573 ct);
574 GNUNET_assert (0 < t->num_ready_connections);
575 t->num_ready_connections--;
576 ct->is_ready = GNUNET_NO;
577 GNUNET_CONTAINER_DLL_insert (t->connection_busy_head,
578 t->connection_busy_tail,
579 ct);
580 t->num_busy_connections++;
581}
582
583
591const char *
592GCT_2s (const struct CadetTunnel *t)
593{
594 static char buf[64];
595
596 if (NULL == t)
597 return "Tunnel(NULL)";
598 GNUNET_snprintf (buf,
599 sizeof(buf),
600 "Tunnel %s",
601 GNUNET_i2s (GCP_get_id (t->destination)));
602 return buf;
603}
604
605
613static const char *
615{
616 static char buf[32];
617
618 switch (es)
619 {
621 return "CADET_TUNNEL_KEY_UNINITIALIZED";
623 return "CADET_TUNNEL_KEY_AX_RECV";
625 return "CADET_TUNNEL_KEY_AX_SENT";
627 return "CADET_TUNNEL_KEY_AX_SENT_AND_RECV";
629 return "CADET_TUNNEL_KEY_AX_AUTH_SENT";
631 return "CADET_TUNNEL_KEY_OK";
632 }
633 GNUNET_snprintf (buf,
634 sizeof(buf),
635 "%u (UNKNOWN STATE)",
636 es);
637 return buf;
638}
639
640
647struct CadetPeer *
649{
650 return t->destination;
651}
652
653
654unsigned int
656{
657 return GNUNET_CONTAINER_multihashmap32_size (t->channels);
658}
659
660
668static struct CadetChannel *
671{
672 return GNUNET_CONTAINER_multihashmap32_get (t->channels,
673 ntohl (ctn.cn));
674}
675
676
677unsigned int
679{
680 return t->num_ready_connections + t->num_busy_connections;
681}
682
683
691static struct CadetTConnection *
693{
694 struct CadetTConnection *hd = t->connection_ready_head;
695
696 GNUNET_assert ((NULL == hd) ||
697 (GNUNET_YES == hd->is_ready));
698 return hd;
699}
700
701
711{
712 return t->estate;
713}
714
715
724static void
725trigger_transmissions (void *cls);
726
727
728/* ************************************** start core crypto ***************************** */
729
730
736static void
738{
740 "Creating new ephemeral ratchet key (DHRs)\n");
742}
743
744
754static void
755t_hmac (const void *plaintext,
756 size_t size,
757 uint32_t iv,
759 struct GNUNET_ShortHashCode *hmac)
760{
761 static const char ctx[] = "cadet authentication key";
762 struct GNUNET_CRYPTO_AuthKey auth_key;
763 struct GNUNET_HashCode hash;
764
765 // FIXME now that we directly invoke HKDF instead of a
766 // thin wrapper we can clearly see the sillyness of adding
767 // the key parameter twice...
769 &auth_key,
770 sizeof auth_key,
771 &iv,
772 sizeof(iv),
773 key,
774 sizeof(*key),
777 /* Two step: GNUNET_ShortHash is only 256 bits,
778 GNUNET_HashCode is 512, so we truncate. */
779 GNUNET_CRYPTO_hmac (&auth_key,
780 plaintext,
781 size,
782 &hash);
783 GNUNET_memcpy (hmac,
784 &hash,
785 sizeof(*hmac));
786}
787
788
797static void
799 struct GNUNET_HashCode *hash,
800 const void *source,
801 unsigned int len)
802{
803 static const char ctx[] = "axolotl HMAC-HASH";
804 struct GNUNET_CRYPTO_AuthKey auth_key;
805
807 &auth_key,
808 sizeof auth_key,
809 ctx,
810 sizeof(ctx),
811 key,
812 sizeof *key);
813 GNUNET_CRYPTO_hmac (&auth_key,
814 source,
815 len,
816 hash);
817}
818
819
828static void
831 const void *source,
832 unsigned int len)
833{
834 static const char ctx[] = "axolotl derive key";
835 struct GNUNET_HashCode h;
836
838 &h,
839 source,
840 len);
842 out, sizeof(*out),
843 ctx, sizeof(ctx),
844 &h, sizeof(h));
845}
846
847
856static void
858 void *dst,
859 const void *src,
860 size_t size)
861{
864 size_t out_size;
865
866 ax->ratchet_counter++;
867 if ((GNUNET_YES == ax->ratchet_allowed) &&
868 ((ratchet_messages <= ax->ratchet_counter) ||
871 {
873 }
874 if (GNUNET_YES == ax->ratchet_flag)
875 {
876 /* Advance ratchet */
878 struct GNUNET_HashCode dh;
879 struct GNUNET_HashCode hmac;
880 static const char ctx[] = "axolotl ratchet";
881
882 new_ephemeral (ax);
883 ax->HKs = ax->NHKs;
884
885 /* RK, NHKs, CKs = KDF( HMAC-HASH(RK, DH(DHRs, DHRr)) ) */
887 &ax->DHRr,
888 &dh);
889 t_ax_hmac_hash (&ax->RK,
890 &hmac,
891 &dh,
892 sizeof(dh));
894 keys, sizeof(keys),
895 ctx, sizeof(ctx),
896 &hmac, sizeof(hmac));
897 ax->RK = keys[0];
898 ax->NHKs = keys[1];
899 ax->CKs = keys[2];
900
901 ax->PNs = ax->Ns;
902 ax->Ns = 0;
905 ax->ratchet_counter = 0;
909 }
910
912 &MK,
913 "0",
914 1);
915
917 sizeof iv,
918 NULL,
919 0,
920 &MK,
921 sizeof MK);
922
923 out_size = GNUNET_CRYPTO_symmetric_encrypt (src,
924 size,
925 &MK,
926 &iv,
927 dst);
928 GNUNET_assert (size == out_size);
930 &ax->CKs,
931 "1",
932 1);
933}
934
935
944static void
946 void *dst,
947 const void *src,
948 size_t size)
949{
952 size_t out_size;
953
955 &MK,
956 "0",
957 1);
958
960 sizeof iv,
961 NULL,
962 0,
963 &MK,
964 sizeof MK);
965 GNUNET_assert (size >= sizeof(struct GNUNET_MessageHeader));
966 out_size = GNUNET_CRYPTO_symmetric_decrypt (src,
967 size,
968 &MK,
969 &iv,
970 dst);
971 GNUNET_assert (out_size == size);
973 &ax->CKr,
974 "1",
975 1);
976}
977
978
985static void
988{
990 size_t out_size;
991
993 sizeof iv,
994 NULL,
995 0,
996 &ax->HKs,
997 sizeof ax->HKs);
998 out_size = GNUNET_CRYPTO_symmetric_encrypt (&msg->ax_header,
999 sizeof(struct
1001 &ax->HKs,
1002 &iv,
1003 &msg->ax_header);
1004 GNUNET_assert (sizeof(struct GNUNET_CADET_AxHeader) == out_size);
1005}
1006
1007
1015static void
1017 const struct GNUNET_CADET_TunnelEncryptedMessage *src,
1019{
1021 size_t out_size;
1022
1024 sizeof iv,
1025 NULL,
1026 0,
1027 &ax->HKr,
1028 sizeof ax->HKr);
1029
1030
1032 sizeof(struct
1034 &ax->HKr,
1035 &iv,
1036 &dst->ax_header.Ns);
1037 GNUNET_assert (sizeof(struct GNUNET_CADET_AxHeader) == out_size);
1038}
1039
1040
1047static void
1049 struct CadetTunnelSkippedKey *key)
1050{
1052 ax->skipped_tail,
1053 key);
1054 GNUNET_free (key);
1055 ax->skipped--;
1056}
1057
1058
1069static ssize_t
1071 void *dst,
1072 const struct GNUNET_CADET_TunnelEncryptedMessage *src,
1073 size_t size)
1074{
1075 struct CadetTunnelSkippedKey *key;
1076 struct GNUNET_ShortHashCode *hmac;
1078 struct GNUNET_CADET_TunnelEncryptedMessage plaintext_header;
1079 struct GNUNET_CRYPTO_SymmetricSessionKey *valid_HK;
1080 size_t esize;
1081 size_t res;
1082 size_t len;
1083 unsigned int N;
1084
1086 "Trying skipped keys\n");
1087 hmac = &plaintext_header.hmac;
1088 esize = size - sizeof(struct GNUNET_CADET_TunnelEncryptedMessage);
1089
1090 /* Find a correct Header Key */
1091 valid_HK = NULL;
1092 for (key = ax->skipped_head; NULL != key; key = key->next)
1093 {
1094 t_hmac (&src->ax_header,
1095 sizeof(struct GNUNET_CADET_AxHeader) + esize,
1096 0,
1097 &key->HK,
1098 hmac);
1099 if (0 == GNUNET_memcmp (hmac,
1100 &src->hmac))
1101 {
1102 valid_HK = &key->HK;
1103 break;
1104 }
1105 }
1106 if (NULL == key)
1107 return -1;
1108
1109 /* Should've been checked in -cadet_connection.c handle_cadet_encrypted. */
1111 len = size - sizeof(struct GNUNET_CADET_TunnelEncryptedMessage);
1112 GNUNET_assert (len >= sizeof(struct GNUNET_MessageHeader));
1113
1114 /* Decrypt header */
1116 sizeof iv,
1117 NULL,
1118 0,
1119 &key->HK,
1120 sizeof key->HK);
1121
1123 sizeof(struct GNUNET_CADET_AxHeader),
1124 &key->HK,
1125 &iv,
1126 &plaintext_header.ax_header.Ns);
1127 GNUNET_assert (sizeof(struct GNUNET_CADET_AxHeader) == res);
1128
1129 /* Find the correct message key */
1130 N = ntohl (plaintext_header.ax_header.Ns);
1131 while ((NULL != key) &&
1132 (N != key->Kn))
1133 key = key->next;
1134 if ((NULL == key) ||
1135 (0 != GNUNET_memcmp (&key->HK,
1136 valid_HK)))
1137 return -1;
1138
1139 /* Decrypt payload */
1141 sizeof iv,
1142 NULL,
1143 0,
1144 &key->MK,
1145 sizeof key->MK);
1146
1148 len,
1149 &key->MK,
1150 &iv,
1151 dst);
1153 key);
1154 return res;
1155}
1156
1157
1164static void
1166 const struct GNUNET_CRYPTO_SymmetricSessionKey *HKr)
1167{
1168 struct CadetTunnelSkippedKey *key;
1169
1171 key->timestamp = GNUNET_TIME_absolute_get ();
1172 key->Kn = ax->Nr;
1173 key->HK = ax->HKr;
1174 t_hmac_derive_key (&ax->CKr,
1175 &key->MK,
1176 "0",
1177 1);
1178 t_hmac_derive_key (&ax->CKr,
1179 &ax->CKr,
1180 "1",
1181 1);
1183 ax->skipped_tail,
1184 key);
1185 ax->skipped++;
1186 ax->Nr++;
1187}
1188
1189
1200static int
1202 const struct GNUNET_CRYPTO_SymmetricSessionKey *HKr,
1203 uint32_t Np)
1204{
1205 int gap;
1206
1207 gap = Np - ax->Nr;
1209 "Storing skipped keys [%u, %u)\n",
1210 ax->Nr,
1211 Np);
1212 if (MAX_KEY_GAP < gap)
1213 {
1214 /* Avoid DoS (forcing peer to do more than #MAX_KEY_GAP HMAC operations) */
1215 /* TODO: start new key exchange on return */
1216 GNUNET_break_op (0);
1218 "Got message %u, expected %u+\n",
1219 Np,
1220 ax->Nr);
1221 return GNUNET_SYSERR;
1222 }
1223 if (0 > gap)
1224 {
1225 /* Delayed message: don't store keys, flag to try old keys. */
1226 return GNUNET_SYSERR;
1227 }
1228
1229 while (ax->Nr < Np)
1231 HKr);
1232
1233 while (ax->skipped > MAX_SKIPPED_KEYS)
1235 ax->skipped_tail);
1236 return GNUNET_OK;
1237}
1238
1239
1250static ssize_t
1252 void *dst,
1253 const struct
1255 size_t size)
1256{
1257 struct GNUNET_ShortHashCode msg_hmac;
1258 struct GNUNET_HashCode hmac;
1259 struct GNUNET_CADET_TunnelEncryptedMessage plaintext_header;
1260 uint32_t Np;
1261 uint32_t PNp;
1262 size_t esize; /* Size of encrypted payload */
1263
1264 esize = size - sizeof(struct GNUNET_CADET_TunnelEncryptedMessage);
1265
1266 /* Try current HK */
1267 t_hmac (&src->ax_header,
1268 sizeof(struct GNUNET_CADET_AxHeader) + esize,
1269 0, &ax->HKr,
1270 &msg_hmac);
1271 if (0 != GNUNET_memcmp (&msg_hmac,
1272 &src->hmac))
1273 {
1274 static const char ctx[] = "axolotl ratchet";
1275 struct GNUNET_CRYPTO_SymmetricSessionKey keys[3]; /* RKp, NHKp, CKp */
1277 struct GNUNET_HashCode dh;
1278 struct GNUNET_CRYPTO_EcdhePublicKey *DHRp;
1279
1280 /* Try Next HK */
1281 t_hmac (&src->ax_header,
1282 sizeof(struct GNUNET_CADET_AxHeader) + esize,
1283 0,
1284 &ax->NHKr,
1285 &msg_hmac);
1286 if (0 != GNUNET_memcmp (&msg_hmac,
1287 &src->hmac))
1288 {
1289 /* Try the skipped keys, if that fails, we're out of luck. */
1290 return try_old_ax_keys (ax,
1291 dst,
1292 src,
1293 size);
1294 }
1295 HK = ax->HKr;
1296 ax->HKr = ax->NHKr;
1297 t_h_decrypt (ax,
1298 src,
1299 &plaintext_header);
1300 Np = ntohl (plaintext_header.ax_header.Ns);
1301 PNp = ntohl (plaintext_header.ax_header.PNs);
1302 DHRp = &plaintext_header.ax_header.DHRs;
1303 store_ax_keys (ax,
1304 &HK,
1305 PNp);
1306
1307 /* RKp, NHKp, CKp = KDF (HMAC-HASH (RK, DH (DHRp, DHRs))) */
1309 DHRp,
1310 &dh);
1311 t_ax_hmac_hash (&ax->RK,
1312 &hmac,
1313 &dh, sizeof(dh));
1315 keys, sizeof(keys),
1316 ctx, sizeof(ctx),
1317 &hmac, sizeof(hmac));
1318
1319 /* Commit "purported" keys */
1320 ax->RK = keys[0];
1321 ax->NHKr = keys[1];
1322 ax->CKr = keys[2];
1323 ax->DHRr = *DHRp;
1324 ax->Nr = 0;
1326 }
1327 else
1328 {
1329 t_h_decrypt (ax,
1330 src,
1331 &plaintext_header);
1332 Np = ntohl (plaintext_header.ax_header.Ns);
1333 PNp = ntohl (plaintext_header.ax_header.PNs);
1334 }
1335 if ((Np != ax->Nr) &&
1336 (GNUNET_OK != store_ax_keys (ax,
1337 &ax->HKr,
1338 Np)))
1339 {
1340 /* Try the skipped keys, if that fails, we're out of luck. */
1341 return try_old_ax_keys (ax,
1342 dst,
1343 src,
1344 size);
1345 }
1346
1347 t_ax_decrypt (ax,
1348 dst,
1349 &src[1],
1350 esize);
1351 ax->Nr = Np + 1;
1352 return esize;
1353}
1354
1355
1365static int
1367 uint32_t key,
1368 void *value)
1369{
1370 struct CadetChannel *ch = value;
1371
1373 return GNUNET_OK;
1374}
1375
1376
1384void
1387{
1388 enum CadetTunnelEState old = t->estate;
1389
1390 t->estate = state;
1392 "%s estate changed from %s to %s\n",
1393 GCT_2s (t),
1394 estate2s (old),
1395 estate2s (state));
1396
1397 if ((CADET_TUNNEL_KEY_OK != old) &&
1398 (CADET_TUNNEL_KEY_OK == t->estate))
1399 {
1400 if (NULL != t->kx_task)
1401 {
1402 GNUNET_SCHEDULER_cancel (t->kx_task);
1403 t->kx_task = NULL;
1404 }
1405 /* notify all channels that have been waiting */
1408 t);
1409 if (NULL != t->send_task)
1410 GNUNET_SCHEDULER_cancel (t->send_task);
1412 t);
1413 }
1414}
1415
1416
1425static void
1427 struct CadetTConnection *ct,
1428 struct CadetTunnelAxolotl *ax)
1429{
1430 struct CadetConnection *cc;
1431 struct GNUNET_MQ_Envelope *env;
1434
1435 if (GNUNET_YES != GCT_alice_or_betty (GCP_get_id (t->destination)))
1436 return; /* only Alice may send KX */
1437 if ((NULL == ct) ||
1438 (GNUNET_NO == ct->is_ready))
1439 ct = get_ready_connection (t);
1440 if (NULL == ct)
1441 {
1443 "Wanted to send %s in state %s, but no connection is ready, deferring\n",
1444 GCT_2s (t),
1445 estate2s (t->estate));
1446 t->next_kx_attempt = GNUNET_TIME_absolute_get ();
1447 return;
1448 }
1449 cc = ct->cc;
1452 flags = GNUNET_CADET_KX_FLAG_FORCE_REPLY; /* always for KX */
1453 msg->flags = htonl (flags);
1454 msg->cid = *GCC_get_id (cc);
1456 &msg->ephemeral_key);
1457#if DEBUG_KX
1458 msg->ephemeral_key_XXX = ax->kx_0;
1459#endif
1461 "Sending KX message to %s with ephemeral %s on CID %s\n",
1462 GCT_2s (t),
1463 GNUNET_e2s (&msg->ephemeral_key),
1464 GNUNET_sh2s (&msg->cid.connection_of_tunnel));
1466 &msg->ratchet_key);
1468 t->kx_retry_delay = GNUNET_TIME_STD_BACKOFF (t->kx_retry_delay);
1469 t->next_kx_attempt = GNUNET_TIME_relative_to_absolute (t->kx_retry_delay);
1470 if (CADET_TUNNEL_KEY_UNINITIALIZED == t->estate)
1473 else if (CADET_TUNNEL_KEY_AX_RECV == t->estate)
1476 GCC_transmit (cc,
1477 env);
1479 "# KX transmitted",
1480 1,
1481 GNUNET_NO);
1482}
1483
1484
1495static void
1497 struct CadetTConnection *ct,
1498 struct CadetTunnelAxolotl *ax,
1499 int force_reply)
1500{
1501 struct CadetConnection *cc;
1502 struct GNUNET_MQ_Envelope *env;
1504 enum GNUNET_CADET_KX_Flags flags;
1505
1506 if ((NULL == ct) ||
1507 (GNUNET_NO == ct->is_ready))
1508 ct = get_ready_connection (t);
1509 if (NULL == ct)
1510 {
1512 "Wanted to send KX_AUTH on %s, but no connection is ready, deferring\n",
1513 GCT_2s (t));
1514 t->next_kx_attempt = GNUNET_TIME_absolute_get ();
1515 t->kx_auth_requested = GNUNET_YES; /* queue KX_AUTH independent of estate */
1516 return;
1517 }
1518 t->kx_auth_requested = GNUNET_NO; /* clear flag */
1519 cc = ct->cc;
1523 if (GNUNET_YES == force_reply)
1525 msg->kx.flags = htonl (flags);
1526 msg->kx.cid = *GCC_get_id (cc);
1528 &msg->kx.ephemeral_key);
1530 &msg->kx.ratchet_key);
1531#if DEBUG_KX
1532 msg->kx.ephemeral_key_XXX = ax->kx_0;
1533 msg->r_ephemeral_key_XXX = ax->last_ephemeral;
1534#endif
1536 "Sending KX_AUTH message to %s with ephemeral %s on CID %s\n",
1537 GCT_2s (t),
1538 GNUNET_e2s (&msg->kx.ephemeral_key),
1539 GNUNET_sh2s (&msg->kx.cid.connection_of_tunnel));
1540
1541 /* Compute authenticator (this is the main difference to #send_kx()) */
1542 GNUNET_CRYPTO_hash (&ax->RK,
1543 sizeof(ax->RK),
1544 &msg->auth);
1545 /* Compute when to be triggered again; actual job will
1546 be scheduled via #connection_ready_cb() */
1547 t->kx_retry_delay
1548 = GNUNET_TIME_STD_BACKOFF (t->kx_retry_delay);
1549 t->next_kx_attempt
1550 = GNUNET_TIME_relative_to_absolute (t->kx_retry_delay);
1551
1552 /* Send via cc, mark it as unready */
1554
1555 /* Update state machine, unless we are already OK */
1556 if (CADET_TUNNEL_KEY_OK != t->estate)
1559 GCC_transmit (cc,
1560 env);
1562 "# KX_AUTH transmitted",
1563 1,
1564 GNUNET_NO);
1565}
1566
1567
1573static void
1575{
1576 while (NULL != ax->skipped_head)
1578 ax->skipped_head);
1579 GNUNET_assert (0 == ax->skipped);
1582}
1583
1584
1596static void
1598 const struct GNUNET_HashCode *key_result)
1599{
1600 struct CadetTunnelAsync *as;
1601 struct GNUNET_HashCode key_material[3];
1602 struct GNUNET_CRYPTO_SymmetricSessionKey keys[5];
1603 struct CadetTunnelAxolotl *ax;
1604 const struct GNUNET_PeerIdentity *pid;
1605 const struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral_key;
1606 const struct GNUNET_CRYPTO_EcdhePublicKey *ratchet_key;
1607 const char salt[] = "CADET Axolotl salt";
1608 int am_I_alice;
1609
1610 as = cls;
1611 ax = &as->ax;
1612 pid = &as->peer_id;
1613 ephemeral_key = &as->ephemeral_key;
1614 ratchet_key = &as->ratchet_key;
1615
1616 as->ecdh_op = NULL;
1617
1619 "Updating AX by KX with result from ECDH using ephemeral %s\n",
1620 GNUNET_e2s (ephemeral_key));
1621
1622 if (GNUNET_SYSERR == (am_I_alice = GCT_alice_or_betty (pid)))
1623 {
1624 GNUNET_break_op (0);
1625 if (as->cb)
1626 as->cb (as->cb_cls, GNUNET_SYSERR);
1627 return;
1628 }
1629
1630 if (0 == GNUNET_memcmp (&ax->DHRr,
1631 ratchet_key))
1632 {
1634 "# Ratchet key already known",
1635 1,
1636 GNUNET_NO);
1638 "Ratchet key already known. Ignoring KX.\n");
1639 if (as->cb)
1640 as->cb (as->cb_cls, GNUNET_NO);
1641 return;
1642 }
1643
1644 ax->DHRr = *ratchet_key;
1645 ax->last_ephemeral = *ephemeral_key;
1646 /* ECDH A B0 */
1647 if (GNUNET_YES == am_I_alice)
1648 {
1649 GNUNET_memcpy (&key_material[0], key_result,
1650 sizeof (*key_result));
1651 }
1652 else
1653 {
1654 GNUNET_CRYPTO_ecdh_eddsa (&ax->kx_0, /* b0 */
1655 &pid->public_key, /* A */
1656 &key_material[0]);
1657 }
1658 /* ECDH A0 B */
1659 if (GNUNET_YES == am_I_alice)
1660 {
1661 GNUNET_CRYPTO_ecdh_eddsa (&ax->kx_0, /* a0 */
1662 &pid->public_key, /* B */
1663 &key_material[1]);
1664 }
1665 else
1666 {
1667 GNUNET_memcpy (&key_material[1], key_result,
1668 sizeof (*key_result));
1669 }
1670
1671 /* ECDH A0 B0 */
1672 GNUNET_CRYPTO_ecc_ecdh (&ax->kx_0, /* a0 or b0 */
1673 ephemeral_key, /* B0 or A0 */
1674 &key_material[2]);
1675 /* KDF */
1677 keys, sizeof(keys),
1678 salt, sizeof(salt),
1679 &key_material, sizeof(key_material));
1680
1681 if (0 == memcmp (&ax->RK,
1682 &keys[0],
1683 sizeof(ax->RK)))
1684 {
1686 "Root key already known. Ignoring KX.\n");
1688 "# Root key already known",
1689 1,
1690 GNUNET_NO);
1691 if (as->cb)
1692 as->cb (as->cb_cls, GNUNET_NO);
1693 return;
1694 }
1695
1696 ax->RK = keys[0];
1697 if (GNUNET_YES == am_I_alice)
1698 {
1699 ax->HKr = keys[1];
1700 ax->NHKs = keys[2];
1701 ax->NHKr = keys[3];
1702 ax->CKr = keys[4];
1704 }
1705 else
1706 {
1707 ax->HKs = keys[1];
1708 ax->NHKr = keys[2];
1709 ax->NHKs = keys[3];
1710 ax->CKs = keys[4];
1711 ax->ratchet_flag = GNUNET_NO;
1714 ratchet_time);
1715 }
1716
1717 if (as->cb)
1718 as->cb (as->cb_cls, GNUNET_OK);
1719}
1720
1721
1727static void
1728retry_kx (void *cls)
1729{
1730 struct CadetTunnel *t = cls;
1731 struct CadetTunnelAxolotl *ax;
1732
1733 t->kx_task = NULL;
1735 "Trying to make KX progress on %s in state %s\n",
1736 GCT_2s (t),
1737 estate2s (t->estate));
1738 switch (t->estate)
1739 {
1740 case CADET_TUNNEL_KEY_UNINITIALIZED: /* first attempt */
1741 case CADET_TUNNEL_KEY_AX_SENT: /* trying again */
1742 send_kx (t,
1743 NULL,
1744 &t->ax);
1745 break;
1746
1749 /* We are responding, so only require reply
1750 if WE have a channel waiting. */
1751 if (NULL != t->unverified_ax)
1752 {
1753 /* Send AX_AUTH so we might get this one verified */
1754 ax = t->unverified_ax;
1755 }
1756 else
1757 {
1758 /* How can this be? */
1759 GNUNET_break (0);
1760 ax = &t->ax;
1761 }
1762 send_kx_auth (t,
1763 NULL,
1764 ax,
1765 (0 == GCT_count_channels (t))
1766 ? GNUNET_NO
1767 : GNUNET_YES);
1768 break;
1769
1771 /* We are responding, so only require reply
1772 if WE have a channel waiting. */
1773 if (NULL != t->unverified_ax)
1774 {
1775 /* Send AX_AUTH so we might get this one verified */
1776 ax = t->unverified_ax;
1777 }
1778 else
1779 {
1780 /* How can this be? */
1781 GNUNET_break (0);
1782 ax = &t->ax;
1783 }
1784 send_kx_auth (t,
1785 NULL,
1786 ax,
1787 (0 == GCT_count_channels (t))
1788 ? GNUNET_NO
1789 : GNUNET_YES);
1790 break;
1791
1793 /* Must have been the *other* peer asking us to
1794 respond with a KX_AUTH. */
1795 if (NULL != t->unverified_ax)
1796 {
1797 /* Sending AX_AUTH in response to AX so we might get this one verified */
1798 ax = t->unverified_ax;
1799 }
1800 else
1801 {
1802 /* Sending AX_AUTH in response to AX_AUTH */
1803 ax = &t->ax;
1804 }
1805 send_kx_auth (t,
1806 NULL,
1807 ax,
1808 GNUNET_NO);
1809 break;
1810 }
1811}
1812
1813
1820static void
1823{
1824 struct CadetTunnel *t = cls;
1825
1826 if (t->unverified_ax)
1827 *(t->unverified_ax) = t->as.ax;
1828
1830 "Continue handling KX message from %s from %s\n",
1831 GCT_2s (t),
1832 GNUNET_i2s (GCP_get_id (t->destination)));
1833
1835 if (GNUNET_OK != ret)
1836 {
1838 "# Useless KX",
1839 1,
1840 GNUNET_NO);
1841 return; /* duplicate KX, nothing to do */
1842 }
1843 /* move ahead in our state machine */
1844 if (CADET_TUNNEL_KEY_UNINITIALIZED == t->estate)
1847 else if (CADET_TUNNEL_KEY_AX_SENT == t->estate)
1850
1851 /* KX is still not done, try again our end. */
1852 if (CADET_TUNNEL_KEY_OK != t->estate)
1853 {
1854 if (NULL != t->kx_task)
1855 GNUNET_SCHEDULER_cancel (t->kx_task);
1856 t->kx_task
1858 t);
1859 }
1860}
1861
1862
1869void
1872{
1873 struct CadetTunnel *t = ct->t;
1874
1876 "# KX received",
1877 1,
1878 GNUNET_NO);
1879 if (GNUNET_YES ==
1880 GCT_alice_or_betty (GCP_get_id (t->destination)))
1881 {
1882 /* Betty/Bob is not allowed to send KX! */
1883 GNUNET_break_op (0);
1884 return;
1885 }
1887 "Received KX message from %s with ephemeral %s from %s on connection %s\n",
1888 GCT_2s (t),
1889 GNUNET_e2s (&msg->ephemeral_key),
1890 GNUNET_i2s (GCP_get_id (t->destination)),
1891 GCC_2s (ct->cc));
1892#if 1
1893 if ((0 ==
1894 memcmp (&t->ax.DHRr,
1895 &msg->ratchet_key,
1896 sizeof(msg->ratchet_key))) &&
1897 (0 ==
1898 memcmp (&t->ax.last_ephemeral,
1899 &msg->ephemeral_key,
1900 sizeof(msg->ephemeral_key))))
1901
1902 {
1904 "# Duplicate KX received",
1905 1,
1906 GNUNET_NO);
1907 send_kx_auth (t,
1908 ct,
1909 &t->ax,
1910 GNUNET_NO);
1911 return;
1912 }
1913#endif
1914 /* We only keep ONE unverified KX around, so if there is an existing one,
1915 clean it up. */
1916 if (NULL != t->unverified_ax)
1917 {
1918 if ((0 ==
1919 memcmp (&t->unverified_ax->DHRr,
1920 &msg->ratchet_key,
1921 sizeof(msg->ratchet_key))) &&
1922 (0 ==
1923 memcmp (&t->unverified_ax->last_ephemeral,
1924 &msg->ephemeral_key,
1925 sizeof(msg->ephemeral_key))))
1926 {
1928 "# Duplicate unverified KX received",
1929 1,
1930 GNUNET_NO);
1931#if 1
1932 send_kx_auth (t,
1933 ct,
1934 t->unverified_ax,
1935 GNUNET_NO);
1936 return;
1937#endif
1938 }
1939 if ((t->as.ecdh_op) &&
1940 (0 ==
1941 memcmp (&t->as.ratchet_key,
1942 &msg->ratchet_key,
1943 sizeof(msg->ratchet_key))) &&
1944 (0 ==
1945 memcmp (&t->as.ephemeral_key,
1946 &msg->ephemeral_key,
1947 sizeof(msg->ephemeral_key))))
1948 {
1950 "Waiting for previous ECDH operation\n");
1951 return;
1952 }
1954 "Dropping old unverified KX state.\n");
1956 "# Unverified KX dropped for fresh KX",
1957 1,
1958 GNUNET_NO);
1959 GNUNET_break (NULL == t->unverified_ax->skipped_head);
1960 memset (t->unverified_ax,
1961 0,
1962 sizeof(struct CadetTunnelAxolotl));
1963 }
1964 else
1965 {
1967 "Creating fresh unverified KX for %s\n",
1968 GCT_2s (t));
1970 "# Fresh KX setup",
1971 1,
1972 GNUNET_NO);
1973 t->unverified_ax = GNUNET_new (struct CadetTunnelAxolotl);
1974 }
1975 /* Set as the 'current' RK/DHRr the one we are currently using,
1976 so that the duplicate-detection logic of
1977 #update_ax_by_kx can work. */
1978 t->unverified_ax->RK = t->ax.RK;
1979 t->unverified_ax->DHRr = t->ax.DHRr;
1980 t->unverified_ax->DHRs = t->ax.DHRs;
1981 t->unverified_ax->kx_0 = t->ax.kx_0;
1982 t->unverified_attempts = 0;
1983
1984 t->as.ax = *(t->unverified_ax);
1985 GNUNET_memcpy (&t->as.peer_id, GCP_get_id (t->destination),
1986 sizeof (t->as.peer_id));
1987 GNUNET_memcpy (&t->as.ephemeral_key, &msg->ephemeral_key,
1988 sizeof (t->as.ephemeral_key));
1989 GNUNET_memcpy (&t->as.ratchet_key, &msg->ratchet_key,
1990 sizeof (t->as.ratchet_key));
1991 memset (&t->as.auth, 0, sizeof (t->as.auth));
1992 t->as.flags = 0;
1993 t->as.cb_cls = t;
1994 t->as.cb = &cont_GCT_handle_kx;
1995
1996 if (t->as.ecdh_op)
1997 {
1999 "Cancelling previous ECDH operation\n");
2000
2001 GNUNET_PILS_cancel (t->as.ecdh_op);
2002 }
2003
2004 t->as.ecdh_op = GNUNET_PILS_ecdh (pils, &msg->ephemeral_key,
2005 &update_ax_by_kx, &t->as);
2006}
2007
2008
2015static void
2018{
2019 struct CadetTunnel *t = cls;
2020 struct CadetTunnelAxolotl *ax_tmp;
2021 struct GNUNET_HashCode kx_auth;
2022
2023 ax_tmp = &t->as.ax;
2024
2026 "Continue handling KX_AUTH message from %s\n",
2027 GCT_2s (t));
2028
2029 if (GNUNET_OK != ret)
2030 {
2031 if (GNUNET_NO == ret)
2033 "# redundant KX_AUTH received",
2034 1,
2035 GNUNET_NO);
2036 else
2037 GNUNET_break (0); /* connect to self!? */
2038 return;
2039 }
2040 GNUNET_CRYPTO_hash (&ax_tmp->RK,
2041 sizeof(ax_tmp->RK),
2042 &kx_auth);
2043 if (0 != GNUNET_memcmp (&kx_auth,
2044 &t->as.auth))
2045 {
2046 /* This KX_AUTH is not using the latest KX/KX_AUTH data
2047 we transmitted to the sender, refuse it, try KX again. */
2049 "# KX_AUTH not using our last KX received (auth failure)",
2050 1,
2051 GNUNET_NO);
2053 "KX AUTH mismatch!\n");
2054#if DEBUG_KX
2055 {
2056 struct GNUNET_CRYPTO_EcdhePublicKey ephemeral_key;
2057
2059 &ephemeral_key);
2060 if (0 != GNUNET_memcmp (&ephemeral_key,
2061 &msg->r_ephemeral_key_XXX))
2062 {
2064 "My ephemeral is %s!\n",
2065 GNUNET_e2s (&ephemeral_key));
2067 "Response is for ephemeral %s!\n",
2068 GNUNET_e2s (&msg->r_ephemeral_key_XXX));
2069 }
2070 }
2071#endif
2072 if (NULL == t->kx_task)
2073 t->kx_task
2074 = GNUNET_SCHEDULER_add_at (t->next_kx_attempt,
2075 &retry_kx,
2076 t);
2077 return;
2078 }
2079 /* Yep, we're good. */
2080 t->ax = *ax_tmp;
2081 if (NULL != t->unverified_ax)
2082 {
2083 /* We got some "stale" KX before, drop that. */
2084 cleanup_ax (t->unverified_ax);
2085 GNUNET_free (t->unverified_ax);
2086 t->unverified_ax = NULL;
2087 }
2088
2089 /* move ahead in our state machine */
2090 switch (t->estate)
2091 {
2094 /* Checked above, this is impossible. */
2095 GNUNET_assert (0);
2096 break;
2097
2098 case CADET_TUNNEL_KEY_AX_SENT: /* This is the normal case */
2099 case CADET_TUNNEL_KEY_AX_SENT_AND_RECV: /* both peers started KX */
2100 case CADET_TUNNEL_KEY_AX_AUTH_SENT: /* both peers now did KX_AUTH */
2103 break;
2104
2106 /* Did not expect another KX_AUTH, but so what, still acceptable.
2107 Nothing to do here. */
2108 break;
2109 }
2110 if (0 != (GNUNET_CADET_KX_FLAG_FORCE_REPLY & ntohl (t->as.flags)))
2111 {
2112 send_kx_auth (t,
2113 NULL,
2114 &t->ax,
2115 GNUNET_NO);
2116 }
2117}
2118
2119
2126void
2129{
2130 struct CadetTunnel *t = ct->t;
2131
2133 "# KX_AUTH received",
2134 1,
2135 GNUNET_NO);
2136 if ((CADET_TUNNEL_KEY_UNINITIALIZED == t->estate) ||
2137 (CADET_TUNNEL_KEY_AX_RECV == t->estate))
2138 {
2139 /* Confusing, we got a KX_AUTH before we even send our own
2140 KX. This should not happen. We'll send our own KX ASAP anyway,
2141 so let's ignore this here. */
2142 GNUNET_break_op (0);
2143 return;
2144 }
2146 "Handling KX_AUTH message from %s with ephemeral %s\n",
2147 GCT_2s (t),
2148 GNUNET_e2s (&msg->kx.ephemeral_key));
2149 if ((t->as.ecdh_op) &&
2150 (0 ==
2151 memcmp (&t->as.ratchet_key,
2152 &msg->kx.ratchet_key,
2153 sizeof(msg->kx.ratchet_key))) &&
2154 (0 ==
2155 memcmp (&t->as.ephemeral_key,
2156 &msg->kx.ephemeral_key,
2157 sizeof(msg->kx.ephemeral_key))))
2158 {
2160 "Waiting for previous ECDH operation\n");
2161 return;
2162 }
2163 /* We do everything in a copy until we've checked the authentication
2164 so we don't clobber anything we care about by accident. */
2165 t->as.ax = t->ax;
2166 GNUNET_memcpy (&t->as.peer_id, GCP_get_id (t->destination),
2167 sizeof (t->as.peer_id));
2168 GNUNET_memcpy (&t->as.ephemeral_key, &msg->kx.ephemeral_key,
2169 sizeof (t->as.ephemeral_key));
2170 GNUNET_memcpy (&t->as.ratchet_key, &msg->kx.ratchet_key,
2171 sizeof (t->as.ratchet_key));
2172 t->as.auth = msg->auth;
2173 t->as.flags = msg->kx.flags;
2174 t->as.cb_cls = t;
2175 t->as.cb = &cont_GCT_handle_kx_auth;
2176
2177 if (t->as.ecdh_op)
2178 {
2180 "Cancelling previous ECDH operation\n");
2181
2182 GNUNET_PILS_cancel (t->as.ecdh_op);
2183 }
2184
2185 /* Update 'ax' by the new key material */
2186 t->as.ecdh_op = GNUNET_PILS_ecdh (pils, &msg->kx.ephemeral_key,
2187 &update_ax_by_kx, &t->as);
2188}
2189
2190
2191/* ************************************** end core crypto ***************************** */
2192
2193
2202{
2203#define HIGH_BIT 0x8000000
2204 const struct GNUNET_PeerIdentity *my_identity;
2206 uint32_t ctn;
2207 int cmp;
2208 uint32_t highbit;
2209
2212
2215 if (0 < cmp)
2216 highbit = HIGH_BIT;
2217 else if (0 > cmp)
2218 highbit = 0;
2219 else
2220 GNUNET_assert (0); // loopback must never go here!
2221 ctn = ntohl (t->next_ctn.cn);
2222 while (NULL !=
2224 ctn | highbit))
2225 {
2226 ctn = ((ctn + 1) & (~HIGH_BIT));
2227 }
2228 t->next_ctn.cn = htonl ((ctn + 1) & (~HIGH_BIT));
2229 ret.cn = htonl (ctn | highbit);
2230 return ret;
2231}
2232
2233
2245 struct CadetChannel *ch)
2246{
2248
2249 ctn = get_next_free_ctn (t);
2250 if (NULL != t->destroy_task)
2251 {
2252 GNUNET_SCHEDULER_cancel (t->destroy_task);
2253 t->destroy_task = NULL;
2254 }
2257 ntohl (ctn.cn),
2258 ch,
2261 "Adding %s to %s with state %d\n",
2262 GCCH_2s (ch),
2263 GCT_2s (t),
2264 t->estate);
2265 switch (t->estate)
2266 {
2268 /* waiting for connection to start KX */
2269 break;
2270
2274 /* we're currently waiting for KX to complete */
2275 break;
2276
2278 /* waiting for OTHER peer to send us data,
2279 we might need to prompt more aggressively! */
2280 if (NULL == t->kx_task)
2281 t->kx_task
2282 = GNUNET_SCHEDULER_add_at (t->next_kx_attempt,
2283 &retry_kx,
2284 t);
2285 break;
2286
2288 /* We are ready. Tell the new channel that we are up. */
2290 break;
2291 }
2292 return ctn;
2293}
2294
2295
2302void
2304{
2305 struct CadetTunnel *t = ct->t;
2306
2307 if (GNUNET_YES == ct->is_ready)
2308 {
2309 GNUNET_CONTAINER_DLL_remove (t->connection_ready_head,
2310 t->connection_ready_tail,
2311 ct);
2312 t->num_ready_connections--;
2313 }
2314 else
2315 {
2316 GNUNET_CONTAINER_DLL_remove (t->connection_busy_head,
2317 t->connection_busy_tail,
2318 ct);
2319 t->num_busy_connections--;
2320 }
2321 GNUNET_free (ct);
2322}
2323
2324
2331static void
2333 struct CadetTConnection *ct)
2334{
2335 struct CadetTunnel *t = cls;
2336 struct CadetConnection *cc = ct->cc;
2337
2338 GNUNET_assert (ct->t == t);
2341}
2342
2343
2349static void
2351{
2352 struct CadetTunnel *t = cls;
2353 struct CadetTunnelQueueEntry *tq;
2354
2355 t->destroy_task = NULL;
2357 "Destroying idle %s\n",
2358 GCT_2s (t));
2362 t);
2363 GNUNET_assert (NULL == t->connection_ready_head);
2364 GNUNET_assert (NULL == t->connection_busy_head);
2365 while (NULL != (tq = t->tq_head))
2366 {
2367 if (NULL != tq->cont)
2368 tq->cont (tq->cont_cls,
2369 NULL);
2370 GCT_send_cancel (tq);
2371 }
2372 GCP_drop_tunnel (t->destination,
2373 t);
2375 if (NULL != t->maintain_connections_task)
2376 {
2377 GNUNET_SCHEDULER_cancel (t->maintain_connections_task);
2378 t->maintain_connections_task = NULL;
2379 }
2380 if (NULL != t->send_task)
2381 {
2382 GNUNET_SCHEDULER_cancel (t->send_task);
2383 t->send_task = NULL;
2384 }
2385 if (NULL != t->kx_task)
2386 {
2387 GNUNET_SCHEDULER_cancel (t->kx_task);
2388 t->kx_task = NULL;
2389 }
2390 if (NULL != t->as.ecdh_op)
2391 {
2392 GNUNET_PILS_cancel (t->as.ecdh_op);
2393 t->as.ecdh_op = NULL;
2394 }
2395 GNUNET_MST_destroy (t->mst);
2396 GNUNET_MQ_destroy (t->mq);
2397 if (NULL != t->unverified_ax)
2398 {
2399 cleanup_ax (t->unverified_ax);
2400 GNUNET_free (t->unverified_ax);
2401 }
2402 cleanup_ax (&t->ax);
2403 GNUNET_assert (NULL == t->destroy_task);
2404 GNUNET_free (t);
2405}
2406
2407
2415void
2417 struct CadetChannel *ch,
2419{
2421 "Removing %s from %s\n",
2422 GCCH_2s (ch),
2423 GCT_2s (t));
2426 ntohl (ctn.cn),
2427 ch));
2428 if ((0 ==
2429 GCT_count_channels (t)) &&
2430 (NULL == t->destroy_task))
2431 {
2432 t->destroy_task
2435 t);
2436 }
2437}
2438
2439
2448static int
2450 uint32_t key,
2451 void *value)
2452{
2453 struct CadetChannel *ch = value;
2454
2456 NULL);
2457 return GNUNET_OK;
2458}
2459
2460
2466void
2468{
2472 t);
2473 GNUNET_assert (0 ==
2475 if (NULL != t->destroy_task)
2476 {
2477 GNUNET_SCHEDULER_cancel (t->destroy_task);
2478 t->destroy_task = NULL;
2479 }
2480 destroy_tunnel (t);
2481}
2482
2483
2491static void
2493 struct CadetTConnection *ct)
2494{
2495 struct CadetTunnelQueueEntry *tq;
2496
2498 tq = t->tq_head;
2499 if (NULL == tq)
2500 {
2501 /* no messages pending right now */
2503 "Not sending payload of %s on ready %s (nothing pending)\n",
2504 GCT_2s (t),
2505 GCC_2s (ct->cc));
2506 return;
2507 }
2508 /* ready to send message 'tq' on tunnel 'ct' */
2509 GNUNET_assert (t == tq->t);
2511 t->tq_tail,
2512 tq);
2513 if (NULL != tq->cid)
2514 *tq->cid = *GCC_get_id (ct->cc);
2517 "Sending payload of %s on %s\n",
2518 GCT_2s (t),
2519 GCC_2s (ct->cc));
2520 GCC_transmit (ct->cc,
2521 tq->env);
2522 if (NULL != tq->cont)
2523 tq->cont (tq->cont_cls,
2524 GCC_get_id (ct->cc));
2525 GNUNET_free (tq);
2526}
2527
2528
2537static void
2539 int is_ready)
2540{
2541 struct CadetTConnection *ct = cls;
2542 struct CadetTunnel *t = ct->t;
2543
2544 if (GNUNET_NO == is_ready)
2545 {
2547 "%s no longer ready for %s\n",
2548 GCC_2s (ct->cc),
2549 GCT_2s (t));
2551 return;
2552 }
2554 GNUNET_CONTAINER_DLL_remove (t->connection_busy_head,
2555 t->connection_busy_tail,
2556 ct);
2557 GNUNET_assert (0 < t->num_busy_connections);
2558 t->num_busy_connections--;
2559 ct->is_ready = GNUNET_YES;
2560 GNUNET_CONTAINER_DLL_insert_tail (t->connection_ready_head,
2561 t->connection_ready_tail,
2562 ct);
2563 t->num_ready_connections++;
2564
2566 "%s now ready for %s in state %s\n",
2567 GCC_2s (ct->cc),
2568 GCT_2s (t),
2569 estate2s (t->estate));
2570 switch (t->estate)
2571 {
2574 "Do not begin KX for %s if WE have no channels waiting. Retrying after %llu\n",
2575 GCT_2s (t),
2576 (unsigned long long) GNUNET_TIME_absolute_get_remaining (
2577 t->next_kx_attempt).rel_value_us);
2578 /* Do not begin KX if WE have no channels waiting! */
2580 t->next_kx_attempt).rel_value_us)
2581 return; /* wait for timeout before retrying */
2582 /* We are uninitialized, just transmit immediately,
2583 without undue delay. */
2584
2586 "Why for %s \n",
2587 GCT_2s (t));
2588
2589 if (NULL != t->kx_task)
2590 {
2591 GNUNET_SCHEDULER_cancel (t->kx_task);
2592 t->kx_task = NULL;
2593 }
2594 send_kx (t,
2595 ct,
2596 &t->ax);
2597 if ((0 ==
2598 GCT_count_channels (t)) &&
2599 (NULL == t->destroy_task))
2600 {
2601 t->destroy_task
2604 t);
2605 }
2606 break;
2607
2612 /* we're currently waiting for KX to complete, schedule job */
2613 if (NULL == t->kx_task)
2614 t->kx_task
2615 = GNUNET_SCHEDULER_add_at (t->next_kx_attempt,
2616 &retry_kx,
2617 t);
2618 break;
2619
2621 if (GNUNET_YES == t->kx_auth_requested)
2622 {
2624 t->next_kx_attempt).rel_value_us)
2625 return; /* wait for timeout */
2626 if (NULL != t->kx_task)
2627 {
2628 GNUNET_SCHEDULER_cancel (t->kx_task);
2629 t->kx_task = NULL;
2630 }
2631 send_kx_auth (t,
2632 ct,
2633 &t->ax,
2634 GNUNET_NO);
2635 return;
2636 }
2638 ct);
2639 break;
2640 }
2641}
2642
2643
2652static void
2654{
2655 struct CadetTunnel *t = cls;
2656 struct CadetTConnection *ct;
2657
2658 t->send_task = NULL;
2659 if (NULL == t->tq_head)
2660 return; /* no messages pending right now */
2661 ct = get_ready_connection (t);
2662 if (NULL == ct)
2663 return; /* no connections ready */
2665 ct);
2666}
2667
2668
2716
2717
2725static void
2727 struct CadetTConnection *ct)
2728{
2729 struct EvaluationSummary *es = cls;
2730 struct CadetConnection *cc = ct->cc;
2731 unsigned int ct_length;
2732 struct CadetPeerPath *ps;
2733 const struct CadetConnectionMetrics *metrics;
2734 GNUNET_CONTAINER_HeapCostType ct_desirability;
2735 struct GNUNET_TIME_Relative uptime;
2736 struct GNUNET_TIME_Relative last_use;
2737 double score;
2738 double success_rate;
2739
2740 ps = GCC_get_path (cc,
2741 &ct_length);
2743 "Evaluating path %s of existing %s\n",
2744 GCPP_2s (ps),
2745 GCC_2s (cc));
2746 if (ps == es->path)
2747 {
2749 "Ignoring duplicate path %s.\n",
2750 GCPP_2s (es->path));
2751 es->duplicate = GNUNET_YES;
2752 return;
2753 }
2754 if (NULL != es->path)
2755 {
2756 int duplicate = GNUNET_YES;
2757
2758 for (unsigned int i = 0; i < ct_length; i++)
2759 {
2762 i) !=
2764 i))
2765 {
2766 duplicate = GNUNET_NO;
2767 break;
2768 }
2769 }
2770 if (GNUNET_YES == duplicate)
2771 {
2773 "Ignoring overlapping path %s.\n",
2774 GCPP_2s (es->path));
2775 es->duplicate = GNUNET_YES;
2776 return;
2777 }
2778 else
2779 {
2781 "Known path %s differs from proposed path\n",
2782 GCPP_2s (ps));
2783 }
2784 }
2785
2786 ct_desirability = GCPP_get_desirability (ps);
2787 metrics = GCC_get_metrics (cc);
2788 uptime = GNUNET_TIME_absolute_get_duration (metrics->age);
2789 last_use = GNUNET_TIME_absolute_get_duration (metrics->last_use);
2790 /* We add 1.0 here to avoid division by zero. */
2791 success_rate = (metrics->num_acked_transmissions + 1.0)
2792 / (metrics->num_successes + 1.0);
2793 score
2794 = ct_desirability
2795 + 100.0 / (1.0 + ct_length) /* longer paths = better */
2796 + sqrt (uptime.rel_value_us / 60000000LL) /* larger uptime = better */
2797 - last_use.rel_value_us / 1000L; /* longer idle = worse */
2798 score *= success_rate; /* weigh overall by success rate */
2799
2800 if ((NULL == es->worst) ||
2801 (score < es->worst_score))
2802 {
2803 es->worst = ct;
2804 es->worst_score = score;
2805 }
2806 es->min_length = GNUNET_MIN (es->min_length,
2807 ct_length);
2808 es->max_length = GNUNET_MAX (es->max_length,
2809 ct_length);
2810 es->min_desire = GNUNET_MIN (es->min_desire,
2811 ct_desirability);
2812 es->max_desire = GNUNET_MAX (es->max_desire,
2813 ct_desirability);
2814}
2815
2816
2826static int
2828 struct CadetPeerPath *path,
2829 unsigned int off)
2830{
2831 struct CadetTunnel *t = cls;
2832 struct EvaluationSummary es;
2833 struct CadetTConnection *ct;
2834
2835 GNUNET_assert (off < GCPP_get_length (path));
2837 off) == t->destination);
2838 es.min_length = UINT_MAX;
2839 es.max_length = 0;
2840 es.max_desire = 0;
2841 es.min_desire = UINT64_MAX;
2842 es.path = path;
2843 es.duplicate = GNUNET_NO;
2844 es.worst = NULL;
2845
2846 /* Compute evaluation summary over existing connections. */
2848 "Evaluating proposed path %s for target %s\n",
2849 GCPP_2s (path),
2850 GCT_2s (t));
2851 /* FIXME: suspect this does not ACTUALLY iterate
2852 over all existing paths, otherwise dup detection
2853 should work!!! */
2856 &es);
2857 if (GNUNET_YES == es.duplicate)
2858 return GNUNET_YES;
2859
2860 /* FIXME: not sure we should really just count
2861 'num_connections' here, as they may all have
2862 consistently failed to connect. */
2863
2864 /* We iterate by increasing path length; if we have enough paths and
2865 this one is more than twice as long than what we are currently
2866 using, then ignore all of these super-long ones! */
2868 (es.min_length * 2 < off) &&
2869 (es.max_length < off))
2870 {
2872 "Ignoring paths of length %u, they are way too long.\n",
2873 es.min_length * 2);
2874 return GNUNET_NO;
2875 }
2876 /* If we have enough paths and this one looks no better, ignore it. */
2878 (es.min_length < GCPP_get_length (path)) &&
2879 (es.min_desire > GCPP_get_desirability (path)) &&
2880 (es.max_length < off))
2881 {
2883 "Ignoring path (%u/%llu) to %s, got something better already.\n",
2884 GCPP_get_length (path),
2885 (unsigned long long) GCPP_get_desirability (path),
2886 GCP_2s (t->destination));
2887 return GNUNET_YES;
2888 }
2889
2890 /* Path is interesting (better by some metric, or we don't have
2891 enough paths yet). */
2892 ct = GNUNET_new (struct CadetTConnection);
2894 ct->t = t;
2895 ct->cc = GCC_create (t->destination,
2896 path,
2897 off,
2898 ct,
2900 ct);
2901
2902 /* FIXME: schedule job to kill connection (and path?) if it takes
2903 too long to get ready! (And track performance data on how long
2904 other connections took with the tunnel!)
2905 => Note: to be done within 'connection'-logic! */
2906 GNUNET_CONTAINER_DLL_insert (t->connection_busy_head,
2907 t->connection_busy_tail,
2908 ct);
2909 t->num_busy_connections++;
2911 "Found interesting path %s for %s, created %s\n",
2912 GCPP_2s (path),
2913 GCT_2s (t),
2914 GCC_2s (ct->cc));
2915 return GNUNET_YES;
2916}
2917
2918
2932static void
2934{
2935 struct CadetTunnel *t = cls;
2936 struct GNUNET_TIME_Relative delay;
2937 struct EvaluationSummary es;
2938
2939 t->maintain_connections_task = NULL;
2941 "Performing connection maintenance for %s.\n",
2942 GCT_2s (t));
2943
2944 es.min_length = UINT_MAX;
2945 es.max_length = 0;
2946 es.max_desire = 0;
2947 es.min_desire = UINT64_MAX;
2948 es.path = NULL;
2949 es.worst = NULL;
2950 es.duplicate = GNUNET_NO;
2953 &es);
2954 if ((NULL != es.worst) &&
2956 {
2957 /* Clear out worst-performing connection 'es.worst'. */
2959 es.worst);
2960 }
2961
2962 /* Consider additional paths */
2963 (void) GCP_iterate_paths (t->destination,
2965 t);
2966
2967 /* FIXME: calculate when to try again based on how well we are doing;
2968 in particular, if we have to few connections, we might be able
2969 to do without this (as PATHS should tell us whenever a new path
2970 is available instantly; however, need to make sure this job is
2971 restarted after that happens).
2972 Furthermore, if the paths we do know are in a reasonably narrow
2973 quality band and are plentyful, we might also consider us stabilized
2974 and then reduce the frequency accordingly. */delay = GNUNET_TIME_UNIT_MINUTES;
2975 t->maintain_connections_task
2978 t);
2979}
2980
2981
2982void
2984 struct CadetPeerPath *p,
2985 unsigned int off)
2986{
2988 "Considering %s for %s (offset %u)\n",
2989 GCPP_2s (p),
2990 GCT_2s (t),
2991 off);
2992 (void) consider_path_cb (t,
2993 p,
2994 off);
2995}
2996
2997
3004static void
3006 const struct GNUNET_MessageHeader *msg)
3007{
3008 struct CadetTunnel *t = cls;
3009
3011 "Received KEEPALIVE on %s\n",
3012 GCT_2s (t));
3014 "# keepalives received",
3015 1,
3016 GNUNET_NO);
3017}
3018
3019
3027static int
3030{
3031 return GNUNET_OK;
3032}
3033
3034
3042static void
3045{
3046 struct CadetTunnel *t = cls;
3047 struct CadetChannel *ch;
3048
3049 ch = lookup_channel (t,
3050 msg->ctn);
3051 if (NULL == ch)
3052 {
3053 /* We don't know about such a channel, might have been destroyed on our
3054 end in the meantime, or never existed. Send back a DESTROY. */
3056 "Received %u bytes of application data for unknown channel %u, sending DESTROY\n",
3057 (unsigned int) (ntohs (msg->header.size) - sizeof(*msg)),
3058 ntohl (msg->ctn.cn));
3060 msg->ctn);
3061 return;
3062 }
3064 GCC_get_id (t->current_ct->cc),
3065 msg);
3066}
3067
3068
3077static void
3079 const struct GNUNET_CADET_ChannelDataAckMessage *ack)
3080{
3081 struct CadetTunnel *t = cls;
3082 struct CadetChannel *ch;
3083
3084 ch = lookup_channel (t,
3085 ack->ctn);
3086 if (NULL == ch)
3087 {
3088 /* We don't know about such a channel, might have been destroyed on our
3089 end in the meantime, or never existed. Send back a DESTROY. */
3091 "Received DATA_ACK for unknown channel %u, sending DESTROY\n",
3092 ntohl (ack->ctn.cn));
3094 ack->ctn);
3095 return;
3096 }
3098 GCC_get_id (t->current_ct->cc),
3099 ack);
3100}
3101
3102
3110static void
3112 const struct
3114{
3115 struct CadetTunnel *t = cls;
3116 struct CadetChannel *ch;
3117
3119 ntohl (copen->ctn.cn));
3120 if (NULL != ch)
3121 {
3123 "Received duplicate channel CHANNEL_OPEN on h_port %s from %s (%s), resending ACK\n",
3124 GNUNET_h2s (&copen->h_port),
3125 GCT_2s (t),
3126 GCCH_2s (ch));
3128 GCC_get_id (t->current_ct->cc));
3129 return;
3130 }
3132 "Received CHANNEL_OPEN on h_port %s from %s\n",
3133 GNUNET_h2s (&copen->h_port),
3134 GCT_2s (t));
3136 copen->ctn,
3137 &copen->h_port,
3138 ntohl (copen->opt));
3139 if (NULL != t->destroy_task)
3140 {
3141 GNUNET_SCHEDULER_cancel (t->destroy_task);
3142 t->destroy_task = NULL;
3143 }
3146 ntohl (copen->ctn.cn),
3147 ch,
3149}
3150
3151
3158void
3161{
3163
3165 "Sending DESTROY message for channel ID %u\n",
3166 ntohl (ctn.cn));
3167 msg.header.size = htons (sizeof(msg));
3169 msg.reserved = htonl (0);
3170 msg.ctn = ctn;
3171 GCT_send (t,
3172 &msg.header,
3173 NULL,
3174 NULL,
3175 &ctn);
3176}
3177
3178
3187static void
3189 const struct
3191{
3192 struct CadetTunnel *t = cls;
3193 struct CadetChannel *ch;
3194
3195 ch = lookup_channel (t,
3196 cm->ctn);
3197 if (NULL == ch)
3198 {
3199 /* We don't know about such a channel, might have been destroyed on our
3200 end in the meantime, or never existed. Send back a DESTROY. */
3202 "Received channel OPEN_ACK for unknown channel %u, sending DESTROY\n",
3203 ntohl (cm->ctn.cn));
3205 cm->ctn);
3206 return;
3207 }
3209 "Received channel OPEN_ACK on channel %s from %s\n",
3210 GCCH_2s (ch),
3211 GCT_2s (t));
3213 GCC_get_id (t->current_ct->cc),
3214 &cm->port);
3215}
3216
3217
3225static void
3227 const struct
3229{
3230 struct CadetTunnel *t = cls;
3231 struct CadetChannel *ch;
3232
3233 ch = lookup_channel (t,
3234 cm->ctn);
3235 if (NULL == ch)
3236 {
3237 /* We don't know about such a channel, might have been destroyed on our
3238 end in the meantime, or never existed. */
3240 "Received channel DESTROY for unknown channel %u. Ignoring.\n",
3241 ntohl (cm->ctn.cn));
3242 return;
3243 }
3245 "Received channel DESTROY on %s from %s\n",
3246 GCCH_2s (ch),
3247 GCT_2s (t));
3249 GCC_get_id (t->current_ct->cc));
3250}
3251
3252
3263static int
3265 const struct GNUNET_MessageHeader *msg)
3266{
3267 struct CadetTunnel *t = cls;
3268
3269 GNUNET_assert (NULL != t->current_ct);
3271 msg);
3272 return GNUNET_OK;
3273}
3274
3275
3283static void
3285 enum GNUNET_MQ_Error error)
3286{
3287 GNUNET_break_op (0);
3288}
3289
3290
3298struct CadetTunnel *
3300{
3301 struct CadetTunnel *t = GNUNET_new (struct CadetTunnel);
3303 GNUNET_MQ_hd_fixed_size (plaintext_keepalive,
3305 struct GNUNET_MessageHeader,
3306 t),
3307 GNUNET_MQ_hd_var_size (plaintext_data,
3310 t),
3311 GNUNET_MQ_hd_fixed_size (plaintext_data_ack,
3314 t),
3315 GNUNET_MQ_hd_fixed_size (plaintext_channel_open,
3318 t),
3319 GNUNET_MQ_hd_fixed_size (plaintext_channel_open_ack,
3322 t),
3323 GNUNET_MQ_hd_fixed_size (plaintext_channel_destroy,
3326 t),
3328 };
3329
3330 t->kx_retry_delay = INITIAL_KX_RETRY_DELAY;
3331 new_ephemeral (&t->ax);
3333 t->destination = destination;
3335 t->maintain_connections_task
3337 t);
3338 t->mq = GNUNET_MQ_queue_for_callbacks (NULL,
3339 NULL,
3340 NULL,
3341 NULL,
3342 handlers,
3344 t);
3346 t);
3347 return t;
3348}
3349
3350
3351int
3353 const struct
3355 struct CadetPeerPath *path)
3356{
3357 struct CadetTConnection *ct;
3358
3359 ct = GNUNET_new (struct CadetTConnection);
3361 ct->t = t;
3362 ct->cc = GCC_create_inbound (t->destination,
3363 path,
3364 ct,
3365 cid,
3367 ct);
3368 if (NULL == ct->cc)
3369 {
3371 "%s refused inbound %s (duplicate)\n",
3372 GCT_2s (t),
3373 GCC_2s (ct->cc));
3374 GNUNET_free (ct);
3375 return GNUNET_SYSERR;
3376 }
3377 /* FIXME: schedule job to kill connection (and path?) if it takes
3378 too long to get ready! (And track performance data on how long
3379 other connections took with the tunnel!)
3380 => Note: to be done within 'connection'-logic! */
3381 GNUNET_CONTAINER_DLL_insert (t->connection_busy_head,
3382 t->connection_busy_tail,
3383 ct);
3384 t->num_busy_connections++;
3386 "%s has new %s\n",
3387 GCT_2s (t),
3388 GCC_2s (ct->cc));
3389 return GNUNET_OK;
3390}
3391
3392
3399void
3402{
3403 struct CadetTunnel *t = ct->t;
3404 uint16_t size = ntohs (msg->header.size);
3405 char cbuf[size] GNUNET_ALIGN;
3406 ssize_t decrypted_size;
3407
3409 "%s received %u bytes of encrypted data in state %d\n",
3410 GCT_2s (t),
3411 (unsigned int) size,
3412 t->estate);
3413
3414 switch (t->estate)
3415 {
3418 /* We did not even SEND our KX, how can the other peer
3419 send us encrypted data? Must have been that we went
3420 down and the other peer still things we are up.
3421 Let's send it KX back. */
3423 "# received encrypted without any KX",
3424 1,
3425 GNUNET_NO);
3426 if (NULL != t->kx_task)
3427 {
3428 GNUNET_SCHEDULER_cancel (t->kx_task);
3429 t->kx_task = NULL;
3430 }
3431 send_kx (t,
3432 ct,
3433 &t->ax);
3434 return;
3435
3437 /* We send KX, and other peer send KX to us at the same time.
3438 Neither KX is AUTH'ed, so let's try KX_AUTH this time. */
3440 "# received encrypted without KX_AUTH",
3441 1,
3442 GNUNET_NO);
3443 if (NULL != t->kx_task)
3444 {
3445 GNUNET_SCHEDULER_cancel (t->kx_task);
3446 t->kx_task = NULL;
3447 }
3448 send_kx_auth (t,
3449 ct,
3450 &t->ax,
3451 GNUNET_YES);
3452 return;
3453
3455 /* We did not get the KX of the other peer, but that
3456 might have been lost. Send our KX again immediately. */
3458 "# received encrypted without KX",
3459 1,
3460 GNUNET_NO);
3461 if (NULL != t->kx_task)
3462 {
3463 GNUNET_SCHEDULER_cancel (t->kx_task);
3464 t->kx_task = NULL;
3465 }
3466 send_kx (t,
3467 ct,
3468 &t->ax);
3469 return;
3470
3472 /* Great, first payload, we might graduate to OK! */
3474 /* We are up and running, all good. */
3475 break;
3476 }
3477
3478 decrypted_size = -1;
3479 if (CADET_TUNNEL_KEY_OK == t->estate)
3480 {
3481 /* We have well-established key material available,
3482 try that. (This is the common case.) */
3483 decrypted_size = t_ax_decrypt_and_validate (&t->ax,
3484 cbuf,
3485 msg,
3486 size);
3487 }
3488
3489 if ((-1 == decrypted_size) &&
3490 (NULL != t->unverified_ax))
3491 {
3492 /* We have un-authenticated KX material available. We should try
3493 this as a back-up option, in case the sender crashed and
3494 switched keys. */
3495 decrypted_size = t_ax_decrypt_and_validate (t->unverified_ax,
3496 cbuf,
3497 msg,
3498 size);
3499 if (-1 != decrypted_size)
3500 {
3501 /* It worked! Treat this as authentication of the AX data! */
3502 cleanup_ax (&t->ax);
3503 t->ax = *t->unverified_ax;
3504 GNUNET_free (t->unverified_ax);
3505 t->unverified_ax = NULL;
3506 }
3507 if (CADET_TUNNEL_KEY_AX_AUTH_SENT == t->estate)
3508 {
3509 /* First time it worked, move tunnel into production! */
3512 if (NULL != t->send_task)
3513 GNUNET_SCHEDULER_cancel (t->send_task);
3515 t);
3516 }
3517 }
3518 if (NULL != t->unverified_ax)
3519 {
3520 /* We had unverified KX material that was useless; so increment
3521 counter and eventually move to ignore it. Note that we even do
3522 this increment if we successfully decrypted with the old KX
3523 material and thus didn't even both with the new one. This is
3524 the ideal case, as a malicious injection of bogus KX data
3525 basically only causes us to increment a counter a few times. */t->unverified_attempts++;
3527 "Failed to decrypt message with unverified KX data %u times\n",
3528 t->unverified_attempts);
3529 if (t->unverified_attempts > MAX_UNVERIFIED_ATTEMPTS)
3530 {
3531 cleanup_ax (t->unverified_ax);
3532 GNUNET_free (t->unverified_ax);
3533 t->unverified_ax = NULL;
3534 }
3535 }
3536
3537 if (-1 == decrypted_size)
3538 {
3539 /* Decryption failed for good, complain. */
3541 "%s failed to decrypt and validate encrypted data, retrying KX\n",
3542 GCT_2s (t));
3544 "# unable to decrypt",
3545 1,
3546 GNUNET_NO);
3547 if (NULL != t->kx_task)
3548 {
3549 GNUNET_SCHEDULER_cancel (t->kx_task);
3550 t->kx_task = NULL;
3551 }
3552 send_kx (t,
3553 ct,
3554 &t->ax);
3555 return;
3556 }
3558 "# decrypted bytes",
3559 decrypted_size,
3560 GNUNET_NO);
3561
3562 /* The MST will ultimately call #handle_decrypted() on each message. */
3563 t->current_ct = ct;
3566 cbuf,
3567 decrypted_size,
3568 GNUNET_YES,
3569 GNUNET_NO));
3570 t->current_ct = NULL;
3571}
3572
3573
3574struct CadetTunnelQueueEntry *
3576 const struct GNUNET_MessageHeader *message,
3578 void *cont_cls,
3580{
3581 struct CadetTunnelQueueEntry *tq;
3582 uint16_t payload_size;
3583 struct GNUNET_MQ_Envelope *env;
3585 struct CadetChannel *ch;
3586
3587 if (NULL != ctn)
3588 {
3589 ch = lookup_channel (t,
3590 *ctn);
3591 if ((NULL != ch) && GCCH_is_type_to_drop (ch, message))
3592 {
3593 GNUNET_break (0);
3594 return NULL;
3595 }
3596 }
3597
3598 if (CADET_TUNNEL_KEY_OK != t->estate)
3599 {
3600 GNUNET_break (0);
3601 return NULL;
3602 }
3603 payload_size = ntohs (message->size);
3605 "Encrypting %u bytes for %s\n",
3606 (unsigned int) payload_size,
3607 GCT_2s (t));
3608 env = GNUNET_MQ_msg_extra (ax_msg,
3609 payload_size,
3611 t_ax_encrypt (&t->ax,
3612 &ax_msg[1],
3613 message,
3614 payload_size);
3616 "# encrypted bytes",
3617 payload_size,
3618 GNUNET_NO);
3619 ax_msg->ax_header.Ns = htonl (t->ax.Ns++);
3620 ax_msg->ax_header.PNs = htonl (t->ax.PNs);
3621 /* FIXME: we should do this once, not once per message;
3622 this is a point multiplication, and DHRs does not
3623 change all the time. */
3625 &ax_msg->ax_header.DHRs);
3626 t_h_encrypt (&t->ax,
3627 ax_msg);
3628 t_hmac (&ax_msg->ax_header,
3629 sizeof(struct GNUNET_CADET_AxHeader) + payload_size,
3630 0,
3631 &t->ax.HKs,
3632 &ax_msg->hmac);
3633
3634 tq = GNUNET_malloc (sizeof(*tq));
3635 tq->t = t;
3636 tq->env = env;
3637 tq->cid = &ax_msg->cid; /* will initialize 'ax_msg->cid' once we know the connection */
3638 tq->cont = cont;
3639 tq->cont_cls = cont_cls;
3641 t->tq_tail,
3642 tq);
3643 if (NULL != t->send_task)
3644 GNUNET_SCHEDULER_cancel (t->send_task);
3645 t->send_task
3647 t);
3648 return tq;
3649}
3650
3651
3652void
3654{
3655 struct CadetTunnel *t = tq->t;
3656
3658 t->tq_tail,
3659 tq);
3660 GNUNET_MQ_discard (tq->env);
3661 GNUNET_free (tq);
3662}
3663
3664
3672void
3675 void *iter_cls)
3676{
3677 struct CadetTConnection *n;
3678
3679 for (struct CadetTConnection *ct = t->connection_ready_head;
3680 NULL != ct;
3681 ct = n)
3682 {
3683 n = ct->next;
3684 iter (iter_cls,
3685 ct);
3686 }
3687 for (struct CadetTConnection *ct = t->connection_busy_head;
3688 NULL != ct;
3689 ct = n)
3690 {
3691 n = ct->next;
3692 iter (iter_cls,
3693 ct);
3694 }
3695}
3696
3697
3713
3714
3723static int
3725 uint32_t key,
3726 void *value)
3727{
3728 struct ChanIterCls *ctx = cls;
3729 struct CadetChannel *ch = value;
3730
3731 ctx->iter (ctx->iter_cls,
3732 ch);
3733 return GNUNET_OK;
3734}
3735
3736
3744void
3747 void *iter_cls)
3748{
3749 struct ChanIterCls ctx;
3750
3751 ctx.iter = iter;
3752 ctx.iter_cls = iter_cls;
3755 &ctx);
3756}
3757
3758
3767static int
3768debug_channel (void *cls,
3769 uint32_t key,
3770 void *value)
3771{
3772 const enum GNUNET_ErrorType *level = cls;
3773 struct CadetChannel *ch = value;
3774
3775 GCCH_debug (ch, *level);
3776 return GNUNET_OK;
3777}
3778
3779
3780#define LOG2(level, ...) GNUNET_log_from_nocheck (level, "cadet-tun", \
3781 __VA_ARGS__)
3782
3783
3790void
3791GCT_debug (const struct CadetTunnel *t,
3792 enum GNUNET_ErrorType level)
3793{
3794#if ! defined(GNUNET_CULL_LOGGING)
3795 struct CadetTConnection *iter_c;
3796 int do_log;
3797
3799 "cadet-tun",
3800 __FILE__, __FUNCTION__, __LINE__);
3801 if (0 == do_log)
3802 return;
3803
3804 LOG2 (level,
3805 "TTT TUNNEL TOWARDS %s in estate %s tq_len: %u #cons: %u\n",
3806 GCT_2s (t),
3807 estate2s (t->estate),
3808 t->tq_len,
3810 LOG2 (level,
3811 "TTT channels:\n");
3814 &level);
3815 LOG2 (level,
3816 "TTT connections:\n");
3817 for (iter_c = t->connection_ready_head; NULL != iter_c; iter_c = iter_c->next)
3818 GCC_debug (iter_c->cc,
3819 level);
3820 for (iter_c = t->connection_busy_head; NULL != iter_c; iter_c = iter_c->next)
3821 GCC_debug (iter_c->cc,
3822 level);
3823
3824 LOG2 (level,
3825 "TTT TUNNEL END\n");
3826#endif
3827}
3828
3829
3830/* end of gnunet-service-cadet_tunnels.c */
struct GNUNET_MQ_MessageHandlers handlers[]
Definition 003.c:1
struct GNUNET_MessageHeader * msg
Definition 005.c:2
struct GNUNET_MQ_Envelope * env
Definition 005.c:1
P2P messages used by CADET.
GNUNET_CADET_KX_Flags
Flags to be used in GNUNET_CADET_KX.
@ GNUNET_CADET_KX_FLAG_NONE
Should the peer reply with its KX details?
@ GNUNET_CADET_KX_FLAG_FORCE_REPLY
The peer should reply with its KX details?
static struct GNUNET_ARM_Handle * h
Connection with ARM.
Definition gnunet-arm.c:98
static int ret
Final status code.
Definition gnunet-arm.c:93
static struct GNUNET_CADET_Channel * ch
Channel handle.
static struct GNUNET_PEERSTORE_Handle * ps
Handle to the PEERSTORE service.
struct GNUNET_HashCode key
The key used in the DHT.
static struct GNUNET_FS_Handle * ctx
static GstElement * source
Appsrc instance into which we write data for the pipeline.
static struct GNUNET_SCHEDULER_Task * t
Main task.
static int state
The current state of the parser.
static char * res
Currently read line or NULL on EOF.
static char * value
Value of the record to add/remove.
static struct GNUNET_PILS_Handle * pils
Handle to PILS.
Definition gnunet-pils.c:44
static struct GNUNET_CRYPTO_PowSalt salt
Salt for PoW calculations.
int shutting_down
Signal that shutdown is happening: prevent recovery measures.
struct GNUNET_TIME_Relative ratchet_time
How long until we trigger a ratched advance due to time.
void GCCH_handle_channel_plaintext_data_ack(struct CadetChannel *ch, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti, const struct GNUNET_CADET_ChannelDataAckMessage *ack)
We got an acknowledgement for payload data for a channel.
struct CadetChannel * GCCH_channel_incoming_new(struct CadetTunnel *t, struct GNUNET_CADET_ChannelTunnelNumber ctn, const struct GNUNET_HashCode *h_port, uint32_t options)
Create a new channel based on a request coming in over the network.
const char * GCCH_2s(const struct CadetChannel *ch)
Get the static string for identification of the channel.
void GCCH_handle_duplicate_open(struct CadetChannel *ch, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti)
We got a GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN message again for this channel.
void GCCH_tunnel_up(struct CadetChannel *ch)
Function called once and only once after a channel was bound to its tunnel via GCT_add_channel() is r...
void GCCH_debug(struct CadetChannel *ch, enum GNUNET_ErrorType level)
Log channel info.
void GCCH_handle_channel_plaintext_data(struct CadetChannel *ch, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti, const struct GNUNET_CADET_ChannelAppDataMessage *msg)
We got payload data for a channel.
void GCCH_handle_remote_destroy(struct CadetChannel *ch, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti)
Destroy channel, based on the other peer closing the connection.
void GCCH_handle_channel_open_ack(struct CadetChannel *ch, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti, const struct GNUNET_HashCode *port)
We got an acknowledgement for the creation of the channel (the port is open on the other side).
int GCCH_is_type_to_drop(struct CadetChannel *ch, const struct GNUNET_MessageHeader *message)
Check if type of message is the one to drop.
GNUnet CADET service with encryption.
struct CadetPeerPath * GCC_get_path(struct CadetConnection *cc, unsigned int *off)
Obtain the path used by this connection.
const char * GCC_2s(const struct CadetConnection *cc)
Get a (static) string for a connection.
struct CadetConnection * GCC_create_inbound(struct CadetPeer *destination, struct CadetPeerPath *path, struct CadetTConnection *ct, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid, GCC_ReadyCallback ready_cb, void *ready_cb_cls)
Create a connection to destination via path and notify cb whenever we are ready for more data.
void GCC_destroy_without_tunnel(struct CadetConnection *cc)
Destroy a connection, called if the tunnel association with the connection was already broken,...
struct CadetConnection * GCC_create(struct CadetPeer *destination, struct CadetPeerPath *path, unsigned int off, struct CadetTConnection *ct, GCC_ReadyCallback ready_cb, void *ready_cb_cls)
Create a connection to destination via path and notify cb whenever we are ready for more data.
void GCC_transmit(struct CadetConnection *cc, struct GNUNET_MQ_Envelope *env)
Transmit message msg via connection cc.
void GCC_debug(struct CadetConnection *cc, enum GNUNET_ErrorType level)
Log connection info.
const struct CadetConnectionMetrics * GCC_get_metrics(struct CadetConnection *cc)
Obtain performance metrics from cc.
const struct GNUNET_CADET_ConnectionTunnelIdentifier * GCC_get_id(struct CadetConnection *cc)
Obtain unique ID for the connection.
A connection is a live end-to-end messaging mechanism where the peers are identified by a path and kn...
const char * GCPP_2s(struct CadetPeerPath *path)
Convert a path to a human-readable string.
unsigned int GCPP_get_length(struct CadetPeerPath *path)
Return the length of the path.
GNUNET_CONTAINER_HeapCostType GCPP_get_desirability(const struct CadetPeerPath *path)
Return how much we like keeping the path.
struct CadetPeer * GCPP_get_peer_at_offset(struct CadetPeerPath *path, unsigned int off)
Obtain the peer at offset off in path.
const struct GNUNET_PeerIdentity * GCP_get_id(struct CadetPeer *cp)
Obtain the peer identity for a struct CadetPeer.
void GCP_drop_tunnel(struct CadetPeer *cp, struct CadetTunnel *t)
The tunnel to the given peer no longer exists, remove it from our data structures,...
const char * GCP_2s(const struct CadetPeer *cp)
Get the static string for a peer ID.
unsigned int GCP_iterate_paths(struct CadetPeer *cp, GCP_PathIterator callback, void *callback_cls)
Iterate over the paths to a peer.
Information we track per peer.
static void t_h_decrypt(struct CadetTunnelAxolotl *ax, const struct GNUNET_CADET_TunnelEncryptedMessage *src, struct GNUNET_CADET_TunnelEncryptedMessage *dst)
Decrypt header with the current axolotl header key.
static void cleanup_ax(struct CadetTunnelAxolotl *ax)
Cleanup state used by ax.
void GCT_handle_kx(struct CadetTConnection *ct, const struct GNUNET_CADET_TunnelKeyExchangeMessage *msg)
Continue to handle KX message.
static int consider_path_cb(void *cls, struct CadetPeerPath *path, unsigned int off)
Consider using the path p for the tunnel t.
void GCT_remove_channel(struct CadetTunnel *t, struct CadetChannel *ch, struct GNUNET_CADET_ChannelTunnelNumber ctn)
Remove a channel from a tunnel.
static struct GNUNET_CADET_ChannelTunnelNumber get_next_free_ctn(struct CadetTunnel *t)
Compute the next free channel tunnel number for this tunnel.
static struct CadetChannel * lookup_channel(struct CadetTunnel *t, struct GNUNET_CADET_ChannelTunnelNumber ctn)
Lookup a channel by its ctn.
static int notify_tunnel_up_cb(void *cls, uint32_t key, void *value)
Our tunnel became ready for the first time, notify channels that have been waiting.
struct CadetPeer * GCT_get_destination(struct CadetTunnel *t)
Return the peer to which this tunnel goes.
void(* CadetTunnelAxolotlCallback)(void *cls, enum GNUNET_GenericReturnValue res)
Signature of the follow up function from an udate AX by KX.
void GCT_send_channel_destroy(struct CadetTunnel *t, struct GNUNET_CADET_ChannelTunnelNumber ctn)
Send a DESTROY message via the tunnel.
static int debug_channel(void *cls, uint32_t key, void *value)
Call GCCH_debug() on a channel.
static void mark_connection_unready(struct CadetTConnection *ct)
Connection ct is now unready, clear it's ready flag and move it from the ready DLL to the busy DLL.
static void handle_plaintext_channel_open_ack(void *cls, const struct GNUNET_CADET_ChannelOpenAckMessage *cm)
We have received confirmation from the target peer that the given channel could be established (the p...
unsigned int GCT_count_any_connections(const struct CadetTunnel *t)
Counts the number of connections created for a tunnel, including busy connections.
static void new_ephemeral(struct CadetTunnelAxolotl *ax)
Create a new Axolotl ephemeral (ratchet) key.
#define MAX_KEY_GAP
Maximum number of keys (and thus ratchet steps) we are willing to skip before we decide this is eithe...
#define MAX_UNVERIFIED_ATTEMPTS
How often do we try to decrypt payload with unverified key material? Used to limit CPU increase upon ...
static int handle_decrypted(void *cls, const struct GNUNET_MessageHeader *msg)
Handles a message we decrypted, by injecting it into our message queue (which will do the dispatching...
#define LOG2(level,...)
static void retry_kx(void *cls)
Try to redo the KX or KX_AUTH handshake, if we can.
void GCT_change_estate(struct CadetTunnel *t, enum CadetTunnelEState state)
Change the tunnel encryption state.
static void t_ax_decrypt(struct CadetTunnelAxolotl *ax, void *dst, const void *src, size_t size)
Decrypt data with the axolotl tunnel key.
static void send_kx(struct CadetTunnel *t, struct CadetTConnection *ct, struct CadetTunnelAxolotl *ax)
Send a KX message.
static void try_send_normal_payload(struct CadetTunnel *t, struct CadetTConnection *ct)
Send normal payload from queue in t via connection ct.
void GCT_send_cancel(struct CadetTunnelQueueEntry *tq)
Cancel a previously sent message while it's in the queue.
static void decrypted_error_cb(void *cls, enum GNUNET_MQ_Error error)
Function called if we had an error processing an incoming decrypted message.
unsigned int GCT_count_channels(struct CadetTunnel *t)
Returns the number of channels using a tunnel.
void GCT_handle_kx_auth(struct CadetTConnection *ct, const struct GNUNET_CADET_TunnelKeyExchangeAuthMessage *msg)
Handle KX_AUTH message.
void GCT_iterate_connections(struct CadetTunnel *t, GCT_ConnectionIterator iter, void *iter_cls)
Iterate over all connections of a tunnel.
void GCT_handle_encrypted(struct CadetTConnection *ct, const struct GNUNET_CADET_TunnelEncryptedMessage *msg)
Handle encrypted message.
struct CadetTunnelQueueEntry * GCT_send(struct CadetTunnel *t, const struct GNUNET_MessageHeader *message, GCT_SendContinuation cont, void *cont_cls, struct GNUNET_CADET_ChannelTunnelNumber *ctn)
Sends an already built message on a tunnel, encrypting it and choosing the best connection if not pro...
static void connection_ready_cb(void *cls, int is_ready)
A connection is is_ready for transmission.
static void cont_GCT_handle_kx(void *cls, enum GNUNET_GenericReturnValue ret)
Continue to handle KX message.
static void t_hmac(const void *plaintext, size_t size, uint32_t iv, const struct GNUNET_CRYPTO_SymmetricSessionKey *key, struct GNUNET_ShortHashCode *hmac)
Calculate HMAC.
static void maintain_connections_cb(void *cls)
Function called to maintain the connections underlying our tunnel.
static void handle_plaintext_channel_destroy(void *cls, const struct GNUNET_CADET_ChannelDestroyMessage *cm)
We received a message saying that a channel should be destroyed.
#define HIGH_BIT
static void handle_plaintext_channel_open(void *cls, const struct GNUNET_CADET_ChannelOpenMessage *copen)
We have received a request to open a channel to a port from another peer.
static int iterate_channels_cb(void *cls, uint32_t key, void *value)
Helper function for GCT_iterate_channels.
static void send_kx_auth(struct CadetTunnel *t, struct CadetTConnection *ct, struct CadetTunnelAxolotl *ax, int force_reply)
Send a KX_AUTH message.
static void store_skipped_key(struct CadetTunnelAxolotl *ax, const struct GNUNET_CRYPTO_SymmetricSessionKey *HKr)
Delete a key from the list of skipped keys.
struct GNUNET_CADET_ChannelTunnelNumber GCT_add_channel(struct CadetTunnel *t, struct CadetChannel *ch)
Add a channel to a tunnel, and notify channel that we are ready for transmission if we are already up...
static void t_ax_hmac_hash(const struct GNUNET_CRYPTO_SymmetricSessionKey *key, struct GNUNET_HashCode *hash, const void *source, unsigned int len)
Perform a HMAC.
int GCT_add_inbound_connection(struct CadetTunnel *t, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid, struct CadetPeerPath *path)
Add a connection to the tunnel.
void GCT_connection_lost(struct CadetTConnection *ct)
We lost a connection, remove it from our list and clean up the connection object itself.
enum CadetTunnelEState GCT_get_estate(struct CadetTunnel *t)
Get the encryption state of a tunnel.
#define INITIAL_KX_RETRY_DELAY
How long do we wait initially before retransmitting the KX? TODO: replace by 2 RTT if/once we have co...
static int check_plaintext_data(void *cls, const struct GNUNET_CADET_ChannelAppDataMessage *msg)
Check that msg is well-formed.
static int store_ax_keys(struct CadetTunnelAxolotl *ax, const struct GNUNET_CRYPTO_SymmetricSessionKey *HKr, uint32_t Np)
Stage skipped AX keys and calculate the message key.
static void handle_plaintext_data_ack(void *cls, const struct GNUNET_CADET_ChannelDataAckMessage *ack)
We received an acknowledgement for data we sent on a channel.
static void handle_plaintext_keepalive(void *cls, const struct GNUNET_MessageHeader *msg)
We got a keepalive.
static void handle_plaintext_data(void *cls, const struct GNUNET_CADET_ChannelAppDataMessage *msg)
We received payload data for a channel.
static void trigger_transmissions(void *cls)
Called when either we have a new connection, or a new message in the queue, or some existing connecti...
static void cont_GCT_handle_kx_auth(void *cls, enum GNUNET_GenericReturnValue ret)
Continue to handle KX_AUTH message.
static void evaluate_connection(void *cls, struct CadetTConnection *ct)
Evaluate a connection, updating our summary information in cls about what kinds of connections we hav...
static void t_h_encrypt(struct CadetTunnelAxolotl *ax, struct GNUNET_CADET_TunnelEncryptedMessage *msg)
Encrypt header with the axolotl header key.
static void delete_skipped_key(struct CadetTunnelAxolotl *ax, struct CadetTunnelSkippedKey *key)
Delete a key from the list of skipped keys.
void GCT_destroy_tunnel_now(struct CadetTunnel *t)
Destroys the tunnel t now, without delay.
static void t_ax_encrypt(struct CadetTunnelAxolotl *ax, void *dst, const void *src, size_t size)
Encrypt data with the axolotl tunnel key.
struct CadetTunnel * GCT_create_tunnel(struct CadetPeer *destination)
Create a tunnel to destination.
#define LOG(level,...)
static struct CadetTConnection * get_ready_connection(struct CadetTunnel *t)
Find first connection that is ready in the list of our connections.
static const char * estate2s(enum CadetTunnelEState es)
Get string description for tunnel encryption state.
int GCT_alice_or_betty(const struct GNUNET_PeerIdentity *other)
Am I Alice or Betty (some call her Bob), or talking to myself?
#define IDLE_DESTROY_DELAY
How long do we wait until tearing down an idle tunnel?
static ssize_t try_old_ax_keys(struct CadetTunnelAxolotl *ax, void *dst, const struct GNUNET_CADET_TunnelEncryptedMessage *src, size_t size)
Decrypt and verify data with the appropriate tunnel key and verify that the data has not been altered...
#define MAX_SKIPPED_KEYS
Maximum number of skipped keys we keep in memory per tunnel.
static ssize_t t_ax_decrypt_and_validate(struct CadetTunnelAxolotl *ax, void *dst, const struct GNUNET_CADET_TunnelEncryptedMessage *src, size_t size)
Decrypt and verify data with the appropriate tunnel key and verify that the data has not been altered...
void GCT_consider_path(struct CadetTunnel *t, struct CadetPeerPath *p, unsigned int off)
Consider using the path p for the tunnel t.
void GCT_iterate_channels(struct CadetTunnel *t, GCT_ChannelIterator iter, void *iter_cls)
Iterate over all channels of a tunnel.
static void destroy_tunnel(void *cls)
This tunnel is no longer used, destroy it.
void GCT_debug(const struct CadetTunnel *t, enum GNUNET_ErrorType level)
Log all possible info about the tunnel state.
static int destroy_remaining_channels(void *cls, uint32_t key, void *value)
Destroy remaining channels during shutdown.
static void update_ax_by_kx(void *cls, const struct GNUNET_HashCode *key_result)
Update our Axolotl key state based on the KX data we received.
const char * GCT_2s(const struct CadetTunnel *t)
Get the static string for the peer this tunnel is directed.
static void destroy_t_connection(void *cls, struct CadetTConnection *ct)
Clean up connection ct of a tunnel.
static void t_hmac_derive_key(const struct GNUNET_CRYPTO_SymmetricSessionKey *key, struct GNUNET_CRYPTO_SymmetricSessionKey *out, const void *source, unsigned int len)
Derive a symmetric encryption key from an HMAC-HASH.
Information we track per tunnel.
CadetTunnelEState
All the encryption states a tunnel can be in.
@ CADET_TUNNEL_KEY_AX_AUTH_SENT
KX received and we sent KX_AUTH back, but we got no traffic yet, so we're waiting for either KX_AUTH ...
@ CADET_TUNNEL_KEY_AX_SENT
KX message sent, waiting for other peer's KX_AUTH.
@ CADET_TUNNEL_KEY_UNINITIALIZED
Uninitialized status, we need to send KX.
@ CADET_TUNNEL_KEY_AX_SENT_AND_RECV
KX message sent and received, trying to send back KX_AUTH.
@ CADET_TUNNEL_KEY_OK
Handshake completed: session key available.
@ CADET_TUNNEL_KEY_AX_RECV
KX message received, trying to send back KX_AUTH.
#define DESIRED_CONNECTIONS_PER_TUNNEL
How many connections would we like to have per tunnel?
void(* GCT_ConnectionIterator)(void *cls, struct CadetTConnection *ct)
Iterator over connections.
void(* GCT_SendContinuation)(void *cls, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid)
Function called when a transmission requested using GCT_send is done.
void(* GCT_ChannelIterator)(void *cls, struct CadetChannel *ch)
Iterator over channels.
static struct GNUNET_PeerIdentity my_identity
Identity of this peer.
#define N
static struct GNUNET_PeerIdentity pid
Identity of the peer we transmit to / connect to.
static struct GNUNET_Process * p
Helper process we started.
Definition gnunet-uri.c:38
static struct GNUNET_STATISTICS_Handle * stats
Handle to the statistics service.
commonly used definitions; globals in this file are exempt from the rule that the module name ("commo...
struct GNUNET_PILS_Operation * GNUNET_PILS_ecdh(struct GNUNET_PILS_Handle *handle, const struct GNUNET_CRYPTO_EcdhePublicKey *pub, GNUNET_PILS_EcdhResultCallback cb, void *cb_cls)
Derive key material from a ECDH public key and our private key.
Definition pils_api.c:595
void GNUNET_PILS_cancel(struct GNUNET_PILS_Operation *op)
Cancel request.
Definition pils_api.c:623
const struct GNUNET_PeerIdentity * GNUNET_PILS_get_identity(const struct GNUNET_PILS_Handle *handle)
Return the current peer identity of a given handle.
Definition pils_api.c:727
API to schedule computations using continuation passing style.
API to create, modify and access statistics.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_ecc_ecdh(const struct GNUNET_CRYPTO_EcdhePrivateKey *priv, const struct GNUNET_CRYPTO_EcdhePublicKey *pub, struct GNUNET_HashCode *key_material)
Derive key material from a public and a private ECC key.
Definition crypto_ecc.c:732
void GNUNET_CRYPTO_ecdhe_key_create(struct GNUNET_CRYPTO_EcdhePrivateKey *pk)
Create a new private key.
Definition crypto_ecc.c:454
ssize_t GNUNET_CRYPTO_symmetric_encrypt(const void *block, size_t size, const struct GNUNET_CRYPTO_SymmetricSessionKey *sessionkey, const struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, void *result)
Encrypt a block using a symmetric sessionkey.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_ecdh_eddsa(const struct GNUNET_CRYPTO_EcdhePrivateKey *priv, const struct GNUNET_CRYPTO_EddsaPublicKey *pub, struct GNUNET_HashCode *key_material)
Derive key material from a EdDSA public key and a private ECDH key.
Definition crypto_ecc.c:823
void GNUNET_CRYPTO_ecdhe_key_clear(struct GNUNET_CRYPTO_EcdhePrivateKey *pk)
Clear memory that was used to store a private key.
Definition crypto_ecc.c:433
void GNUNET_CRYPTO_ecdhe_key_get_public(const struct GNUNET_CRYPTO_EcdhePrivateKey *priv, struct GNUNET_CRYPTO_EcdhePublicKey *pub)
Extract the public key for the given private key.
Definition crypto_ecc.c:217
ssize_t GNUNET_CRYPTO_symmetric_decrypt(const void *block, size_t size, const struct GNUNET_CRYPTO_SymmetricSessionKey *sessionkey, const struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, void *result)
Decrypt a given block using a symmetric sessionkey.
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition crypto_hash.c:41
void GNUNET_CRYPTO_hmac(const struct GNUNET_CRYPTO_AuthKey *key, const void *plaintext, size_t plaintext_len, struct GNUNET_HashCode *hmac)
Calculate HMAC of a message (RFC 2104)
#define GNUNET_CRYPTO_hkdf_gnunet(result, out_len, xts, xts_len, skm, skm_len,...)
A peculiar HKDF instantiation that tried to mimic Truncated NMAC.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap32_put(struct GNUNET_CONTAINER_MultiHashMap32 *map, uint32_t key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
struct GNUNET_CONTAINER_MultiHashMap32 * GNUNET_CONTAINER_multihashmap32_create(unsigned int len)
Create a 32-bit key multi hash map.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap32_remove(struct GNUNET_CONTAINER_MultiHashMap32 *map, uint32_t key, const void *value)
Remove the given key-value pair from the map.
unsigned int GNUNET_CONTAINER_multihashmap32_size(const struct GNUNET_CONTAINER_MultiHashMap32 *map)
Get the number of key-value pairs in the map.
void * GNUNET_CONTAINER_multihashmap32_get(const struct GNUNET_CONTAINER_MultiHashMap32 *map, uint32_t key)
Given a key find a value in the map matching the key.
void GNUNET_CONTAINER_multihashmap32_destroy(struct GNUNET_CONTAINER_MultiHashMap32 *map)
Destroy a 32-bit key hash map.
int GNUNET_CONTAINER_multihashmap32_iterate(struct GNUNET_CONTAINER_MultiHashMap32 *map, GNUNET_CONTAINER_MultiHashMapIterator32Callback it, void *it_cls)
Iterate over all entries in the map.
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY
There must only be one value per key; storing a value should fail if a value under the same key alrea...
uint64_t GNUNET_CONTAINER_HeapCostType
Cost by which elements in a heap can be ordered.
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
#define GNUNET_MAX(a, b)
#define GNUNET_CRYPTO_kdf_arg_string(d)
int GNUNET_get_log_call_status(int caller_level, const char *comp, const char *file, const char *function, int line)
Decides whether a particular logging call should or should not be allowed to be made.
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
#define GNUNET_ALIGN
gcc-ism to force alignment; we use this to align char-arrays that may then be cast to 'struct's.
#define GNUNET_CRYPTO_kdf_arg_auto(d)
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
GNUNET_GenericReturnValue
Named constants for return values.
#define GNUNET_MIN(a, b)
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
GNUNET_ErrorType
Types of errors.
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
const char * GNUNET_e2s(const struct GNUNET_CRYPTO_EcdhePublicKey *p)
Convert a public key value to a string (for printing debug messages).
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
const char * GNUNET_sh2s(const struct GNUNET_ShortHashCode *shc)
Convert a short hash value to a string (for printing debug messages).
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_BULK
@ GNUNET_ERROR_TYPE_DEBUG
int GNUNET_snprintf(char *buf, size_t size, const char *format,...) __attribute__((format(printf
Like snprintf, just aborts if the buffer is of insufficient size.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
GNUNET_MQ_Error
Error codes for the queue.
struct GNUNET_MQ_Handle * GNUNET_MQ_queue_for_callbacks(GNUNET_MQ_SendImpl send, GNUNET_MQ_DestroyImpl destroy, GNUNET_MQ_CancelImpl cancel, void *impl_state, const struct GNUNET_MQ_MessageHandler *handlers, GNUNET_MQ_ErrorHandler error_handler, void *cls)
Create a message queue for the specified handlers.
Definition mq.c:482
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
void GNUNET_MQ_discard(struct GNUNET_MQ_Envelope *mqm)
Discard the message queue message, free all allocated resources.
Definition mq.c:285
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct.
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
void GNUNET_MQ_inject_message(struct GNUNET_MQ_Handle *mq, const struct GNUNET_MessageHeader *mh)
Call the message message handler that was registered for the type of the given message in the given m...
Definition mq.c:187
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
#define GNUNET_MQ_hd_fixed_size(name, code, str, ctx)
void GNUNET_MQ_destroy(struct GNUNET_MQ_Handle *mq)
Destroy the message queue.
Definition mq.c:700
#define GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN
Ask the cadet service to create a new channel.
#define GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX
Axolotl key exchange.
#define GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA_ACK
Confirm payload data end-to-end.
#define GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA
Payload data (inside an encrypted tunnel).
#define GNUNET_MESSAGE_TYPE_CADET_CHANNEL_KEEPALIVE
Announce connection is still alive (direction sensitive).
#define GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX_AUTH
Axolotl key exchange response with authentication.
#define GNUNET_MESSAGE_TYPE_CADET_TUNNEL_ENCRYPTED
Axolotl encrypted data.
#define GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY
Ask the cadet service to destroy a channel.
#define GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK
Confirm the creation of a channel.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_at(struct GNUNET_TIME_Absolute at, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run at the specified time.
Definition scheduler.c:1260
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition scheduler.c:986
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition scheduler.c:1310
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition scheduler.c:1283
enum GNUNET_GenericReturnValue GNUNET_MST_from_buffer(struct GNUNET_MessageStreamTokenizer *mst, const char *buf, size_t size, int purge, int one_shot)
Add incoming data to the receive buffer and call the callback for all complete messages.
Definition mst.c:101
struct GNUNET_MessageStreamTokenizer * GNUNET_MST_create(GNUNET_MessageTokenizerCallback cb, void *cb_cls)
Create a message stream tokenizer.
Definition mst.c:86
void GNUNET_MST_destroy(struct GNUNET_MessageStreamTokenizer *mst)
Destroys a tokenizer.
Definition mst.c:404
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_duration(struct GNUNET_TIME_Absolute whence)
Get the duration of an operation as the difference of the current time and the given start time "henc...
Definition time.c:438
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_remaining(struct GNUNET_TIME_Absolute future)
Given a timestamp in the future, how much time remains until then?
Definition time.c:406
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition time.c:111
#define GNUNET_TIME_UNIT_MINUTES
One minute.
struct GNUNET_TIME_Absolute GNUNET_TIME_relative_to_absolute(struct GNUNET_TIME_Relative rel)
Convert relative time to an absolute time in the future.
Definition time.c:316
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_add(struct GNUNET_TIME_Absolute start, struct GNUNET_TIME_Relative duration)
Add a given relative duration to the given start time.
Definition time.c:452
#define GNUNET_TIME_STD_BACKOFF(r)
Perform our standard exponential back-off calculation, starting at 1 ms and then going by a factor of...
static unsigned int size
Size of the "table".
Definition peer.c:68
Struct containing all information regarding a channel to a remote client.
struct GNUNET_CADET_ChannelTunnelNumber ctn
Number identifying this channel in its tunnel.
Performance metrics for a connection.
unsigned long long num_acked_transmissions
How many packets that ought to generate an ACK did we send via this connection?
struct GNUNET_TIME_Absolute age
When was this connection first established? (by us sending or receiving the CREATE_ACK for the first ...
unsigned long long num_successes
Number of packets that were sent via this connection did actually receive an ACK? (Note: ACKs may be ...
struct GNUNET_TIME_Absolute last_use
When was this connection last used? (by us sending or receiving a PAYLOAD message on it)
Low-level connection to a destination.
struct CadetTConnection * ct
Which tunnel is using this connection?
unsigned int off
Offset of our destination in path.
Information regarding a possible path to reach a peer.
Struct containing all information regarding a given peer.
Entry in list of connections used by tunnel, with metadata.
struct CadetTConnection * next
Next in DLL.
struct CadetConnection * cc
Connection handle.
struct GNUNET_TIME_Absolute created
Creation time, to keep oldest connection alive.
int is_ready
Is the connection currently ready for transmission?
struct CadetTunnel * t
Tunnel this connection belongs to.
Struct used to store data required for an async update AX by KX process.
struct GNUNET_PeerIdentity peer_id
Peer identity of other peer.
uint32_t flags
Flags for the key exchange in NBO, based on enum GNUNET_CADET_KX_Flags.
void * cb_cls
Update callback closure.
struct GNUNET_HashCode auth
KDF-proof that sender could compute the 3-DH, used in lieu of a signature or payload data.
struct CadetTunnelAxolotl ax
Struct used for Axolotl.
struct GNUNET_CRYPTO_EcdhePublicKey ephemeral_key
Ephemeral public key of other key.
struct GNUNET_CRYPTO_EcdhePublicKey ratchet_key
Ratchet key.
struct GNUNET_PILS_Operation * ecdh_op
Operation to derive key material.
CadetTunnelAxolotlCallback cb
Update callback.
Axolotl data, according to https://github.com/trevp/axolotl/wiki .
uint32_t PNs
Previous message numbers (# of msgs sent under prev ratchet)
struct GNUNET_CRYPTO_EcdhePublicKey last_ephemeral
Last ephemeral public key received from the other peer, for duplicate detection.
unsigned int skipped
Number of elements in skipped_head <-> skipped_tail.
struct GNUNET_CRYPTO_SymmetricSessionKey HKs
32-byte header key (currently used for sending).
struct GNUNET_TIME_Absolute ratchet_expiration
Time when the current ratchet expires and a new one is triggered (if ratchet_allowed is GNUNET_YES).
struct GNUNET_CRYPTO_EcdhePrivateKey kx_0
ECDH for key exchange (A0 / B0).
struct GNUNET_CRYPTO_EcdhePublicKey DHRr
ECDH Ratchet key (other peer's public key in the current DH).
uint32_t Ns
Message number (reset to 0 with each new ratchet, next message to send).
struct CadetTunnelSkippedKey * skipped_tail
Skipped messages' keys DLL, tail.
struct CadetTunnelSkippedKey * skipped_head
A (double linked) list of stored message keys and associated header keys for "skipped" messages,...
uint32_t Nr
Message number (reset to 0 with each new ratchet, next message to recv).
struct GNUNET_CRYPTO_SymmetricSessionKey RK
32-byte root key which gets updated by DH ratchet.
int ratchet_allowed
True (GNUNET_YES) if we have received a message from the other peer that uses the keys from our last ...
struct GNUNET_CRYPTO_SymmetricSessionKey HKr
32-byte header key (currently used for receiving)
int ratchet_flag
True (GNUNET_YES) if we have to send a new ratchet key in next msg.
struct GNUNET_CRYPTO_SymmetricSessionKey NHKr
32-byte next header key (for receiving).
struct GNUNET_CRYPTO_SymmetricSessionKey CKs
32-byte chain keys (used for forward-secrecy) for sending messages.
struct GNUNET_CRYPTO_SymmetricSessionKey CKr
32-byte chain keys (used for forward-secrecy) for receiving messages.
unsigned int ratchet_counter
Number of messages received since our last ratchet advance.
struct GNUNET_CRYPTO_EcdhePrivateKey DHRs
ECDH Ratchet key (our private key in the current DH).
struct GNUNET_CRYPTO_SymmetricSessionKey NHKs
32-byte next header key (for sending), used once the ratchet advances.
Struct used to save messages in a non-ready tunnel to send once connected.
struct CadetTunnelQueueEntry * prev
We are entries in a DLL.
struct GNUNET_MQ_Envelope * env
Envelope of message to send follows.
GCT_SendContinuation cont
Continuation to call once sent (on the channel layer).
struct GNUNET_CADET_ConnectionTunnelIdentifier * cid
Where to put the connection identifier into the payload of the message in env once we have it?
struct CadetTunnelQueueEntry * next
We are entries in a DLL.
struct CadetTunnel * t
Tunnel these messages belong in.
Struct to old keys for skipped messages while advancing the Axolotl ratchet.
struct GNUNET_CRYPTO_SymmetricSessionKey MK
Message key.
struct GNUNET_CRYPTO_SymmetricSessionKey HK
Header key.
struct GNUNET_TIME_Absolute timestamp
When was this key stored (for timeout).
unsigned int Kn
Key number for a given HK.
struct CadetTunnelSkippedKey * next
DLL next.
struct CadetTunnelSkippedKey * prev
DLL prev.
Struct containing all information regarding a tunnel to a peer.
struct GNUNET_SCHEDULER_Task * send_task
Task to send messages from queue (if possible).
struct CadetPeer * destination
Destination of the tunnel.
struct CadetTConnection * connection_ready_head
DLL of ready connections that are actively used to reach the destination peer.
struct CadetTunnelAsync as
Structure to store data temporally for async operations.
struct CadetTConnection * current_ct
Identification of the connection from which we are currently processing a message.
struct GNUNET_CRYPTO_SymmetricSessionKey d_key
Decryption ("their") key.
struct CadetTunnelQueueEntry * tq_tail
Queued messages, to transmit once tunnel gets connected.
struct GNUNET_SCHEDULER_Task * maintain_connections_task
Task to trim connections if too many are present.
struct CadetTConnection * connection_busy_head
DLL of connections that we maintain that might be used to reach the destination peer.
struct GNUNET_CRYPTO_SymmetricSessionKey e_key
Encryption ("our") key.
struct GNUNET_TIME_Absolute next_kx_attempt
When do we try the next KX?
struct GNUNET_TIME_Relative kx_retry_delay
How long do we wait until we retry the KX?
struct CadetTConnection * connection_busy_tail
DLL of connections that we maintain that might be used to reach the destination peer.
struct GNUNET_MQ_Handle * mq
Dispatcher for decrypted messages only (do NOT use for sending!).
enum CadetTunnelEState estate
State of the tunnel encryption.
struct GNUNET_CRYPTO_EcdhePublicKey peers_ephemeral_key
Peer's ephemeral key, to recreate e_key and d_key when own ephemeral key changes.
unsigned int num_busy_connections
Number of connections in the connection_busy_head DLL.
struct CadetTunnelAxolotl ax
Axolotl info.
struct GNUNET_CONTAINER_MultiHashMap32 * channels
Channels inside this tunnel.
struct GNUNET_SCHEDULER_Task * destroy_task
Task scheduled if there are no more channels using the tunnel.
struct CadetTConnection * connection_ready_tail
DLL of ready connections that are actively used to reach the destination peer.
struct GNUNET_MessageStreamTokenizer * mst
Tokenizer for decrypted messages.
struct CadetTunnelQueueEntry * tq_head
Queued messages, to transmit once tunnel gets connected.
unsigned int num_ready_connections
Number of connections in the connection_ready_head DLL.
struct GNUNET_SCHEDULER_Task * kx_task
Task to trigger KX.
struct CadetTunnelAxolotl * unverified_ax
Unverified Axolotl info, used only if we got a fresh KX (not a KX_AUTH) while our end of the tunnel w...
unsigned int tq_len
Number of entries in the tq_head DLL.
struct GNUNET_CADET_ChannelTunnelNumber next_ctn
Channel ID for the next created channel in this tunnel.
int kx_auth_requested
Force triggering KX_AUTH independent of estate.
unsigned int unverified_attempts
How often have we tried and failed to decrypt a message using the unverified KX material from unverif...
Closure for iterate_channels_cb.
void * iter_cls
Closure for iter.
GCT_ChannelIterator iter
Function to call.
Closure for evaluate_connection.
unsigned int max_length
Maximum length of any of our connections, 0 if we have none.
int duplicate
Set to GNUNET_YES if we have a connection over path already.
GNUNET_CONTAINER_HeapCostType min_desire
Minimum desirability of any of our connections, UINT64_MAX if we have none.
struct CadetTConnection * worst
Connection deemed the "worst" so far encountered by evaluate_connection, NULL if we did not yet encou...
unsigned int min_length
Minimum length of any of our connections, UINT_MAX if we have none.
GNUNET_CONTAINER_HeapCostType max_desire
Maximum desirability of any of our connections, 0 if we have none.
double worst_score
Numeric score of worst, only set if worst is non-NULL.
struct CadetPeerPath * path
Path we are comparing against for evaluate_connection, can be NULL.
Encrypted axolotl header with numbers that identify which keys in which ratchet are to be used to dec...
uint32_t PNs
Number of messages sent with the previous ratchet key.
struct GNUNET_CRYPTO_EcdhePublicKey DHRs
Current ratchet key.
uint32_t Ns
Number of messages sent with the current ratchet key.
Message for cadet data traffic.
Message to acknowledge end-to-end data.
struct GNUNET_CADET_ChannelTunnelNumber ctn
ID of the channel.
Message to destroy a channel of type GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY.
struct GNUNET_CADET_ChannelTunnelNumber ctn
ID of the channel.
Message to acknowledge opening a channel of type GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK.
struct GNUNET_HashCode port
Port number of the channel, used to prove to the initiator that the receiver knows the port.
struct GNUNET_CADET_ChannelTunnelNumber ctn
ID of the channel.
Message to create a Channel.
struct GNUNET_HashCode h_port
Hash of destination port and listener.
struct GNUNET_CADET_ChannelTunnelNumber ctn
ID of the channel within the tunnel.
uint32_t opt
Channel options.
Number identifying a CADET channel within a tunnel.
uint32_t cn
Which number does this channel have that uniquely identifies it within its tunnel,...
Hash uniquely identifying a connection below a tunnel.
Axolotl-encrypted tunnel message with application payload.
struct GNUNET_CADET_AxHeader ax_header
Axolotl-header that specifies which keys to use in which ratchet to decrypt the body that follows.
struct GNUNET_CADET_ConnectionTunnelIdentifier cid
ID of the connection.
struct GNUNET_ShortHashCode hmac
MAC of the encrypted message, used to verify message integrity.
Message for a Key eXchange for a tunnel, with authentication.
Message for a Key eXchange for a tunnel.
uint32_t flags
Flags for the key exchange in NBO, based on enum GNUNET_CADET_KX_Flags.
Internal representation of the hash map.
type for (message) authentication keys
Private ECC key encoded for transmission.
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and encr...
A 512-bit hashcode.
Handle to a message queue.
Definition mq.c:87
Message handler for a specific message type.
Header for all communications.
Handle to a message stream tokenizer.
Definition mst.c:45
The identity of the host (wraps the signing key of the peer).
struct GNUNET_CRYPTO_EddsaPublicKey public_key
Entry in list of pending tasks.
Definition scheduler.c:141
A 256-bit hashcode.
Time for absolute times used by GNUnet, in microseconds.
Time for relative time used by GNUnet, in microseconds.
uint64_t rel_value_us
The actual value.