GNUnet  0.17.6
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 "platform.h"
34 #include "gnunet_util_lib.h"
36 #include "gnunet_signatures.h"
37 #include "cadet_protocol.h"
43 
44 
45 #define LOG(level, ...) GNUNET_log_from (level, "cadet-tun", __VA_ARGS__)
46 
52 #define MAX_UNVERIFIED_ATTEMPTS 16
53 
57 #define IDLE_DESTROY_DELAY GNUNET_TIME_relative_multiply ( \
58  GNUNET_TIME_UNIT_SECONDS, 90)
59 
64 #define INITIAL_KX_RETRY_DELAY GNUNET_TIME_relative_multiply ( \
65  GNUNET_TIME_UNIT_MILLISECONDS, 250)
66 
70 #define MAX_SKIPPED_KEYS 64
71 
76 #define MAX_KEY_GAP 256
77 
78 
83 {
88 
93 
98 
103 
108 
112  unsigned int Kn;
113 };
114 
115 
120 {
127 
132 
137 
142 
147 
154 
161 
167 
175 
180 
185 
190 
196 
202 
206  unsigned int skipped;
207 
211  uint32_t Ns;
212 
216  uint32_t Nr;
217 
221  uint32_t PNs;
222 
227 
239 
252  unsigned int ratchet_counter;
253 };
254 
255 
260 {
265 
270 
274  struct CadetTunnel *t;
275 
280 
284  void *cont_cls;
285 
290 
296 };
297 
298 
303 {
308 
314 
319 
324 
328  struct CadetTunnelAxolotl ax;
329 
338 
343 
348 
353 
358 
363 
368 
373 
378 
383 
388 
394 
399 
404 
409 
416 
421 
426 
430  unsigned int num_ready_connections;
431 
435  unsigned int num_busy_connections;
436 
442  unsigned int unverified_attempts;
443 
447  unsigned int tq_len;
448 
453 
458 };
459 
460 
467 int
469 {
470  if (0 > GNUNET_memcmp (&my_full_id,
471  other))
472  return GNUNET_YES;
473  else if (0 < GNUNET_memcmp (&my_full_id,
474  other))
475  return GNUNET_NO;
476  else
477  {
478  GNUNET_break_op (0);
479  return GNUNET_SYSERR;
480  }
481 }
482 
483 
490 static void
492 {
493  struct CadetTunnel *t = ct->t;
494 
496  GNUNET_CONTAINER_DLL_remove (t->connection_ready_head,
497  t->connection_ready_tail,
498  ct);
499  GNUNET_assert (0 < t->num_ready_connections);
500  t->num_ready_connections--;
501  ct->is_ready = GNUNET_NO;
502  GNUNET_CONTAINER_DLL_insert (t->connection_busy_head,
503  t->connection_busy_tail,
504  ct);
505  t->num_busy_connections++;
506 }
507 
508 
516 const char *
517 GCT_2s (const struct CadetTunnel *t)
518 {
519  static char buf[64];
520 
521  if (NULL == t)
522  return "Tunnel(NULL)";
524  sizeof(buf),
525  "Tunnel %s",
526  GNUNET_i2s (GCP_get_id (t->destination)));
527  return buf;
528 }
529 
530 
538 static const char *
540 {
541  static char buf[32];
542 
543  switch (es)
544  {
546  return "CADET_TUNNEL_KEY_UNINITIALIZED";
548  return "CADET_TUNNEL_KEY_AX_RECV";
550  return "CADET_TUNNEL_KEY_AX_SENT";
552  return "CADET_TUNNEL_KEY_AX_SENT_AND_RECV";
554  return "CADET_TUNNEL_KEY_AX_AUTH_SENT";
555  case CADET_TUNNEL_KEY_OK:
556  return "CADET_TUNNEL_KEY_OK";
557  }
559  sizeof(buf),
560  "%u (UNKNOWN STATE)",
561  es);
562  return buf;
563 }
564 
565 
572 struct CadetPeer *
574 {
575  return t->destination;
576 }
577 
578 
579 unsigned int
581 {
582  return GNUNET_CONTAINER_multihashmap32_size (t->channels);
583 }
584 
585 
593 struct CadetChannel *
596 {
597  return GNUNET_CONTAINER_multihashmap32_get (t->channels,
598  ntohl (ctn.cn));
599 }
600 
601 
602 unsigned int
604 {
605  return t->num_ready_connections + t->num_busy_connections;
606 }
607 
608 
616 static struct CadetTConnection *
618 {
619  struct CadetTConnection *hd = t->connection_ready_head;
620 
621  GNUNET_assert ((NULL == hd) ||
622  (GNUNET_YES == hd->is_ready));
623  return hd;
624 }
625 
626 
635 GCT_get_estate (struct CadetTunnel *t)
636 {
637  return t->estate;
638 }
639 
640 
649 static void
650 trigger_transmissions (void *cls);
651 
652 
653 /* ************************************** start core crypto ***************************** */
654 
655 
661 static void
663 {
665  "Creating new ephemeral ratchet key (DHRs)\n");
667 }
668 
669 
679 static void
680 t_hmac (const void *plaintext,
681  size_t size,
682  uint32_t iv,
684  struct GNUNET_ShortHashCode *hmac)
685 {
686  static const char ctx[] = "cadet authentication key";
687  struct GNUNET_CRYPTO_AuthKey auth_key;
688  struct GNUNET_HashCode hash;
689 
691  key,
692  &iv, sizeof(iv),
693  key, sizeof(*key),
694  ctx, sizeof(ctx),
695  NULL);
696  /* Two step: GNUNET_ShortHash is only 256 bits,
697  GNUNET_HashCode is 512, so we truncate. */
698  GNUNET_CRYPTO_hmac (&auth_key,
699  plaintext,
700  size,
701  &hash);
702  GNUNET_memcpy (hmac,
703  &hash,
704  sizeof(*hmac));
705 }
706 
707 
716 static void
718  struct GNUNET_HashCode *hash,
719  const void *source,
720  unsigned int len)
721 {
722  static const char ctx[] = "axolotl HMAC-HASH";
723  struct GNUNET_CRYPTO_AuthKey auth_key;
724 
726  key,
727  ctx, sizeof(ctx),
728  NULL);
729  GNUNET_CRYPTO_hmac (&auth_key,
730  source,
731  len,
732  hash);
733 }
734 
735 
744 static void
747  const void *source,
748  unsigned int len)
749 {
750  static const char ctx[] = "axolotl derive key";
751  struct GNUNET_HashCode h;
752 
754  &h,
755  source,
756  len);
757  GNUNET_CRYPTO_kdf (out, sizeof(*out),
758  ctx, sizeof(ctx),
759  &h, sizeof(h),
760  NULL);
761 }
762 
763 
772 static void
774  void *dst,
775  const void *src,
776  size_t size)
777 {
780  size_t out_size;
781 
782  ax->ratchet_counter++;
783  if ((GNUNET_YES == ax->ratchet_allowed) &&
784  ((ratchet_messages <= ax->ratchet_counter) ||
787  {
788  ax->ratchet_flag = GNUNET_YES;
789  }
790  if (GNUNET_YES == ax->ratchet_flag)
791  {
792  /* Advance ratchet */
793  struct GNUNET_CRYPTO_SymmetricSessionKey keys[3];
794  struct GNUNET_HashCode dh;
795  struct GNUNET_HashCode hmac;
796  static const char ctx[] = "axolotl ratchet";
797 
798  new_ephemeral (ax);
799  ax->HKs = ax->NHKs;
800 
801  /* RK, NHKs, CKs = KDF( HMAC-HASH(RK, DH(DHRs, DHRr)) ) */
803  &ax->DHRr,
804  &dh);
805  t_ax_hmac_hash (&ax->RK,
806  &hmac,
807  &dh,
808  sizeof(dh));
809  GNUNET_CRYPTO_kdf (keys, sizeof(keys),
810  ctx, sizeof(ctx),
811  &hmac, sizeof(hmac),
812  NULL);
813  ax->RK = keys[0];
814  ax->NHKs = keys[1];
815  ax->CKs = keys[2];
816 
817  ax->PNs = ax->Ns;
818  ax->Ns = 0;
819  ax->ratchet_flag = GNUNET_NO;
821  ax->ratchet_counter = 0;
824  ratchet_time);
825  }
826 
827  t_hmac_derive_key (&ax->CKs,
828  &MK,
829  "0",
830  1);
832  &MK,
833  NULL, 0,
834  NULL);
835 
836  out_size = GNUNET_CRYPTO_symmetric_encrypt (src,
837  size,
838  &MK,
839  &iv,
840  dst);
841  GNUNET_assert (size == out_size);
842  t_hmac_derive_key (&ax->CKs,
843  &ax->CKs,
844  "1",
845  1);
846 }
847 
848 
857 static void
859  void *dst,
860  const void *src,
861  size_t size)
862 {
865  size_t out_size;
866 
867  t_hmac_derive_key (&ax->CKr,
868  &MK,
869  "0",
870  1);
872  &MK,
873  NULL, 0,
874  NULL);
875  GNUNET_assert (size >= sizeof(struct GNUNET_MessageHeader));
876  out_size = GNUNET_CRYPTO_symmetric_decrypt (src,
877  size,
878  &MK,
879  &iv,
880  dst);
881  GNUNET_assert (out_size == size);
882  t_hmac_derive_key (&ax->CKr,
883  &ax->CKr,
884  "1",
885  1);
886 }
887 
888 
895 static void
898 {
900  size_t out_size;
901 
903  &ax->HKs,
904  NULL, 0,
905  NULL);
906  out_size = GNUNET_CRYPTO_symmetric_encrypt (&msg->ax_header,
907  sizeof(struct
909  &ax->HKs,
910  &iv,
911  &msg->ax_header);
912  GNUNET_assert (sizeof(struct GNUNET_CADET_AxHeader) == out_size);
913 }
914 
915 
923 static void
925  const struct GNUNET_CADET_TunnelEncryptedMessage *src,
927 {
929  size_t out_size;
930 
932  &ax->HKr,
933  NULL, 0,
934  NULL);
935  out_size = GNUNET_CRYPTO_symmetric_decrypt (&src->ax_header.Ns,
936  sizeof(struct
938  &ax->HKr,
939  &iv,
940  &dst->ax_header.Ns);
941  GNUNET_assert (sizeof(struct GNUNET_CADET_AxHeader) == out_size);
942 }
943 
944 
951 static void
953  struct CadetTunnelSkippedKey *key)
954 {
956  ax->skipped_tail,
957  key);
958  GNUNET_free (key);
959  ax->skipped--;
960 }
961 
962 
973 static ssize_t
975  void *dst,
976  const struct GNUNET_CADET_TunnelEncryptedMessage *src,
977  size_t size)
978 {
979  struct CadetTunnelSkippedKey *key;
980  struct GNUNET_ShortHashCode *hmac;
982  struct GNUNET_CADET_TunnelEncryptedMessage plaintext_header;
983  struct GNUNET_CRYPTO_SymmetricSessionKey *valid_HK;
984  size_t esize;
985  size_t res;
986  size_t len;
987  unsigned int N;
988 
990  "Trying skipped keys\n");
991  hmac = &plaintext_header.hmac;
992  esize = size - sizeof(struct GNUNET_CADET_TunnelEncryptedMessage);
993 
994  /* Find a correct Header Key */
995  valid_HK = NULL;
996  for (key = ax->skipped_head; NULL != key; key = key->next)
997  {
998  t_hmac (&src->ax_header,
999  sizeof(struct GNUNET_CADET_AxHeader) + esize,
1000  0,
1001  &key->HK,
1002  hmac);
1003  if (0 == GNUNET_memcmp (hmac,
1004  &src->hmac))
1005  {
1006  valid_HK = &key->HK;
1007  break;
1008  }
1009  }
1010  if (NULL == key)
1011  return -1;
1012 
1013  /* Should've been checked in -cadet_connection.c handle_cadet_encrypted. */
1015  len = size - sizeof(struct GNUNET_CADET_TunnelEncryptedMessage);
1016  GNUNET_assert (len >= sizeof(struct GNUNET_MessageHeader));
1017 
1018  /* Decrypt header */
1020  &key->HK,
1021  NULL, 0,
1022  NULL);
1024  sizeof(struct GNUNET_CADET_AxHeader),
1025  &key->HK,
1026  &iv,
1027  &plaintext_header.ax_header.Ns);
1028  GNUNET_assert (sizeof(struct GNUNET_CADET_AxHeader) == res);
1029 
1030  /* Find the correct message key */
1031  N = ntohl (plaintext_header.ax_header.Ns);
1032  while ((NULL != key) &&
1033  (N != key->Kn))
1034  key = key->next;
1035  if ((NULL == key) ||
1036  (0 != GNUNET_memcmp (&key->HK,
1037  valid_HK)))
1038  return -1;
1039 
1040  /* Decrypt payload */
1042  &key->MK,
1043  NULL,
1044  0,
1045  NULL);
1047  len,
1048  &key->MK,
1049  &iv,
1050  dst);
1051  delete_skipped_key (ax,
1052  key);
1053  return res;
1054 }
1055 
1056 
1063 static void
1065  const struct GNUNET_CRYPTO_SymmetricSessionKey *HKr)
1066 {
1067  struct CadetTunnelSkippedKey *key;
1068 
1070  key->timestamp = GNUNET_TIME_absolute_get ();
1071  key->Kn = ax->Nr;
1072  key->HK = ax->HKr;
1073  t_hmac_derive_key (&ax->CKr,
1074  &key->MK,
1075  "0",
1076  1);
1077  t_hmac_derive_key (&ax->CKr,
1078  &ax->CKr,
1079  "1",
1080  1);
1082  ax->skipped_tail,
1083  key);
1084  ax->skipped++;
1085  ax->Nr++;
1086 }
1087 
1088 
1099 static int
1101  const struct GNUNET_CRYPTO_SymmetricSessionKey *HKr,
1102  uint32_t Np)
1103 {
1104  int gap;
1105 
1106  gap = Np - ax->Nr;
1108  "Storing skipped keys [%u, %u)\n",
1109  ax->Nr,
1110  Np);
1111  if (MAX_KEY_GAP < gap)
1112  {
1113  /* Avoid DoS (forcing peer to do more than #MAX_KEY_GAP HMAC operations) */
1114  /* TODO: start new key exchange on return */
1115  GNUNET_break_op (0);
1117  "Got message %u, expected %u+\n",
1118  Np,
1119  ax->Nr);
1120  return GNUNET_SYSERR;
1121  }
1122  if (0 > gap)
1123  {
1124  /* Delayed message: don't store keys, flag to try old keys. */
1125  return GNUNET_SYSERR;
1126  }
1127 
1128  while (ax->Nr < Np)
1129  store_skipped_key (ax,
1130  HKr);
1131 
1132  while (ax->skipped > MAX_SKIPPED_KEYS)
1133  delete_skipped_key (ax,
1134  ax->skipped_tail);
1135  return GNUNET_OK;
1136 }
1137 
1138 
1149 static ssize_t
1151  void *dst,
1152  const struct
1154  size_t size)
1155 {
1156  struct GNUNET_ShortHashCode msg_hmac;
1157  struct GNUNET_HashCode hmac;
1158  struct GNUNET_CADET_TunnelEncryptedMessage plaintext_header;
1159  uint32_t Np;
1160  uint32_t PNp;
1161  size_t esize; /* Size of encryped payload */
1162 
1163  esize = size - sizeof(struct GNUNET_CADET_TunnelEncryptedMessage);
1164 
1165  /* Try current HK */
1166  t_hmac (&src->ax_header,
1167  sizeof(struct GNUNET_CADET_AxHeader) + esize,
1168  0, &ax->HKr,
1169  &msg_hmac);
1170  if (0 != GNUNET_memcmp (&msg_hmac,
1171  &src->hmac))
1172  {
1173  static const char ctx[] = "axolotl ratchet";
1174  struct GNUNET_CRYPTO_SymmetricSessionKey keys[3]; /* RKp, NHKp, CKp */
1176  struct GNUNET_HashCode dh;
1177  struct GNUNET_CRYPTO_EcdhePublicKey *DHRp;
1178 
1179  /* Try Next HK */
1180  t_hmac (&src->ax_header,
1181  sizeof(struct GNUNET_CADET_AxHeader) + esize,
1182  0,
1183  &ax->NHKr,
1184  &msg_hmac);
1185  if (0 != GNUNET_memcmp (&msg_hmac,
1186  &src->hmac))
1187  {
1188  /* Try the skipped keys, if that fails, we're out of luck. */
1189  return try_old_ax_keys (ax,
1190  dst,
1191  src,
1192  size);
1193  }
1194  HK = ax->HKr;
1195  ax->HKr = ax->NHKr;
1196  t_h_decrypt (ax,
1197  src,
1198  &plaintext_header);
1199  Np = ntohl (plaintext_header.ax_header.Ns);
1200  PNp = ntohl (plaintext_header.ax_header.PNs);
1201  DHRp = &plaintext_header.ax_header.DHRs;
1202  store_ax_keys (ax,
1203  &HK,
1204  PNp);
1205 
1206  /* RKp, NHKp, CKp = KDF (HMAC-HASH (RK, DH (DHRp, DHRs))) */
1208  DHRp,
1209  &dh);
1210  t_ax_hmac_hash (&ax->RK,
1211  &hmac,
1212  &dh, sizeof(dh));
1213  GNUNET_CRYPTO_kdf (keys, sizeof(keys),
1214  ctx, sizeof(ctx),
1215  &hmac, sizeof(hmac),
1216  NULL);
1217 
1218  /* Commit "purported" keys */
1219  ax->RK = keys[0];
1220  ax->NHKr = keys[1];
1221  ax->CKr = keys[2];
1222  ax->DHRr = *DHRp;
1223  ax->Nr = 0;
1225  }
1226  else
1227  {
1228  t_h_decrypt (ax,
1229  src,
1230  &plaintext_header);
1231  Np = ntohl (plaintext_header.ax_header.Ns);
1232  PNp = ntohl (plaintext_header.ax_header.PNs);
1233  }
1234  if ((Np != ax->Nr) &&
1235  (GNUNET_OK != store_ax_keys (ax,
1236  &ax->HKr,
1237  Np)))
1238  {
1239  /* Try the skipped keys, if that fails, we're out of luck. */
1240  return try_old_ax_keys (ax,
1241  dst,
1242  src,
1243  size);
1244  }
1245 
1246  t_ax_decrypt (ax,
1247  dst,
1248  &src[1],
1249  esize);
1250  ax->Nr = Np + 1;
1251  return esize;
1252 }
1253 
1254 
1264 static int
1266  uint32_t key,
1267  void *value)
1268 {
1269  struct CadetChannel *ch = value;
1270 
1271  GCCH_tunnel_up (ch);
1272  return GNUNET_OK;
1273 }
1274 
1275 
1283 void
1285  enum CadetTunnelEState state)
1286 {
1287  enum CadetTunnelEState old = t->estate;
1288 
1289  t->estate = state;
1291  "%s estate changed from %s to %s\n",
1292  GCT_2s (t),
1293  estate2s (old),
1294  estate2s (state));
1295 
1296  if ((CADET_TUNNEL_KEY_OK != old) &&
1297  (CADET_TUNNEL_KEY_OK == t->estate))
1298  {
1299  if (NULL != t->kx_task)
1300  {
1301  GNUNET_SCHEDULER_cancel (t->kx_task);
1302  t->kx_task = NULL;
1303  }
1304  /* notify all channels that have been waiting */
1307  t);
1308  if (NULL != t->send_task)
1309  GNUNET_SCHEDULER_cancel (t->send_task);
1311  t);
1312  }
1313 }
1314 
1315 
1324 static void
1326  struct CadetTConnection *ct,
1327  struct CadetTunnelAxolotl *ax)
1328 {
1329  struct CadetConnection *cc;
1330  struct GNUNET_MQ_Envelope *env;
1333 
1334  if (GNUNET_YES != GCT_alice_or_betty (GCP_get_id (t->destination)))
1335  return; /* only Alice may send KX */
1336  if ((NULL == ct) ||
1337  (GNUNET_NO == ct->is_ready))
1338  ct = get_ready_connection (t);
1339  if (NULL == ct)
1340  {
1342  "Wanted to send %s in state %s, but no connection is ready, deferring\n",
1343  GCT_2s (t),
1344  estate2s (t->estate));
1345  t->next_kx_attempt = GNUNET_TIME_absolute_get ();
1346  return;
1347  }
1348  cc = ct->cc;
1349  env = GNUNET_MQ_msg (msg,
1351  flags = GNUNET_CADET_KX_FLAG_FORCE_REPLY; /* always for KX */
1352  msg->flags = htonl (flags);
1353  msg->cid = *GCC_get_id (cc);
1355  &msg->ephemeral_key);
1356 #if DEBUG_KX
1357  msg->ephemeral_key_XXX = ax->kx_0;
1358  msg->private_key_XXX = *my_private_key;
1359 #endif
1361  "Sending KX message to %s with ephemeral %s on CID %s\n",
1362  GCT_2s (t),
1363  GNUNET_e2s (&msg->ephemeral_key),
1364  GNUNET_sh2s (&msg->cid.connection_of_tunnel));
1366  &msg->ratchet_key);
1368  t->kx_retry_delay = GNUNET_TIME_STD_BACKOFF (t->kx_retry_delay);
1369  t->next_kx_attempt = GNUNET_TIME_relative_to_absolute (t->kx_retry_delay);
1370  if (CADET_TUNNEL_KEY_UNINITIALIZED == t->estate)
1373  else if (CADET_TUNNEL_KEY_AX_RECV == t->estate)
1376  GCC_transmit (cc,
1377  env);
1379  "# KX transmitted",
1380  1,
1381  GNUNET_NO);
1382 }
1383 
1384 
1395 static void
1397  struct CadetTConnection *ct,
1398  struct CadetTunnelAxolotl *ax,
1399  int force_reply)
1400 {
1401  struct CadetConnection *cc;
1402  struct GNUNET_MQ_Envelope *env;
1404  enum GNUNET_CADET_KX_Flags flags;
1405 
1406  if ((NULL == ct) ||
1407  (GNUNET_NO == ct->is_ready))
1408  ct = get_ready_connection (t);
1409  if (NULL == ct)
1410  {
1412  "Wanted to send KX_AUTH on %s, but no connection is ready, deferring\n",
1413  GCT_2s (t));
1414  t->next_kx_attempt = GNUNET_TIME_absolute_get ();
1415  t->kx_auth_requested = GNUNET_YES; /* queue KX_AUTH independent of estate */
1416  return;
1417  }
1418  t->kx_auth_requested = GNUNET_NO; /* clear flag */
1419  cc = ct->cc;
1420  env = GNUNET_MQ_msg (msg,
1422  flags = GNUNET_CADET_KX_FLAG_NONE;
1423  if (GNUNET_YES == force_reply)
1425  msg->kx.flags = htonl (flags);
1426  msg->kx.cid = *GCC_get_id (cc);
1428  &msg->kx.ephemeral_key);
1430  &msg->kx.ratchet_key);
1431 #if DEBUG_KX
1432  msg->kx.ephemeral_key_XXX = ax->kx_0;
1433  msg->kx.private_key_XXX = *my_private_key;
1434  msg->r_ephemeral_key_XXX = ax->last_ephemeral;
1435 #endif
1437  "Sending KX_AUTH message to %s with ephemeral %s on CID %s\n",
1438  GCT_2s (t),
1439  GNUNET_e2s (&msg->kx.ephemeral_key),
1440  GNUNET_sh2s (&msg->kx.cid.connection_of_tunnel));
1441 
1442  /* Compute authenticator (this is the main difference to #send_kx()) */
1443  GNUNET_CRYPTO_hash (&ax->RK,
1444  sizeof(ax->RK),
1445  &msg->auth);
1446  /* Compute when to be triggered again; actual job will
1447  be scheduled via #connection_ready_cb() */
1448  t->kx_retry_delay
1449  = GNUNET_TIME_STD_BACKOFF (t->kx_retry_delay);
1450  t->next_kx_attempt
1451  = GNUNET_TIME_relative_to_absolute (t->kx_retry_delay);
1452 
1453  /* Send via cc, mark it as unready */
1455 
1456  /* Update state machine, unless we are already OK */
1457  if (CADET_TUNNEL_KEY_OK != t->estate)
1460  GCC_transmit (cc,
1461  env);
1463  "# KX_AUTH transmitted",
1464  1,
1465  GNUNET_NO);
1466 }
1467 
1468 
1474 static void
1476 {
1477  while (NULL != ax->skipped_head)
1478  delete_skipped_key (ax,
1479  ax->skipped_head);
1480  GNUNET_assert (0 == ax->skipped);
1483 }
1484 
1485 
1499 static int
1501  const struct GNUNET_PeerIdentity *pid,
1502  const struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral_key,
1503  const struct GNUNET_CRYPTO_EcdhePublicKey *ratchet_key)
1504 {
1505  struct GNUNET_HashCode key_material[3];
1506  struct GNUNET_CRYPTO_SymmetricSessionKey keys[5];
1507  const char salt[] = "CADET Axolotl salt";
1508  int am_I_alice;
1509 
1510  if (GNUNET_SYSERR == (am_I_alice = GCT_alice_or_betty (pid)))
1511  {
1512  GNUNET_break_op (0);
1513  return GNUNET_SYSERR;
1514  }
1515  if (0 == GNUNET_memcmp (&ax->DHRr,
1516  ratchet_key))
1517  {
1519  "# Ratchet key already known",
1520  1,
1521  GNUNET_NO);
1523  "Ratchet key already known. Ignoring KX.\n");
1524  return GNUNET_NO;
1525  }
1526 
1527  ax->DHRr = *ratchet_key;
1528  ax->last_ephemeral = *ephemeral_key;
1529  /* ECDH A B0 */
1530  if (GNUNET_YES == am_I_alice)
1531  {
1533  ephemeral_key, /* B0 */
1534  &key_material[0]);
1535  }
1536  else
1537  {
1538  GNUNET_CRYPTO_ecdh_eddsa (&ax->kx_0, /* b0 */
1539  &pid->public_key, /* A */
1540  &key_material[0]);
1541  }
1542  /* ECDH A0 B */
1543  if (GNUNET_YES == am_I_alice)
1544  {
1545  GNUNET_CRYPTO_ecdh_eddsa (&ax->kx_0, /* a0 */
1546  &pid->public_key, /* B */
1547  &key_material[1]);
1548  }
1549  else
1550  {
1552  ephemeral_key, /* A0 */
1553  &key_material[1]);
1554  }
1555 
1556  /* ECDH A0 B0 */
1557  GNUNET_CRYPTO_ecc_ecdh (&ax->kx_0, /* a0 or b0 */
1558  ephemeral_key, /* B0 or A0 */
1559  &key_material[2]);
1560  /* KDF */
1561  GNUNET_CRYPTO_kdf (keys, sizeof(keys),
1562  salt, sizeof(salt),
1563  &key_material, sizeof(key_material),
1564  NULL);
1565 
1566  if (0 == memcmp (&ax->RK,
1567  &keys[0],
1568  sizeof(ax->RK)))
1569  {
1571  "Root key already known. Ignoring KX.\n");
1573  "# Root key already known",
1574  1,
1575  GNUNET_NO);
1576  return GNUNET_NO;
1577  }
1578 
1579  ax->RK = keys[0];
1580  if (GNUNET_YES == am_I_alice)
1581  {
1582  ax->HKr = keys[1];
1583  ax->NHKs = keys[2];
1584  ax->NHKr = keys[3];
1585  ax->CKr = keys[4];
1586  ax->ratchet_flag = GNUNET_YES;
1587  }
1588  else
1589  {
1590  ax->HKs = keys[1];
1591  ax->NHKr = keys[2];
1592  ax->NHKs = keys[3];
1593  ax->CKs = keys[4];
1594  ax->ratchet_flag = GNUNET_NO;
1595  ax->ratchet_expiration
1597  ratchet_time);
1598  }
1599  return GNUNET_OK;
1600 }
1601 
1602 
1608 static void
1609 retry_kx (void *cls)
1610 {
1611  struct CadetTunnel *t = cls;
1612  struct CadetTunnelAxolotl *ax;
1613 
1614  t->kx_task = NULL;
1616  "Trying to make KX progress on %s in state %s\n",
1617  GCT_2s (t),
1618  estate2s (t->estate));
1619  switch (t->estate)
1620  {
1621  case CADET_TUNNEL_KEY_UNINITIALIZED: /* first attempt */
1622  case CADET_TUNNEL_KEY_AX_SENT: /* trying again */
1623  send_kx (t,
1624  NULL,
1625  &t->ax);
1626  break;
1627 
1630  /* We are responding, so only require reply
1631  if WE have a channel waiting. */
1632  if (NULL != t->unverified_ax)
1633  {
1634  /* Send AX_AUTH so we might get this one verified */
1635  ax = t->unverified_ax;
1636  }
1637  else
1638  {
1639  /* How can this be? */
1640  GNUNET_break (0);
1641  ax = &t->ax;
1642  }
1643  send_kx_auth (t,
1644  NULL,
1645  ax,
1646  (0 == GCT_count_channels (t))
1647  ? GNUNET_NO
1648  : GNUNET_YES);
1649  break;
1650 
1652  /* We are responding, so only require reply
1653  if WE have a channel waiting. */
1654  if (NULL != t->unverified_ax)
1655  {
1656  /* Send AX_AUTH so we might get this one verified */
1657  ax = t->unverified_ax;
1658  }
1659  else
1660  {
1661  /* How can this be? */
1662  GNUNET_break (0);
1663  ax = &t->ax;
1664  }
1665  send_kx_auth (t,
1666  NULL,
1667  ax,
1668  (0 == GCT_count_channels (t))
1669  ? GNUNET_NO
1670  : GNUNET_YES);
1671  break;
1672 
1673  case CADET_TUNNEL_KEY_OK:
1674  /* Must have been the *other* peer asking us to
1675  respond with a KX_AUTH. */
1676  if (NULL != t->unverified_ax)
1677  {
1678  /* Sending AX_AUTH in response to AX so we might get this one verified */
1679  ax = t->unverified_ax;
1680  }
1681  else
1682  {
1683  /* Sending AX_AUTH in response to AX_AUTH */
1684  ax = &t->ax;
1685  }
1686  send_kx_auth (t,
1687  NULL,
1688  ax,
1689  GNUNET_NO);
1690  break;
1691  }
1692 }
1693 
1694 
1695 void
1698 {
1699  struct CadetTunnel *t = ct->t;
1700  int ret;
1701 
1703  "# KX received",
1704  1,
1705  GNUNET_NO);
1706  if (GNUNET_YES ==
1707  GCT_alice_or_betty (GCP_get_id (t->destination)))
1708  {
1709  /* Betty/Bob is not allowed to send KX! */
1710  GNUNET_break_op (0);
1711  return;
1712  }
1714  "Received KX message from %s with ephemeral %s from %s on connection %s\n",
1715  GCT_2s (t),
1716  GNUNET_e2s (&msg->ephemeral_key),
1717  GNUNET_i2s (GCP_get_id (t->destination)),
1718  GCC_2s (ct->cc));
1719 #if 1
1720  if ((0 ==
1721  memcmp (&t->ax.DHRr,
1722  &msg->ratchet_key,
1723  sizeof(msg->ratchet_key))) &&
1724  (0 ==
1725  memcmp (&t->ax.last_ephemeral,
1726  &msg->ephemeral_key,
1727  sizeof(msg->ephemeral_key))))
1728 
1729  {
1731  "# Duplicate KX received",
1732  1,
1733  GNUNET_NO);
1734  send_kx_auth (t,
1735  ct,
1736  &t->ax,
1737  GNUNET_NO);
1738  return;
1739  }
1740 #endif
1741  /* We only keep ONE unverified KX around, so if there is an existing one,
1742  clean it up. */
1743  if (NULL != t->unverified_ax)
1744  {
1745  if ((0 ==
1746  memcmp (&t->unverified_ax->DHRr,
1747  &msg->ratchet_key,
1748  sizeof(msg->ratchet_key))) &&
1749  (0 ==
1750  memcmp (&t->unverified_ax->last_ephemeral,
1751  &msg->ephemeral_key,
1752  sizeof(msg->ephemeral_key))))
1753  {
1755  "# Duplicate unverified KX received",
1756  1,
1757  GNUNET_NO);
1758 #if 1
1759  send_kx_auth (t,
1760  ct,
1761  t->unverified_ax,
1762  GNUNET_NO);
1763  return;
1764 #endif
1765  }
1767  "Dropping old unverified KX state.\n");
1769  "# Unverified KX dropped for fresh KX",
1770  1,
1771  GNUNET_NO);
1772  GNUNET_break (NULL == t->unverified_ax->skipped_head);
1773  memset (t->unverified_ax,
1774  0,
1775  sizeof(struct CadetTunnelAxolotl));
1776  }
1777  else
1778  {
1780  "Creating fresh unverified KX for %s\n",
1781  GCT_2s (t));
1783  "# Fresh KX setup",
1784  1,
1785  GNUNET_NO);
1786  t->unverified_ax = GNUNET_new (struct CadetTunnelAxolotl);
1787  }
1788  /* Set as the 'current' RK/DHRr the one we are currently using,
1789  so that the duplicate-detection logic of
1790  #update_ax_by_kx can work. */
1791  t->unverified_ax->RK = t->ax.RK;
1792  t->unverified_ax->DHRr = t->ax.DHRr;
1793  t->unverified_ax->DHRs = t->ax.DHRs;
1794  t->unverified_ax->kx_0 = t->ax.kx_0;
1795  t->unverified_attempts = 0;
1796 
1797  /* Update 'ax' by the new key material */
1798  ret = update_ax_by_kx (t->unverified_ax,
1799  GCP_get_id (t->destination),
1800  &msg->ephemeral_key,
1801  &msg->ratchet_key);
1803  if (GNUNET_OK != ret)
1804  {
1806  "# Useless KX",
1807  1,
1808  GNUNET_NO);
1809  return; /* duplicate KX, nothing to do */
1810  }
1811  /* move ahead in our state machine */
1812  if (CADET_TUNNEL_KEY_UNINITIALIZED == t->estate)
1815  else if (CADET_TUNNEL_KEY_AX_SENT == t->estate)
1818 
1819  /* KX is still not done, try again our end. */
1820  if (CADET_TUNNEL_KEY_OK != t->estate)
1821  {
1822  if (NULL != t->kx_task)
1823  GNUNET_SCHEDULER_cancel (t->kx_task);
1824  t->kx_task
1826  t);
1827  }
1828 }
1829 
1830 
1831 #if DEBUG_KX
1832 static void
1833 check_ee (const struct GNUNET_CRYPTO_EcdhePrivateKey *e1,
1834  const struct GNUNET_CRYPTO_EcdhePrivateKey *e2)
1835 {
1836  struct GNUNET_CRYPTO_EcdhePublicKey p1;
1837  struct GNUNET_CRYPTO_EcdhePublicKey p2;
1838  struct GNUNET_HashCode hc1;
1839  struct GNUNET_HashCode hc2;
1840 
1842  &p1);
1844  &p2);
1847  &p2,
1848  &hc1));
1851  &p1,
1852  &hc2));
1853  GNUNET_break (0 == GNUNET_memcmp (&hc1,
1854  &hc2));
1855 }
1856 
1857 
1858 static void
1859 check_ed (const struct GNUNET_CRYPTO_EcdhePrivateKey *e1,
1860  const struct GNUNET_CRYPTO_EddsaPrivateKey *e2)
1861 {
1862  struct GNUNET_CRYPTO_EcdhePublicKey p1;
1863  struct GNUNET_CRYPTO_EddsaPublicKey p2;
1864  struct GNUNET_HashCode hc1;
1865  struct GNUNET_HashCode hc2;
1866 
1868  &p1);
1870  &p2);
1873  &p2,
1874  &hc1));
1877  &p1,
1878  &hc2));
1879  GNUNET_break (0 == GNUNET_memcmp (&hc1,
1880  &hc2));
1881 }
1882 
1883 
1884 static void
1885 test_crypto_bug (const struct GNUNET_CRYPTO_EcdhePrivateKey *e1,
1886  const struct GNUNET_CRYPTO_EcdhePrivateKey *e2,
1887  const struct GNUNET_CRYPTO_EddsaPrivateKey *d1,
1888  const struct GNUNET_CRYPTO_EddsaPrivateKey *d2)
1889 {
1890  check_ee (e1, e2);
1891  check_ed (e1, d2);
1892  check_ed (e2, d1);
1893 }
1894 
1895 
1896 #endif
1897 
1898 
1905 void
1908 {
1909  struct CadetTunnel *t = ct->t;
1910  struct CadetTunnelAxolotl ax_tmp;
1911  struct GNUNET_HashCode kx_auth;
1912  int ret;
1913 
1915  "# KX_AUTH received",
1916  1,
1917  GNUNET_NO);
1918  if ((CADET_TUNNEL_KEY_UNINITIALIZED == t->estate) ||
1919  (CADET_TUNNEL_KEY_AX_RECV == t->estate))
1920  {
1921  /* Confusing, we got a KX_AUTH before we even send our own
1922  KX. This should not happen. We'll send our own KX ASAP anyway,
1923  so let's ignore this here. */
1924  GNUNET_break_op (0);
1925  return;
1926  }
1928  "Handling KX_AUTH message from %s with ephemeral %s\n",
1929  GCT_2s (t),
1930  GNUNET_e2s (&msg->kx.ephemeral_key));
1931  /* We do everything in ax_tmp until we've checked the authentication
1932  so we don't clobber anything we care about by accident. */
1933  ax_tmp = t->ax;
1934 
1935  /* Update 'ax' by the new key material */
1936  ret = update_ax_by_kx (&ax_tmp,
1937  GCP_get_id (t->destination),
1938  &msg->kx.ephemeral_key,
1939  &msg->kx.ratchet_key);
1940  if (GNUNET_OK != ret)
1941  {
1942  if (GNUNET_NO == ret)
1944  "# redundant KX_AUTH received",
1945  1,
1946  GNUNET_NO);
1947  else
1948  GNUNET_break (0); /* connect to self!? */
1949  return;
1950  }
1951  GNUNET_CRYPTO_hash (&ax_tmp.RK,
1952  sizeof(ax_tmp.RK),
1953  &kx_auth);
1954  if (0 != GNUNET_memcmp (&kx_auth,
1955  &msg->auth))
1956  {
1957  /* This KX_AUTH is not using the latest KX/KX_AUTH data
1958  we transmitted to the sender, refuse it, try KX again. */
1960  "# KX_AUTH not using our last KX received (auth failure)",
1961  1,
1962  GNUNET_NO);
1964  "KX AUTH mismatch!\n");
1965 #if DEBUG_KX
1966  {
1967  struct GNUNET_CRYPTO_EcdhePublicKey ephemeral_key;
1968 
1970  &ephemeral_key);
1971  if (0 != GNUNET_memcmp (&ephemeral_key,
1972  &msg->r_ephemeral_key_XXX))
1973  {
1975  "My ephemeral is %s!\n",
1976  GNUNET_e2s (&ephemeral_key));
1978  "Response is for ephemeral %s!\n",
1979  GNUNET_e2s (&msg->r_ephemeral_key_XXX));
1980  }
1981  else
1982  {
1983  test_crypto_bug (&ax_tmp.kx_0,
1984  &msg->kx.ephemeral_key_XXX,
1986  &msg->kx.private_key_XXX);
1987  }
1988  }
1989 #endif
1990  if (NULL == t->kx_task)
1991  t->kx_task
1992  = GNUNET_SCHEDULER_add_at (t->next_kx_attempt,
1993  &retry_kx,
1994  t);
1995  return;
1996  }
1997  /* Yep, we're good. */
1998  t->ax = ax_tmp;
1999  if (NULL != t->unverified_ax)
2000  {
2001  /* We got some "stale" KX before, drop that. */
2002  cleanup_ax (t->unverified_ax);
2003  GNUNET_free (t->unverified_ax);
2004  t->unverified_ax = NULL;
2005  }
2006 
2007  /* move ahead in our state machine */
2008  switch (t->estate)
2009  {
2012  /* Checked above, this is impossible. */
2013  GNUNET_assert (0);
2014  break;
2015 
2016  case CADET_TUNNEL_KEY_AX_SENT: /* This is the normal case */
2017  case CADET_TUNNEL_KEY_AX_SENT_AND_RECV: /* both peers started KX */
2018  case CADET_TUNNEL_KEY_AX_AUTH_SENT: /* both peers now did KX_AUTH */
2021  break;
2022 
2023  case CADET_TUNNEL_KEY_OK:
2024  /* Did not expect another KX_AUTH, but so what, still acceptable.
2025  Nothing to do here. */
2026  break;
2027  }
2028  if (0 != (GNUNET_CADET_KX_FLAG_FORCE_REPLY & ntohl (msg->kx.flags)))
2029  {
2030  send_kx_auth (t,
2031  NULL,
2032  &t->ax,
2033  GNUNET_NO);
2034  }
2035 }
2036 
2037 
2038 /* ************************************** end core crypto ***************************** */
2039 
2040 
2049 {
2050 #define HIGH_BIT 0x8000000
2052  uint32_t ctn;
2053  int cmp;
2054  uint32_t highbit;
2055 
2056  cmp = GNUNET_memcmp (&my_full_id,
2058  if (0 < cmp)
2059  highbit = HIGH_BIT;
2060  else if (0 > cmp)
2061  highbit = 0;
2062  else
2063  GNUNET_assert (0); // loopback must never go here!
2064  ctn = ntohl (t->next_ctn.cn);
2065  while (NULL !=
2067  ctn | highbit))
2068  {
2069  ctn = ((ctn + 1) & (~HIGH_BIT));
2070  }
2071  t->next_ctn.cn = htonl ((ctn + 1) & (~HIGH_BIT));
2072  ret.cn = htonl (ctn | highbit);
2073  return ret;
2074 }
2075 
2076 
2087 GCT_add_channel (struct CadetTunnel *t,
2088  struct CadetChannel *ch)
2089 {
2091 
2092  ctn = get_next_free_ctn (t);
2093  if (NULL != t->destroy_task)
2094  {
2095  GNUNET_SCHEDULER_cancel (t->destroy_task);
2096  t->destroy_task = NULL;
2097  }
2100  ntohl (ctn.cn),
2101  ch,
2104  "Adding %s to %s with state %d\n",
2105  GCCH_2s (ch),
2106  GCT_2s (t),
2107  t->estate);
2108  switch (t->estate)
2109  {
2111  /* waiting for connection to start KX */
2112  break;
2113 
2117  /* we're currently waiting for KX to complete */
2118  break;
2119 
2121  /* waiting for OTHER peer to send us data,
2122  we might need to prompt more aggressively! */
2123  if (NULL == t->kx_task)
2124  t->kx_task
2125  = GNUNET_SCHEDULER_add_at (t->next_kx_attempt,
2126  &retry_kx,
2127  t);
2128  break;
2129 
2130  case CADET_TUNNEL_KEY_OK:
2131  /* We are ready. Tell the new channel that we are up. */
2132  GCCH_tunnel_up (ch);
2133  break;
2134  }
2135  return ctn;
2136 }
2137 
2138 
2145 void
2147 {
2148  struct CadetTunnel *t = ct->t;
2149 
2150  if (GNUNET_YES == ct->is_ready)
2151  {
2152  GNUNET_CONTAINER_DLL_remove (t->connection_ready_head,
2153  t->connection_ready_tail,
2154  ct);
2155  t->num_ready_connections--;
2156  }
2157  else
2158  {
2159  GNUNET_CONTAINER_DLL_remove (t->connection_busy_head,
2160  t->connection_busy_tail,
2161  ct);
2162  t->num_busy_connections--;
2163  }
2164  GNUNET_free (ct);
2165 }
2166 
2167 
2174 static void
2176  struct CadetTConnection *ct)
2177 {
2178  struct CadetTunnel *t = cls;
2179  struct CadetConnection *cc = ct->cc;
2180 
2181  GNUNET_assert (ct->t == t);
2184 }
2185 
2186 
2192 static void
2193 destroy_tunnel (void *cls)
2194 {
2195  struct CadetTunnel *t = cls;
2196  struct CadetTunnelQueueEntry *tq;
2197 
2198  t->destroy_task = NULL;
2200  "Destroying idle %s\n",
2201  GCT_2s (t));
2205  t);
2206  GNUNET_assert (NULL == t->connection_ready_head);
2207  GNUNET_assert (NULL == t->connection_busy_head);
2208  while (NULL != (tq = t->tq_head))
2209  {
2210  if (NULL != tq->cont)
2211  tq->cont (tq->cont_cls,
2212  NULL);
2213  GCT_send_cancel (tq);
2214  }
2215  GCP_drop_tunnel (t->destination,
2216  t);
2218  if (NULL != t->maintain_connections_task)
2219  {
2220  GNUNET_SCHEDULER_cancel (t->maintain_connections_task);
2221  t->maintain_connections_task = NULL;
2222  }
2223  if (NULL != t->send_task)
2224  {
2225  GNUNET_SCHEDULER_cancel (t->send_task);
2226  t->send_task = NULL;
2227  }
2228  if (NULL != t->kx_task)
2229  {
2230  GNUNET_SCHEDULER_cancel (t->kx_task);
2231  t->kx_task = NULL;
2232  }
2233  GNUNET_MST_destroy (t->mst);
2234  GNUNET_MQ_destroy (t->mq);
2235  if (NULL != t->unverified_ax)
2236  {
2237  cleanup_ax (t->unverified_ax);
2238  GNUNET_free (t->unverified_ax);
2239  }
2240  cleanup_ax (&t->ax);
2241  GNUNET_assert (NULL == t->destroy_task);
2242  GNUNET_free (t);
2243 }
2244 
2245 
2253 void
2255  struct CadetChannel *ch,
2257 {
2259  "Removing %s from %s\n",
2260  GCCH_2s (ch),
2261  GCT_2s (t));
2264  ntohl (ctn.cn),
2265  ch));
2266  if ((0 ==
2267  GCT_count_channels (t)) &&
2268  (NULL == t->destroy_task))
2269  {
2270  t->destroy_task
2272  &destroy_tunnel,
2273  t);
2274  }
2275 }
2276 
2277 
2286 static int
2288  uint32_t key,
2289  void *value)
2290 {
2291  struct CadetChannel *ch = value;
2292 
2294  NULL);
2295  return GNUNET_OK;
2296 }
2297 
2298 
2304 void
2306 {
2310  t);
2311  GNUNET_assert (0 ==
2312  GCT_count_channels (t));
2313  if (NULL != t->destroy_task)
2314  {
2315  GNUNET_SCHEDULER_cancel (t->destroy_task);
2316  t->destroy_task = NULL;
2317  }
2318  destroy_tunnel (t);
2319 }
2320 
2321 
2329 static void
2331  struct CadetTConnection *ct)
2332 {
2333  struct CadetTunnelQueueEntry *tq;
2334 
2336  tq = t->tq_head;
2337  if (NULL == tq)
2338  {
2339  /* no messages pending right now */
2341  "Not sending payload of %s on ready %s (nothing pending)\n",
2342  GCT_2s (t),
2343  GCC_2s (ct->cc));
2344  return;
2345  }
2346  /* ready to send message 'tq' on tunnel 'ct' */
2347  GNUNET_assert (t == tq->t);
2348  GNUNET_CONTAINER_DLL_remove (t->tq_head,
2349  t->tq_tail,
2350  tq);
2351  if (NULL != tq->cid)
2352  *tq->cid = *GCC_get_id (ct->cc);
2355  "Sending payload of %s on %s\n",
2356  GCT_2s (t),
2357  GCC_2s (ct->cc));
2358  GCC_transmit (ct->cc,
2359  tq->env);
2360  if (NULL != tq->cont)
2361  tq->cont (tq->cont_cls,
2362  GCC_get_id (ct->cc));
2363  GNUNET_free (tq);
2364 }
2365 
2366 
2375 static void
2377  int is_ready)
2378 {
2379  struct CadetTConnection *ct = cls;
2380  struct CadetTunnel *t = ct->t;
2381 
2382  if (GNUNET_NO == is_ready)
2383  {
2385  "%s no longer ready for %s\n",
2386  GCC_2s (ct->cc),
2387  GCT_2s (t));
2389  return;
2390  }
2391  GNUNET_assert (GNUNET_NO == ct->is_ready);
2392  GNUNET_CONTAINER_DLL_remove (t->connection_busy_head,
2393  t->connection_busy_tail,
2394  ct);
2395  GNUNET_assert (0 < t->num_busy_connections);
2396  t->num_busy_connections--;
2397  ct->is_ready = GNUNET_YES;
2398  GNUNET_CONTAINER_DLL_insert_tail (t->connection_ready_head,
2399  t->connection_ready_tail,
2400  ct);
2401  t->num_ready_connections++;
2402 
2404  "%s now ready for %s in state %s\n",
2405  GCC_2s (ct->cc),
2406  GCT_2s (t),
2407  estate2s (t->estate));
2408  switch (t->estate)
2409  {
2412  "Do not begin KX for %s if WE have no channels waiting. Retrying after %llu\n",
2413  GCT_2s (t),
2414  (unsigned long long) GNUNET_TIME_absolute_get_remaining (
2415  t->next_kx_attempt).rel_value_us);
2416  /* Do not begin KX if WE have no channels waiting! */
2418  t->next_kx_attempt).rel_value_us)
2419  return; /* wait for timeout before retrying */
2420  /* We are uninitialized, just transmit immediately,
2421  without undue delay. */
2422 
2424  "Why for %s \n",
2425  GCT_2s (t));
2426 
2427  if (NULL != t->kx_task)
2428  {
2429  GNUNET_SCHEDULER_cancel (t->kx_task);
2430  t->kx_task = NULL;
2431  }
2432  send_kx (t,
2433  ct,
2434  &t->ax);
2435  if ((0 ==
2436  GCT_count_channels (t)) &&
2437  (NULL == t->destroy_task))
2438  {
2439  t->destroy_task
2441  &destroy_tunnel,
2442  t);
2443  }
2444  break;
2445 
2450  /* we're currently waiting for KX to complete, schedule job */
2451  if (NULL == t->kx_task)
2452  t->kx_task
2453  = GNUNET_SCHEDULER_add_at (t->next_kx_attempt,
2454  &retry_kx,
2455  t);
2456  break;
2457 
2458  case CADET_TUNNEL_KEY_OK:
2459  if (GNUNET_YES == t->kx_auth_requested)
2460  {
2462  t->next_kx_attempt).rel_value_us)
2463  return; /* wait for timeout */
2464  if (NULL != t->kx_task)
2465  {
2466  GNUNET_SCHEDULER_cancel (t->kx_task);
2467  t->kx_task = NULL;
2468  }
2469  send_kx_auth (t,
2470  ct,
2471  &t->ax,
2472  GNUNET_NO);
2473  return;
2474  }
2476  ct);
2477  break;
2478  }
2479 }
2480 
2481 
2490 static void
2492 {
2493  struct CadetTunnel *t = cls;
2494  struct CadetTConnection *ct;
2495 
2496  t->send_task = NULL;
2497  if (NULL == t->tq_head)
2498  return; /* no messages pending right now */
2499  ct = get_ready_connection (t);
2500  if (NULL == ct)
2501  return; /* no connections ready */
2503  ct);
2504 }
2505 
2506 
2512 {
2516  unsigned int min_length;
2517 
2521  unsigned int max_length;
2522 
2527 
2532 
2537 
2543 
2547  double worst_score;
2548 
2553 };
2554 
2555 
2563 static void
2565  struct CadetTConnection *ct)
2566 {
2567  struct EvaluationSummary *es = cls;
2568  struct CadetConnection *cc = ct->cc;
2569  unsigned int ct_length;
2570  struct CadetPeerPath *ps;
2571  const struct CadetConnectionMetrics *metrics;
2572  GNUNET_CONTAINER_HeapCostType ct_desirability;
2573  struct GNUNET_TIME_Relative uptime;
2574  struct GNUNET_TIME_Relative last_use;
2575  double score;
2576  double success_rate;
2577 
2578  ps = GCC_get_path (cc,
2579  &ct_length);
2581  "Evaluating path %s of existing %s\n",
2582  GCPP_2s (ps),
2583  GCC_2s (cc));
2584  if (ps == es->path)
2585  {
2587  "Ignoring duplicate path %s.\n",
2588  GCPP_2s (es->path));
2589  es->duplicate = GNUNET_YES;
2590  return;
2591  }
2592  if (NULL != es->path)
2593  {
2594  int duplicate = GNUNET_YES;
2595 
2596  for (unsigned int i = 0; i < ct_length; i++)
2597  {
2598  GNUNET_assert (GCPP_get_length (es->path) > i);
2599  if (GCPP_get_peer_at_offset (es->path,
2600  i) !=
2602  i))
2603  {
2604  duplicate = GNUNET_NO;
2605  break;
2606  }
2607  }
2608  if (GNUNET_YES == duplicate)
2609  {
2611  "Ignoring overlapping path %s.\n",
2612  GCPP_2s (es->path));
2613  es->duplicate = GNUNET_YES;
2614  return;
2615  }
2616  else
2617  {
2619  "Known path %s differs from proposed path\n",
2620  GCPP_2s (ps));
2621  }
2622  }
2623 
2624  ct_desirability = GCPP_get_desirability (ps);
2625  metrics = GCC_get_metrics (cc);
2626  uptime = GNUNET_TIME_absolute_get_duration (metrics->age);
2627  last_use = GNUNET_TIME_absolute_get_duration (metrics->last_use);
2628  /* We add 1.0 here to avoid division by zero. */
2629  success_rate = (metrics->num_acked_transmissions + 1.0)
2630  / (metrics->num_successes + 1.0);
2631  score
2632  = ct_desirability
2633  + 100.0 / (1.0 + ct_length) /* longer paths = better */
2634  + sqrt (uptime.rel_value_us / 60000000LL) /* larger uptime = better */
2635  - last_use.rel_value_us / 1000L; /* longer idle = worse */
2636  score *= success_rate; /* weigh overall by success rate */
2637 
2638  if ((NULL == es->worst) ||
2639  (score < es->worst_score))
2640  {
2641  es->worst = ct;
2642  es->worst_score = score;
2643  }
2644  es->min_length = GNUNET_MIN (es->min_length,
2645  ct_length);
2646  es->max_length = GNUNET_MAX (es->max_length,
2647  ct_length);
2648  es->min_desire = GNUNET_MIN (es->min_desire,
2649  ct_desirability);
2650  es->max_desire = GNUNET_MAX (es->max_desire,
2651  ct_desirability);
2652 }
2653 
2654 
2664 static int
2665 consider_path_cb (void *cls,
2666  struct CadetPeerPath *path,
2667  unsigned int off)
2668 {
2669  struct CadetTunnel *t = cls;
2670  struct EvaluationSummary es;
2671  struct CadetTConnection *ct;
2672 
2673  GNUNET_assert (off < GCPP_get_length (path));
2675  off) == t->destination);
2676  es.min_length = UINT_MAX;
2677  es.max_length = 0;
2678  es.max_desire = 0;
2679  es.min_desire = UINT64_MAX;
2680  es.path = path;
2681  es.duplicate = GNUNET_NO;
2682  es.worst = NULL;
2683 
2684  /* Compute evaluation summary over existing connections. */
2686  "Evaluating proposed path %s for target %s\n",
2687  GCPP_2s (path),
2688  GCT_2s (t));
2689  /* FIXME: suspect this does not ACTUALLY iterate
2690  over all existing paths, otherwise dup detection
2691  should work!!! */
2694  &es);
2695  if (GNUNET_YES == es.duplicate)
2696  return GNUNET_YES;
2697 
2698  /* FIXME: not sure we should really just count
2699  'num_connections' here, as they may all have
2700  consistently failed to connect. */
2701 
2702  /* We iterate by increasing path length; if we have enough paths and
2703  this one is more than twice as long than what we are currently
2704  using, then ignore all of these super-long ones! */
2706  (es.min_length * 2 < off) &&
2707  (es.max_length < off))
2708  {
2710  "Ignoring paths of length %u, they are way too long.\n",
2711  es.min_length * 2);
2712  return GNUNET_NO;
2713  }
2714  /* If we have enough paths and this one looks no better, ignore it. */
2716  (es.min_length < GCPP_get_length (path)) &&
2717  (es.min_desire > GCPP_get_desirability (path)) &&
2718  (es.max_length < off))
2719  {
2721  "Ignoring path (%u/%llu) to %s, got something better already.\n",
2722  GCPP_get_length (path),
2723  (unsigned long long) GCPP_get_desirability (path),
2724  GCP_2s (t->destination));
2725  return GNUNET_YES;
2726  }
2727 
2728  /* Path is interesting (better by some metric, or we don't have
2729  enough paths yet). */
2730  ct = GNUNET_new (struct CadetTConnection);
2732  ct->t = t;
2733  ct->cc = GCC_create (t->destination,
2734  path,
2735  off,
2736  ct,
2738  ct);
2739 
2740  /* FIXME: schedule job to kill connection (and path?) if it takes
2741  too long to get ready! (And track performance data on how long
2742  other connections took with the tunnel!)
2743  => Note: to be done within 'connection'-logic! */
2744  GNUNET_CONTAINER_DLL_insert (t->connection_busy_head,
2745  t->connection_busy_tail,
2746  ct);
2747  t->num_busy_connections++;
2749  "Found interesting path %s for %s, created %s\n",
2750  GCPP_2s (path),
2751  GCT_2s (t),
2752  GCC_2s (ct->cc));
2753  return GNUNET_YES;
2754 }
2755 
2756 
2770 static void
2772 {
2773  struct CadetTunnel *t = cls;
2774  struct GNUNET_TIME_Relative delay;
2775  struct EvaluationSummary es;
2776 
2777  t->maintain_connections_task = NULL;
2779  "Performing connection maintenance for %s.\n",
2780  GCT_2s (t));
2781 
2782  es.min_length = UINT_MAX;
2783  es.max_length = 0;
2784  es.max_desire = 0;
2785  es.min_desire = UINT64_MAX;
2786  es.path = NULL;
2787  es.worst = NULL;
2788  es.duplicate = GNUNET_NO;
2791  &es);
2792  if ((NULL != es.worst) &&
2794  {
2795  /* Clear out worst-performing connection 'es.worst'. */
2797  es.worst);
2798  }
2799 
2800  /* Consider additional paths */
2801  (void) GCP_iterate_paths (t->destination,
2803  t);
2804 
2805  /* FIXME: calculate when to try again based on how well we are doing;
2806  in particular, if we have to few connections, we might be able
2807  to do without this (as PATHS should tell us whenever a new path
2808  is available instantly; however, need to make sure this job is
2809  restarted after that happens).
2810  Furthermore, if the paths we do know are in a reasonably narrow
2811  quality band and are plentyful, we might also consider us stabilized
2812  and then reduce the frequency accordingly. */delay = GNUNET_TIME_UNIT_MINUTES;
2813  t->maintain_connections_task
2816  t);
2817 }
2818 
2819 
2820 void
2822  struct CadetPeerPath *p,
2823  unsigned int off)
2824 {
2826  "Considering %s for %s (offset %u)\n",
2827  GCPP_2s (p),
2828  GCT_2s (t),
2829  off);
2830  (void) consider_path_cb (t,
2831  p,
2832  off);
2833 }
2834 
2835 
2842 static void
2844  const struct GNUNET_MessageHeader *msg)
2845 {
2846  struct CadetTunnel *t = cls;
2847 
2849  "Received KEEPALIVE on %s\n",
2850  GCT_2s (t));
2852  "# keepalives received",
2853  1,
2854  GNUNET_NO);
2855 }
2856 
2857 
2865 static int
2868 {
2869  return GNUNET_OK;
2870 }
2871 
2872 
2880 static void
2883 {
2884  struct CadetTunnel *t = cls;
2885  struct CadetChannel *ch;
2886 
2887  ch = lookup_channel (t,
2888  msg->ctn);
2889  if (NULL == ch)
2890  {
2891  /* We don't know about such a channel, might have been destroyed on our
2892  end in the meantime, or never existed. Send back a DESTROY. */
2894  "Received %u bytes of application data for unknown channel %u, sending DESTROY\n",
2895  (unsigned int) (ntohs (msg->header.size) - sizeof(*msg)),
2896  ntohl (msg->ctn.cn));
2898  msg->ctn);
2899  return;
2900  }
2902  GCC_get_id (t->current_ct->cc),
2903  msg);
2904 }
2905 
2906 
2915 static void
2917  const struct GNUNET_CADET_ChannelDataAckMessage *ack)
2918 {
2919  struct CadetTunnel *t = cls;
2920  struct CadetChannel *ch;
2921 
2922  ch = lookup_channel (t,
2923  ack->ctn);
2924  if (NULL == ch)
2925  {
2926  /* We don't know about such a channel, might have been destroyed on our
2927  end in the meantime, or never existed. Send back a DESTROY. */
2929  "Received DATA_ACK for unknown channel %u, sending DESTROY\n",
2930  ntohl (ack->ctn.cn));
2932  ack->ctn);
2933  return;
2934  }
2936  GCC_get_id (t->current_ct->cc),
2937  ack);
2938 }
2939 
2940 
2948 static void
2950  const struct
2952 {
2953  struct CadetTunnel *t = cls;
2954  struct CadetChannel *ch;
2955 
2957  ntohl (copen->ctn.cn));
2958  if (NULL != ch)
2959  {
2961  "Received duplicate channel CHANNEL_OPEN on h_port %s from %s (%s), resending ACK\n",
2962  GNUNET_h2s (&copen->h_port),
2963  GCT_2s (t),
2964  GCCH_2s (ch));
2966  GCC_get_id (t->current_ct->cc));
2967  return;
2968  }
2970  "Received CHANNEL_OPEN on h_port %s from %s\n",
2971  GNUNET_h2s (&copen->h_port),
2972  GCT_2s (t));
2974  copen->ctn,
2975  &copen->h_port,
2976  ntohl (copen->opt));
2977  if (NULL != t->destroy_task)
2978  {
2979  GNUNET_SCHEDULER_cancel (t->destroy_task);
2980  t->destroy_task = NULL;
2981  }
2984  ntohl (copen->ctn.cn),
2985  ch,
2987 }
2988 
2989 
2996 void
2999 {
3001 
3003  "Sending DESTROY message for channel ID %u\n",
3004  ntohl (ctn.cn));
3005  msg.header.size = htons (sizeof(msg));
3007  msg.reserved = htonl (0);
3008  msg.ctn = ctn;
3009  GCT_send (t,
3010  &msg.header,
3011  NULL,
3012  NULL,
3013  &ctn);
3014 }
3015 
3016 
3025 static void
3027  const struct
3029 {
3030  struct CadetTunnel *t = cls;
3031  struct CadetChannel *ch;
3032 
3033  ch = lookup_channel (t,
3034  cm->ctn);
3035  if (NULL == ch)
3036  {
3037  /* We don't know about such a channel, might have been destroyed on our
3038  end in the meantime, or never existed. Send back a DESTROY. */
3040  "Received channel OPEN_ACK for unknown channel %u, sending DESTROY\n",
3041  ntohl (cm->ctn.cn));
3043  cm->ctn);
3044  return;
3045  }
3047  "Received channel OPEN_ACK on channel %s from %s\n",
3048  GCCH_2s (ch),
3049  GCT_2s (t));
3051  GCC_get_id (t->current_ct->cc),
3052  &cm->port);
3053 }
3054 
3055 
3063 static void
3065  const struct
3067 {
3068  struct CadetTunnel *t = cls;
3069  struct CadetChannel *ch;
3070 
3071  ch = lookup_channel (t,
3072  cm->ctn);
3073  if (NULL == ch)
3074  {
3075  /* We don't know about such a channel, might have been destroyed on our
3076  end in the meantime, or never existed. */
3078  "Received channel DESTROY for unknown channel %u. Ignoring.\n",
3079  ntohl (cm->ctn.cn));
3080  return;
3081  }
3083  "Received channel DESTROY on %s from %s\n",
3084  GCCH_2s (ch),
3085  GCT_2s (t));
3087  GCC_get_id (t->current_ct->cc));
3088 }
3089 
3090 
3101 static int
3102 handle_decrypted (void *cls,
3103  const struct GNUNET_MessageHeader *msg)
3104 {
3105  struct CadetTunnel *t = cls;
3106 
3107  GNUNET_assert (NULL != t->current_ct);
3109  msg);
3110  return GNUNET_OK;
3111 }
3112 
3113 
3121 static void
3123  enum GNUNET_MQ_Error error)
3124 {
3125  GNUNET_break_op (0);
3126 }
3127 
3128 
3136 struct CadetTunnel *
3138 {
3139  struct CadetTunnel *t = GNUNET_new (struct CadetTunnel);
3140  struct GNUNET_MQ_MessageHandler handlers[] = {
3141  GNUNET_MQ_hd_fixed_size (plaintext_keepalive,
3143  struct GNUNET_MessageHeader,
3144  t),
3145  GNUNET_MQ_hd_var_size (plaintext_data,
3148  t),
3149  GNUNET_MQ_hd_fixed_size (plaintext_data_ack,
3152  t),
3153  GNUNET_MQ_hd_fixed_size (plaintext_channel_open,
3156  t),
3157  GNUNET_MQ_hd_fixed_size (plaintext_channel_open_ack,
3160  t),
3161  GNUNET_MQ_hd_fixed_size (plaintext_channel_destroy,
3164  t),
3166  };
3167 
3168  t->kx_retry_delay = INITIAL_KX_RETRY_DELAY;
3169  new_ephemeral (&t->ax);
3170  GNUNET_CRYPTO_ecdhe_key_create (&t->ax.kx_0);
3171  t->destination = destination;
3172  t->channels = GNUNET_CONTAINER_multihashmap32_create (8);
3173  t->maintain_connections_task
3175  t);
3176  t->mq = GNUNET_MQ_queue_for_callbacks (NULL,
3177  NULL,
3178  NULL,
3179  NULL,
3180  handlers,
3182  t);
3184  t);
3185  return t;
3186 }
3187 
3188 
3189 int
3191  const struct
3193  struct CadetPeerPath *path)
3194 {
3195  struct CadetTConnection *ct;
3196 
3197  ct = GNUNET_new (struct CadetTConnection);
3199  ct->t = t;
3200  ct->cc = GCC_create_inbound (t->destination,
3201  path,
3202  ct,
3203  cid,
3205  ct);
3206  if (NULL == ct->cc)
3207  {
3209  "%s refused inbound %s (duplicate)\n",
3210  GCT_2s (t),
3211  GCC_2s (ct->cc));
3212  GNUNET_free (ct);
3213  return GNUNET_SYSERR;
3214  }
3215  /* FIXME: schedule job to kill connection (and path?) if it takes
3216  too long to get ready! (And track performance data on how long
3217  other connections took with the tunnel!)
3218  => Note: to be done within 'connection'-logic! */
3219  GNUNET_CONTAINER_DLL_insert (t->connection_busy_head,
3220  t->connection_busy_tail,
3221  ct);
3222  t->num_busy_connections++;
3224  "%s has new %s\n",
3225  GCT_2s (t),
3226  GCC_2s (ct->cc));
3227  return GNUNET_OK;
3228 }
3229 
3230 
3237 void
3240 {
3241  struct CadetTunnel *t = ct->t;
3242  uint16_t size = ntohs (msg->header.size);
3243  char cbuf[size] GNUNET_ALIGN;
3244  ssize_t decrypted_size;
3245 
3247  "%s received %u bytes of encrypted data in state %d\n",
3248  GCT_2s (t),
3249  (unsigned int) size,
3250  t->estate);
3251 
3252  switch (t->estate)
3253  {
3256  /* We did not even SEND our KX, how can the other peer
3257  send us encrypted data? Must have been that we went
3258  down and the other peer still things we are up.
3259  Let's send it KX back. */
3261  "# received encrypted without any KX",
3262  1,
3263  GNUNET_NO);
3264  if (NULL != t->kx_task)
3265  {
3266  GNUNET_SCHEDULER_cancel (t->kx_task);
3267  t->kx_task = NULL;
3268  }
3269  send_kx (t,
3270  ct,
3271  &t->ax);
3272  return;
3273 
3275  /* We send KX, and other peer send KX to us at the same time.
3276  Neither KX is AUTH'ed, so let's try KX_AUTH this time. */
3278  "# received encrypted without KX_AUTH",
3279  1,
3280  GNUNET_NO);
3281  if (NULL != t->kx_task)
3282  {
3283  GNUNET_SCHEDULER_cancel (t->kx_task);
3284  t->kx_task = NULL;
3285  }
3286  send_kx_auth (t,
3287  ct,
3288  &t->ax,
3289  GNUNET_YES);
3290  return;
3291 
3293  /* We did not get the KX of the other peer, but that
3294  might have been lost. Send our KX again immediately. */
3296  "# received encrypted without KX",
3297  1,
3298  GNUNET_NO);
3299  if (NULL != t->kx_task)
3300  {
3301  GNUNET_SCHEDULER_cancel (t->kx_task);
3302  t->kx_task = NULL;
3303  }
3304  send_kx (t,
3305  ct,
3306  &t->ax);
3307  return;
3308 
3310  /* Great, first payload, we might graduate to OK! */
3311  case CADET_TUNNEL_KEY_OK:
3312  /* We are up and running, all good. */
3313  break;
3314  }
3315 
3316  decrypted_size = -1;
3317  if (CADET_TUNNEL_KEY_OK == t->estate)
3318  {
3319  /* We have well-established key material available,
3320  try that. (This is the common case.) */
3321  decrypted_size = t_ax_decrypt_and_validate (&t->ax,
3322  cbuf,
3323  msg,
3324  size);
3325  }
3326 
3327  if ((-1 == decrypted_size) &&
3328  (NULL != t->unverified_ax))
3329  {
3330  /* We have un-authenticated KX material available. We should try
3331  this as a back-up option, in case the sender crashed and
3332  switched keys. */
3333  decrypted_size = t_ax_decrypt_and_validate (t->unverified_ax,
3334  cbuf,
3335  msg,
3336  size);
3337  if (-1 != decrypted_size)
3338  {
3339  /* It worked! Treat this as authentication of the AX data! */
3340  cleanup_ax (&t->ax);
3341  t->ax = *t->unverified_ax;
3342  GNUNET_free (t->unverified_ax);
3343  t->unverified_ax = NULL;
3344  }
3345  if (CADET_TUNNEL_KEY_AX_AUTH_SENT == t->estate)
3346  {
3347  /* First time it worked, move tunnel into production! */
3350  if (NULL != t->send_task)
3351  GNUNET_SCHEDULER_cancel (t->send_task);
3353  t);
3354  }
3355  }
3356  if (NULL != t->unverified_ax)
3357  {
3358  /* We had unverified KX material that was useless; so increment
3359  counter and eventually move to ignore it. Note that we even do
3360  this increment if we successfully decrypted with the old KX
3361  material and thus didn't even both with the new one. This is
3362  the ideal case, as a malicious injection of bogus KX data
3363  basically only causes us to increment a counter a few times. */t->unverified_attempts++;
3365  "Failed to decrypt message with unverified KX data %u times\n",
3366  t->unverified_attempts);
3367  if (t->unverified_attempts > MAX_UNVERIFIED_ATTEMPTS)
3368  {
3369  cleanup_ax (t->unverified_ax);
3370  GNUNET_free (t->unverified_ax);
3371  t->unverified_ax = NULL;
3372  }
3373  }
3374 
3375  if (-1 == decrypted_size)
3376  {
3377  /* Decryption failed for good, complain. */
3379  "%s failed to decrypt and validate encrypted data, retrying KX\n",
3380  GCT_2s (t));
3382  "# unable to decrypt",
3383  1,
3384  GNUNET_NO);
3385  if (NULL != t->kx_task)
3386  {
3387  GNUNET_SCHEDULER_cancel (t->kx_task);
3388  t->kx_task = NULL;
3389  }
3390  send_kx (t,
3391  ct,
3392  &t->ax);
3393  return;
3394  }
3396  "# decrypted bytes",
3397  decrypted_size,
3398  GNUNET_NO);
3399 
3400  /* The MST will ultimately call #handle_decrypted() on each message. */
3401  t->current_ct = ct;
3403  GNUNET_MST_from_buffer (t->mst,
3404  cbuf,
3405  decrypted_size,
3406  GNUNET_YES,
3407  GNUNET_NO));
3408  t->current_ct = NULL;
3409 }
3410 
3411 
3412 struct CadetTunnelQueueEntry *
3414  const struct GNUNET_MessageHeader *message,
3416  void *cont_cls,
3418 {
3419  struct CadetTunnelQueueEntry *tq;
3420  uint16_t payload_size;
3421  struct GNUNET_MQ_Envelope *env;
3422  struct GNUNET_CADET_TunnelEncryptedMessage *ax_msg;
3423  struct CadetChannel *ch;
3424 
3425  if (NULL != ctn)
3426  {
3427  ch = lookup_channel (t,
3428  *ctn);
3429  if ((NULL != ch) && GCCH_is_type_to_drop (ch, message))
3430  {
3431  GNUNET_break (0);
3432  return NULL;
3433  }
3434  }
3435 
3436  if (CADET_TUNNEL_KEY_OK != t->estate)
3437  {
3438  GNUNET_break (0);
3439  return NULL;
3440  }
3441  payload_size = ntohs (message->size);
3443  "Encrypting %u bytes for %s\n",
3444  (unsigned int) payload_size,
3445  GCT_2s (t));
3446  env = GNUNET_MQ_msg_extra (ax_msg,
3447  payload_size,
3449  t_ax_encrypt (&t->ax,
3450  &ax_msg[1],
3451  message,
3452  payload_size);
3454  "# encrypted bytes",
3455  payload_size,
3456  GNUNET_NO);
3457  ax_msg->ax_header.Ns = htonl (t->ax.Ns++);
3458  ax_msg->ax_header.PNs = htonl (t->ax.PNs);
3459  /* FIXME: we should do this once, not once per message;
3460  this is a point multiplication, and DHRs does not
3461  change all the time. */
3463  &ax_msg->ax_header.DHRs);
3464  t_h_encrypt (&t->ax,
3465  ax_msg);
3466  t_hmac (&ax_msg->ax_header,
3467  sizeof(struct GNUNET_CADET_AxHeader) + payload_size,
3468  0,
3469  &t->ax.HKs,
3470  &ax_msg->hmac);
3471 
3472  tq = GNUNET_malloc (sizeof(*tq));
3473  tq->t = t;
3474  tq->env = env;
3475  tq->cid = &ax_msg->cid; /* will initialize 'ax_msg->cid' once we know the connection */
3476  tq->cont = cont;
3477  tq->cont_cls = cont_cls;
3479  t->tq_tail,
3480  tq);
3481  if (NULL != t->send_task)
3482  GNUNET_SCHEDULER_cancel (t->send_task);
3483  t->send_task
3485  t);
3486  return tq;
3487 }
3488 
3489 
3499 void
3501 {
3502  struct CadetTunnel *t = tq->t;
3503 
3504  GNUNET_CONTAINER_DLL_remove (t->tq_head,
3505  t->tq_tail,
3506  tq);
3507  GNUNET_MQ_discard (tq->env);
3508  GNUNET_free (tq);
3509 }
3510 
3511 
3519 void
3522  void *iter_cls)
3523 {
3524  struct CadetTConnection *n;
3525 
3526  for (struct CadetTConnection *ct = t->connection_ready_head;
3527  NULL != ct;
3528  ct = n)
3529  {
3530  n = ct->next;
3531  iter (iter_cls,
3532  ct);
3533  }
3534  for (struct CadetTConnection *ct = t->connection_busy_head;
3535  NULL != ct;
3536  ct = n)
3537  {
3538  n = ct->next;
3539  iter (iter_cls,
3540  ct);
3541  }
3542 }
3543 
3544 
3549 {
3554 
3558  void *iter_cls;
3559 };
3560 
3561 
3570 static int
3572  uint32_t key,
3573  void *value)
3574 {
3575  struct ChanIterCls *ctx = cls;
3576  struct CadetChannel *ch = value;
3577 
3578  ctx->iter (ctx->iter_cls,
3579  ch);
3580  return GNUNET_OK;
3581 }
3582 
3583 
3591 void
3593  GCT_ChannelIterator iter,
3594  void *iter_cls)
3595 {
3596  struct ChanIterCls ctx;
3597 
3598  ctx.iter = iter;
3599  ctx.iter_cls = iter_cls;
3602  &ctx);
3603 }
3604 
3605 
3614 static int
3615 debug_channel (void *cls,
3616  uint32_t key,
3617  void *value)
3618 {
3619  const enum GNUNET_ErrorType *level = cls;
3620  struct CadetChannel *ch = value;
3621 
3622  GCCH_debug (ch, *level);
3623  return GNUNET_OK;
3624 }
3625 
3626 
3627 #define LOG2(level, ...) GNUNET_log_from_nocheck (level, "cadet-tun", \
3628  __VA_ARGS__)
3629 
3630 
3637 void
3638 GCT_debug (const struct CadetTunnel *t,
3639  enum GNUNET_ErrorType level)
3640 {
3641 #if ! defined(GNUNET_CULL_LOGGING)
3642  struct CadetTConnection *iter_c;
3643  int do_log;
3644 
3646  "cadet-tun",
3647  __FILE__, __FUNCTION__, __LINE__);
3648  if (0 == do_log)
3649  return;
3650 
3651  LOG2 (level,
3652  "TTT TUNNEL TOWARDS %s in estate %s tq_len: %u #cons: %u\n",
3653  GCT_2s (t),
3654  estate2s (t->estate),
3655  t->tq_len,
3657  LOG2 (level,
3658  "TTT channels:\n");
3660  &debug_channel,
3661  &level);
3662  LOG2 (level,
3663  "TTT connections:\n");
3664  for (iter_c = t->connection_ready_head; NULL != iter_c; iter_c = iter_c->next)
3665  GCC_debug (iter_c->cc,
3666  level);
3667  for (iter_c = t->connection_busy_head; NULL != iter_c; iter_c = iter_c->next)
3668  GCC_debug (iter_c->cc,
3669  level);
3670 
3671  LOG2 (level,
3672  "TTT TUNNEL END\n");
3673 #endif
3674 }
3675 
3676 
3677 /* end of gnunet-service-cadet_tunnels.c */
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 int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
static struct GNUNET_ARM_Handle * h
Connection with ARM.
Definition: gnunet-arm.c:99
static int res
static struct GNUNET_CADET_MessageHandler handlers[]
Handlers, for diverse services.
static struct GNUNET_CADET_Channel * ch
Channel handle.
Definition: gnunet-cadet.c:117
struct GNUNET_HashCode key
The key used in the DHT.
static GstElement * source
Appsrc instance into which we write data for the pipeline.
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...
static char * value
Value of the record to add/remove.
enum State state
current state of profiling
static struct GNUNET_TIME_Relative delay
When should dkg communication start?
struct GNUNET_PeerIdentity my_full_id
Local peer own ID.
struct GNUNET_STATISTICS_Handle * stats
Handle to the statistics service.
int shutting_down
Signal that shutdown is happening: prevent recovery measures.
struct GNUNET_CRYPTO_EddsaPrivateKey * my_private_key
Own private key.
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.
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.
const char * GCCH_2s(const struct CadetChannel *ch)
Get the static string for identification of the 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.
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.
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.
const char * GCC_2s(const struct CadetConnection *cc)
Get a (static) string for a connection.
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.
const struct CadetConnectionMetrics * GCC_get_metrics(struct CadetConnection *cc)
Obtain performance metrics from cc.
struct CadetPeerPath * GCC_get_path(struct CadetConnection *cc, unsigned int *off)
Obtain the path used by this connection.
void GCC_destroy_without_tunnel(struct CadetConnection *cc)
Destroy a connection, called if the tunnel association with the connection was already broken,...
void GCC_transmit(struct CadetConnection *cc, struct GNUNET_MQ_Envelope *env)
Transmit message msg via connection cc.
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_debug(struct CadetConnection *cc, enum GNUNET_ErrorType level)
Log connection info.
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...
struct CadetPeer * GCPP_get_peer_at_offset(struct CadetPeerPath *path, unsigned int off)
Obtain the peer at offset off in path.
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.
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)
Handle KX message that lacks authentication (and which will thus only be considered authenticated aft...
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 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.
void GCT_send_channel_destroy(struct CadetTunnel *t, struct GNUNET_CADET_ChannelTunnelNumber ctn)
Send a DESTROY message via the tunnel.
const char * GCT_2s(const struct CadetTunnel *t)
Get the static string for the peer this tunnel is directed.
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 const char * estate2s(enum CadetTunnelEState es)
Get string description for 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.
static void connection_ready_cb(void *cls, int is_ready)
A connection is is_ready for transmission.
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...
struct CadetTunnel * GCT_create_tunnel(struct CadetPeer *destination)
Create a tunnel to destination.
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.
static int update_ax_by_kx(struct CadetTunnelAxolotl *ax, const struct GNUNET_PeerIdentity *pid, const struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral_key, const struct GNUNET_CRYPTO_EcdhePublicKey *ratchet_key)
Update our Axolotl key state based on the KX data we received.
struct CadetChannel * lookup_channel(struct CadetTunnel *t, struct GNUNET_CADET_ChannelTunnelNumber ctn)
Lookup a channel by its ctn.
#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.
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 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 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.
static struct CadetTConnection * get_ready_connection(struct CadetTunnel *t)
Find first connection that is ready in the list of our connections.
#define LOG(level,...)
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...
struct CadetPeer * GCT_get_destination(struct CadetTunnel *t)
Return the peer to which this tunnel goes.
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 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.
#define N
static struct GNUNET_CRYPTO_PowSalt salt
Salt for PoW calcualations.
static char buf[2048]
static struct GNUNET_PeerIdentity pid
Identity of the peer we transmit to / connect to.
static struct GNUNET_OS_Process * p
Helper process we started.
Definition: gnunet-uri.c:37
static struct GNUNET_DNSSTUB_Context * ctx
Context for DNS resolution.
static struct GNUNET_SCHEDULER_Task * t
Main task.
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:726
void GNUNET_CRYPTO_ecdhe_key_create(struct GNUNET_CRYPTO_EcdhePrivateKey *pk)
Create a new private key.
Definition: crypto_ecc.c:435
void GNUNET_CRYPTO_eddsa_key_get_public(const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, struct GNUNET_CRYPTO_EddsaPublicKey *pub)
Extract the public key for the given private key.
Definition: crypto_ecc.c:197
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_eddsa_ecdh(const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, const struct GNUNET_CRYPTO_EcdhePublicKey *pub, struct GNUNET_HashCode *key_material)
Derive key material from a ECDH public key and a private EdDSA key.
Definition: crypto_ecc.c:739
void GNUNET_CRYPTO_symmetric_derive_iv(struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, const struct GNUNET_CRYPTO_SymmetricSessionKey *skey, const void *salt, size_t salt_len,...)
Derive an IV.
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:779
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:414
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:213
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)
Definition: crypto_hash.c:328
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_kdf(void *result, size_t out_len, const void *xts, size_t xts_len, const void *skm, size_t skm_len,...)
Derive key.
Definition: crypto_kdf.c:69
void GNUNET_CRYPTO_hmac_derive_key(struct GNUNET_CRYPTO_AuthKey *key, const struct GNUNET_CRYPTO_SymmetricSessionKey *rkey, const void *salt, size_t salt_len,...)
Derive an authentication key.
Definition: crypto_hash.c:266
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.
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.
int GNUNET_CONTAINER_multihashmap32_iterate(struct GNUNET_CONTAINER_MultiHashMap32 *map, GNUNET_CONTAINER_MulitHashMapIterator32Callback it, void *it_cls)
Iterate over all entries in the map.
struct GNUNET_CONTAINER_MultiHashMap32 * GNUNET_CONTAINER_multihashmap32_create(unsigned int len)
Create a 32-bit key multi hash 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.
@ 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.
#define GNUNET_MAX(a, b)
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_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#define GNUNET_MIN(a, b)
@ GNUNET_OK
Definition: gnunet_common.h:99
@ GNUNET_YES
@ GNUNET_NO
Definition: gnunet_common.h:98
@ GNUNET_SYSERR
Definition: gnunet_common.h:97
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.
#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:283
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:467
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct.
Definition: gnunet_mq_lib.h:56
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:71
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:186
#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:685
#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_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1281
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:1231
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:957
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:1254
void GNUNET_MST_destroy(struct GNUNET_MessageStreamTokenizer *mst)
Destroys a tokenizer.
Definition: mst.c:418
struct GNUNET_MessageStreamTokenizer * GNUNET_MST_create(GNUNET_MessageTokenizerCallback cb, void *cb_cls)
Create a message stream tokenizer.
Definition: mst.c:85
int 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:114
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:435
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:404
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:110
#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:315
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:449
#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:67
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?
Information regarding a possible path to reach a peer.
Peer description.
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.
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?
void * cont_cls
Closure for cont.
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 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 identfies it within its tunnel, in network byte ord...
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...
Private ECC key encoded for transmission.
Public ECC key (always for curve Ed25519) encoded in a format suitable for network transmission and E...
A 512-bit hashcode.
Handle to a message queue.
Definition: mq.c:86
Message handler for a specific message type.
Header for all communications.
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
Handle to a message stream tokenizer.
Definition: mst.c:44
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:135
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.