diff options
author | Christian Grothoff <christian@grothoff.org> | 2012-04-01 09:13:40 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2012-04-01 09:13:40 +0000 |
commit | e8553bf0149be837260ea002932aae48f9d647e9 (patch) | |
tree | cd4f0749a902d2d51e2de4ab69f08956136eadb6 /src/core | |
parent | b02e7ec363ef07b22a96bc63e5edf79e0f2316ad (diff) | |
download | gnunet-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.c | 206 |
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 | }; |
218 | GNUNET_NETWORK_STRUCT_END | 225 | GNUNET_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; | |||
413 | static struct GNUNET_SERVER_MessageStreamTokenizer *mst; | 433 | static 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 | */ |
420 | static void | 444 | static void |
421 | derive_auth_key (struct GNUNET_CRYPTO_AuthKey *akey, | 445 | derive_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 | */ |
439 | static void | 467 | static void |
440 | derive_iv (struct GNUNET_CRYPTO_AesInitializationVector *iv, | 468 | derive_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 | */ |
455 | static void | 490 | static void |
456 | derive_pong_iv (struct GNUNET_CRYPTO_AesInitializationVector *iv, | 491 | derive_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 | */ | ||
1116 | static void | ||
1117 | trigger_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 | */ | ||
1135 | static void | ||
1136 | schedule_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 */ |