aboutsummaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2012-04-01 09:13:40 +0000
committerChristian Grothoff <christian@grothoff.org>2012-04-01 09:13:40 +0000
commite8553bf0149be837260ea002932aae48f9d647e9 (patch)
treecd4f0749a902d2d51e2de4ab69f08956136eadb6 /src/core
parentb02e7ec363ef07b22a96bc63e5edf79e0f2316ad (diff)
downloadgnunet-e8553bf0149be837260ea002932aae48f9d647e9.tar.gz
gnunet-e8553bf0149be837260ea002932aae48f9d647e9.zip
implementing rekeying, some code cleanup
Diffstat (limited to 'src/core')
-rw-r--r--src/core/gnunet-service-core_kx.c206
1 files changed, 153 insertions, 53 deletions
diff --git a/src/core/gnunet-service-core_kx.c b/src/core/gnunet-service-core_kx.c
index ae6b7a183..a2188dabe 100644
--- a/src/core/gnunet-service-core_kx.c
+++ b/src/core/gnunet-service-core_kx.c
@@ -37,6 +37,7 @@
37#include "gnunet_protocols.h" 37#include "gnunet_protocols.h"
38#include "core.h" 38#include "core.h"
39 39
40
40/** 41/**
41 * How long do we wait for SET_KEY confirmation initially? 42 * How long do we wait for SET_KEY confirmation initially?
42 */ 43 */
@@ -48,6 +49,12 @@
48#define MIN_PING_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5) 49#define MIN_PING_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5)
49 50
50/** 51/**
52 * How often do we rekey?
53 */
54#define REKEY_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 90)
55
56
57/**
51 * What is the maximum age of a message for us to consider processing 58 * What is the maximum age of a message for us to consider processing
52 * it? Note that this looks at the timestamp used by the other peer, 59 * it? Note that this looks at the timestamp used by the other peer,
53 * so clock skew between machines does come into play here. So this 60 * so clock skew between machines does come into play here. So this
@@ -216,6 +223,8 @@ struct EncryptedMessage
216 223
217}; 224};
218GNUNET_NETWORK_STRUCT_END 225GNUNET_NETWORK_STRUCT_END
226
227
219/** 228/**
220 * Number of bytes (at the beginning) of "struct EncryptedMessage" 229 * Number of bytes (at the beginning) of "struct EncryptedMessage"
221 * that are NOT encrypted. 230 * that are NOT encrypted.
@@ -253,7 +262,19 @@ enum KxStateMachine
253 * encrypted with his session key (which we got). Key exchange 262 * encrypted with his session key (which we got). Key exchange
254 * is done. 263 * is done.
255 */ 264 */
256 KX_STATE_UP 265 KX_STATE_UP,
266
267 /**
268 * We're rekeying, so we have received the other peer's session
269 * key, but he didn't get ours yet.
270 */
271 KX_STATE_REKEY,
272
273 /**
274 * We're rekeying but have not yet received confirmation for our new
275 * key from the other peer.
276 */
277 KX_STATE_REKEY_SENT
257}; 278};
258 279
259 280
@@ -391,7 +412,6 @@ struct GSC_KeyExchangeInfo
391}; 412};
392 413
393 414
394
395/** 415/**
396 * Handle to peerinfo service. 416 * Handle to peerinfo service.
397 */ 417 */
@@ -413,9 +433,13 @@ static struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded my_public_key;
413static struct GNUNET_SERVER_MessageStreamTokenizer *mst; 433static struct GNUNET_SERVER_MessageStreamTokenizer *mst;
414 434
415 435
416
417/** 436/**
418 * Derive an authentication key from "set key" information 437 * Derive an authentication key from "set key" information
438 *
439 * @param akey authentication key to derive
440 * @param skey session key to use
441 * @param seed seed to use
442 * @param creation_time creation time to use
419 */ 443 */
420static void 444static void
421derive_auth_key (struct GNUNET_CRYPTO_AuthKey *akey, 445derive_auth_key (struct GNUNET_CRYPTO_AuthKey *akey,
@@ -425,7 +449,6 @@ derive_auth_key (struct GNUNET_CRYPTO_AuthKey *akey,
425 static const char ctx[] = "authentication key"; 449 static const char ctx[] = "authentication key";
426 struct GNUNET_TIME_AbsoluteNBO ctbe; 450 struct GNUNET_TIME_AbsoluteNBO ctbe;
427 451
428
429 ctbe = GNUNET_TIME_absolute_hton (creation_time); 452 ctbe = GNUNET_TIME_absolute_hton (creation_time);
430 GNUNET_CRYPTO_hmac_derive_key (akey, skey, &seed, sizeof (seed), &skey->key, 453 GNUNET_CRYPTO_hmac_derive_key (akey, skey, &seed, sizeof (seed), &skey->key,
431 sizeof (skey->key), &ctbe, sizeof (ctbe), ctx, 454 sizeof (skey->key), &ctbe, sizeof (ctbe), ctx,
@@ -435,6 +458,11 @@ derive_auth_key (struct GNUNET_CRYPTO_AuthKey *akey,
435 458
436/** 459/**
437 * Derive an IV from packet information 460 * Derive an IV from packet information
461 *
462 * @param iv initialization vector to initialize
463 * @param skey session key to use
464 * @param seed seed to use
465 * @param creation_time creation time to use
438 */ 466 */
439static void 467static void
440derive_iv (struct GNUNET_CRYPTO_AesInitializationVector *iv, 468derive_iv (struct GNUNET_CRYPTO_AesInitializationVector *iv,
@@ -449,8 +477,15 @@ derive_iv (struct GNUNET_CRYPTO_AesInitializationVector *iv,
449 sizeof (ctx), NULL); 477 sizeof (ctx), NULL);
450} 478}
451 479
480
452/** 481/**
453 * Derive an IV from pong packet information 482 * Derive an IV from pong packet information
483 *
484 * @param iv initialization vector to initialize
485 * @param skey session key to use
486 * @param seed seed to use
487 * @param creation_time creation time to use
488 * @param identity identity of the other peer to use
454 */ 489 */
455static void 490static void
456derive_pong_iv (struct GNUNET_CRYPTO_AesInitializationVector *iv, 491derive_pong_iv (struct GNUNET_CRYPTO_AesInitializationVector *iv,
@@ -492,7 +527,9 @@ do_encrypt (struct GSC_KeyExchangeInfo *kx,
492 &kx->encrypt_key, iv, out)); 527 &kx->encrypt_key, iv, out));
493 GNUNET_STATISTICS_update (GSC_stats, gettext_noop ("# bytes encrypted"), size, 528 GNUNET_STATISTICS_update (GSC_stats, gettext_noop ("# bytes encrypted"), size,
494 GNUNET_NO); 529 GNUNET_NO);
495#if DEBUG_CORE > 2 530 /* the following is too sensitive to write to log files by accident,
531 so we require manual intervention to get this one... */
532#if 0
496 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 533 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
497 "Encrypted %u bytes for `%4s' using key %u, IV %u\n", 534 "Encrypted %u bytes for `%4s' using key %u, IV %u\n",
498 (unsigned int) size, GNUNET_i2s (&kx->peer), 535 (unsigned int) size, GNUNET_i2s (&kx->peer),
@@ -504,8 +541,6 @@ do_encrypt (struct GSC_KeyExchangeInfo *kx,
504} 541}
505 542
506 543
507
508
509/** 544/**
510 * Decrypt size bytes from in and write the result to out. Use the 545 * Decrypt size bytes from in and write the result to out. Use the
511 * key for inbound traffic of the given neighbour. This function does 546 * key for inbound traffic of the given neighbour. This function does
@@ -528,7 +563,8 @@ do_decrypt (struct GSC_KeyExchangeInfo *kx,
528 GNUNET_break (0); 563 GNUNET_break (0);
529 return GNUNET_NO; 564 return GNUNET_NO;
530 } 565 }
531 if ((kx->status != KX_STATE_KEY_RECEIVED) && (kx->status != KX_STATE_UP)) 566 if ( (kx->status != KX_STATE_KEY_RECEIVED) && (kx->status != KX_STATE_UP) &&
567 (kx->status != KX_STATE_REKEY_SENT) )
532 { 568 {
533 GNUNET_break_op (0); 569 GNUNET_break_op (0);
534 return GNUNET_SYSERR; 570 return GNUNET_SYSERR;
@@ -542,7 +578,9 @@ do_decrypt (struct GSC_KeyExchangeInfo *kx,
542 } 578 }
543 GNUNET_STATISTICS_update (GSC_stats, gettext_noop ("# bytes decrypted"), size, 579 GNUNET_STATISTICS_update (GSC_stats, gettext_noop ("# bytes decrypted"), size,
544 GNUNET_NO); 580 GNUNET_NO);
545#if DEBUG_CORE > 1 581 /* the following is too sensitive to write to log files by accident,
582 so we require manual intervention to get this one... */
583#if 0
546 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 584 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
547 "Decrypted %u bytes from `%4s' using key %u, IV %u\n", 585 "Decrypted %u bytes from `%4s' using key %u, IV %u\n",
548 (unsigned int) size, GNUNET_i2s (&kx->peer), 586 (unsigned int) size, GNUNET_i2s (&kx->peer),
@@ -615,11 +653,9 @@ process_hello (void *cls, const struct GNUNET_PeerIdentity *peer,
615 kx->pitr = NULL; 653 kx->pitr = NULL;
616 if (kx->public_key != NULL) 654 if (kx->public_key != NULL)
617 return; /* done here */ 655 return; /* done here */
618#if DEBUG_CORE
619 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 656 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
620 "Failed to obtain public key for peer `%4s', delaying processing of SET_KEY\n", 657 "Failed to obtain public key for peer `%4s', delaying processing of SET_KEY\n",
621 GNUNET_i2s (&kx->peer)); 658 GNUNET_i2s (&kx->peer));
622#endif
623 GNUNET_STATISTICS_update (GSC_stats, 659 GNUNET_STATISTICS_update (GSC_stats,
624 gettext_noop 660 gettext_noop
625 ("# Delayed connecting due to lack of public key"), 661 ("# Delayed connecting due to lack of public key"),
@@ -669,10 +705,8 @@ GSC_KX_start (const struct GNUNET_PeerIdentity *pid)
669{ 705{
670 struct GSC_KeyExchangeInfo *kx; 706 struct GSC_KeyExchangeInfo *kx;
671 707
672#if DEBUG_CORE
673 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Initiating key exchange with `%s'\n", 708 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Initiating key exchange with `%s'\n",
674 GNUNET_i2s (pid)); 709 GNUNET_i2s (pid));
675#endif
676 GNUNET_STATISTICS_update (GSC_stats, 710 GNUNET_STATISTICS_update (GSC_stats,
677 gettext_noop ("# key exchanges initiated"), 1, 711 gettext_noop ("# key exchanges initiated"), 1,
678 GNUNET_NO); 712 GNUNET_NO);
@@ -750,11 +784,9 @@ GSC_KX_handle_set_key (struct GSC_KeyExchangeInfo *kx,
750 GNUNET_STATISTICS_update (GSC_stats, gettext_noop ("# session keys received"), 784 GNUNET_STATISTICS_update (GSC_stats, gettext_noop ("# session keys received"),
751 1, GNUNET_NO); 785 1, GNUNET_NO);
752 786
753#if DEBUG_CORE
754 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 787 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
755 "Core service receives `%s' request from `%4s'.\n", "SET_KEY", 788 "Core service receives `%s' request from `%4s'.\n", "SET_KEY",
756 GNUNET_i2s (&kx->peer)); 789 GNUNET_i2s (&kx->peer));
757#endif
758 if (kx->public_key == NULL) 790 if (kx->public_key == NULL)
759 { 791 {
760 GNUNET_free_non_null (kx->skm_received); 792 GNUNET_free_non_null (kx->skm_received);
@@ -806,10 +838,8 @@ GSC_KX_handle_set_key (struct GSC_KeyExchangeInfo *kx,
806 GNUNET_STATISTICS_update (GSC_stats, 838 GNUNET_STATISTICS_update (GSC_stats,
807 gettext_noop ("# SET_KEY messages decrypted"), 1, 839 gettext_noop ("# SET_KEY messages decrypted"), 1,
808 GNUNET_NO); 840 GNUNET_NO);
809#if DEBUG_CORE
810 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received SET_KEY from `%s'\n", 841 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received SET_KEY from `%s'\n",
811 GNUNET_i2s (&kx->peer)); 842 GNUNET_i2s (&kx->peer));
812#endif
813 kx->decrypt_key = k; 843 kx->decrypt_key = k;
814 if (kx->decrypt_key_created.abs_value != t.abs_value) 844 if (kx->decrypt_key_created.abs_value != t.abs_value)
815 { 845 {
@@ -819,7 +849,6 @@ GSC_KX_handle_set_key (struct GSC_KeyExchangeInfo *kx,
819 kx->decrypt_key_created = t; 849 kx->decrypt_key_created = t;
820 } 850 }
821 sender_status = (enum KxStateMachine) ntohl (m->sender_status); 851 sender_status = (enum KxStateMachine) ntohl (m->sender_status);
822
823 switch (kx->status) 852 switch (kx->status)
824 { 853 {
825 case KX_STATE_DOWN: 854 case KX_STATE_DOWN:
@@ -833,7 +862,17 @@ GSC_KX_handle_set_key (struct GSC_KeyExchangeInfo *kx,
833 case KX_STATE_KEY_RECEIVED: 862 case KX_STATE_KEY_RECEIVED:
834 /* we're not up, so we are already doing 'send_key' */ 863 /* we're not up, so we are already doing 'send_key' */
835 break; 864 break;
836 case KX_STATE_UP: 865 case KX_STATE_UP:
866 if ((sender_status == KX_STATE_DOWN) ||
867 (sender_status == KX_STATE_KEY_SENT))
868 send_key (kx); /* we are up, but other peer is not! */
869 break;
870 case KX_STATE_REKEY:
871 if ((sender_status == KX_STATE_DOWN) ||
872 (sender_status == KX_STATE_KEY_SENT))
873 send_key (kx); /* we are up, but other peer is not! */
874 break;
875 case KX_STATE_REKEY_SENT:
837 if ((sender_status == KX_STATE_DOWN) || 876 if ((sender_status == KX_STATE_DOWN) ||
838 (sender_status == KX_STATE_KEY_SENT)) 877 (sender_status == KX_STATE_KEY_SENT))
839 send_key (kx); /* we are up, but other peer is not! */ 878 send_key (kx); /* we are up, but other peer is not! */
@@ -886,7 +925,8 @@ GSC_KX_handle_ping (struct GSC_KeyExchangeInfo *kx,
886 GNUNET_STATISTICS_update (GSC_stats, 925 GNUNET_STATISTICS_update (GSC_stats,
887 gettext_noop ("# PING messages received"), 1, 926 gettext_noop ("# PING messages received"), 1,
888 GNUNET_NO); 927 GNUNET_NO);
889 if ((kx->status != KX_STATE_KEY_RECEIVED) && (kx->status != KX_STATE_UP)) 928 if ((kx->status != KX_STATE_KEY_RECEIVED) && (kx->status != KX_STATE_UP) &&
929 (kx->status != KX_STATE_REKEY_SENT))
890 { 930 {
891 /* defer */ 931 /* defer */
892 GNUNET_free_non_null (kx->ping_received); 932 GNUNET_free_non_null (kx->ping_received);
@@ -894,11 +934,9 @@ GSC_KX_handle_ping (struct GSC_KeyExchangeInfo *kx,
894 return; 934 return;
895 } 935 }
896 m = (const struct PingMessage *) msg; 936 m = (const struct PingMessage *) msg;
897#if DEBUG_CORE
898 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 937 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
899 "Core service receives `%s' request from `%4s'.\n", "PING", 938 "Core service receives `%s' request from `%4s'.\n", "PING",
900 GNUNET_i2s (&kx->peer)); 939 GNUNET_i2s (&kx->peer));
901#endif
902 derive_iv (&iv, &kx->decrypt_key, m->iv_seed, &GSC_my_identity); 940 derive_iv (&iv, &kx->decrypt_key, m->iv_seed, &GSC_my_identity);
903 if (GNUNET_OK != 941 if (GNUNET_OK !=
904 do_decrypt (kx, &iv, &m->target, &t.target, 942 do_decrypt (kx, &iv, &m->target, &t.target,
@@ -923,10 +961,8 @@ GSC_KX_handle_ping (struct GSC_KeyExchangeInfo *kx,
923 GNUNET_break_op (0); 961 GNUNET_break_op (0);
924 return; 962 return;
925 } 963 }
926#if DEBUG_CORE
927 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received PING from `%s'\n", 964 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received PING from `%s'\n",
928 GNUNET_i2s (&kx->peer)); 965 GNUNET_i2s (&kx->peer));
929#endif
930 /* construct PONG */ 966 /* construct PONG */
931 tx.reserved = GNUNET_BANDWIDTH_VALUE_MAX; 967 tx.reserved = GNUNET_BANDWIDTH_VALUE_MAX;
932 tx.challenge = t.challenge; 968 tx.challenge = t.challenge;
@@ -1033,10 +1069,8 @@ send_keep_alive (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1033 kx->status = KX_STATE_DOWN; 1069 kx->status = KX_STATE_DOWN;
1034 return; 1070 return;
1035 } 1071 }
1036#if DEBUG_CORE
1037 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending KEEPALIVE to `%s'\n", 1072 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending KEEPALIVE to `%s'\n",
1038 GNUNET_i2s (&kx->peer)); 1073 GNUNET_i2s (&kx->peer));
1039#endif
1040 GNUNET_STATISTICS_update (GSC_stats, 1074 GNUNET_STATISTICS_update (GSC_stats,
1041 gettext_noop ("# keepalive messages sent"), 1, 1075 gettext_noop ("# keepalive messages sent"), 1,
1042 GNUNET_NO); 1076 GNUNET_NO);
@@ -1074,6 +1108,48 @@ update_timeout (struct GSC_KeyExchangeInfo *kx)
1074 1108
1075 1109
1076/** 1110/**
1111 * Trigger rekeying event.
1112 *
1113 * @param cls the 'struct GSC_KeyExchangeInfo'
1114 * @param tc schedule context (unused)
1115 */
1116static void
1117trigger_rekey (void *cls,
1118 const struct GNUNET_SCHEDULER_TaskContext *tc)
1119{
1120 struct GSC_KeyExchangeInfo *kx = cls;
1121
1122 kx->status = KX_STATE_REKEY;
1123 kx->set_key_retry_frequency = INITIAL_SET_KEY_RETRY_FREQUENCY;
1124 kx->retry_set_key_task =
1125 GNUNET_SCHEDULER_add_delayed (kx->set_key_retry_frequency,
1126 &set_key_retry_task, kx);
1127}
1128
1129
1130/**
1131 * Schedule rekey operation.
1132 *
1133 * @param kx key exchange to schedule rekey for
1134 */
1135static void
1136schedule_rekey (struct GSC_KeyExchangeInfo *kx)
1137{
1138 struct GNUNET_TIME_Relative rdelay;
1139
1140 if (GNUNET_SCHEDULER_NO_TASK != kx->retry_set_key_task)
1141 GNUNET_SCHEDULER_cancel (kx->retry_set_key_task);
1142 rdelay = REKEY_FREQUENCY;
1143 /* randomize rekey frequency by one minute to avoid synchronization */
1144 rdelay.rel_value += GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
1145 60 * 1000);
1146 kx->retry_set_key_task = GNUNET_SCHEDULER_add_delayed (REKEY_FREQUENCY,
1147 &trigger_rekey,
1148 kx);
1149}
1150
1151
1152/**
1077 * We received a PONG message. Validate and update our status. 1153 * We received a PONG message. Validate and update our status.
1078 * 1154 *
1079 * @param kx key exchange context for the the PONG 1155 * @param kx key exchange context for the the PONG
@@ -1098,21 +1174,30 @@ GSC_KX_handle_pong (struct GSC_KeyExchangeInfo *kx,
1098 GNUNET_STATISTICS_update (GSC_stats, 1174 GNUNET_STATISTICS_update (GSC_stats,
1099 gettext_noop ("# PONG messages received"), 1, 1175 gettext_noop ("# PONG messages received"), 1,
1100 GNUNET_NO); 1176 GNUNET_NO);
1101 if ((kx->status != KX_STATE_KEY_RECEIVED) && (kx->status != KX_STATE_UP)) 1177 switch (kx->status)
1102 { 1178 {
1103 if (kx->status == KX_STATE_KEY_SENT) 1179 case KX_STATE_DOWN:
1104 { 1180 return;
1105 GNUNET_free_non_null (kx->pong_received); 1181 case KX_STATE_KEY_SENT:
1106 kx->pong_received = (struct PongMessage *) GNUNET_copy_message (msg); 1182 GNUNET_free_non_null (kx->pong_received);
1107 } 1183 kx->pong_received = (struct PongMessage *) GNUNET_copy_message (msg);
1184 return;
1185 case KX_STATE_KEY_RECEIVED:
1186 break;
1187 case KX_STATE_UP:
1188 break;
1189 case KX_STATE_REKEY:
1190 break;
1191 case KX_STATE_REKEY_SENT:
1192 break;
1193 default:
1194 GNUNET_break (0);
1108 return; 1195 return;
1109 } 1196 }
1110 m = (const struct PongMessage *) msg; 1197 m = (const struct PongMessage *) msg;
1111#if DEBUG_HANDSHAKE
1112 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1198 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1113 "Core service receives `%s' response from `%4s'.\n", "PONG", 1199 "Core service receives `%s' response from `%4s'.\n", "PONG",
1114 GNUNET_i2s (&kx->peer)); 1200 GNUNET_i2s (&kx->peer));
1115#endif
1116 /* mark as garbage, just to be sure */ 1201 /* mark as garbage, just to be sure */
1117 memset (&t, 255, sizeof (t)); 1202 memset (&t, 255, sizeof (t));
1118 derive_pong_iv (&iv, &kx->decrypt_key, m->iv_seed, kx->ping_challenge, 1203 derive_pong_iv (&iv, &kx->decrypt_key, m->iv_seed, kx->ping_challenge,
@@ -1132,7 +1217,6 @@ GSC_KX_handle_pong (struct GSC_KeyExchangeInfo *kx,
1132 || (kx->ping_challenge != t.challenge)) 1217 || (kx->ping_challenge != t.challenge))
1133 { 1218 {
1134 /* PONG malformed */ 1219 /* PONG malformed */
1135#if DEBUG_CORE
1136 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1220 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1137 "Received malformed `%s' wanted sender `%4s' with challenge %u\n", 1221 "Received malformed `%s' wanted sender `%4s' with challenge %u\n",
1138 "PONG", GNUNET_i2s (&kx->peer), 1222 "PONG", GNUNET_i2s (&kx->peer),
@@ -1140,13 +1224,10 @@ GSC_KX_handle_pong (struct GSC_KeyExchangeInfo *kx,
1140 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1224 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1141 "Received malformed `%s' received from `%4s' with challenge %u\n", 1225 "Received malformed `%s' received from `%4s' with challenge %u\n",
1142 "PONG", GNUNET_i2s (&t.target), (unsigned int) t.challenge); 1226 "PONG", GNUNET_i2s (&t.target), (unsigned int) t.challenge);
1143#endif
1144 return; 1227 return;
1145 } 1228 }
1146#if DEBUG_CORE
1147 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received PONG from `%s'\n", 1229 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received PONG from `%s'\n",
1148 GNUNET_i2s (&kx->peer)); 1230 GNUNET_i2s (&kx->peer));
1149#endif
1150 switch (kx->status) 1231 switch (kx->status)
1151 { 1232 {
1152 case KX_STATE_DOWN: 1233 case KX_STATE_DOWN:
@@ -1162,11 +1243,7 @@ GSC_KX_handle_pong (struct GSC_KeyExchangeInfo *kx,
1162 GNUNET_NO); 1243 GNUNET_NO);
1163 kx->status = KX_STATE_UP; 1244 kx->status = KX_STATE_UP;
1164 GSC_SESSIONS_create (&kx->peer, kx); 1245 GSC_SESSIONS_create (&kx->peer, kx);
1165 if (GNUNET_SCHEDULER_NO_TASK != kx->retry_set_key_task) 1246 schedule_rekey (kx);
1166 {
1167 GNUNET_SCHEDULER_cancel (kx->retry_set_key_task);
1168 kx->retry_set_key_task = GNUNET_SCHEDULER_NO_TASK;
1169 }
1170 GNUNET_assert (kx->keep_alive_task == GNUNET_SCHEDULER_NO_TASK); 1247 GNUNET_assert (kx->keep_alive_task == GNUNET_SCHEDULER_NO_TASK);
1171 if (kx->emsg_received != NULL) 1248 if (kx->emsg_received != NULL)
1172 { 1249 {
@@ -1181,6 +1258,18 @@ GSC_KX_handle_pong (struct GSC_KeyExchangeInfo *kx,
1181 case KX_STATE_UP: 1258 case KX_STATE_UP:
1182 update_timeout (kx); 1259 update_timeout (kx);
1183 break; 1260 break;
1261 case KX_STATE_REKEY:
1262 update_timeout (kx);
1263 break;
1264 case KX_STATE_REKEY_SENT:
1265 GNUNET_STATISTICS_update (GSC_stats,
1266 gettext_noop
1267 ("# rekey operations confirmed via PONG"), 1,
1268 GNUNET_NO);
1269 kx->status = KX_STATE_UP;
1270 schedule_rekey (kx);
1271 update_timeout (kx);
1272 break;
1184 default: 1273 default:
1185 GNUNET_break (0); 1274 GNUNET_break (0);
1186 break; 1275 break;
@@ -1202,11 +1291,9 @@ send_key (struct GSC_KeyExchangeInfo *kx)
1202 if (kx->public_key == NULL) 1291 if (kx->public_key == NULL)
1203 { 1292 {
1204 /* lookup public key, then try again */ 1293 /* lookup public key, then try again */
1205#if DEBUG_CORE
1206 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1294 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1207 "Trying to obtain public key for `%s'\n", 1295 "Trying to obtain public key for `%s'\n",
1208 GNUNET_i2s (&kx->peer)); 1296 GNUNET_i2s (&kx->peer));
1209#endif
1210 kx->pitr = 1297 kx->pitr =
1211 GNUNET_PEERINFO_iterate (peerinfo, &kx->peer, 1298 GNUNET_PEERINFO_iterate (peerinfo, &kx->peer,
1212 GNUNET_TIME_UNIT_FOREVER_REL /* timeout? */ , 1299 GNUNET_TIME_UNIT_FOREVER_REL /* timeout? */ ,
@@ -1234,17 +1321,33 @@ send_key (struct GSC_KeyExchangeInfo *kx)
1234 case KX_STATE_UP: 1321 case KX_STATE_UP:
1235 GNUNET_break (0); 1322 GNUNET_break (0);
1236 return; 1323 return;
1324 case KX_STATE_REKEY:
1325 kx->status = KX_STATE_REKEY_SENT;
1326 /* setup fresh SET KEY message */
1327 setup_fresh_setkey (kx);
1328 setup_fresh_ping (kx);
1329 GNUNET_STATISTICS_update (GSC_stats,
1330 gettext_noop
1331 ("# SET_KEY and PING messages created"), 1,
1332 GNUNET_NO);
1333 GNUNET_STATISTICS_update (GSC_stats,
1334 gettext_noop
1335 ("# REKEY operations performed"), 1,
1336 GNUNET_NO);
1337 break;
1338 case KX_STATE_REKEY_SENT:
1339 break;
1237 default: 1340 default:
1238 GNUNET_break (0); 1341 GNUNET_break (0);
1239 return; 1342 return;
1240 } 1343 }
1241 1344
1242 /* always update sender status in SET KEY message */ 1345 /* always update sender status in SET KEY message */
1243 kx->skm.sender_status = htonl ((int32_t) kx->status); 1346 /* Not sending rekey sent state to be compatible with GNUnet 0.9.2 */
1244#if DEBUG_CORE 1347 kx->skm.sender_status = htonl ((int32_t) ((kx->status == KX_STATE_REKEY_SENT) ?
1348 KX_STATE_KEY_RECEIVED : kx->status));
1245 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending SET_KEY and PING to `%s'\n", 1349 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending SET_KEY and PING to `%s'\n",
1246 GNUNET_i2s (&kx->peer)); 1350 GNUNET_i2s (&kx->peer));
1247#endif
1248 GSC_NEIGHBOURS_transmit (&kx->peer, &kx->skm.header, 1351 GSC_NEIGHBOURS_transmit (&kx->peer, &kx->skm.header,
1249 kx->set_key_retry_frequency); 1352 kx->set_key_retry_frequency);
1250 GSC_NEIGHBOURS_transmit (&kx->peer, &kx->ping.header, 1353 GSC_NEIGHBOURS_transmit (&kx->peer, &kx->ping.header,
@@ -1292,10 +1395,8 @@ GSC_KX_encrypt_and_transmit (struct GSC_KeyExchangeInfo *kx,
1292 do_encrypt (kx, &iv, &ph->sequence_number, 1395 do_encrypt (kx, &iv, &ph->sequence_number,
1293 &em->sequence_number, 1396 &em->sequence_number,
1294 used - ENCRYPTED_HEADER_SIZE)); 1397 used - ENCRYPTED_HEADER_SIZE));
1295#if DEBUG_CORE
1296 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Encrypted %u bytes for %s\n", 1398 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Encrypted %u bytes for %s\n",
1297 used - ENCRYPTED_HEADER_SIZE, GNUNET_i2s (&kx->peer)); 1399 used - ENCRYPTED_HEADER_SIZE, GNUNET_i2s (&kx->peer));
1298#endif
1299 derive_auth_key (&auth_key, &kx->encrypt_key, ph->iv_seed, 1400 derive_auth_key (&auth_key, &kx->encrypt_key, ph->iv_seed,
1300 kx->encrypt_key_created); 1401 kx->encrypt_key_created);
1301 GNUNET_CRYPTO_hmac (&auth_key, &em->sequence_number, 1402 GNUNET_CRYPTO_hmac (&auth_key, &em->sequence_number,
@@ -1361,7 +1462,8 @@ GSC_KX_handle_encrypted_message (struct GSC_KeyExchangeInfo *kx,
1361 return; 1462 return;
1362 } 1463 }
1363 m = (const struct EncryptedMessage *) msg; 1464 m = (const struct EncryptedMessage *) msg;
1364 if ((kx->status != KX_STATE_KEY_RECEIVED) && (kx->status != KX_STATE_UP)) 1465 if ((kx->status != KX_STATE_KEY_RECEIVED) && (kx->status != KX_STATE_UP) &&
1466 (kx->status != KX_STATE_REKEY_SENT) )
1365 { 1467 {
1366 GNUNET_STATISTICS_update (GSC_stats, 1468 GNUNET_STATISTICS_update (GSC_stats,
1367 gettext_noop 1469 gettext_noop
@@ -1393,10 +1495,8 @@ GSC_KX_handle_encrypted_message (struct GSC_KeyExchangeInfo *kx,
1393 do_decrypt (kx, &iv, &m->sequence_number, &buf[ENCRYPTED_HEADER_SIZE], 1495 do_decrypt (kx, &iv, &m->sequence_number, &buf[ENCRYPTED_HEADER_SIZE],
1394 size - ENCRYPTED_HEADER_SIZE)) 1496 size - ENCRYPTED_HEADER_SIZE))
1395 return; 1497 return;
1396#if DEBUG_CORE
1397 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Decrypted %u bytes from %s\n", 1498 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Decrypted %u bytes from %s\n",
1398 size - ENCRYPTED_HEADER_SIZE, GNUNET_i2s (&kx->peer)); 1499 size - ENCRYPTED_HEADER_SIZE, GNUNET_i2s (&kx->peer));
1399#endif
1400 pt = (struct EncryptedMessage *) buf; 1500 pt = (struct EncryptedMessage *) buf;
1401 1501
1402 /* validate sequence number */ 1502 /* validate sequence number */