GNUnet  0.10.x
gnunet-service-core_kx.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2009-2013, 2016 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 */
20 
27 #include "platform.h"
28 #include "gnunet-service-core_kx.h"
29 #include "gnunet-service-core.h"
33 #include "gnunet_constants.h"
34 #include "gnunet_signatures.h"
35 #include "gnunet_protocols.h"
36 #include "core.h"
37 
41 #define DEBUG_KX 0
42 
46 #define INITIAL_SET_KEY_RETRY_FREQUENCY \
47  GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10)
48 
52 #define MIN_PING_FREQUENCY \
53  GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5)
54 
58 #define REKEY_FREQUENCY \
59  GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 12)
60 
64 #define REKEY_TOLERANCE \
65  GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5)
66 
74 #define MAX_MESSAGE_AGE GNUNET_TIME_UNIT_DAYS
75 
76 
78 
84 {
85 
90 
95 
101 
106 
111 
116 
121 
127 };
128 
129 
136 {
141 
145  uint32_t iv_seed GNUNET_PACKED;
146 
151  struct GNUNET_PeerIdentity target;
152 
156  uint32_t challenge GNUNET_PACKED;
157 };
158 
159 
164 {
169 
173  uint32_t iv_seed GNUNET_PACKED;
174 
178  uint32_t challenge GNUNET_PACKED;
179 
183  uint32_t reserved;
184 
189  struct GNUNET_PeerIdentity target;
190 };
191 
192 
198 {
203 
207  uint32_t iv_seed GNUNET_PACKED;
208 
216  struct GNUNET_HashCode hmac;
217 
222  uint32_t sequence_number GNUNET_PACKED;
223 
228 
233  struct GNUNET_TIME_AbsoluteNBO timestamp;
234 };
236 
237 
242 #define ENCRYPTED_HEADER_SIZE \
243  (offsetof (struct EncryptedMessage, sequence_number))
244 
245 
250 {
251 
256 
261 
265  const struct GNUNET_PeerIdentity *peer;
266 
271 
276 
281 
285  struct GNUNET_CRYPTO_EcdhePublicKey other_ephemeral_key;
286 
292 
298 
302  struct GNUNET_TIME_Absolute foreign_key_expires;
303 
308 
312  struct GNUNET_TIME_Absolute last_notify_timeout;
313 
317  struct GNUNET_TIME_Relative set_key_retry_frequency;
318 
323 
328 
335 
340 
345 
349  uint32_t ping_challenge;
350 
355 
360 };
361 
362 
367 
372 
377 
382 
387 
392 
398 
403 
404 
410 static uint32_t
412 {
413  /* Note: may want to make this non-random and instead
414  derive from key material to avoid having an undetectable
415  side-channel */
416  return htonl (
418 }
419 
420 
426 static void
428 {
429  struct MonitorNotifyMessage msg;
430 
432  msg.header.size = htons (sizeof (msg));
433  msg.state = htonl ((uint32_t) kx->status);
434  msg.peer = *kx->peer;
437  kx->last_notify_timeout = kx->timeout;
438 }
439 
440 
448 static void
450  const struct GNUNET_CRYPTO_SymmetricSessionKey *skey,
451  uint32_t seed)
452 {
453  static const char ctx[] = "authentication key";
454 #if DEBUG_KX
455  struct GNUNET_HashCode sh;
456 
457  GNUNET_CRYPTO_hash (skey, sizeof (*skey), &sh);
459  "Deriving Auth key from SKEY %s and seed %u\n",
460  GNUNET_h2s (&sh),
461  (unsigned int) seed);
462 #endif
464  skey,
465  &seed,
466  sizeof (seed),
467  skey,
468  sizeof (
470  ctx,
471  sizeof (ctx),
472  NULL);
473 }
474 
475 
484 static void
486  const struct GNUNET_CRYPTO_SymmetricSessionKey *skey,
487  uint32_t seed,
488  const struct GNUNET_PeerIdentity *identity)
489 {
490  static const char ctx[] = "initialization vector";
491 #if DEBUG_KX
492  struct GNUNET_HashCode sh;
493 
494  GNUNET_CRYPTO_hash (skey, sizeof (*skey), &sh);
496  "Deriving IV from SKEY %s and seed %u for peer %s\n",
497  GNUNET_h2s (&sh),
498  (unsigned int) seed,
499  GNUNET_i2s (identity));
500 #endif
502  skey,
503  &seed,
504  sizeof (seed),
505  identity,
506  sizeof (struct GNUNET_PeerIdentity),
507  ctx,
508  sizeof (ctx),
509  NULL);
510 }
511 
512 
522 static void
524  const struct GNUNET_CRYPTO_SymmetricSessionKey *skey,
525  uint32_t seed,
526  uint32_t challenge,
527  const struct GNUNET_PeerIdentity *identity)
528 {
529  static const char ctx[] = "pong initialization vector";
530 #if DEBUG_KX
531  struct GNUNET_HashCode sh;
532 
533  GNUNET_CRYPTO_hash (skey, sizeof (*skey), &sh);
535  "Deriving PONG IV from SKEY %s and seed %u/%u for %s\n",
536  GNUNET_h2s (&sh),
537  (unsigned int) seed,
538  (unsigned int) challenge,
539  GNUNET_i2s (identity));
540 #endif
542  skey,
543  &seed,
544  sizeof (seed),
545  identity,
546  sizeof (struct GNUNET_PeerIdentity),
547  &challenge,
548  sizeof (challenge),
549  ctx,
550  sizeof (ctx),
551  NULL);
552 }
553 
554 
563 static void
564 derive_aes_key (const struct GNUNET_PeerIdentity *sender,
565  const struct GNUNET_PeerIdentity *receiver,
566  const struct GNUNET_HashCode *key_material,
568 {
569  static const char ctx[] = "aes key generation vector";
570 #if DEBUG_KX
571  struct GNUNET_HashCode sh;
572 
573  GNUNET_CRYPTO_hash (skey, sizeof (*skey), &sh);
575  "Deriving AES Keys for %s to %s from %s\n",
576  GNUNET_i2s (sender),
577  GNUNET_i2s2 (receiver),
578  GNUNET_h2s (key_material));
579 #endif
580  GNUNET_CRYPTO_kdf (skey,
581  sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
582  ctx,
583  sizeof (ctx),
584  key_material,
585  sizeof (struct GNUNET_HashCode),
586  sender,
587  sizeof (struct GNUNET_PeerIdentity),
588  receiver,
589  sizeof (struct GNUNET_PeerIdentity),
590  NULL);
591 }
592 
593 
605 static int
608  const void *in,
609  void *out,
610  size_t size)
611 {
612  if (size != (uint16_t) size)
613  {
614  GNUNET_break (0);
615  return GNUNET_NO;
616  }
618  (uint16_t) size,
619  &kx->encrypt_key,
620  iv,
621  out));
623  gettext_noop ("# bytes encrypted"),
624  size,
625  GNUNET_NO);
626  /* the following is too sensitive to write to log files by accident,
627  so we require manual intervention to get this one... */
628 #if DEBUG_KX
630  "Encrypted %u bytes for `%s' using key %u, IV %u\n",
631  (unsigned int) size,
632  GNUNET_i2s (kx->peer),
633  (unsigned int) kx->encrypt_key.crc32,
634  GNUNET_CRYPTO_crc32_n (iv, sizeof (iv)));
635 #endif
636  return GNUNET_OK;
637 }
638 
639 
652 static int
655  const void *in,
656  void *out,
657  size_t size)
658 {
659  if (size != (uint16_t) size)
660  {
661  GNUNET_break (0);
662  return GNUNET_NO;
663  }
665  (kx->status != GNUNET_CORE_KX_STATE_UP) &&
667  {
668  GNUNET_break_op (0);
669  return GNUNET_SYSERR;
670  }
671  if (size != GNUNET_CRYPTO_symmetric_decrypt (in,
672  (uint16_t) size,
673  &kx->decrypt_key,
674  iv,
675  out))
676  {
677  GNUNET_break (0);
678  return GNUNET_SYSERR;
679  }
681  gettext_noop ("# bytes decrypted"),
682  size,
683  GNUNET_NO);
684  /* the following is too sensitive to write to log files by accident,
685  so we require manual intervention to get this one... */
686 #if DEBUG_KX
688  "Decrypted %u bytes from `%s' using key %u, IV %u\n",
689  (unsigned int) size,
690  GNUNET_i2s (kx->peer),
691  (unsigned int) kx->decrypt_key.crc32,
692  GNUNET_CRYPTO_crc32_n (iv, sizeof (*iv)));
693 #endif
694  return GNUNET_OK;
695 }
696 
697 
703 static void
704 send_key (struct GSC_KeyExchangeInfo *kx);
705 
706 
712 static void
714 {
715  struct GSC_KeyExchangeInfo *kx = cls;
716 
717  kx->retry_set_key_task = NULL;
721  send_key (kx);
722 }
723 
724 
730 static void
732 {
733  struct PingMessage pp;
734  struct PingMessage *pm;
736 
737  pm = &kx->ping;
738  kx->ping_challenge =
740  pm->header.size = htons (sizeof (struct PingMessage));
741  pm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_PING);
742  pm->iv_seed = calculate_seed (kx);
743  derive_iv (&iv, &kx->encrypt_key, pm->iv_seed, kx->peer);
744  pp.challenge = kx->ping_challenge;
745  pp.target = *kx->peer;
746  do_encrypt (kx,
747  &iv,
748  &pp.target,
749  &pm->target,
750  sizeof (struct PingMessage) -
751  ((void *) &pm->target - (void *) pm));
752 }
753 
754 
766 static int
767 deliver_message (void *cls, const struct GNUNET_MessageHeader *m)
768 {
769  struct GSC_KeyExchangeInfo *kx = cls;
770 
772  "Decrypted message of type %d from %s\n",
773  ntohs (m->type),
774  GNUNET_i2s (kx->peer));
775  if (GNUNET_CORE_KX_STATE_UP != kx->status)
776  {
778  gettext_noop ("# PAYLOAD dropped (out of order)"),
779  1,
780  GNUNET_NO);
781  return GNUNET_OK;
782  }
783  switch (ntohs (m->type))
784  {
788  return GNUNET_OK;
791  return GNUNET_OK;
792  default:
794  m,
795  ntohs (m->size),
798  m,
799  sizeof (struct GNUNET_MessageHeader),
801  }
802  return GNUNET_OK;
803 }
804 
805 
815 static void *
817  const struct GNUNET_PeerIdentity *pid,
818  struct GNUNET_MQ_Handle *mq)
819 {
820  struct GSC_KeyExchangeInfo *kx;
821  struct GNUNET_HashCode h1;
822  struct GNUNET_HashCode h2;
823 
825  "Initiating key exchange with `%s'\n",
826  GNUNET_i2s (pid));
828  gettext_noop ("# key exchanges initiated"),
829  1,
830  GNUNET_NO);
831  kx = GNUNET_new (struct GSC_KeyExchangeInfo);
833  kx->mq = mq;
834  kx->peer = pid;
836  GNUNET_CONTAINER_DLL_insert (kx_head, kx_tail, kx);
838  monitor_notify_all (kx);
839  GNUNET_CRYPTO_hash (pid, sizeof (struct GNUNET_PeerIdentity), &h1);
841  sizeof (struct GNUNET_PeerIdentity),
842  &h2);
843  if (0 < GNUNET_CRYPTO_hash_cmp (&h1, &h2))
844  {
845  /* peer with "lower" identity starts KX, otherwise we typically end up
846  with both peers starting the exchange and transmit the 'set key'
847  message twice */
848  send_key (kx);
849  }
850  else
851  {
852  /* peer with "higher" identity starts a delayed KX, if the "lower" peer
853  * does not start a KX since it sees no reasons to do so */
854  kx->retry_set_key_task =
857  kx);
858  }
859  return kx;
860 }
861 
862 
872 static void
874  const struct GNUNET_PeerIdentity *peer,
875  void *handler_cls)
876 {
877  struct GSC_KeyExchangeInfo *kx = handler_cls;
878 
880  "Peer `%s' disconnected from us.\n",
881  GNUNET_i2s (peer));
882  GSC_SESSIONS_end (kx->peer);
884  gettext_noop ("# key exchanges stopped"),
885  1,
886  GNUNET_NO);
887  if (NULL != kx->retry_set_key_task)
888  {
890  kx->retry_set_key_task = NULL;
891  }
892  if (NULL != kx->keep_alive_task)
893  {
895  kx->keep_alive_task = NULL;
896  }
898  monitor_notify_all (kx);
899  GNUNET_CONTAINER_DLL_remove (kx_head, kx_tail, kx);
900  GNUNET_MST_destroy (kx->mst);
901  GNUNET_free (kx);
902 }
903 
904 
910 static void
912 {
913  struct GNUNET_MQ_Envelope *env;
914 
916  gettext_noop ("# PING messages transmitted"),
917  1,
918  GNUNET_NO);
919  env = GNUNET_MQ_msg_copy (&kx->ping.header);
920  GNUNET_MQ_send (kx->mq, env);
921 }
922 
923 
929 static void
931 {
932  struct GNUNET_HashCode key_material;
933 
934  if (GNUNET_OK != GNUNET_CRYPTO_ecc_ecdh (my_ephemeral_key,
935  &kx->other_ephemeral_key,
936  &key_material))
937  {
938  GNUNET_break (0);
939  return;
940  }
941  derive_aes_key (&GSC_my_identity, kx->peer, &key_material, &kx->encrypt_key);
942  derive_aes_key (kx->peer, &GSC_my_identity, &key_material, &kx->decrypt_key);
943  memset (&key_material, 0, sizeof (key_material));
944  /* fresh key, reset sequence numbers */
946  kx->last_packets_bitmap = 0;
947  setup_fresh_ping (kx);
948 }
949 
950 
958 static void
959 handle_ephemeral_key (void *cls, const struct EphemeralKeyMessage *m)
960 {
961  struct GSC_KeyExchangeInfo *kx = cls;
962  struct GNUNET_TIME_Absolute start_t;
963  struct GNUNET_TIME_Absolute end_t;
964  struct GNUNET_TIME_Absolute now;
966 
969  (GNUNET_CORE_KX_STATE_UP == kx->status) ||
972  {
974  gettext_noop ("# old ephemeral keys ignored"),
975  1,
976  GNUNET_NO);
978  "Received expired EPHEMERAL_KEY from %s\n",
980  return;
981  }
982  if (0 == memcmp (&m->ephemeral_key,
983  &kx->other_ephemeral_key,
984  sizeof (m->ephemeral_key)))
985  {
987  gettext_noop (
988  "# duplicate ephemeral keys ignored"),
989  1,
990  GNUNET_NO);
992  "Ignoring duplicate EPHEMERAL_KEY from %s\n",
994  return;
995  }
996  if (0 != memcmp (&m->origin_identity,
997  kx->peer,
998  sizeof (struct GNUNET_PeerIdentity)))
999  {
1001  "Received EPHEMERAL_KEY from %s, but expected %s\n",
1003  GNUNET_i2s_full (kx->peer));
1004  GNUNET_break_op (0);
1005  return;
1006  }
1007  if ((ntohl (m->purpose.size) !=
1008  sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) +
1009  sizeof (struct GNUNET_TIME_AbsoluteNBO) +
1010  sizeof (struct GNUNET_TIME_AbsoluteNBO) +
1011  sizeof (struct GNUNET_CRYPTO_EddsaPublicKey) +
1012  sizeof (struct GNUNET_CRYPTO_EddsaPublicKey)) ||
1013  (GNUNET_OK !=
1015  &m->purpose,
1016  &m->signature,
1018  {
1019  /* invalid signature */
1020  GNUNET_break_op (0);
1022  gettext_noop (
1023  "# EPHEMERAL_KEYs rejected (bad signature)"),
1024  1,
1025  GNUNET_NO);
1027  "Received EPHEMERAL_KEY from %s with bad signature\n",
1028  GNUNET_i2s (&m->origin_identity));
1029  return;
1030  }
1031  now = GNUNET_TIME_absolute_get ();
1033  if ((end_t.abs_value_us <
1035  (start_t.abs_value_us >
1036  GNUNET_TIME_absolute_add (now, REKEY_TOLERANCE).abs_value_us))
1037  {
1038  GNUNET_log (
1040  _ (
1041  "EPHEMERAL_KEY from peer `%s' rejected as its validity range does not match our system time (%llu not in [%llu,%llu]).\n"),
1042  GNUNET_i2s (kx->peer),
1043  (unsigned long long) now.abs_value_us,
1044  (unsigned long long) start_t.abs_value_us,
1045  (unsigned long long) end_t.abs_value_us);
1047  gettext_noop (
1048  "# EPHEMERAL_KEY messages rejected due to time"),
1049  1,
1050  GNUNET_NO);
1051  return;
1052  }
1053 #if DEBUG_KX
1054  {
1055  struct GNUNET_HashCode eh;
1056 
1057  GNUNET_CRYPTO_hash (&m->ephemeral_key, sizeof (m->ephemeral_key), &eh);
1059  "Received valid EPHEMERAL_KEY `%s' from `%s' in state %d.\n",
1060  GNUNET_h2s (&eh),
1061  GNUNET_i2s (kx->peer),
1062  kx->status);
1063  }
1064 #endif
1066  gettext_noop ("# valid ephemeral keys received"),
1067  1,
1068  GNUNET_NO);
1070  kx->foreign_key_expires = end_t;
1071  derive_session_keys (kx);
1072 
1073  /* check if we still need to send the sender our key */
1074  sender_status = (enum GNUNET_CORE_KxState) ntohl (m->sender_status);
1075  switch (sender_status)
1076  {
1078  GNUNET_break_op (0);
1079  break;
1081  /* fine, need to send our key after updating our status, see below */
1082  GSC_SESSIONS_reinit (kx->peer);
1083  break;
1085  /* other peer already got our key, but typemap did go down */
1086  GSC_SESSIONS_reinit (kx->peer);
1087  break;
1089  /* other peer already got our key, typemap NOT down */
1090  break;
1092  /* other peer already got our key, typemap NOT down */
1093  break;
1094  default:
1095  GNUNET_break (0);
1096  break;
1097  }
1098  /* check if we need to confirm everything is fine via PING + PONG */
1099  switch (kx->status)
1100  {
1102  GNUNET_assert (NULL == kx->keep_alive_task);
1104  monitor_notify_all (kx);
1105  if (GNUNET_CORE_KX_STATE_KEY_SENT == sender_status)
1106  send_key (kx);
1107  else
1108  send_ping (kx);
1109  break;
1111  GNUNET_assert (NULL == kx->keep_alive_task);
1113  monitor_notify_all (kx);
1114  if (GNUNET_CORE_KX_STATE_KEY_SENT == sender_status)
1115  send_key (kx);
1116  else
1117  send_ping (kx);
1118  break;
1120  GNUNET_assert (NULL == kx->keep_alive_task);
1121  if (GNUNET_CORE_KX_STATE_KEY_SENT == sender_status)
1122  send_key (kx);
1123  else
1124  send_ping (kx);
1125  break;
1128  monitor_notify_all (kx);
1129  if (GNUNET_CORE_KX_STATE_KEY_SENT == sender_status)
1130  send_key (kx);
1131  else
1132  send_ping (kx);
1133  break;
1135  if (GNUNET_CORE_KX_STATE_KEY_SENT == sender_status)
1136  send_key (kx);
1137  else
1138  send_ping (kx);
1139  break;
1140  default:
1141  GNUNET_break (0);
1142  break;
1143  }
1144 }
1145 
1146 
1154 static void
1155 handle_ping (void *cls, const struct PingMessage *m)
1156 {
1157  struct GSC_KeyExchangeInfo *kx = cls;
1158  struct PingMessage t;
1159  struct PongMessage tx;
1160  struct PongMessage *tp;
1161  struct GNUNET_MQ_Envelope *env;
1163 
1165  gettext_noop ("# PING messages received"),
1166  1,
1167  GNUNET_NO);
1169  (kx->status != GNUNET_CORE_KX_STATE_UP) &&
1171  {
1172  /* ignore */
1174  gettext_noop (
1175  "# PING messages dropped (out of order)"),
1176  1,
1177  GNUNET_NO);
1178  return;
1179  }
1181  "Core service receives PING request from `%s'.\n",
1182  GNUNET_i2s (kx->peer));
1183  derive_iv (&iv, &kx->decrypt_key, m->iv_seed, &GSC_my_identity);
1184  if (GNUNET_OK != do_decrypt (kx,
1185  &iv,
1186  &m->target,
1187  &t.target,
1188  sizeof (struct PingMessage) -
1189  ((void *) &m->target - (void *) m)))
1190  {
1191  GNUNET_break_op (0);
1192  return;
1193  }
1194  if (0 !=
1195  memcmp (&t.target, &GSC_my_identity, sizeof (struct GNUNET_PeerIdentity)))
1196  {
1199  "Decryption of PING from peer `%s' failed, PING for `%s'?\n",
1200  GNUNET_i2s (kx->peer),
1201  GNUNET_i2s2 (&t.target));
1202  else
1203  GNUNET_log (
1205  "Decryption of PING from peer `%s' failed after rekey (harmless)\n",
1206  GNUNET_i2s (kx->peer));
1207  GNUNET_break_op (0);
1208  return;
1209  }
1210  /* construct PONG */
1211  tx.reserved = 0;
1212  tx.challenge = t.challenge;
1213  tx.target = t.target;
1215  tp->iv_seed = calculate_seed (kx);
1216  derive_pong_iv (&iv, &kx->encrypt_key, tp->iv_seed, t.challenge, kx->peer);
1217  do_encrypt (kx,
1218  &iv,
1219  &tx.challenge,
1220  &tp->challenge,
1221  sizeof (struct PongMessage) -
1222  ((void *) &tp->challenge - (void *) tp));
1224  gettext_noop ("# PONG messages created"),
1225  1,
1226  GNUNET_NO);
1227  GNUNET_MQ_send (kx->mq, env);
1228 }
1229 
1230 
1237 static void
1238 send_keep_alive (void *cls)
1239 {
1240  struct GSC_KeyExchangeInfo *kx = cls;
1241  struct GNUNET_TIME_Relative retry;
1242  struct GNUNET_TIME_Relative left;
1243 
1244  kx->keep_alive_task = NULL;
1246  if (0 == left.rel_value_us)
1247  {
1249  gettext_noop ("# sessions terminated by timeout"),
1250  1,
1251  GNUNET_NO);
1252  GSC_SESSIONS_end (kx->peer);
1254  monitor_notify_all (kx);
1255  send_key (kx);
1256  return;
1257  }
1259  "Sending KEEPALIVE to `%s'\n",
1260  GNUNET_i2s (kx->peer));
1262  gettext_noop ("# keepalive messages sent"),
1263  1,
1264  GNUNET_NO);
1265  setup_fresh_ping (kx);
1266  send_ping (kx);
1269  kx->keep_alive_task =
1271 }
1272 
1273 
1281 static void
1283 {
1284  struct GNUNET_TIME_Relative delta;
1285 
1286  kx->timeout =
1288  delta =
1290  if (delta.rel_value_us > 5LL * 1000LL * 1000LL)
1291  {
1292  /* we only notify monitors about timeout changes if those
1293  are bigger than the threshold (5s) */
1294  monitor_notify_all (kx);
1295  }
1296  if (NULL != kx->keep_alive_task)
1300  &send_keep_alive,
1301  kx);
1302 }
1303 
1304 
1311 static void
1312 handle_pong (void *cls, const struct PongMessage *m)
1313 {
1314  struct GSC_KeyExchangeInfo *kx = cls;
1315  struct PongMessage t;
1317 
1319  gettext_noop ("# PONG messages received"),
1320  1,
1321  GNUNET_NO);
1322  switch (kx->status)
1323  {
1326  gettext_noop (
1327  "# PONG messages dropped (connection down)"),
1328  1,
1329  GNUNET_NO);
1330  return;
1333  gettext_noop (
1334  "# PONG messages dropped (out of order)"),
1335  1,
1336  GNUNET_NO);
1337  return;
1339  break;
1341  break;
1343  break;
1344  default:
1345  GNUNET_break (0);
1346  return;
1347  }
1349  "Core service receives PONG response from `%s'.\n",
1350  GNUNET_i2s (kx->peer));
1351  /* mark as garbage, just to be sure */
1352  memset (&t, 255, sizeof (t));
1353  derive_pong_iv (&iv,
1354  &kx->decrypt_key,
1355  m->iv_seed,
1356  kx->ping_challenge,
1357  &GSC_my_identity);
1358  if (GNUNET_OK != do_decrypt (kx,
1359  &iv,
1360  &m->challenge,
1361  &t.challenge,
1362  sizeof (struct PongMessage) -
1363  ((void *) &m->challenge - (void *) m)))
1364  {
1365  GNUNET_break_op (0);
1366  return;
1367  }
1369  gettext_noop ("# PONG messages decrypted"),
1370  1,
1371  GNUNET_NO);
1372  if ((0 !=
1373  memcmp (&t.target, kx->peer, sizeof (struct GNUNET_PeerIdentity))) ||
1374  (kx->ping_challenge != t.challenge))
1375  {
1376  /* PONG malformed */
1378  "Received malformed PONG wanted sender `%s' with challenge %u\n",
1379  GNUNET_i2s (kx->peer),
1380  (unsigned int) kx->ping_challenge);
1382  "Received malformed PONG received from `%s' with challenge %u\n",
1383  GNUNET_i2s (&t.target),
1384  (unsigned int) t.challenge);
1385  return;
1386  }
1388  "Received valid PONG from `%s'\n",
1389  GNUNET_i2s (kx->peer));
1390  /* no need to resend key any longer */
1391  if (NULL != kx->retry_set_key_task)
1392  {
1394  kx->retry_set_key_task = NULL;
1395  }
1396  switch (kx->status)
1397  {
1399  GNUNET_assert (0); /* should be impossible */
1400  return;
1402  GNUNET_assert (0); /* should be impossible */
1403  return;
1406  gettext_noop (
1407  "# session keys confirmed via PONG"),
1408  1,
1409  GNUNET_NO);
1411  monitor_notify_all (kx);
1412  GSC_SESSIONS_create (kx->peer, kx);
1413  GNUNET_assert (NULL == kx->keep_alive_task);
1414  update_timeout (kx);
1415  break;
1418  gettext_noop ("# timeouts prevented via PONG"),
1419  1,
1420  GNUNET_NO);
1421  update_timeout (kx);
1422  break;
1425  gettext_noop (
1426  "# rekey operations confirmed via PONG"),
1427  1,
1428  GNUNET_NO);
1430  monitor_notify_all (kx);
1431  update_timeout (kx);
1432  break;
1433  default:
1434  GNUNET_break (0);
1435  break;
1436  }
1437 }
1438 
1439 
1445 static void
1447 {
1448  struct GNUNET_MQ_Envelope *env;
1449 
1451  if (NULL != kx->retry_set_key_task)
1452  {
1454  kx->retry_set_key_task = NULL;
1455  }
1456  /* always update sender status in SET KEY message */
1457 #if DEBUG_KX
1458  {
1459  struct GNUNET_HashCode hc;
1460 
1462  sizeof (current_ekm.ephemeral_key),
1463  &hc);
1465  "Sending EPHEMERAL_KEY %s to `%s' (my status: %d)\n",
1466  GNUNET_h2s (&hc),
1467  GNUNET_i2s (kx->peer),
1468  kx->status);
1469  }
1470 #endif
1471  current_ekm.sender_status = htonl ((int32_t) (kx->status));
1473  GNUNET_MQ_send (kx->mq, env);
1475  send_ping (kx);
1476  kx->retry_set_key_task =
1479  kx);
1480 }
1481 
1482 
1490 void
1492  const void *payload,
1493  size_t payload_size)
1494 {
1495  size_t used = payload_size + sizeof (struct EncryptedMessage);
1496  char pbuf[used]; /* plaintext */
1497  struct EncryptedMessage *em; /* encrypted message */
1498  struct EncryptedMessage *ph; /* plaintext header */
1499  struct GNUNET_MQ_Envelope *env;
1501  struct GNUNET_CRYPTO_AuthKey auth_key;
1502 
1503  ph = (struct EncryptedMessage *) pbuf;
1504  ph->sequence_number = htonl (++kx->last_sequence_number_sent);
1505  ph->iv_seed = calculate_seed (kx);
1506  ph->reserved = 0;
1508  GNUNET_memcpy (&ph[1], payload, payload_size);
1509  env = GNUNET_MQ_msg_extra (em,
1510  payload_size,
1512  em->iv_seed = ph->iv_seed;
1513  derive_iv (&iv, &kx->encrypt_key, ph->iv_seed, kx->peer);
1515  &iv,
1516  &ph->sequence_number,
1517  &em->sequence_number,
1518  used - ENCRYPTED_HEADER_SIZE));
1519 #if DEBUG_KX
1520  {
1521  struct GNUNET_HashCode hc;
1522 
1523  GNUNET_CRYPTO_hash (&ph->sequence_number,
1524  used - ENCRYPTED_HEADER_SIZE,
1525  &hc);
1527  "Encrypted payload `%s' of %u bytes for %s\n",
1528  GNUNET_h2s (&hc),
1529  (unsigned int) (used - ENCRYPTED_HEADER_SIZE),
1530  GNUNET_i2s (kx->peer));
1531  }
1532 #endif
1533  derive_auth_key (&auth_key, &kx->encrypt_key, ph->iv_seed);
1534  GNUNET_CRYPTO_hmac (&auth_key,
1535  &em->sequence_number,
1536  used - ENCRYPTED_HEADER_SIZE,
1537  &em->hmac);
1538 #if DEBUG_KX
1539  {
1540  struct GNUNET_HashCode hc;
1541 
1542  GNUNET_CRYPTO_hash (&auth_key, sizeof (auth_key), &hc);
1544  "For peer %s, used AC %s to create hmac %s\n",
1545  GNUNET_i2s (kx->peer),
1546  GNUNET_h2s (&hc),
1547  GNUNET_h2s2 (&em->hmac));
1548  }
1549 #endif
1551  GNUNET_MQ_send (kx->mq, env);
1552 }
1553 
1554 
1563 static int
1564 check_encrypted (void *cls, const struct EncryptedMessage *m)
1565 {
1566  uint16_t size = ntohs (m->header.size) - sizeof (*m);
1567 
1568  if (size < sizeof (struct GNUNET_MessageHeader))
1569  {
1570  GNUNET_break_op (0);
1571  return GNUNET_SYSERR;
1572  }
1573  return GNUNET_OK;
1574 }
1575 
1576 
1584 static void
1585 handle_encrypted (void *cls, const struct EncryptedMessage *m)
1586 {
1587  struct GSC_KeyExchangeInfo *kx = cls;
1588  struct EncryptedMessage *pt; /* plaintext */
1589  struct GNUNET_HashCode ph;
1590  uint32_t snum;
1591  struct GNUNET_TIME_Absolute t;
1593  struct GNUNET_CRYPTO_AuthKey auth_key;
1594  uint16_t size = ntohs (m->header.size);
1595  char buf[size] GNUNET_ALIGN;
1596 
1597  if (GNUNET_CORE_KX_STATE_UP != kx->status)
1598  {
1600  gettext_noop (
1601  "# DATA message dropped (out of order)"),
1602  1,
1603  GNUNET_NO);
1604  return;
1605  }
1606  if (0 ==
1608  {
1609  GNUNET_log (
1611  _ (
1612  "Session to peer `%s' went down due to key expiration (should not happen)\n"),
1613  GNUNET_i2s (kx->peer));
1615  gettext_noop (
1616  "# sessions terminated by key expiration"),
1617  1,
1618  GNUNET_NO);
1619  GSC_SESSIONS_end (kx->peer);
1620  if (NULL != kx->keep_alive_task)
1621  {
1623  kx->keep_alive_task = NULL;
1624  }
1626  monitor_notify_all (kx);
1627  send_key (kx);
1628  return;
1629  }
1630 
1631  /* validate hash */
1632 #if DEBUG_KX
1633  {
1634  struct GNUNET_HashCode hc;
1635 
1638  "Received encrypted payload `%s' of %u bytes from %s\n",
1639  GNUNET_h2s (&hc),
1640  (unsigned int) (size - ENCRYPTED_HEADER_SIZE),
1641  GNUNET_i2s (kx->peer));
1642  }
1643 #endif
1644  derive_auth_key (&auth_key, &kx->decrypt_key, m->iv_seed);
1645  GNUNET_CRYPTO_hmac (&auth_key,
1646  &m->sequence_number,
1647  size - ENCRYPTED_HEADER_SIZE,
1648  &ph);
1649 #if DEBUG_KX
1650  {
1651  struct GNUNET_HashCode hc;
1652 
1653  GNUNET_CRYPTO_hash (&auth_key, sizeof (auth_key), &hc);
1655  "For peer %s, used AC %s to verify hmac %s\n",
1656  GNUNET_i2s (kx->peer),
1657  GNUNET_h2s (&hc),
1658  GNUNET_h2s2 (&m->hmac));
1659  }
1660 #endif
1661  if (0 != memcmp (&ph, &m->hmac, sizeof (struct GNUNET_HashCode)))
1662  {
1663  /* checksum failed */
1665  "Failed checksum validation for a message from `%s'\n",
1666  GNUNET_i2s (kx->peer));
1667  return;
1668  }
1669  derive_iv (&iv, &kx->decrypt_key, m->iv_seed, &GSC_my_identity);
1670  /* decrypt */
1671  if (GNUNET_OK != do_decrypt (kx,
1672  &iv,
1673  &m->sequence_number,
1675  size - ENCRYPTED_HEADER_SIZE))
1676  {
1677  GNUNET_break_op (0);
1678  return;
1679  }
1681  "Decrypted %u bytes from %s\n",
1682  (unsigned int) (size - ENCRYPTED_HEADER_SIZE),
1683  GNUNET_i2s (kx->peer));
1684  pt = (struct EncryptedMessage *) buf;
1685 
1686  /* validate sequence number */
1687  snum = ntohl (pt->sequence_number);
1688  if (kx->last_sequence_number_received == snum)
1689  {
1691  "Received duplicate message, ignoring.\n");
1692  /* duplicate, ignore */
1694  gettext_noop ("# bytes dropped (duplicates)"),
1695  size,
1696  GNUNET_NO);
1697  return;
1698  }
1699  if ((kx->last_sequence_number_received > snum) &&
1700  (kx->last_sequence_number_received - snum > 32))
1701  {
1703  "Received ancient out of sequence message, ignoring.\n");
1704  /* ancient out of sequence, ignore */
1706  gettext_noop (
1707  "# bytes dropped (out of sequence)"),
1708  size,
1709  GNUNET_NO);
1710  return;
1711  }
1712  if (kx->last_sequence_number_received > snum)
1713  {
1714  uint32_t rotbit = 1U << (kx->last_sequence_number_received - snum - 1);
1715 
1716  if ((kx->last_packets_bitmap & rotbit) != 0)
1717  {
1719  "Received duplicate message, ignoring.\n");
1721  gettext_noop ("# bytes dropped (duplicates)"),
1722  size,
1723  GNUNET_NO);
1724  /* duplicate, ignore */
1725  return;
1726  }
1727  kx->last_packets_bitmap |= rotbit;
1728  }
1729  if (kx->last_sequence_number_received < snum)
1730  {
1731  unsigned int shift = (snum - kx->last_sequence_number_received);
1732 
1733  if (shift >= 8 * sizeof (kx->last_packets_bitmap))
1734  kx->last_packets_bitmap = 0;
1735  else
1736  kx->last_packets_bitmap <<= shift;
1737  kx->last_sequence_number_received = snum;
1738  }
1739 
1740  /* check timestamp */
1742  if (GNUNET_TIME_absolute_get_duration (t).rel_value_us >
1743  MAX_MESSAGE_AGE.rel_value_us)
1744  {
1746  "Message received far too old (%s). Content ignored.\n",
1749  GNUNET_YES));
1751  gettext_noop (
1752  "# bytes dropped (ancient message)"),
1753  size,
1754  GNUNET_NO);
1755  return;
1756  }
1757 
1758  /* process decrypted message(s) */
1759  update_timeout (kx);
1761  gettext_noop ("# bytes of payload decrypted"),
1762  size - sizeof (struct EncryptedMessage),
1763  GNUNET_NO);
1764  if (GNUNET_OK !=
1766  &buf[sizeof (struct EncryptedMessage)],
1767  size - sizeof (struct EncryptedMessage),
1768  GNUNET_YES,
1769  GNUNET_NO))
1770  GNUNET_break_op (0);
1771 }
1772 
1773 
1781 static void
1783  const struct GNUNET_PeerIdentity *pid,
1784  void *connect_cls)
1785 {
1786  struct GSC_KeyExchangeInfo *kx = connect_cls;
1787 
1789  "Peer %s has excess bandwidth available\n",
1790  GNUNET_i2s (pid));
1792  GSC_SESSIONS_solicit (pid);
1793 }
1794 
1795 
1800 static void
1802 {
1803  current_ekm.header.size = htons (sizeof (struct EphemeralKeyMessage));
1805  current_ekm.sender_status = 0; /* to be set later */
1808  htonl (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) +
1809  sizeof (struct GNUNET_TIME_AbsoluteNBO) +
1810  sizeof (struct GNUNET_TIME_AbsoluteNBO) +
1811  sizeof (struct GNUNET_CRYPTO_EcdhePublicKey) +
1812  sizeof (struct GNUNET_PeerIdentity));
1816  "core",
1817  "USE_EPHEMERAL_KEYS"))
1818  {
1822  }
1823  else
1824  {
1827  }
1828  GNUNET_CRYPTO_ecdhe_key_get_public (my_ephemeral_key,
1832  GNUNET_CRYPTO_eddsa_sign (my_private_key,
1835 }
1836 
1837 
1843 static void
1844 do_rekey (void *cls)
1845 {
1846  struct GSC_KeyExchangeInfo *pos;
1847 
1848  rekey_task = GNUNET_SCHEDULER_add_delayed (REKEY_FREQUENCY, &do_rekey, NULL);
1849  if (NULL != my_ephemeral_key)
1850  GNUNET_free (my_ephemeral_key);
1851  my_ephemeral_key = GNUNET_CRYPTO_ecdhe_key_create ();
1852  GNUNET_assert (NULL != my_ephemeral_key);
1853  sign_ephemeral_key ();
1854  {
1855  struct GNUNET_HashCode eh;
1856 
1858  sizeof (current_ekm.ephemeral_key),
1859  &eh);
1860  GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Rekeying to %s\n", GNUNET_h2s (&eh));
1861  }
1862  for (pos = kx_head; NULL != pos; pos = pos->next)
1863  {
1864  if (GNUNET_CORE_KX_STATE_UP == pos->status)
1865  {
1867  monitor_notify_all (pos);
1868  derive_session_keys (pos);
1869  }
1870  if (GNUNET_CORE_KX_STATE_DOWN == pos->status)
1871  {
1873  monitor_notify_all (pos);
1874  }
1875  monitor_notify_all (pos);
1876  send_key (pos);
1877  }
1878 }
1879 
1880 
1887 int
1889 {
1890  struct GNUNET_MQ_MessageHandler handlers[] =
1893  struct EphemeralKeyMessage,
1894  NULL),
1897  struct PingMessage,
1898  NULL),
1901  struct PongMessage,
1902  NULL),
1903  GNUNET_MQ_hd_var_size (encrypted,
1905  struct EncryptedMessage,
1906  NULL),
1908 
1909  my_private_key = pk;
1910  GNUNET_CRYPTO_eddsa_key_get_public (my_private_key,
1912  my_ephemeral_key = GNUNET_CRYPTO_ecdhe_key_create ();
1913  if (NULL == my_ephemeral_key)
1914  {
1915  GNUNET_break (0);
1916  GNUNET_free (my_private_key);
1917  my_private_key = NULL;
1918  return GNUNET_SYSERR;
1919  }
1920  sign_ephemeral_key ();
1921  {
1922  struct GNUNET_HashCode eh;
1923 
1925  sizeof (current_ekm.ephemeral_key),
1926  &eh);
1928  "Starting with ephemeral key %s\n",
1929  GNUNET_h2s (&eh));
1930  }
1931 
1933  rekey_task = GNUNET_SCHEDULER_add_delayed (REKEY_FREQUENCY, &do_rekey, NULL);
1934  transport =
1936  &GSC_my_identity,
1937  handlers,
1938  NULL,
1942  if (NULL == transport)
1943  {
1944  GSC_KX_done ();
1945  return GNUNET_SYSERR;
1946  }
1947  return GNUNET_OK;
1948 }
1949 
1950 
1954 void
1956 {
1957  if (NULL != transport)
1958  {
1960  transport = NULL;
1961  }
1962  if (NULL != rekey_task)
1963  {
1964  GNUNET_SCHEDULER_cancel (rekey_task);
1965  rekey_task = NULL;
1966  }
1967  if (NULL != my_ephemeral_key)
1968  {
1969  GNUNET_free (my_ephemeral_key);
1970  my_ephemeral_key = NULL;
1971  }
1972  if (NULL != my_private_key)
1973  {
1974  GNUNET_free (my_private_key);
1975  my_private_key = NULL;
1976  }
1977  if (NULL != nc)
1978  {
1980  nc = NULL;
1981  }
1982 }
1983 
1984 
1991 unsigned int
1993 {
1994  return GNUNET_MQ_get_length (kxinfo->mq);
1995 }
1996 
1997 
2004 int
2006 {
2007  return kxinfo->has_excess_bandwidth;
2008 }
2009 
2010 
2019 void
2021 {
2022  struct GNUNET_MQ_Envelope *env;
2023  struct MonitorNotifyMessage *done_msg;
2024  struct GSC_KeyExchangeInfo *kx;
2025 
2027  for (kx = kx_head; NULL != kx; kx = kx->next)
2028  {
2029  struct GNUNET_MQ_Envelope *env;
2030  struct MonitorNotifyMessage *msg;
2031 
2033  msg->state = htonl ((uint32_t) kx->status);
2034  msg->peer = *kx->peer;
2036  GNUNET_MQ_send (mq, env);
2037  }
2039  done_msg->state = htonl ((uint32_t) GNUNET_CORE_KX_ITERATION_FINISHED);
2041  GNUNET_MQ_send (mq, env);
2042 }
2043 
2044 
2045 /* end of gnunet-service-core_kx.c */
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_SIGNATURE_PURPOSE_SET_ECC_KEY
Purpose is to set a session key.
#define REKEY_TOLERANCE
What time difference do we tolerate?
void GSC_SESSIONS_confirm_typemap(const struct GNUNET_PeerIdentity *peer, const struct GNUNET_MessageHeader *msg)
The other peer has confirmed receiving our type map, check if it is current and if so...
struct GNUNET_MQ_Envelope * GNUNET_MQ_msg_copy(const struct GNUNET_MessageHeader *hdr)
Create a new envelope by copying an existing message.
Definition: mq.c:653
The notification context is the key datastructure for a convenience API used for transmission of noti...
Definition: nc.c:77
static struct GNUNET_CRYPTO_EddsaPrivateKey * pk
Private key of this peer.
const char * GNUNET_i2s2(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
static void ping(void *cls)
Send a ping to destination.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_subtract(struct GNUNET_TIME_Absolute start, struct GNUNET_TIME_Relative duration)
Subtract a given relative duration from the given start time.
Definition: time.c:419
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh(struct GNUNET_TIME_AbsoluteNBO a)
Convert absolute time from network byte order.
Definition: time.c:670
static void derive_aes_key(const struct GNUNET_PeerIdentity *sender, const struct GNUNET_PeerIdentity *receiver, const struct GNUNET_HashCode *key_material, struct GNUNET_CRYPTO_SymmetricSessionKey *skey)
Derive an AES key from key material.
const struct GNUNET_PeerIdentity * peer
Identity of the peer.
void GSC_KX_handle_client_monitor_peers(struct GNUNET_MQ_Handle *mq)
Handle GNUNET_MESSAGE_TYPE_CORE_MONITOR_PEERS request.
uint64_t rel_value_us
The actual value.
struct GNUNET_TIME_Relative set_key_retry_frequency
At what frequency are we currently re-trying SET_KEY messages?
uint32_t iv_seed
Seed for the IV.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
enum GNUNET_CORE_KxState status
What is our connection status?
uint32_t last_packets_bitmap
Bit map indicating which of the 32 sequence numbers before the last were received (good for accepting...
struct GNUNET_PeerIdentity target
Intended target of the PING, used primarily to check that decryption actually worked.
int32_t GNUNET_CRYPTO_crc32_n(const void *buf, size_t len)
Compute the CRC32 checksum for the first len bytes of the buffer.
Definition: crypto_crc.c:105
uint32_t purpose
What does this signature vouch for? This must contain a GNUNET_SIGNATURE_PURPOSE_XXX constant (from g...
struct PingMessage ping
PING message we transmit to the other peer.
uint32_t sequence_number
Sequence number, in network byte order.
static struct GNUNET_CRYPTO_EcdhePrivateKey * my_ephemeral_key
Our ephemeral private key.
static void do_rekey(void *cls)
Task run to trigger rekeying.
struct GNUNET_TIME_Relative GNUNET_TIME_relative_max(struct GNUNET_TIME_Relative t1, struct GNUNET_TIME_Relative t2)
Return the maximum of two relative time values.
Definition: time.c:286
static void handle_ephemeral_key(void *cls, const struct EphemeralKeyMessage *m)
We received a GNUNET_MESSAGE_TYPE_CORE_EPHEMERAL_KEY message.
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:245
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random value.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
Response to a PING.
static struct GNUNET_ATS_PerformanceHandle * ph
ATS performance handle used.
Definition: gnunet-ats.c:116
static void send_key(struct GSC_KeyExchangeInfo *kx)
Send our key (and encrypted PING) to the other peer.
#define GNUNET_TIME_UNIT_SECONDS
One second.
uint32_t last_sequence_number_sent
last sequence number transmitted
struct GNUNET_TIME_AbsoluteNBO timeout
How long will we stay in this state (if nothing else happens)?
Definition: core.h:324
static int do_encrypt(struct GSC_KeyExchangeInfo *kx, const struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, const void *in, void *out, size_t size)
Encrypt size bytes from in and write the result to out.
int GNUNET_CRYPTO_eddsa_sign(const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose, struct GNUNET_CRYPTO_EddsaSignature *sig)
EdDSA sign a given block.
Definition: crypto_ecc.c:989
static struct GNUNET_TRANSPORT_CoreHandle * transport
Transport service.
static void derive_session_keys(struct GSC_KeyExchangeInfo *kx)
Derive fresh session keys from the current ephemeral keys.
unsigned int GSC_NEIGHBOURS_get_queue_length(const struct GSC_KeyExchangeInfo *kxinfo)
Check how many messages are queued for the given neighbour.
common internal definitions for core service
#define GNUNET_MQ_hd_fixed_size(name, code, str, ctx)
int 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:1184
static struct GNUNET_CRYPTO_EddsaPrivateKey * my_private_key
Our private key.
static void handle_transport_notify_excess_bw(void *cls, const struct GNUNET_PeerIdentity *pid, void *connect_cls)
One of our neighbours has excess bandwidth, remember this.
struct GNUNET_CRYPTO_EcdhePrivateKey * GNUNET_CRYPTO_ecdhe_key_create(void)
Create a new private key.
Definition: crypto_ecc.c:610
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:67
#define GNUNET_NO
Definition: gnunet_common.h:81
const char * GNUNET_i2s_full(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
static void sign_ephemeral_key()
Setup the message that links the ephemeral key to our persistent public key and generate the appropri...
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:393
GNUNET_CORE_KxState
State machine for our P2P encryption handshake.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
static void handle_encrypted(void *cls, const struct EncryptedMessage *m)
We received an encrypted message.
static struct GSC_KeyExchangeInfo * kx_head
DLL head.
struct GNUNET_TRANSPORT_CoreHandle * GNUNET_TRANSPORT_core_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, const struct GNUNET_PeerIdentity *self, const struct GNUNET_MQ_MessageHandler *handlers, void *cls, GNUNET_TRANSPORT_NotifyConnect nc, GNUNET_TRANSPORT_NotifyDisconnect nd)
Connect to the transport service.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
static void handle_ping(void *cls, const struct PingMessage *m)
We received a PING message.
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_HashCode hmac
MAC of the encrypted message (starting at sequence_number), used to verify message integrity...
struct GNUNET_STATISTICS_Handle * GSC_stats
For creating statistics.
We&#39;ve received the other peers session key.
struct GNUNET_MessageStreamTokenizer * mst
Our message stream tokenizer (for encrypted payload).
Time for absolute time used by GNUnet, in microseconds and in network byte order. ...
static void derive_auth_key(struct GNUNET_CRYPTO_AuthKey *akey, const struct GNUNET_CRYPTO_SymmetricSessionKey *skey, uint32_t seed)
Derive an authentication key from "set key" information.
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:418
void GNUNET_notification_context_add(struct GNUNET_NotificationContext *nc, struct GNUNET_MQ_Handle *mq)
Add a subscriber to the notification context.
Definition: nc.c:164
uint64_t abs_value_us
The actual value.
struct GNUNET_TIME_Absolute last_notify_timeout
What was the last timeout we informed our monitors about?
#define GNUNET_MESSAGE_TYPE_CORE_COMPRESSED_TYPE_MAP
gzip-compressed type map of the sender
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
#define GNUNET_MESSAGE_TYPE_CORE_PONG
Confirmation that other peer is alive.
#define GNUNET_NETWORK_STRUCT_BEGIN
Define as empty, GNUNET_PACKED should suffice, but this won&#39;t work on W32.
static struct GNUNET_DNSSTUB_Context * ctx
Context for DNS resolution.
#define GNUNET_TIME_UNIT_FOREVER_ABS
Constant used to specify "forever".
#define _(String)
GNU gettext support macro.
Definition: platform.h:208
struct GNUNET_TIME_AbsoluteNBO expiration_time
When does the given ephemeral key expire (end of validity).
struct GNUNET_MessageHeader header
Header with type GNUNET_MESSAGE_TYPE_CORE_MONITOR_NOTIFY.
Definition: core.h:309
struct GNUNET_MessageHeader header
Message type is GNUNET_MESSAGE_TYPE_CORE_ENCRYPTED_MESSAGE.
header of what an ECC signature signs this must be followed by "size - 8" bytes of the actual signed ...
static int deliver_message(void *cls, const struct GNUNET_MessageHeader *m)
Deliver P2P message to interested clients.
struct GNUNET_SCHEDULER_Task * retry_set_key_task
ID of task used for re-trying SET_KEY and PING message.
static struct GNUNET_ARM_MonitorHandle * m
Monitor connection with ARM.
Definition: gnunet-arm.c:99
struct GNUNET_CRYPTO_EddsaSignature signature
An ECC signature of the origin_identity asserting the validity of the given ephemeral key...
struct GNUNET_TIME_AbsoluteNBO creation_time
At what time was this key created (beginning of validity).
struct GNUNET_MQ_Handle * mq
Message queue for sending messages to peer.
const char * GNUNET_h2s2(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
#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:52
static void monitor_notify_all(struct GSC_KeyExchangeInfo *kx)
Inform all monitors about the KX state of the given peer.
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:1246
static int do_decrypt(struct GSC_KeyExchangeInfo *kx, const struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, const void *in, void *out, size_t size)
Decrypt size bytes from in and write the result to out.
uint32_t challenge
Random number to make replay attacks harder.
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
static struct GNUNET_TIME_Relative timeout
User defined timestamp for completing operations.
Definition: gnunet-arm.c:114
#define GNUNET_memcpy(dst, src, n)
int GNUNET_CRYPTO_eddsa_verify(uint32_t purpose, const struct GNUNET_CRYPTO_EccSignaturePurpose *validate, const struct GNUNET_CRYPTO_EddsaSignature *sig, const struct GNUNET_CRYPTO_EddsaPublicKey *pub)
Verify EdDSA signature.
Definition: crypto_ecc.c:1116
void GSC_KX_encrypt_and_transmit(struct GSC_KeyExchangeInfo *kx, const void *payload, size_t payload_size)
Encrypt and transmit a message with the given payload.
static int check_encrypted(void *cls, const struct EncryptedMessage *m)
We received an encrypted message.
static void send_ping(struct GSC_KeyExchangeInfo *kx)
Send our PING to the other peer.
We&#39;re sending an (encrypted) PING to the other peer to check if it can decrypt.
static void send_keep_alive(void *cls)
Task triggered when a neighbour entry is about to time out (and we should prevent this by sending a P...
void GNUNET_MST_destroy(struct GNUNET_MessageStreamTokenizer *mst)
Destroys a tokenizer.
Definition: mst.c:413
uint32_t challenge
Random number chosen to make replay harder.
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:44
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.
#define GNUNET_MESSAGE_TYPE_CORE_CONFIRM_TYPE_MAP
Other peer confirms having received the type map.
unsigned int GNUNET_MQ_get_length(struct GNUNET_MQ_Handle *mq)
Obtain the current length of the message queue.
Definition: mq.c:335
Encapsulation for encrypted messages exchanged between peers.
struct GSC_KeyExchangeInfo * next
DLL.
static struct GSC_KeyExchangeInfo * kx_tail
DLL tail.
struct GNUNET_CRYPTO_EcdhePublicKey other_ephemeral_key
Ephemeral public ECC key of the other peer.
uint32_t iv_seed
Seed for the IV.
void GSC_SESSIONS_set_typemap(const struct GNUNET_PeerIdentity *peer, const struct GNUNET_MessageHeader *msg)
We have received a typemap message from a peer, update ours.
Handle to a message stream tokenizer.
Definition: mst.c:43
const char * GNUNET_STRINGS_relative_time_to_string(struct GNUNET_TIME_Relative delta, int do_round)
Give relative time in human-readable fancy format.
Definition: strings.c:727
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.
#define GNUNET_CORE_OPTION_SEND_FULL_INBOUND
Client wants all inbound messages in full.
Definition: core.h:55
Randomness for IVs etc.
uint16_t status
See PRISM_STATUS_*-constants.
static char buf[2048]
#define MIN_PING_FREQUENCY
What is the minimum frequency for a PING message?
uint32_t ping_challenge
What was our PING challenge number (for this peer)?
struct GNUNET_MessageHeader header
Message type is GNUNET_MESSAGE_TYPE_CORE_PING.
struct GNUNET_MessageStreamTokenizer * GNUNET_MST_create(GNUNET_MessageTokenizerCallback cb, void *cb_cls)
Create a message stream tokenizer.
Definition: mst.c:87
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:116
int GSC_KX_init(struct GNUNET_CRYPTO_EddsaPrivateKey *pk)
Initialize KX subsystem.
uint32_t size
How many bytes does this signature sign? (including this purpose header); in network byte order (!)...
Information about the status of a key exchange with another peer.
struct GNUNET_CRYPTO_EccSignaturePurpose purpose
Information about what is being signed.
void GSC_CLIENTS_deliver_message(const struct GNUNET_PeerIdentity *sender, const struct GNUNET_MessageHeader *msg, uint16_t msize, uint32_t options)
Deliver P2P message to interested clients.
A 512-bit hashcode.
Globals for gnunet-service-core.
Message handler for a specific message type.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:118
struct GNUNET_CRYPTO_SymmetricSessionKey decrypt_key
Key we use to decrypt messages from the other peer (given to us by the other peer during the handshak...
#define GNUNET_MESSAGE_TYPE_CORE_EPHEMERAL_KEY
Session key exchange between peers.
struct GNUNET_PeerIdentity GSC_my_identity
Our identity.
Private ECC key encoded for transmission.
static void pong(struct GNUNET_CADET_Channel *channel, const struct CadetPingMessage *ping)
Reply with a pong to origin.
static struct GNUNET_IDENTITY_Handle * identity
Which namespace do we publish to? NULL if we do not publish to a namespace.
struct GNUNET_SCHEDULER_Task * keep_alive_task
ID of task used for sending keep-alive pings.
static void update_timeout(struct GSC_KeyExchangeInfo *kx)
We&#39;ve seen a valid message from the other peer.
static void setup_fresh_ping(struct GSC_KeyExchangeInfo *kx)
Create a fresh PING message for transmission to the other peer.
struct GNUNET_TESTBED_Peer * peer
The peer associated with this model.
void GSC_SESSIONS_solicit(const struct GNUNET_PeerIdentity *pid)
Traffic is being solicited for the given peer.
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
static unsigned int size
Size of the "table".
Definition: peer.c:67
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:303
This is not a state in a peer&#39;s state machine, but a special value used with the GNUNET_CORE_MonitorC...
void GSC_SESSIONS_create(const struct GNUNET_PeerIdentity *peer, struct GSC_KeyExchangeInfo *kx)
Create a session, a key exchange was just completed.
uint32_t iv_seed
Random value used for IV generation.
#define MAX_MESSAGE_AGE
What is the maximum age of a message for us to consider processing it? Note that this looks at the ti...
struct GNUNET_CRYPTO_EcdhePublicKey ephemeral_key
Ephemeral public ECC key.
static void set_key_retry_task(void *cls)
Task that will retry send_key() if our previous attempt failed.
static uint32_t calculate_seed(struct GSC_KeyExchangeInfo *kx)
Calculate seed value we should use for a message.
#define GNUNET_MESSAGE_TYPE_CORE_BINARY_TYPE_MAP
uncompressed type map of the sender
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
static void * handle_transport_notify_connect(void *cls, const struct GNUNET_PeerIdentity *pid, struct GNUNET_MQ_Handle *mq)
Function called by transport to notify us that a peer connected to us (on the network level)...
#define GNUNET_MESSAGE_TYPE_CORE_PING
Check that other peer is alive (challenge).
The other peer has confirmed our session key + PING with a PONG message encrypted with their session ...
static struct GNUNET_NotificationContext * nc
Notification context for broadcasting to monitors.
#define GNUNET_TIME_STD_BACKOFF(r)
Perform our standard exponential back-off calculation, starting at 1 ms and then going by a factor of...
struct GSC_KeyExchangeInfo * prev
DLL.
static unsigned long long payload
How much data are we currently storing in the database?
code for managing the key exchange (SET_KEY, PING, PONG) with other peers
struct GNUNET_PeerIdentity target
Intended target of the PING, used primarily to check that decryption actually worked.
#define ENCRYPTED_HEADER_SIZE
Number of bytes (at the beginning) of struct EncryptedMessage that are NOT encrypted.
an ECC signature using EdDSA.
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:272
struct GNUNET_NotificationContext * GNUNET_notification_context_create(unsigned int queue_length)
Create a new notification context.
Definition: nc.c:125
static void derive_pong_iv(struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, const struct GNUNET_CRYPTO_SymmetricSessionKey *skey, uint32_t seed, uint32_t challenge, const struct GNUNET_PeerIdentity *identity)
Derive an IV from pong packet information.
#define GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT
After how long do we consider a connection to a peer dead if we don&#39;t receive messages from the peer...
Handle to a message queue.
Definition: mq.c:85
#define GNUNET_NETWORK_STRUCT_END
Define as empty, GNUNET_PACKED should suffice, but this won&#39;t work on W32;.
Private ECC key encoded for transmission.
struct GNUNET_TIME_Relative GNUNET_TIME_relative_add(struct GNUNET_TIME_Relative a1, struct GNUNET_TIME_Relative a2)
Add relative times together.
Definition: time.c:576
#define GNUNET_MESSAGE_TYPE_CORE_ENCRYPTED_MESSAGE
Encapsulation for an encrypted message between peers.
void GNUNET_notification_context_broadcast(struct GNUNET_NotificationContext *nc, const struct GNUNET_MessageHeader *msg, int can_drop)
Send a message to all subscribers of this context.
Definition: nc.c:192
The identity of the host (wraps the signing key of the peer).
static void derive_iv(struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, const struct GNUNET_CRYPTO_SymmetricSessionKey *skey, uint32_t seed, const struct GNUNET_PeerIdentity *identity)
Derive an IV from packet information.
#define GNUNET_ALIGN
gcc-ism to force alignment; we use this to align char-arrays that may then be cast to &#39;struct&#39;s...
uint32_t last_sequence_number_received
last sequence number received on this connection (highest)
static struct GNUNET_SCHEDULER_Task * rekey_task
Task scheduled for periodic re-generation (and thus rekeying) of our ephemeral key.
#define GNUNET_PACKED
gcc-ism to get packed structs.
int has_excess_bandwidth
GNUNET_YES if this peer currently has excess bandwidth.
#define REKEY_FREQUENCY
How often do we rekey?
uint32_t reserved
Reserved, always zero.
struct GNUNET_MessageHeader header
Message type is GNUNET_MESSAGE_TYPE_CORE_EPHEMERAL_KEY.
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:373
int GNUNET_CRYPTO_hash_cmp(const struct GNUNET_HashCode *h1, const struct GNUNET_HashCode *h2)
Compare function for HashCodes, producing a total ordering of all hashcodes.
Definition: crypto_hash.c:278
struct GNUNET_TIME_Absolute foreign_key_expires
At what time did the other peer generate the decryption key?
void GNUNET_TRANSPORT_core_disconnect(struct GNUNET_TRANSPORT_CoreHandle *handle)
Disconnect from the transport service.
uint32_t state
New peer state, an enum GNUNET_CORE_KxState in NBO.
Definition: core.h:314
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and encr...
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
#define GNUNET_log(kind,...)
Entry in list of pending tasks.
Definition: scheduler.c:134
struct GNUNET_CRYPTO_SymmetricSessionKey encrypt_key
Key we use to encrypt our messages for the other peer (initialized by us when we do the handshake)...
int32_t sender_status
Status of the sender (should be in enum PeerStateMachine), nbo.
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:331
struct GNUNET_TIME_Absolute timeout
When should the session time out (if there are no PONGs)?
Last state of a KX (when it is being terminated).
Header for all communications.
struct GNUNET_TIME_Relative GNUNET_TIME_relative_divide(struct GNUNET_TIME_Relative rel, unsigned long long factor)
Divide relative time by a given factor.
Definition: time.c:525
Time for absolute times used by GNUnet, in microseconds.
#define GNUNET_YES
Definition: gnunet_common.h:80
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_difference(struct GNUNET_TIME_Absolute start, struct GNUNET_TIME_Absolute end)
Compute the time difference between the given start and end times.
Definition: time.c:353
void GNUNET_notification_context_destroy(struct GNUNET_NotificationContext *nc)
Destroy the context, force disconnect for all subscribers.
Definition: nc.c:141
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:353
static struct EphemeralKeyMessage current_ekm
Current message we send for a key exchange.
Message sent by the service to monitor clients to notify them about a peer changing status...
Definition: core.h:304
We&#39;ve sent our session key.
static unsigned long long reserved
How much space have we currently reserved?
static void handle_transport_notify_disconnect(void *cls, const struct GNUNET_PeerIdentity *peer, void *handler_cls)
Function called by transport telling us that a peer disconnected.
int GSC_NEIGHBOURS_check_excess_bandwidth(const struct GSC_KeyExchangeInfo *kxinfo)
Check if the given neighbour has excess bandwidth available.
Message transmitted with the signed ephemeral key of a peer.
static struct GNUNET_PeerIdentity pid
Identity of the peer we transmit to / connect to.
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.
struct GNUNET_PeerIdentity origin_identity
Public key of the signing peer (persistent version, not the ephemeral public key).
int GNUNET_CONFIGURATION_get_value_yesno(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option)
Get a configuration value that should be in a set of "YES" or "NO".
Handle for the transport service (includes all of the state for the transport service).
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:338
#define GNUNET_CORE_OPTION_SEND_HDR_INBOUND
Client just wants the 4-byte message headers of all inbound messages.
Definition: core.h:61
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition: time.c:654
void GSC_SESSIONS_end(const struct GNUNET_PeerIdentity *pid)
End the session with the given peer (we are no longer connected).
int 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:91
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define INITIAL_SET_KEY_RETRY_FREQUENCY
How long do we wait for SET_KEY confirmation initially?
void GSC_KX_done()
Shutdown KX subsystem.
struct GNUNET_TIME_AbsoluteNBO timestamp
Timestamp.
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
const struct GNUNET_CONFIGURATION_Handle * GSC_cfg
Our configuration.
type for (message) authentication keys
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).
void GSC_SESSIONS_reinit(const struct GNUNET_PeerIdentity *peer)
The other peer has indicated that it &#39;lost&#39; the session (KX down), reinitialize the session on our en...
#define GNUNET_free(ptr)
Wrapper around free.
#define GNUNET_MESSAGE_TYPE_CORE_MONITOR_NOTIFY
Reply for monitor by CORE service.
Time for relative time used by GNUnet, in microseconds.
static void handle_pong(void *cls, const struct PongMessage *m)
We received a PONG message.
struct GNUNET_CRYPTO_EddsaPublicKey public_key
static struct GNUNET_TRANSPORT_PluginMonitor * pm
Handle if we are monitoring plugin session activity.
#define gettext_noop(String)
Definition: gettext.h:69
struct GNUNET_PeerIdentity peer
Identity of the peer.
Definition: core.h:319
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:965
We&#39;re rekeying (or had a timeout), so we have sent the other peer our new ephemeral key...
Public ECC key (always for curve Ed25519) encoded in a format suitable for network transmission and E...