diff options
author | Christian Grothoff <christian@grothoff.org> | 2019-04-28 19:32:10 +0200 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2019-04-28 19:32:20 +0200 |
commit | 3f945e6798d8d736ceb104b59ea1269a7abdfe8a (patch) | |
tree | b93e3dc99deda0987e85cb256b3903de8bd74853 /src/core | |
parent | 1227fc30369a55b82e77d35d8d128090e37dd437 (diff) | |
download | gnunet-3f945e6798d8d736ceb104b59ea1269a7abdfe8a.tar.gz gnunet-3f945e6798d8d736ceb104b59ea1269a7abdfe8a.zip |
towards flow control in TNG
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/gnunet-service-core_kx.c | 681 |
1 files changed, 314 insertions, 367 deletions
diff --git a/src/core/gnunet-service-core_kx.c b/src/core/gnunet-service-core_kx.c index bfd855285..d226b65e2 100644 --- a/src/core/gnunet-service-core_kx.c +++ b/src/core/gnunet-service-core_kx.c | |||
@@ -11,7 +11,7 @@ | |||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | 11 | WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | Affero General Public License for more details. | 13 | Affero General Public License for more details. |
14 | 14 | ||
15 | You should have received a copy of the GNU Affero General Public License | 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/>. | 16 | along with this program. If not, see <http://www.gnu.org/licenses/>. |
17 | 17 | ||
@@ -20,7 +20,8 @@ | |||
20 | 20 | ||
21 | /** | 21 | /** |
22 | * @file core/gnunet-service-core_kx.c | 22 | * @file core/gnunet-service-core_kx.c |
23 | * @brief code for managing the key exchange (SET_KEY, PING, PONG) with other peers | 23 | * @brief code for managing the key exchange (SET_KEY, PING, PONG) with other |
24 | * peers | ||
24 | * @author Christian Grothoff | 25 | * @author Christian Grothoff |
25 | */ | 26 | */ |
26 | #include "platform.h" | 27 | #include "platform.h" |
@@ -28,7 +29,7 @@ | |||
28 | #include "gnunet-service-core.h" | 29 | #include "gnunet-service-core.h" |
29 | #include "gnunet-service-core_sessions.h" | 30 | #include "gnunet-service-core_sessions.h" |
30 | #include "gnunet_statistics_service.h" | 31 | #include "gnunet_statistics_service.h" |
31 | #include "gnunet_transport_core_service.h" | 32 | #include "gnunet_transport_service.h" |
32 | #include "gnunet_constants.h" | 33 | #include "gnunet_constants.h" |
33 | #include "gnunet_signatures.h" | 34 | #include "gnunet_signatures.h" |
34 | #include "gnunet_protocols.h" | 35 | #include "gnunet_protocols.h" |
@@ -42,22 +43,26 @@ | |||
42 | /** | 43 | /** |
43 | * How long do we wait for SET_KEY confirmation initially? | 44 | * How long do we wait for SET_KEY confirmation initially? |
44 | */ | 45 | */ |
45 | #define INITIAL_SET_KEY_RETRY_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10) | 46 | #define INITIAL_SET_KEY_RETRY_FREQUENCY \ |
47 | GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10) | ||
46 | 48 | ||
47 | /** | 49 | /** |
48 | * What is the minimum frequency for a PING message? | 50 | * What is the minimum frequency for a PING message? |
49 | */ | 51 | */ |
50 | #define MIN_PING_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5) | 52 | #define MIN_PING_FREQUENCY \ |
53 | GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5) | ||
51 | 54 | ||
52 | /** | 55 | /** |
53 | * How often do we rekey? | 56 | * How often do we rekey? |
54 | */ | 57 | */ |
55 | #define REKEY_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 12) | 58 | #define REKEY_FREQUENCY \ |
59 | GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 12) | ||
56 | 60 | ||
57 | /** | 61 | /** |
58 | * What time difference do we tolerate? | 62 | * What time difference do we tolerate? |
59 | */ | 63 | */ |
60 | #define REKEY_TOLERANCE GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5) | 64 | #define REKEY_TOLERANCE \ |
65 | GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5) | ||
61 | 66 | ||
62 | /** | 67 | /** |
63 | * What is the maximum age of a message for us to consider processing | 68 | * What is the maximum age of a message for us to consider processing |
@@ -69,7 +74,6 @@ | |||
69 | #define MAX_MESSAGE_AGE GNUNET_TIME_UNIT_DAYS | 74 | #define MAX_MESSAGE_AGE GNUNET_TIME_UNIT_DAYS |
70 | 75 | ||
71 | 76 | ||
72 | |||
73 | GNUNET_NETWORK_STRUCT_BEGIN | 77 | GNUNET_NETWORK_STRUCT_BEGIN |
74 | 78 | ||
75 | /** | 79 | /** |
@@ -120,7 +124,6 @@ struct EphemeralKeyMessage | |||
120 | * ephemeral public key). | 124 | * ephemeral public key). |
121 | */ | 125 | */ |
122 | struct GNUNET_PeerIdentity origin_identity; | 126 | struct GNUNET_PeerIdentity origin_identity; |
123 | |||
124 | }; | 127 | }; |
125 | 128 | ||
126 | 129 | ||
@@ -228,7 +231,6 @@ struct EncryptedMessage | |||
228 | * (recent messages are caught with the sequence number). | 231 | * (recent messages are caught with the sequence number). |
229 | */ | 232 | */ |
230 | struct GNUNET_TIME_AbsoluteNBO timestamp; | 233 | struct GNUNET_TIME_AbsoluteNBO timestamp; |
231 | |||
232 | }; | 234 | }; |
233 | GNUNET_NETWORK_STRUCT_END | 235 | GNUNET_NETWORK_STRUCT_END |
234 | 236 | ||
@@ -237,7 +239,8 @@ GNUNET_NETWORK_STRUCT_END | |||
237 | * Number of bytes (at the beginning) of `struct EncryptedMessage` | 239 | * Number of bytes (at the beginning) of `struct EncryptedMessage` |
238 | * that are NOT encrypted. | 240 | * that are NOT encrypted. |
239 | */ | 241 | */ |
240 | #define ENCRYPTED_HEADER_SIZE (offsetof(struct EncryptedMessage, sequence_number)) | 242 | #define ENCRYPTED_HEADER_SIZE \ |
243 | (offsetof (struct EncryptedMessage, sequence_number)) | ||
241 | 244 | ||
242 | 245 | ||
243 | /** | 246 | /** |
@@ -354,7 +357,6 @@ struct GSC_KeyExchangeInfo | |||
354 | * What is our connection status? | 357 | * What is our connection status? |
355 | */ | 358 | */ |
356 | enum GNUNET_CORE_KxState status; | 359 | enum GNUNET_CORE_KxState status; |
357 | |||
358 | }; | 360 | }; |
359 | 361 | ||
360 | 362 | ||
@@ -411,8 +413,8 @@ calculate_seed (struct GSC_KeyExchangeInfo *kx) | |||
411 | /* Note: may want to make this non-random and instead | 413 | /* Note: may want to make this non-random and instead |
412 | derive from key material to avoid having an undetectable | 414 | derive from key material to avoid having an undetectable |
413 | side-channel */ | 415 | side-channel */ |
414 | return htonl (GNUNET_CRYPTO_random_u32 | 416 | return htonl ( |
415 | (GNUNET_CRYPTO_QUALITY_NONCE, UINT32_MAX)); | 417 | GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, UINT32_MAX)); |
416 | } | 418 | } |
417 | 419 | ||
418 | 420 | ||
@@ -431,9 +433,7 @@ monitor_notify_all (struct GSC_KeyExchangeInfo *kx) | |||
431 | msg.state = htonl ((uint32_t) kx->status); | 433 | msg.state = htonl ((uint32_t) kx->status); |
432 | msg.peer = *kx->peer; | 434 | msg.peer = *kx->peer; |
433 | msg.timeout = GNUNET_TIME_absolute_hton (kx->timeout); | 435 | msg.timeout = GNUNET_TIME_absolute_hton (kx->timeout); |
434 | GNUNET_notification_context_broadcast (nc, | 436 | GNUNET_notification_context_broadcast (nc, &msg.header, GNUNET_NO); |
435 | &msg.header, | ||
436 | GNUNET_NO); | ||
437 | kx->last_notify_timeout = kx->timeout; | 437 | kx->last_notify_timeout = kx->timeout; |
438 | } | 438 | } |
439 | 439 | ||
@@ -453,10 +453,8 @@ derive_auth_key (struct GNUNET_CRYPTO_AuthKey *akey, | |||
453 | static const char ctx[] = "authentication key"; | 453 | static const char ctx[] = "authentication key"; |
454 | #if DEBUG_KX | 454 | #if DEBUG_KX |
455 | struct GNUNET_HashCode sh; | 455 | struct GNUNET_HashCode sh; |
456 | 456 | ||
457 | GNUNET_CRYPTO_hash (skey, | 457 | GNUNET_CRYPTO_hash (skey, sizeof (*skey), &sh); |
458 | sizeof (*skey), | ||
459 | &sh); | ||
460 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 458 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
461 | "Deriving Auth key from SKEY %s and seed %u\n", | 459 | "Deriving Auth key from SKEY %s and seed %u\n", |
462 | GNUNET_h2s (&sh), | 460 | GNUNET_h2s (&sh), |
@@ -464,9 +462,13 @@ derive_auth_key (struct GNUNET_CRYPTO_AuthKey *akey, | |||
464 | #endif | 462 | #endif |
465 | GNUNET_CRYPTO_hmac_derive_key (akey, | 463 | GNUNET_CRYPTO_hmac_derive_key (akey, |
466 | skey, | 464 | skey, |
467 | &seed, sizeof (seed), | 465 | &seed, |
468 | skey, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey), | 466 | sizeof (seed), |
469 | ctx, sizeof (ctx), | 467 | skey, |
468 | sizeof ( | ||
469 | struct GNUNET_CRYPTO_SymmetricSessionKey), | ||
470 | ctx, | ||
471 | sizeof (ctx), | ||
470 | NULL); | 472 | NULL); |
471 | } | 473 | } |
472 | 474 | ||
@@ -488,10 +490,8 @@ derive_iv (struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, | |||
488 | static const char ctx[] = "initialization vector"; | 490 | static const char ctx[] = "initialization vector"; |
489 | #if DEBUG_KX | 491 | #if DEBUG_KX |
490 | struct GNUNET_HashCode sh; | 492 | struct GNUNET_HashCode sh; |
491 | 493 | ||
492 | GNUNET_CRYPTO_hash (skey, | 494 | GNUNET_CRYPTO_hash (skey, sizeof (*skey), &sh); |
493 | sizeof (*skey), | ||
494 | &sh); | ||
495 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 495 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
496 | "Deriving IV from SKEY %s and seed %u for peer %s\n", | 496 | "Deriving IV from SKEY %s and seed %u for peer %s\n", |
497 | GNUNET_h2s (&sh), | 497 | GNUNET_h2s (&sh), |
@@ -500,10 +500,13 @@ derive_iv (struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, | |||
500 | #endif | 500 | #endif |
501 | GNUNET_CRYPTO_symmetric_derive_iv (iv, | 501 | GNUNET_CRYPTO_symmetric_derive_iv (iv, |
502 | skey, | 502 | skey, |
503 | &seed, sizeof (seed), | 503 | &seed, |
504 | identity, | 504 | sizeof (seed), |
505 | sizeof (struct GNUNET_PeerIdentity), ctx, | 505 | identity, |
506 | sizeof (ctx), NULL); | 506 | sizeof (struct GNUNET_PeerIdentity), |
507 | ctx, | ||
508 | sizeof (ctx), | ||
509 | NULL); | ||
507 | } | 510 | } |
508 | 511 | ||
509 | 512 | ||
@@ -526,10 +529,8 @@ derive_pong_iv (struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, | |||
526 | static const char ctx[] = "pong initialization vector"; | 529 | static const char ctx[] = "pong initialization vector"; |
527 | #if DEBUG_KX | 530 | #if DEBUG_KX |
528 | struct GNUNET_HashCode sh; | 531 | struct GNUNET_HashCode sh; |
529 | 532 | ||
530 | GNUNET_CRYPTO_hash (skey, | 533 | GNUNET_CRYPTO_hash (skey, sizeof (*skey), &sh); |
531 | sizeof (*skey), | ||
532 | &sh); | ||
533 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 534 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
534 | "Deriving PONG IV from SKEY %s and seed %u/%u for %s\n", | 535 | "Deriving PONG IV from SKEY %s and seed %u/%u for %s\n", |
535 | GNUNET_h2s (&sh), | 536 | GNUNET_h2s (&sh), |
@@ -539,12 +540,15 @@ derive_pong_iv (struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, | |||
539 | #endif | 540 | #endif |
540 | GNUNET_CRYPTO_symmetric_derive_iv (iv, | 541 | GNUNET_CRYPTO_symmetric_derive_iv (iv, |
541 | skey, | 542 | skey, |
542 | &seed, sizeof (seed), | 543 | &seed, |
543 | identity, | 544 | sizeof (seed), |
544 | sizeof (struct GNUNET_PeerIdentity), | 545 | identity, |
545 | &challenge, sizeof (challenge), | 546 | sizeof (struct GNUNET_PeerIdentity), |
546 | ctx, sizeof (ctx), | 547 | &challenge, |
547 | NULL); | 548 | sizeof (challenge), |
549 | ctx, | ||
550 | sizeof (ctx), | ||
551 | NULL); | ||
548 | } | 552 | } |
549 | 553 | ||
550 | 554 | ||
@@ -558,29 +562,32 @@ derive_pong_iv (struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, | |||
558 | */ | 562 | */ |
559 | static void | 563 | static void |
560 | derive_aes_key (const struct GNUNET_PeerIdentity *sender, | 564 | derive_aes_key (const struct GNUNET_PeerIdentity *sender, |
561 | const struct GNUNET_PeerIdentity *receiver, | 565 | const struct GNUNET_PeerIdentity *receiver, |
562 | const struct GNUNET_HashCode *key_material, | 566 | const struct GNUNET_HashCode *key_material, |
563 | struct GNUNET_CRYPTO_SymmetricSessionKey *skey) | 567 | struct GNUNET_CRYPTO_SymmetricSessionKey *skey) |
564 | { | 568 | { |
565 | static const char ctx[] = "aes key generation vector"; | 569 | static const char ctx[] = "aes key generation vector"; |
566 | #if DEBUG_KX | 570 | #if DEBUG_KX |
567 | struct GNUNET_HashCode sh; | 571 | struct GNUNET_HashCode sh; |
568 | 572 | ||
569 | GNUNET_CRYPTO_hash (skey, | 573 | GNUNET_CRYPTO_hash (skey, sizeof (*skey), &sh); |
570 | sizeof (*skey), | ||
571 | &sh); | ||
572 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 574 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
573 | "Deriving AES Keys for %s to %s from %s\n", | 575 | "Deriving AES Keys for %s to %s from %s\n", |
574 | GNUNET_i2s (sender), | 576 | GNUNET_i2s (sender), |
575 | GNUNET_i2s2 (receiver), | 577 | GNUNET_i2s2 (receiver), |
576 | GNUNET_h2s (key_material)); | 578 | GNUNET_h2s (key_material)); |
577 | #endif | 579 | #endif |
578 | GNUNET_CRYPTO_kdf (skey, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey), | 580 | GNUNET_CRYPTO_kdf (skey, |
579 | ctx, sizeof (ctx), | 581 | sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey), |
580 | key_material, sizeof (struct GNUNET_HashCode), | 582 | ctx, |
581 | sender, sizeof (struct GNUNET_PeerIdentity), | 583 | sizeof (ctx), |
582 | receiver, sizeof (struct GNUNET_PeerIdentity), | 584 | key_material, |
583 | NULL); | 585 | sizeof (struct GNUNET_HashCode), |
586 | sender, | ||
587 | sizeof (struct GNUNET_PeerIdentity), | ||
588 | receiver, | ||
589 | sizeof (struct GNUNET_PeerIdentity), | ||
590 | NULL); | ||
584 | } | 591 | } |
585 | 592 | ||
586 | 593 | ||
@@ -607,15 +614,14 @@ do_encrypt (struct GSC_KeyExchangeInfo *kx, | |||
607 | GNUNET_break (0); | 614 | GNUNET_break (0); |
608 | return GNUNET_NO; | 615 | return GNUNET_NO; |
609 | } | 616 | } |
610 | GNUNET_assert (size == | 617 | GNUNET_assert (size == GNUNET_CRYPTO_symmetric_encrypt (in, |
611 | GNUNET_CRYPTO_symmetric_encrypt (in, | 618 | (uint16_t) size, |
612 | (uint16_t) size, | 619 | &kx->encrypt_key, |
613 | &kx->encrypt_key, | 620 | iv, |
614 | iv, | 621 | out)); |
615 | out)); | ||
616 | GNUNET_STATISTICS_update (GSC_stats, | 622 | GNUNET_STATISTICS_update (GSC_stats, |
617 | gettext_noop ("# bytes encrypted"), | 623 | gettext_noop ("# bytes encrypted"), |
618 | size, | 624 | size, |
619 | GNUNET_NO); | 625 | GNUNET_NO); |
620 | /* the following is too sensitive to write to log files by accident, | 626 | /* the following is too sensitive to write to log files by accident, |
621 | so we require manual intervention to get this one... */ | 627 | so we require manual intervention to get this one... */ |
@@ -625,8 +631,7 @@ do_encrypt (struct GSC_KeyExchangeInfo *kx, | |||
625 | (unsigned int) size, | 631 | (unsigned int) size, |
626 | GNUNET_i2s (kx->peer), | 632 | GNUNET_i2s (kx->peer), |
627 | (unsigned int) kx->encrypt_key.crc32, | 633 | (unsigned int) kx->encrypt_key.crc32, |
628 | GNUNET_CRYPTO_crc32_n (iv, | 634 | GNUNET_CRYPTO_crc32_n (iv, sizeof (iv))); |
629 | sizeof (iv))); | ||
630 | #endif | 635 | #endif |
631 | return GNUNET_OK; | 636 | return GNUNET_OK; |
632 | } | 637 | } |
@@ -656,19 +661,18 @@ do_decrypt (struct GSC_KeyExchangeInfo *kx, | |||
656 | GNUNET_break (0); | 661 | GNUNET_break (0); |
657 | return GNUNET_NO; | 662 | return GNUNET_NO; |
658 | } | 663 | } |
659 | if ( (kx->status != GNUNET_CORE_KX_STATE_KEY_RECEIVED) && | 664 | if ((kx->status != GNUNET_CORE_KX_STATE_KEY_RECEIVED) && |
660 | (kx->status != GNUNET_CORE_KX_STATE_UP) && | 665 | (kx->status != GNUNET_CORE_KX_STATE_UP) && |
661 | (kx->status != GNUNET_CORE_KX_STATE_REKEY_SENT) ) | 666 | (kx->status != GNUNET_CORE_KX_STATE_REKEY_SENT)) |
662 | { | 667 | { |
663 | GNUNET_break_op (0); | 668 | GNUNET_break_op (0); |
664 | return GNUNET_SYSERR; | 669 | return GNUNET_SYSERR; |
665 | } | 670 | } |
666 | if (size != | 671 | if (size != GNUNET_CRYPTO_symmetric_decrypt (in, |
667 | GNUNET_CRYPTO_symmetric_decrypt (in, | 672 | (uint16_t) size, |
668 | (uint16_t) size, | 673 | &kx->decrypt_key, |
669 | &kx->decrypt_key, | 674 | iv, |
670 | iv, | 675 | out)) |
671 | out)) | ||
672 | { | 676 | { |
673 | GNUNET_break (0); | 677 | GNUNET_break (0); |
674 | return GNUNET_SYSERR; | 678 | return GNUNET_SYSERR; |
@@ -685,9 +689,7 @@ do_decrypt (struct GSC_KeyExchangeInfo *kx, | |||
685 | (unsigned int) size, | 689 | (unsigned int) size, |
686 | GNUNET_i2s (kx->peer), | 690 | GNUNET_i2s (kx->peer), |
687 | (unsigned int) kx->decrypt_key.crc32, | 691 | (unsigned int) kx->decrypt_key.crc32, |
688 | GNUNET_CRYPTO_crc32_n (iv, | 692 | GNUNET_CRYPTO_crc32_n (iv, sizeof (*iv))); |
689 | sizeof | ||
690 | (*iv))); | ||
691 | #endif | 693 | #endif |
692 | return GNUNET_OK; | 694 | return GNUNET_OK; |
693 | } | 695 | } |
@@ -713,7 +715,8 @@ set_key_retry_task (void *cls) | |||
713 | struct GSC_KeyExchangeInfo *kx = cls; | 715 | struct GSC_KeyExchangeInfo *kx = cls; |
714 | 716 | ||
715 | kx->retry_set_key_task = NULL; | 717 | kx->retry_set_key_task = NULL; |
716 | kx->set_key_retry_frequency = GNUNET_TIME_STD_BACKOFF (kx->set_key_retry_frequency); | 718 | kx->set_key_retry_frequency = |
719 | GNUNET_TIME_STD_BACKOFF (kx->set_key_retry_frequency); | ||
717 | GNUNET_assert (GNUNET_CORE_KX_STATE_DOWN != kx->status); | 720 | GNUNET_assert (GNUNET_CORE_KX_STATE_DOWN != kx->status); |
718 | send_key (kx); | 721 | send_key (kx); |
719 | } | 722 | } |
@@ -732,23 +735,20 @@ setup_fresh_ping (struct GSC_KeyExchangeInfo *kx) | |||
732 | struct GNUNET_CRYPTO_SymmetricInitializationVector iv; | 735 | struct GNUNET_CRYPTO_SymmetricInitializationVector iv; |
733 | 736 | ||
734 | pm = &kx->ping; | 737 | pm = &kx->ping; |
735 | kx->ping_challenge = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, | 738 | kx->ping_challenge = |
736 | UINT32_MAX); | 739 | GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, UINT32_MAX); |
737 | pm->header.size = htons (sizeof (struct PingMessage)); | 740 | pm->header.size = htons (sizeof (struct PingMessage)); |
738 | pm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_PING); | 741 | pm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_PING); |
739 | pm->iv_seed = calculate_seed (kx); | 742 | pm->iv_seed = calculate_seed (kx); |
740 | derive_iv (&iv, | 743 | derive_iv (&iv, &kx->encrypt_key, pm->iv_seed, kx->peer); |
741 | &kx->encrypt_key, | ||
742 | pm->iv_seed, | ||
743 | kx->peer); | ||
744 | pp.challenge = kx->ping_challenge; | 744 | pp.challenge = kx->ping_challenge; |
745 | pp.target = *kx->peer; | 745 | pp.target = *kx->peer; |
746 | do_encrypt (kx, | 746 | do_encrypt (kx, |
747 | &iv, | 747 | &iv, |
748 | &pp.target, | 748 | &pp.target, |
749 | &pm->target, | 749 | &pm->target, |
750 | sizeof (struct PingMessage) - ((void *) &pm->target - | 750 | sizeof (struct PingMessage) - |
751 | (void *) pm)); | 751 | ((void *) &pm->target - (void *) pm)); |
752 | } | 752 | } |
753 | 753 | ||
754 | 754 | ||
@@ -764,8 +764,7 @@ setup_fresh_ping (struct GSC_KeyExchangeInfo *kx) | |||
764 | * #GNUNET_SYSERR to stop further processing with error | 764 | * #GNUNET_SYSERR to stop further processing with error |
765 | */ | 765 | */ |
766 | static int | 766 | static int |
767 | deliver_message (void *cls, | 767 | deliver_message (void *cls, const struct GNUNET_MessageHeader *m) |
768 | const struct GNUNET_MessageHeader *m) | ||
769 | { | 768 | { |
770 | struct GSC_KeyExchangeInfo *kx = cls; | 769 | struct GSC_KeyExchangeInfo *kx = cls; |
771 | 770 | ||
@@ -816,38 +815,32 @@ deliver_message (void *cls, | |||
816 | static void * | 815 | static void * |
817 | handle_transport_notify_connect (void *cls, | 816 | handle_transport_notify_connect (void *cls, |
818 | const struct GNUNET_PeerIdentity *pid, | 817 | const struct GNUNET_PeerIdentity *pid, |
819 | struct GNUNET_MQ_Handle *mq) | 818 | struct GNUNET_MQ_Handle *mq) |
820 | { | 819 | { |
821 | struct GSC_KeyExchangeInfo *kx; | 820 | struct GSC_KeyExchangeInfo *kx; |
822 | struct GNUNET_HashCode h1; | 821 | struct GNUNET_HashCode h1; |
823 | struct GNUNET_HashCode h2; | 822 | struct GNUNET_HashCode h2; |
824 | 823 | ||
825 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 824 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
826 | "Initiating key exchange with `%s'\n", | 825 | "Initiating key exchange with `%s'\n", |
827 | GNUNET_i2s (pid)); | 826 | GNUNET_i2s (pid)); |
828 | GNUNET_STATISTICS_update (GSC_stats, | 827 | GNUNET_STATISTICS_update (GSC_stats, |
829 | gettext_noop ("# key exchanges initiated"), | 828 | gettext_noop ("# key exchanges initiated"), |
830 | 1, | 829 | 1, |
831 | GNUNET_NO); | 830 | GNUNET_NO); |
832 | kx = GNUNET_new (struct GSC_KeyExchangeInfo); | 831 | kx = GNUNET_new (struct GSC_KeyExchangeInfo); |
833 | kx->mst = GNUNET_MST_create (&deliver_message, | 832 | kx->mst = GNUNET_MST_create (&deliver_message, kx); |
834 | kx); | ||
835 | kx->mq = mq; | 833 | kx->mq = mq; |
836 | kx->peer = pid; | 834 | kx->peer = pid; |
837 | kx->set_key_retry_frequency = INITIAL_SET_KEY_RETRY_FREQUENCY; | 835 | kx->set_key_retry_frequency = INITIAL_SET_KEY_RETRY_FREQUENCY; |
838 | GNUNET_CONTAINER_DLL_insert (kx_head, | 836 | GNUNET_CONTAINER_DLL_insert (kx_head, kx_tail, kx); |
839 | kx_tail, | ||
840 | kx); | ||
841 | kx->status = GNUNET_CORE_KX_STATE_KEY_SENT; | 837 | kx->status = GNUNET_CORE_KX_STATE_KEY_SENT; |
842 | monitor_notify_all (kx); | 838 | monitor_notify_all (kx); |
843 | GNUNET_CRYPTO_hash (pid, | 839 | GNUNET_CRYPTO_hash (pid, sizeof (struct GNUNET_PeerIdentity), &h1); |
844 | sizeof (struct GNUNET_PeerIdentity), | ||
845 | &h1); | ||
846 | GNUNET_CRYPTO_hash (&GSC_my_identity, | 840 | GNUNET_CRYPTO_hash (&GSC_my_identity, |
847 | sizeof (struct GNUNET_PeerIdentity), | 841 | sizeof (struct GNUNET_PeerIdentity), |
848 | &h2); | 842 | &h2); |
849 | if (0 < GNUNET_CRYPTO_hash_cmp (&h1, | 843 | if (0 < GNUNET_CRYPTO_hash_cmp (&h1, &h2)) |
850 | &h2)) | ||
851 | { | 844 | { |
852 | /* peer with "lower" identity starts KX, otherwise we typically end up | 845 | /* peer with "lower" identity starts KX, otherwise we typically end up |
853 | with both peers starting the exchange and transmit the 'set key' | 846 | with both peers starting the exchange and transmit the 'set key' |
@@ -858,10 +851,10 @@ handle_transport_notify_connect (void *cls, | |||
858 | { | 851 | { |
859 | /* peer with "higher" identity starts a delayed KX, if the "lower" peer | 852 | /* peer with "higher" identity starts a delayed KX, if the "lower" peer |
860 | * does not start a KX since it sees no reasons to do so */ | 853 | * does not start a KX since it sees no reasons to do so */ |
861 | kx->retry_set_key_task | 854 | kx->retry_set_key_task = |
862 | = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, | 855 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, |
863 | &set_key_retry_task, | 856 | &set_key_retry_task, |
864 | kx); | 857 | kx); |
865 | } | 858 | } |
866 | return kx; | 859 | return kx; |
867 | } | 860 | } |
@@ -879,7 +872,7 @@ handle_transport_notify_connect (void *cls, | |||
879 | static void | 872 | static void |
880 | handle_transport_notify_disconnect (void *cls, | 873 | handle_transport_notify_disconnect (void *cls, |
881 | const struct GNUNET_PeerIdentity *peer, | 874 | const struct GNUNET_PeerIdentity *peer, |
882 | void *handler_cls) | 875 | void *handler_cls) |
883 | { | 876 | { |
884 | struct GSC_KeyExchangeInfo *kx = handler_cls; | 877 | struct GSC_KeyExchangeInfo *kx = handler_cls; |
885 | 878 | ||
@@ -888,9 +881,9 @@ handle_transport_notify_disconnect (void *cls, | |||
888 | GNUNET_i2s (peer)); | 881 | GNUNET_i2s (peer)); |
889 | GSC_SESSIONS_end (kx->peer); | 882 | GSC_SESSIONS_end (kx->peer); |
890 | GNUNET_STATISTICS_update (GSC_stats, | 883 | GNUNET_STATISTICS_update (GSC_stats, |
891 | gettext_noop ("# key exchanges stopped"), | 884 | gettext_noop ("# key exchanges stopped"), |
892 | 1, | 885 | 1, |
893 | GNUNET_NO); | 886 | GNUNET_NO); |
894 | if (NULL != kx->retry_set_key_task) | 887 | if (NULL != kx->retry_set_key_task) |
895 | { | 888 | { |
896 | GNUNET_SCHEDULER_cancel (kx->retry_set_key_task); | 889 | GNUNET_SCHEDULER_cancel (kx->retry_set_key_task); |
@@ -903,9 +896,7 @@ handle_transport_notify_disconnect (void *cls, | |||
903 | } | 896 | } |
904 | kx->status = GNUNET_CORE_KX_PEER_DISCONNECT; | 897 | kx->status = GNUNET_CORE_KX_PEER_DISCONNECT; |
905 | monitor_notify_all (kx); | 898 | monitor_notify_all (kx); |
906 | GNUNET_CONTAINER_DLL_remove (kx_head, | 899 | GNUNET_CONTAINER_DLL_remove (kx_head, kx_tail, kx); |
907 | kx_tail, | ||
908 | kx); | ||
909 | GNUNET_MST_destroy (kx->mst); | 900 | GNUNET_MST_destroy (kx->mst); |
910 | GNUNET_free (kx); | 901 | GNUNET_free (kx); |
911 | } | 902 | } |
@@ -926,8 +917,7 @@ send_ping (struct GSC_KeyExchangeInfo *kx) | |||
926 | 1, | 917 | 1, |
927 | GNUNET_NO); | 918 | GNUNET_NO); |
928 | env = GNUNET_MQ_msg_copy (&kx->ping.header); | 919 | env = GNUNET_MQ_msg_copy (&kx->ping.header); |
929 | GNUNET_MQ_send (kx->mq, | 920 | GNUNET_MQ_send (kx->mq, env); |
930 | env); | ||
931 | } | 921 | } |
932 | 922 | ||
933 | 923 | ||
@@ -941,22 +931,15 @@ derive_session_keys (struct GSC_KeyExchangeInfo *kx) | |||
941 | { | 931 | { |
942 | struct GNUNET_HashCode key_material; | 932 | struct GNUNET_HashCode key_material; |
943 | 933 | ||
944 | if (GNUNET_OK != | 934 | if (GNUNET_OK != GNUNET_CRYPTO_ecc_ecdh (my_ephemeral_key, |
945 | GNUNET_CRYPTO_ecc_ecdh (my_ephemeral_key, | 935 | &kx->other_ephemeral_key, |
946 | &kx->other_ephemeral_key, | 936 | &key_material)) |
947 | &key_material)) | ||
948 | { | 937 | { |
949 | GNUNET_break (0); | 938 | GNUNET_break (0); |
950 | return; | 939 | return; |
951 | } | 940 | } |
952 | derive_aes_key (&GSC_my_identity, | 941 | derive_aes_key (&GSC_my_identity, kx->peer, &key_material, &kx->encrypt_key); |
953 | kx->peer, | 942 | derive_aes_key (kx->peer, &GSC_my_identity, &key_material, &kx->decrypt_key); |
954 | &key_material, | ||
955 | &kx->encrypt_key); | ||
956 | derive_aes_key (kx->peer, | ||
957 | &GSC_my_identity, | ||
958 | &key_material, | ||
959 | &kx->decrypt_key); | ||
960 | memset (&key_material, 0, sizeof (key_material)); | 943 | memset (&key_material, 0, sizeof (key_material)); |
961 | /* fresh key, reset sequence numbers */ | 944 | /* fresh key, reset sequence numbers */ |
962 | kx->last_sequence_number_received = 0; | 945 | kx->last_sequence_number_received = 0; |
@@ -973,8 +956,7 @@ derive_session_keys (struct GSC_KeyExchangeInfo *kx) | |||
973 | * @param m the set key message we received | 956 | * @param m the set key message we received |
974 | */ | 957 | */ |
975 | static void | 958 | static void |
976 | handle_ephemeral_key (void *cls, | 959 | handle_ephemeral_key (void *cls, const struct EphemeralKeyMessage *m) |
977 | const struct EphemeralKeyMessage *m) | ||
978 | { | 960 | { |
979 | struct GSC_KeyExchangeInfo *kx = cls; | 961 | struct GSC_KeyExchangeInfo *kx = cls; |
980 | struct GNUNET_TIME_Absolute start_t; | 962 | struct GNUNET_TIME_Absolute start_t; |
@@ -983,14 +965,14 @@ handle_ephemeral_key (void *cls, | |||
983 | enum GNUNET_CORE_KxState sender_status; | 965 | enum GNUNET_CORE_KxState sender_status; |
984 | 966 | ||
985 | end_t = GNUNET_TIME_absolute_ntoh (m->expiration_time); | 967 | end_t = GNUNET_TIME_absolute_ntoh (m->expiration_time); |
986 | if ( ( (GNUNET_CORE_KX_STATE_KEY_RECEIVED == kx->status) || | 968 | if (((GNUNET_CORE_KX_STATE_KEY_RECEIVED == kx->status) || |
987 | (GNUNET_CORE_KX_STATE_UP == kx->status) || | 969 | (GNUNET_CORE_KX_STATE_UP == kx->status) || |
988 | (GNUNET_CORE_KX_STATE_REKEY_SENT == kx->status) ) && | 970 | (GNUNET_CORE_KX_STATE_REKEY_SENT == kx->status)) && |
989 | (end_t.abs_value_us < kx->foreign_key_expires.abs_value_us) ) | 971 | (end_t.abs_value_us < kx->foreign_key_expires.abs_value_us)) |
990 | { | 972 | { |
991 | GNUNET_STATISTICS_update (GSC_stats, | 973 | GNUNET_STATISTICS_update (GSC_stats, |
992 | gettext_noop ("# old ephemeral keys ignored"), | 974 | gettext_noop ("# old ephemeral keys ignored"), |
993 | 1, | 975 | 1, |
994 | GNUNET_NO); | 976 | GNUNET_NO); |
995 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 977 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
996 | "Received expired EPHEMERAL_KEY from %s\n", | 978 | "Received expired EPHEMERAL_KEY from %s\n", |
@@ -1002,18 +984,18 @@ handle_ephemeral_key (void *cls, | |||
1002 | sizeof (m->ephemeral_key))) | 984 | sizeof (m->ephemeral_key))) |
1003 | { | 985 | { |
1004 | GNUNET_STATISTICS_update (GSC_stats, | 986 | GNUNET_STATISTICS_update (GSC_stats, |
1005 | gettext_noop ("# duplicate ephemeral keys ignored"), | 987 | gettext_noop ( |
1006 | 1, | 988 | "# duplicate ephemeral keys ignored"), |
989 | 1, | ||
1007 | GNUNET_NO); | 990 | GNUNET_NO); |
1008 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 991 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
1009 | "Ignoring duplicate EPHEMERAL_KEY from %s\n", | 992 | "Ignoring duplicate EPHEMERAL_KEY from %s\n", |
1010 | GNUNET_i2s (&m->origin_identity)); | 993 | GNUNET_i2s (&m->origin_identity)); |
1011 | return; | 994 | return; |
1012 | } | 995 | } |
1013 | if (0 != | 996 | if (0 != memcmp (&m->origin_identity, |
1014 | memcmp (&m->origin_identity, | 997 | kx->peer, |
1015 | kx->peer, | 998 | sizeof (struct GNUNET_PeerIdentity))) |
1016 | sizeof (struct GNUNET_PeerIdentity))) | ||
1017 | { | 999 | { |
1018 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 1000 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
1019 | "Received EPHEMERAL_KEY from %s, but expected %s\n", | 1001 | "Received EPHEMERAL_KEY from %s, but expected %s\n", |
@@ -1024,10 +1006,10 @@ handle_ephemeral_key (void *cls, | |||
1024 | } | 1006 | } |
1025 | if ((ntohl (m->purpose.size) != | 1007 | if ((ntohl (m->purpose.size) != |
1026 | sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) + | 1008 | sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) + |
1027 | sizeof (struct GNUNET_TIME_AbsoluteNBO) + | 1009 | sizeof (struct GNUNET_TIME_AbsoluteNBO) + |
1028 | sizeof (struct GNUNET_TIME_AbsoluteNBO) + | 1010 | sizeof (struct GNUNET_TIME_AbsoluteNBO) + |
1029 | sizeof (struct GNUNET_CRYPTO_EddsaPublicKey) + | 1011 | sizeof (struct GNUNET_CRYPTO_EddsaPublicKey) + |
1030 | sizeof (struct GNUNET_CRYPTO_EddsaPublicKey)) || | 1012 | sizeof (struct GNUNET_CRYPTO_EddsaPublicKey)) || |
1031 | (GNUNET_OK != | 1013 | (GNUNET_OK != |
1032 | GNUNET_CRYPTO_eddsa_verify (GNUNET_SIGNATURE_PURPOSE_SET_ECC_KEY, | 1014 | GNUNET_CRYPTO_eddsa_verify (GNUNET_SIGNATURE_PURPOSE_SET_ECC_KEY, |
1033 | &m->purpose, | 1015 | &m->purpose, |
@@ -1037,7 +1019,8 @@ handle_ephemeral_key (void *cls, | |||
1037 | /* invalid signature */ | 1019 | /* invalid signature */ |
1038 | GNUNET_break_op (0); | 1020 | GNUNET_break_op (0); |
1039 | GNUNET_STATISTICS_update (GSC_stats, | 1021 | GNUNET_STATISTICS_update (GSC_stats, |
1040 | gettext_noop ("# EPHEMERAL_KEYs rejected (bad signature)"), | 1022 | gettext_noop ( |
1023 | "# EPHEMERAL_KEYs rejected (bad signature)"), | ||
1041 | 1, | 1024 | 1, |
1042 | GNUNET_NO); | 1025 | GNUNET_NO); |
1043 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 1026 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
@@ -1047,17 +1030,22 @@ handle_ephemeral_key (void *cls, | |||
1047 | } | 1030 | } |
1048 | now = GNUNET_TIME_absolute_get (); | 1031 | now = GNUNET_TIME_absolute_get (); |
1049 | start_t = GNUNET_TIME_absolute_ntoh (m->creation_time); | 1032 | start_t = GNUNET_TIME_absolute_ntoh (m->creation_time); |
1050 | if ( (end_t.abs_value_us < GNUNET_TIME_absolute_subtract (now, REKEY_TOLERANCE).abs_value_us) || | 1033 | if ((end_t.abs_value_us < |
1051 | (start_t.abs_value_us > GNUNET_TIME_absolute_add (now, REKEY_TOLERANCE).abs_value_us) ) | 1034 | GNUNET_TIME_absolute_subtract (now, REKEY_TOLERANCE).abs_value_us) || |
1035 | (start_t.abs_value_us > | ||
1036 | GNUNET_TIME_absolute_add (now, REKEY_TOLERANCE).abs_value_us)) | ||
1052 | { | 1037 | { |
1053 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 1038 | GNUNET_log ( |
1054 | _("EPHEMERAL_KEY from peer `%s' rejected as its validity range does not match our system time (%llu not in [%llu,%llu]).\n"), | 1039 | GNUNET_ERROR_TYPE_WARNING, |
1055 | GNUNET_i2s (kx->peer), | 1040 | _ ( |
1056 | (unsigned long long) now.abs_value_us, | 1041 | "EPHEMERAL_KEY from peer `%s' rejected as its validity range does not match our system time (%llu not in [%llu,%llu]).\n"), |
1057 | (unsigned long long) start_t.abs_value_us, | 1042 | GNUNET_i2s (kx->peer), |
1058 | (unsigned long long) end_t.abs_value_us); | 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); | ||
1059 | GNUNET_STATISTICS_update (GSC_stats, | 1046 | GNUNET_STATISTICS_update (GSC_stats, |
1060 | gettext_noop ("# EPHEMERAL_KEY messages rejected due to time"), | 1047 | gettext_noop ( |
1048 | "# EPHEMERAL_KEY messages rejected due to time"), | ||
1061 | 1, | 1049 | 1, |
1062 | GNUNET_NO); | 1050 | GNUNET_NO); |
1063 | return; | 1051 | return; |
@@ -1066,9 +1054,7 @@ handle_ephemeral_key (void *cls, | |||
1066 | { | 1054 | { |
1067 | struct GNUNET_HashCode eh; | 1055 | struct GNUNET_HashCode eh; |
1068 | 1056 | ||
1069 | GNUNET_CRYPTO_hash (&m->ephemeral_key, | 1057 | GNUNET_CRYPTO_hash (&m->ephemeral_key, sizeof (m->ephemeral_key), &eh); |
1070 | sizeof (m->ephemeral_key), | ||
1071 | &eh); | ||
1072 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1058 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1073 | "Received valid EPHEMERAL_KEY `%s' from `%s' in state %d.\n", | 1059 | "Received valid EPHEMERAL_KEY `%s' from `%s' in state %d.\n", |
1074 | GNUNET_h2s (&eh), | 1060 | GNUNET_h2s (&eh), |
@@ -1166,8 +1152,7 @@ handle_ephemeral_key (void *cls, | |||
1166 | * @param m the encrypted PING message itself | 1152 | * @param m the encrypted PING message itself |
1167 | */ | 1153 | */ |
1168 | static void | 1154 | static void |
1169 | handle_ping (void *cls, | 1155 | handle_ping (void *cls, const struct PingMessage *m) |
1170 | const struct PingMessage *m) | ||
1171 | { | 1156 | { |
1172 | struct GSC_KeyExchangeInfo *kx = cls; | 1157 | struct GSC_KeyExchangeInfo *kx = cls; |
1173 | struct PingMessage t; | 1158 | struct PingMessage t; |
@@ -1180,39 +1165,34 @@ handle_ping (void *cls, | |||
1180 | gettext_noop ("# PING messages received"), | 1165 | gettext_noop ("# PING messages received"), |
1181 | 1, | 1166 | 1, |
1182 | GNUNET_NO); | 1167 | GNUNET_NO); |
1183 | if ( (kx->status != GNUNET_CORE_KX_STATE_KEY_RECEIVED) && | 1168 | if ((kx->status != GNUNET_CORE_KX_STATE_KEY_RECEIVED) && |
1184 | (kx->status != GNUNET_CORE_KX_STATE_UP) && | 1169 | (kx->status != GNUNET_CORE_KX_STATE_UP) && |
1185 | (kx->status != GNUNET_CORE_KX_STATE_REKEY_SENT)) | 1170 | (kx->status != GNUNET_CORE_KX_STATE_REKEY_SENT)) |
1186 | { | 1171 | { |
1187 | /* ignore */ | 1172 | /* ignore */ |
1188 | GNUNET_STATISTICS_update (GSC_stats, | 1173 | GNUNET_STATISTICS_update (GSC_stats, |
1189 | gettext_noop ("# PING messages dropped (out of order)"), | 1174 | gettext_noop ( |
1175 | "# PING messages dropped (out of order)"), | ||
1190 | 1, | 1176 | 1, |
1191 | GNUNET_NO); | 1177 | GNUNET_NO); |
1192 | return; | 1178 | return; |
1193 | } | 1179 | } |
1194 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1180 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1195 | "Core service receives PING request from `%s'.\n", | 1181 | "Core service receives PING request from `%s'.\n", |
1196 | GNUNET_i2s (kx->peer)); | 1182 | GNUNET_i2s (kx->peer)); |
1197 | derive_iv (&iv, | 1183 | derive_iv (&iv, &kx->decrypt_key, m->iv_seed, &GSC_my_identity); |
1198 | &kx->decrypt_key, | 1184 | if (GNUNET_OK != do_decrypt (kx, |
1199 | m->iv_seed, | 1185 | &iv, |
1200 | &GSC_my_identity); | 1186 | &m->target, |
1201 | if (GNUNET_OK != | 1187 | &t.target, |
1202 | do_decrypt (kx, | 1188 | sizeof (struct PingMessage) - |
1203 | &iv, | 1189 | ((void *) &m->target - (void *) m))) |
1204 | &m->target, | ||
1205 | &t.target, | ||
1206 | sizeof (struct PingMessage) - ((void *) &m->target - | ||
1207 | (void *) m))) | ||
1208 | { | 1190 | { |
1209 | GNUNET_break_op (0); | 1191 | GNUNET_break_op (0); |
1210 | return; | 1192 | return; |
1211 | } | 1193 | } |
1212 | if (0 != | 1194 | if (0 != |
1213 | memcmp (&t.target, | 1195 | memcmp (&t.target, &GSC_my_identity, sizeof (struct GNUNET_PeerIdentity))) |
1214 | &GSC_my_identity, | ||
1215 | sizeof (struct GNUNET_PeerIdentity))) | ||
1216 | { | 1196 | { |
1217 | if (GNUNET_CORE_KX_STATE_REKEY_SENT != kx->status) | 1197 | if (GNUNET_CORE_KX_STATE_REKEY_SENT != kx->status) |
1218 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 1198 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
@@ -1220,9 +1200,10 @@ handle_ping (void *cls, | |||
1220 | GNUNET_i2s (kx->peer), | 1200 | GNUNET_i2s (kx->peer), |
1221 | GNUNET_i2s2 (&t.target)); | 1201 | GNUNET_i2s2 (&t.target)); |
1222 | else | 1202 | else |
1223 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1203 | GNUNET_log ( |
1224 | "Decryption of PING from peer `%s' failed after rekey (harmless)\n", | 1204 | GNUNET_ERROR_TYPE_DEBUG, |
1225 | GNUNET_i2s (kx->peer)); | 1205 | "Decryption of PING from peer `%s' failed after rekey (harmless)\n", |
1206 | GNUNET_i2s (kx->peer)); | ||
1226 | GNUNET_break_op (0); | 1207 | GNUNET_break_op (0); |
1227 | return; | 1208 | return; |
1228 | } | 1209 | } |
@@ -1230,26 +1211,20 @@ handle_ping (void *cls, | |||
1230 | tx.reserved = 0; | 1211 | tx.reserved = 0; |
1231 | tx.challenge = t.challenge; | 1212 | tx.challenge = t.challenge; |
1232 | tx.target = t.target; | 1213 | tx.target = t.target; |
1233 | env = GNUNET_MQ_msg (tp, | 1214 | env = GNUNET_MQ_msg (tp, GNUNET_MESSAGE_TYPE_CORE_PONG); |
1234 | GNUNET_MESSAGE_TYPE_CORE_PONG); | ||
1235 | tp->iv_seed = calculate_seed (kx); | 1215 | tp->iv_seed = calculate_seed (kx); |
1236 | derive_pong_iv (&iv, | 1216 | derive_pong_iv (&iv, &kx->encrypt_key, tp->iv_seed, t.challenge, kx->peer); |
1237 | &kx->encrypt_key, | ||
1238 | tp->iv_seed, | ||
1239 | t.challenge, | ||
1240 | kx->peer); | ||
1241 | do_encrypt (kx, | 1217 | do_encrypt (kx, |
1242 | &iv, | 1218 | &iv, |
1243 | &tx.challenge, | 1219 | &tx.challenge, |
1244 | &tp->challenge, | 1220 | &tp->challenge, |
1245 | sizeof (struct PongMessage) - ((void *) &tp->challenge - | 1221 | sizeof (struct PongMessage) - |
1246 | (void *) tp)); | 1222 | ((void *) &tp->challenge - (void *) tp)); |
1247 | GNUNET_STATISTICS_update (GSC_stats, | 1223 | GNUNET_STATISTICS_update (GSC_stats, |
1248 | gettext_noop ("# PONG messages created"), | 1224 | gettext_noop ("# PONG messages created"), |
1249 | 1, | 1225 | 1, |
1250 | GNUNET_NO); | 1226 | GNUNET_NO); |
1251 | GNUNET_MQ_send (kx->mq, | 1227 | GNUNET_MQ_send (kx->mq, env); |
1252 | env); | ||
1253 | } | 1228 | } |
1254 | 1229 | ||
1255 | 1230 | ||
@@ -1289,13 +1264,10 @@ send_keep_alive (void *cls) | |||
1289 | GNUNET_NO); | 1264 | GNUNET_NO); |
1290 | setup_fresh_ping (kx); | 1265 | setup_fresh_ping (kx); |
1291 | send_ping (kx); | 1266 | send_ping (kx); |
1292 | retry = | 1267 | retry = GNUNET_TIME_relative_max (GNUNET_TIME_relative_divide (left, 2), |
1293 | GNUNET_TIME_relative_max (GNUNET_TIME_relative_divide (left, 2), | 1268 | MIN_PING_FREQUENCY); |
1294 | MIN_PING_FREQUENCY); | ||
1295 | kx->keep_alive_task = | 1269 | kx->keep_alive_task = |
1296 | GNUNET_SCHEDULER_add_delayed (retry, | 1270 | GNUNET_SCHEDULER_add_delayed (retry, &send_keep_alive, kx); |
1297 | &send_keep_alive, | ||
1298 | kx); | ||
1299 | } | 1271 | } |
1300 | 1272 | ||
1301 | 1273 | ||
@@ -1312,10 +1284,9 @@ update_timeout (struct GSC_KeyExchangeInfo *kx) | |||
1312 | struct GNUNET_TIME_Relative delta; | 1284 | struct GNUNET_TIME_Relative delta; |
1313 | 1285 | ||
1314 | kx->timeout = | 1286 | kx->timeout = |
1315 | GNUNET_TIME_relative_to_absolute | 1287 | GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT); |
1316 | (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT); | 1288 | delta = |
1317 | delta = GNUNET_TIME_absolute_get_difference (kx->last_notify_timeout, | 1289 | GNUNET_TIME_absolute_get_difference (kx->last_notify_timeout, kx->timeout); |
1318 | kx->timeout); | ||
1319 | if (delta.rel_value_us > 5LL * 1000LL * 1000LL) | 1290 | if (delta.rel_value_us > 5LL * 1000LL * 1000LL) |
1320 | { | 1291 | { |
1321 | /* we only notify monitors about timeout changes if those | 1292 | /* we only notify monitors about timeout changes if those |
@@ -1324,12 +1295,10 @@ update_timeout (struct GSC_KeyExchangeInfo *kx) | |||
1324 | } | 1295 | } |
1325 | if (NULL != kx->keep_alive_task) | 1296 | if (NULL != kx->keep_alive_task) |
1326 | GNUNET_SCHEDULER_cancel (kx->keep_alive_task); | 1297 | GNUNET_SCHEDULER_cancel (kx->keep_alive_task); |
1327 | kx->keep_alive_task = | 1298 | kx->keep_alive_task = GNUNET_SCHEDULER_add_delayed ( |
1328 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_divide | 1299 | GNUNET_TIME_relative_divide (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, 2), |
1329 | (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, | 1300 | &send_keep_alive, |
1330 | 2), | 1301 | kx); |
1331 | &send_keep_alive, | ||
1332 | kx); | ||
1333 | } | 1302 | } |
1334 | 1303 | ||
1335 | 1304 | ||
@@ -1340,8 +1309,7 @@ update_timeout (struct GSC_KeyExchangeInfo *kx) | |||
1340 | * @param m the encrypted PONG message itself | 1309 | * @param m the encrypted PONG message itself |
1341 | */ | 1310 | */ |
1342 | static void | 1311 | static void |
1343 | handle_pong (void *cls, | 1312 | handle_pong (void *cls, const struct PongMessage *m) |
1344 | const struct PongMessage *m) | ||
1345 | { | 1313 | { |
1346 | struct GSC_KeyExchangeInfo *kx = cls; | 1314 | struct GSC_KeyExchangeInfo *kx = cls; |
1347 | struct PongMessage t; | 1315 | struct PongMessage t; |
@@ -1355,13 +1323,17 @@ handle_pong (void *cls, | |||
1355 | { | 1323 | { |
1356 | case GNUNET_CORE_KX_STATE_DOWN: | 1324 | case GNUNET_CORE_KX_STATE_DOWN: |
1357 | GNUNET_STATISTICS_update (GSC_stats, | 1325 | GNUNET_STATISTICS_update (GSC_stats, |
1358 | gettext_noop ("# PONG messages dropped (connection down)"), 1, | 1326 | gettext_noop ( |
1359 | GNUNET_NO); | 1327 | "# PONG messages dropped (connection down)"), |
1328 | 1, | ||
1329 | GNUNET_NO); | ||
1360 | return; | 1330 | return; |
1361 | case GNUNET_CORE_KX_STATE_KEY_SENT: | 1331 | case GNUNET_CORE_KX_STATE_KEY_SENT: |
1362 | GNUNET_STATISTICS_update (GSC_stats, | 1332 | GNUNET_STATISTICS_update (GSC_stats, |
1363 | gettext_noop ("# PONG messages dropped (out of order)"), 1, | 1333 | gettext_noop ( |
1364 | GNUNET_NO); | 1334 | "# PONG messages dropped (out of order)"), |
1335 | 1, | ||
1336 | GNUNET_NO); | ||
1365 | return; | 1337 | return; |
1366 | case GNUNET_CORE_KX_STATE_KEY_RECEIVED: | 1338 | case GNUNET_CORE_KX_STATE_KEY_RECEIVED: |
1367 | break; | 1339 | break; |
@@ -1383,13 +1355,12 @@ handle_pong (void *cls, | |||
1383 | m->iv_seed, | 1355 | m->iv_seed, |
1384 | kx->ping_challenge, | 1356 | kx->ping_challenge, |
1385 | &GSC_my_identity); | 1357 | &GSC_my_identity); |
1386 | if (GNUNET_OK != | 1358 | if (GNUNET_OK != do_decrypt (kx, |
1387 | do_decrypt (kx, | 1359 | &iv, |
1388 | &iv, | 1360 | &m->challenge, |
1389 | &m->challenge, | 1361 | &t.challenge, |
1390 | &t.challenge, | 1362 | sizeof (struct PongMessage) - |
1391 | sizeof (struct PongMessage) - ((void *) &m->challenge - | 1363 | ((void *) &m->challenge - (void *) m))) |
1392 | (void *) m))) | ||
1393 | { | 1364 | { |
1394 | GNUNET_break_op (0); | 1365 | GNUNET_break_op (0); |
1395 | return; | 1366 | return; |
@@ -1398,9 +1369,8 @@ handle_pong (void *cls, | |||
1398 | gettext_noop ("# PONG messages decrypted"), | 1369 | gettext_noop ("# PONG messages decrypted"), |
1399 | 1, | 1370 | 1, |
1400 | GNUNET_NO); | 1371 | GNUNET_NO); |
1401 | if ((0 != memcmp (&t.target, | 1372 | if ((0 != |
1402 | kx->peer, | 1373 | memcmp (&t.target, kx->peer, sizeof (struct GNUNET_PeerIdentity))) || |
1403 | sizeof (struct GNUNET_PeerIdentity))) || | ||
1404 | (kx->ping_challenge != t.challenge)) | 1374 | (kx->ping_challenge != t.challenge)) |
1405 | { | 1375 | { |
1406 | /* PONG malformed */ | 1376 | /* PONG malformed */ |
@@ -1426,14 +1396,15 @@ handle_pong (void *cls, | |||
1426 | switch (kx->status) | 1396 | switch (kx->status) |
1427 | { | 1397 | { |
1428 | case GNUNET_CORE_KX_STATE_DOWN: | 1398 | case GNUNET_CORE_KX_STATE_DOWN: |
1429 | GNUNET_assert (0); /* should be impossible */ | 1399 | GNUNET_assert (0); /* should be impossible */ |
1430 | return; | 1400 | return; |
1431 | case GNUNET_CORE_KX_STATE_KEY_SENT: | 1401 | case GNUNET_CORE_KX_STATE_KEY_SENT: |
1432 | GNUNET_assert (0); /* should be impossible */ | 1402 | GNUNET_assert (0); /* should be impossible */ |
1433 | return; | 1403 | return; |
1434 | case GNUNET_CORE_KX_STATE_KEY_RECEIVED: | 1404 | case GNUNET_CORE_KX_STATE_KEY_RECEIVED: |
1435 | GNUNET_STATISTICS_update (GSC_stats, | 1405 | GNUNET_STATISTICS_update (GSC_stats, |
1436 | gettext_noop ("# session keys confirmed via PONG"), | 1406 | gettext_noop ( |
1407 | "# session keys confirmed via PONG"), | ||
1437 | 1, | 1408 | 1, |
1438 | GNUNET_NO); | 1409 | GNUNET_NO); |
1439 | kx->status = GNUNET_CORE_KX_STATE_UP; | 1410 | kx->status = GNUNET_CORE_KX_STATE_UP; |
@@ -1451,7 +1422,8 @@ handle_pong (void *cls, | |||
1451 | break; | 1422 | break; |
1452 | case GNUNET_CORE_KX_STATE_REKEY_SENT: | 1423 | case GNUNET_CORE_KX_STATE_REKEY_SENT: |
1453 | GNUNET_STATISTICS_update (GSC_stats, | 1424 | GNUNET_STATISTICS_update (GSC_stats, |
1454 | gettext_noop ("# rekey operations confirmed via PONG"), | 1425 | gettext_noop ( |
1426 | "# rekey operations confirmed via PONG"), | ||
1455 | 1, | 1427 | 1, |
1456 | GNUNET_NO); | 1428 | GNUNET_NO); |
1457 | kx->status = GNUNET_CORE_KX_STATE_UP; | 1429 | kx->status = GNUNET_CORE_KX_STATE_UP; |
@@ -1478,8 +1450,8 @@ send_key (struct GSC_KeyExchangeInfo *kx) | |||
1478 | GNUNET_assert (GNUNET_CORE_KX_STATE_DOWN != kx->status); | 1450 | GNUNET_assert (GNUNET_CORE_KX_STATE_DOWN != kx->status); |
1479 | if (NULL != kx->retry_set_key_task) | 1451 | if (NULL != kx->retry_set_key_task) |
1480 | { | 1452 | { |
1481 | GNUNET_SCHEDULER_cancel (kx->retry_set_key_task); | 1453 | GNUNET_SCHEDULER_cancel (kx->retry_set_key_task); |
1482 | kx->retry_set_key_task = NULL; | 1454 | kx->retry_set_key_task = NULL; |
1483 | } | 1455 | } |
1484 | /* always update sender status in SET KEY message */ | 1456 | /* always update sender status in SET KEY message */ |
1485 | #if DEBUG_KX | 1457 | #if DEBUG_KX |
@@ -1498,14 +1470,13 @@ send_key (struct GSC_KeyExchangeInfo *kx) | |||
1498 | #endif | 1470 | #endif |
1499 | current_ekm.sender_status = htonl ((int32_t) (kx->status)); | 1471 | current_ekm.sender_status = htonl ((int32_t) (kx->status)); |
1500 | env = GNUNET_MQ_msg_copy (¤t_ekm.header); | 1472 | env = GNUNET_MQ_msg_copy (¤t_ekm.header); |
1501 | GNUNET_MQ_send (kx->mq, | 1473 | GNUNET_MQ_send (kx->mq, env); |
1502 | env); | ||
1503 | if (GNUNET_CORE_KX_STATE_KEY_SENT != kx->status) | 1474 | if (GNUNET_CORE_KX_STATE_KEY_SENT != kx->status) |
1504 | send_ping (kx); | 1475 | send_ping (kx); |
1505 | kx->retry_set_key_task = | 1476 | kx->retry_set_key_task = |
1506 | GNUNET_SCHEDULER_add_delayed (kx->set_key_retry_frequency, | 1477 | GNUNET_SCHEDULER_add_delayed (kx->set_key_retry_frequency, |
1507 | &set_key_retry_task, | 1478 | &set_key_retry_task, |
1508 | kx); | 1479 | kx); |
1509 | } | 1480 | } |
1510 | 1481 | ||
1511 | 1482 | ||
@@ -1522,9 +1493,9 @@ GSC_KX_encrypt_and_transmit (struct GSC_KeyExchangeInfo *kx, | |||
1522 | size_t payload_size) | 1493 | size_t payload_size) |
1523 | { | 1494 | { |
1524 | size_t used = payload_size + sizeof (struct EncryptedMessage); | 1495 | size_t used = payload_size + sizeof (struct EncryptedMessage); |
1525 | char pbuf[used]; /* plaintext */ | 1496 | char pbuf[used]; /* plaintext */ |
1526 | struct EncryptedMessage *em; /* encrypted message */ | 1497 | struct EncryptedMessage *em; /* encrypted message */ |
1527 | struct EncryptedMessage *ph; /* plaintext header */ | 1498 | struct EncryptedMessage *ph; /* plaintext header */ |
1528 | struct GNUNET_MQ_Envelope *env; | 1499 | struct GNUNET_MQ_Envelope *env; |
1529 | struct GNUNET_CRYPTO_SymmetricInitializationVector iv; | 1500 | struct GNUNET_CRYPTO_SymmetricInitializationVector iv; |
1530 | struct GNUNET_CRYPTO_AuthKey auth_key; | 1501 | struct GNUNET_CRYPTO_AuthKey auth_key; |
@@ -1534,23 +1505,17 @@ GSC_KX_encrypt_and_transmit (struct GSC_KeyExchangeInfo *kx, | |||
1534 | ph->iv_seed = calculate_seed (kx); | 1505 | ph->iv_seed = calculate_seed (kx); |
1535 | ph->reserved = 0; | 1506 | ph->reserved = 0; |
1536 | ph->timestamp = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get ()); | 1507 | ph->timestamp = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get ()); |
1537 | GNUNET_memcpy (&ph[1], | 1508 | GNUNET_memcpy (&ph[1], payload, payload_size); |
1538 | payload, | ||
1539 | payload_size); | ||
1540 | env = GNUNET_MQ_msg_extra (em, | 1509 | env = GNUNET_MQ_msg_extra (em, |
1541 | payload_size, | 1510 | payload_size, |
1542 | GNUNET_MESSAGE_TYPE_CORE_ENCRYPTED_MESSAGE); | 1511 | GNUNET_MESSAGE_TYPE_CORE_ENCRYPTED_MESSAGE); |
1543 | em->iv_seed = ph->iv_seed; | 1512 | em->iv_seed = ph->iv_seed; |
1544 | derive_iv (&iv, | 1513 | derive_iv (&iv, &kx->encrypt_key, ph->iv_seed, kx->peer); |
1545 | &kx->encrypt_key, | 1514 | GNUNET_assert (GNUNET_OK == do_encrypt (kx, |
1546 | ph->iv_seed, | 1515 | &iv, |
1547 | kx->peer); | 1516 | &ph->sequence_number, |
1548 | GNUNET_assert (GNUNET_OK == | 1517 | &em->sequence_number, |
1549 | do_encrypt (kx, | 1518 | used - ENCRYPTED_HEADER_SIZE)); |
1550 | &iv, | ||
1551 | &ph->sequence_number, | ||
1552 | &em->sequence_number, | ||
1553 | used - ENCRYPTED_HEADER_SIZE)); | ||
1554 | #if DEBUG_KX | 1519 | #if DEBUG_KX |
1555 | { | 1520 | { |
1556 | struct GNUNET_HashCode hc; | 1521 | struct GNUNET_HashCode hc; |
@@ -1565,9 +1530,7 @@ GSC_KX_encrypt_and_transmit (struct GSC_KeyExchangeInfo *kx, | |||
1565 | GNUNET_i2s (kx->peer)); | 1530 | GNUNET_i2s (kx->peer)); |
1566 | } | 1531 | } |
1567 | #endif | 1532 | #endif |
1568 | derive_auth_key (&auth_key, | 1533 | derive_auth_key (&auth_key, &kx->encrypt_key, ph->iv_seed); |
1569 | &kx->encrypt_key, | ||
1570 | ph->iv_seed); | ||
1571 | GNUNET_CRYPTO_hmac (&auth_key, | 1534 | GNUNET_CRYPTO_hmac (&auth_key, |
1572 | &em->sequence_number, | 1535 | &em->sequence_number, |
1573 | used - ENCRYPTED_HEADER_SIZE, | 1536 | used - ENCRYPTED_HEADER_SIZE, |
@@ -1576,9 +1539,7 @@ GSC_KX_encrypt_and_transmit (struct GSC_KeyExchangeInfo *kx, | |||
1576 | { | 1539 | { |
1577 | struct GNUNET_HashCode hc; | 1540 | struct GNUNET_HashCode hc; |
1578 | 1541 | ||
1579 | GNUNET_CRYPTO_hash (&auth_key, | 1542 | GNUNET_CRYPTO_hash (&auth_key, sizeof (auth_key), &hc); |
1580 | sizeof (auth_key), | ||
1581 | &hc); | ||
1582 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1543 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1583 | "For peer %s, used AC %s to create hmac %s\n", | 1544 | "For peer %s, used AC %s to create hmac %s\n", |
1584 | GNUNET_i2s (kx->peer), | 1545 | GNUNET_i2s (kx->peer), |
@@ -1587,8 +1548,7 @@ GSC_KX_encrypt_and_transmit (struct GSC_KeyExchangeInfo *kx, | |||
1587 | } | 1548 | } |
1588 | #endif | 1549 | #endif |
1589 | kx->has_excess_bandwidth = GNUNET_NO; | 1550 | kx->has_excess_bandwidth = GNUNET_NO; |
1590 | GNUNET_MQ_send (kx->mq, | 1551 | GNUNET_MQ_send (kx->mq, env); |
1591 | env); | ||
1592 | } | 1552 | } |
1593 | 1553 | ||
1594 | 1554 | ||
@@ -1601,8 +1561,7 @@ GSC_KX_encrypt_and_transmit (struct GSC_KeyExchangeInfo *kx, | |||
1601 | * @return #GNUNET_OK if @a msg is well-formed (size-wise) | 1561 | * @return #GNUNET_OK if @a msg is well-formed (size-wise) |
1602 | */ | 1562 | */ |
1603 | static int | 1563 | static int |
1604 | check_encrypted (void *cls, | 1564 | check_encrypted (void *cls, const struct EncryptedMessage *m) |
1605 | const struct EncryptedMessage *m) | ||
1606 | { | 1565 | { |
1607 | uint16_t size = ntohs (m->header.size) - sizeof (*m); | 1566 | uint16_t size = ntohs (m->header.size) - sizeof (*m); |
1608 | 1567 | ||
@@ -1623,11 +1582,10 @@ check_encrypted (void *cls, | |||
1623 | * @param m encrypted message | 1582 | * @param m encrypted message |
1624 | */ | 1583 | */ |
1625 | static void | 1584 | static void |
1626 | handle_encrypted (void *cls, | 1585 | handle_encrypted (void *cls, const struct EncryptedMessage *m) |
1627 | const struct EncryptedMessage *m) | ||
1628 | { | 1586 | { |
1629 | struct GSC_KeyExchangeInfo *kx = cls; | 1587 | struct GSC_KeyExchangeInfo *kx = cls; |
1630 | struct EncryptedMessage *pt; /* plaintext */ | 1588 | struct EncryptedMessage *pt; /* plaintext */ |
1631 | struct GNUNET_HashCode ph; | 1589 | struct GNUNET_HashCode ph; |
1632 | uint32_t snum; | 1590 | uint32_t snum; |
1633 | struct GNUNET_TIME_Absolute t; | 1591 | struct GNUNET_TIME_Absolute t; |
@@ -1639,19 +1597,25 @@ handle_encrypted (void *cls, | |||
1639 | if (GNUNET_CORE_KX_STATE_UP != kx->status) | 1597 | if (GNUNET_CORE_KX_STATE_UP != kx->status) |
1640 | { | 1598 | { |
1641 | GNUNET_STATISTICS_update (GSC_stats, | 1599 | GNUNET_STATISTICS_update (GSC_stats, |
1642 | gettext_noop ("# DATA message dropped (out of order)"), | 1600 | gettext_noop ( |
1601 | "# DATA message dropped (out of order)"), | ||
1643 | 1, | 1602 | 1, |
1644 | GNUNET_NO); | 1603 | GNUNET_NO); |
1645 | return; | 1604 | return; |
1646 | } | 1605 | } |
1647 | if (0 == GNUNET_TIME_absolute_get_remaining (kx->foreign_key_expires).rel_value_us) | 1606 | if (0 == |
1607 | GNUNET_TIME_absolute_get_remaining (kx->foreign_key_expires).rel_value_us) | ||
1648 | { | 1608 | { |
1649 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 1609 | GNUNET_log ( |
1650 | _("Session to peer `%s' went down due to key expiration (should not happen)\n"), | 1610 | GNUNET_ERROR_TYPE_WARNING, |
1651 | GNUNET_i2s (kx->peer)); | 1611 | _ ( |
1612 | "Session to peer `%s' went down due to key expiration (should not happen)\n"), | ||
1613 | GNUNET_i2s (kx->peer)); | ||
1652 | GNUNET_STATISTICS_update (GSC_stats, | 1614 | GNUNET_STATISTICS_update (GSC_stats, |
1653 | gettext_noop ("# sessions terminated by key expiration"), | 1615 | gettext_noop ( |
1654 | 1, GNUNET_NO); | 1616 | "# sessions terminated by key expiration"), |
1617 | 1, | ||
1618 | GNUNET_NO); | ||
1655 | GSC_SESSIONS_end (kx->peer); | 1619 | GSC_SESSIONS_end (kx->peer); |
1656 | if (NULL != kx->keep_alive_task) | 1620 | if (NULL != kx->keep_alive_task) |
1657 | { | 1621 | { |
@@ -1669,9 +1633,7 @@ handle_encrypted (void *cls, | |||
1669 | { | 1633 | { |
1670 | struct GNUNET_HashCode hc; | 1634 | struct GNUNET_HashCode hc; |
1671 | 1635 | ||
1672 | GNUNET_CRYPTO_hash (&m->sequence_number, | 1636 | GNUNET_CRYPTO_hash (&m->sequence_number, size - ENCRYPTED_HEADER_SIZE, &hc); |
1673 | size - ENCRYPTED_HEADER_SIZE, | ||
1674 | &hc); | ||
1675 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1637 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1676 | "Received encrypted payload `%s' of %u bytes from %s\n", | 1638 | "Received encrypted payload `%s' of %u bytes from %s\n", |
1677 | GNUNET_h2s (&hc), | 1639 | GNUNET_h2s (&hc), |
@@ -1679,9 +1641,7 @@ handle_encrypted (void *cls, | |||
1679 | GNUNET_i2s (kx->peer)); | 1641 | GNUNET_i2s (kx->peer)); |
1680 | } | 1642 | } |
1681 | #endif | 1643 | #endif |
1682 | derive_auth_key (&auth_key, | 1644 | derive_auth_key (&auth_key, &kx->decrypt_key, m->iv_seed); |
1683 | &kx->decrypt_key, | ||
1684 | m->iv_seed); | ||
1685 | GNUNET_CRYPTO_hmac (&auth_key, | 1645 | GNUNET_CRYPTO_hmac (&auth_key, |
1686 | &m->sequence_number, | 1646 | &m->sequence_number, |
1687 | size - ENCRYPTED_HEADER_SIZE, | 1647 | size - ENCRYPTED_HEADER_SIZE, |
@@ -1690,9 +1650,7 @@ handle_encrypted (void *cls, | |||
1690 | { | 1650 | { |
1691 | struct GNUNET_HashCode hc; | 1651 | struct GNUNET_HashCode hc; |
1692 | 1652 | ||
1693 | GNUNET_CRYPTO_hash (&auth_key, | 1653 | GNUNET_CRYPTO_hash (&auth_key, sizeof (auth_key), &hc); |
1694 | sizeof (auth_key), | ||
1695 | &hc); | ||
1696 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1654 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1697 | "For peer %s, used AC %s to verify hmac %s\n", | 1655 | "For peer %s, used AC %s to verify hmac %s\n", |
1698 | GNUNET_i2s (kx->peer), | 1656 | GNUNET_i2s (kx->peer), |
@@ -1700,27 +1658,21 @@ handle_encrypted (void *cls, | |||
1700 | GNUNET_h2s2 (&m->hmac)); | 1658 | GNUNET_h2s2 (&m->hmac)); |
1701 | } | 1659 | } |
1702 | #endif | 1660 | #endif |
1703 | if (0 != memcmp (&ph, | 1661 | if (0 != memcmp (&ph, &m->hmac, sizeof (struct GNUNET_HashCode))) |
1704 | &m->hmac, | ||
1705 | sizeof (struct GNUNET_HashCode))) | ||
1706 | { | 1662 | { |
1707 | /* checksum failed */ | 1663 | /* checksum failed */ |
1708 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 1664 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
1709 | "Failed checksum validation for a message from `%s'\n", | 1665 | "Failed checksum validation for a message from `%s'\n", |
1710 | GNUNET_i2s (kx->peer)); | 1666 | GNUNET_i2s (kx->peer)); |
1711 | return; | 1667 | return; |
1712 | } | 1668 | } |
1713 | derive_iv (&iv, | 1669 | derive_iv (&iv, &kx->decrypt_key, m->iv_seed, &GSC_my_identity); |
1714 | &kx->decrypt_key, | ||
1715 | m->iv_seed, | ||
1716 | &GSC_my_identity); | ||
1717 | /* decrypt */ | 1670 | /* decrypt */ |
1718 | if (GNUNET_OK != | 1671 | if (GNUNET_OK != do_decrypt (kx, |
1719 | do_decrypt (kx, | 1672 | &iv, |
1720 | &iv, | 1673 | &m->sequence_number, |
1721 | &m->sequence_number, | 1674 | &buf[ENCRYPTED_HEADER_SIZE], |
1722 | &buf[ENCRYPTED_HEADER_SIZE], | 1675 | size - ENCRYPTED_HEADER_SIZE)) |
1723 | size - ENCRYPTED_HEADER_SIZE)) | ||
1724 | { | 1676 | { |
1725 | GNUNET_break_op (0); | 1677 | GNUNET_break_op (0); |
1726 | return; | 1678 | return; |
@@ -1751,8 +1703,9 @@ handle_encrypted (void *cls, | |||
1751 | "Received ancient out of sequence message, ignoring.\n"); | 1703 | "Received ancient out of sequence message, ignoring.\n"); |
1752 | /* ancient out of sequence, ignore */ | 1704 | /* ancient out of sequence, ignore */ |
1753 | GNUNET_STATISTICS_update (GSC_stats, | 1705 | GNUNET_STATISTICS_update (GSC_stats, |
1754 | gettext_noop | 1706 | gettext_noop ( |
1755 | ("# bytes dropped (out of sequence)"), size, | 1707 | "# bytes dropped (out of sequence)"), |
1708 | size, | ||
1756 | GNUNET_NO); | 1709 | GNUNET_NO); |
1757 | return; | 1710 | return; |
1758 | } | 1711 | } |
@@ -1766,7 +1719,8 @@ handle_encrypted (void *cls, | |||
1766 | "Received duplicate message, ignoring.\n"); | 1719 | "Received duplicate message, ignoring.\n"); |
1767 | GNUNET_STATISTICS_update (GSC_stats, | 1720 | GNUNET_STATISTICS_update (GSC_stats, |
1768 | gettext_noop ("# bytes dropped (duplicates)"), | 1721 | gettext_noop ("# bytes dropped (duplicates)"), |
1769 | size, GNUNET_NO); | 1722 | size, |
1723 | GNUNET_NO); | ||
1770 | /* duplicate, ignore */ | 1724 | /* duplicate, ignore */ |
1771 | return; | 1725 | return; |
1772 | } | 1726 | } |
@@ -1790,11 +1744,13 @@ handle_encrypted (void *cls, | |||
1790 | { | 1744 | { |
1791 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1745 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1792 | "Message received far too old (%s). Content ignored.\n", | 1746 | "Message received far too old (%s). Content ignored.\n", |
1793 | GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration (t), | 1747 | GNUNET_STRINGS_relative_time_to_string ( |
1794 | GNUNET_YES)); | 1748 | GNUNET_TIME_absolute_get_duration (t), |
1749 | GNUNET_YES)); | ||
1795 | GNUNET_STATISTICS_update (GSC_stats, | 1750 | GNUNET_STATISTICS_update (GSC_stats, |
1796 | gettext_noop | 1751 | gettext_noop ( |
1797 | ("# bytes dropped (ancient message)"), size, | 1752 | "# bytes dropped (ancient message)"), |
1753 | size, | ||
1798 | GNUNET_NO); | 1754 | GNUNET_NO); |
1799 | return; | 1755 | return; |
1800 | } | 1756 | } |
@@ -1825,7 +1781,7 @@ handle_encrypted (void *cls, | |||
1825 | static void | 1781 | static void |
1826 | handle_transport_notify_excess_bw (void *cls, | 1782 | handle_transport_notify_excess_bw (void *cls, |
1827 | const struct GNUNET_PeerIdentity *pid, | 1783 | const struct GNUNET_PeerIdentity *pid, |
1828 | void *connect_cls) | 1784 | void *connect_cls) |
1829 | { | 1785 | { |
1830 | struct GSC_KeyExchangeInfo *kx = connect_cls; | 1786 | struct GSC_KeyExchangeInfo *kx = connect_cls; |
1831 | 1787 | ||
@@ -1848,31 +1804,34 @@ sign_ephemeral_key () | |||
1848 | current_ekm.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_EPHEMERAL_KEY); | 1804 | current_ekm.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_EPHEMERAL_KEY); |
1849 | current_ekm.sender_status = 0; /* to be set later */ | 1805 | current_ekm.sender_status = 0; /* to be set later */ |
1850 | current_ekm.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_SET_ECC_KEY); | 1806 | current_ekm.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_SET_ECC_KEY); |
1851 | current_ekm.purpose.size = htonl (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) + | 1807 | current_ekm.purpose.size = |
1852 | sizeof (struct GNUNET_TIME_AbsoluteNBO) + | 1808 | htonl (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) + |
1853 | sizeof (struct GNUNET_TIME_AbsoluteNBO) + | 1809 | sizeof (struct GNUNET_TIME_AbsoluteNBO) + |
1854 | sizeof (struct GNUNET_CRYPTO_EcdhePublicKey) + | 1810 | sizeof (struct GNUNET_TIME_AbsoluteNBO) + |
1855 | sizeof (struct GNUNET_PeerIdentity)); | 1811 | sizeof (struct GNUNET_CRYPTO_EcdhePublicKey) + |
1856 | current_ekm.creation_time = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get ()); | 1812 | sizeof (struct GNUNET_PeerIdentity)); |
1857 | if (GNUNET_YES == | 1813 | current_ekm.creation_time = |
1858 | GNUNET_CONFIGURATION_get_value_yesno (GSC_cfg, | 1814 | GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get ()); |
1859 | "core", | 1815 | if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_yesno (GSC_cfg, |
1860 | "USE_EPHEMERAL_KEYS")) | 1816 | "core", |
1817 | "USE_EPHEMERAL_KEYS")) | ||
1861 | { | 1818 | { |
1862 | current_ekm.expiration_time = GNUNET_TIME_absolute_hton (GNUNET_TIME_relative_to_absolute (GNUNET_TIME_relative_add (REKEY_FREQUENCY, | 1819 | current_ekm.expiration_time = |
1863 | REKEY_TOLERANCE))); | 1820 | GNUNET_TIME_absolute_hton (GNUNET_TIME_relative_to_absolute ( |
1821 | GNUNET_TIME_relative_add (REKEY_FREQUENCY, REKEY_TOLERANCE))); | ||
1864 | } | 1822 | } |
1865 | else | 1823 | else |
1866 | { | 1824 | { |
1867 | current_ekm.expiration_time = GNUNET_TIME_absolute_hton (GNUNET_TIME_UNIT_FOREVER_ABS); | 1825 | current_ekm.expiration_time = |
1826 | GNUNET_TIME_absolute_hton (GNUNET_TIME_UNIT_FOREVER_ABS); | ||
1868 | } | 1827 | } |
1869 | GNUNET_CRYPTO_ecdhe_key_get_public (my_ephemeral_key, | 1828 | GNUNET_CRYPTO_ecdhe_key_get_public (my_ephemeral_key, |
1870 | ¤t_ekm.ephemeral_key); | 1829 | ¤t_ekm.ephemeral_key); |
1871 | current_ekm.origin_identity = GSC_my_identity; | 1830 | current_ekm.origin_identity = GSC_my_identity; |
1872 | GNUNET_assert (GNUNET_OK == | 1831 | GNUNET_assert (GNUNET_OK == |
1873 | GNUNET_CRYPTO_eddsa_sign (my_private_key, | 1832 | GNUNET_CRYPTO_eddsa_sign (my_private_key, |
1874 | ¤t_ekm.purpose, | 1833 | ¤t_ekm.purpose, |
1875 | ¤t_ekm.signature)); | 1834 | ¤t_ekm.signature)); |
1876 | } | 1835 | } |
1877 | 1836 | ||
1878 | 1837 | ||
@@ -1886,9 +1845,7 @@ do_rekey (void *cls) | |||
1886 | { | 1845 | { |
1887 | struct GSC_KeyExchangeInfo *pos; | 1846 | struct GSC_KeyExchangeInfo *pos; |
1888 | 1847 | ||
1889 | rekey_task = GNUNET_SCHEDULER_add_delayed (REKEY_FREQUENCY, | 1848 | rekey_task = GNUNET_SCHEDULER_add_delayed (REKEY_FREQUENCY, &do_rekey, NULL); |
1890 | &do_rekey, | ||
1891 | NULL); | ||
1892 | if (NULL != my_ephemeral_key) | 1849 | if (NULL != my_ephemeral_key) |
1893 | GNUNET_free (my_ephemeral_key); | 1850 | GNUNET_free (my_ephemeral_key); |
1894 | my_ephemeral_key = GNUNET_CRYPTO_ecdhe_key_create (); | 1851 | my_ephemeral_key = GNUNET_CRYPTO_ecdhe_key_create (); |
@@ -1900,9 +1857,7 @@ do_rekey (void *cls) | |||
1900 | GNUNET_CRYPTO_hash (¤t_ekm.ephemeral_key, | 1857 | GNUNET_CRYPTO_hash (¤t_ekm.ephemeral_key, |
1901 | sizeof (current_ekm.ephemeral_key), | 1858 | sizeof (current_ekm.ephemeral_key), |
1902 | &eh); | 1859 | &eh); |
1903 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 1860 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Rekeying to %s\n", GNUNET_h2s (&eh)); |
1904 | "Rekeying to %s\n", | ||
1905 | GNUNET_h2s (&eh)); | ||
1906 | } | 1861 | } |
1907 | for (pos = kx_head; NULL != pos; pos = pos->next) | 1862 | for (pos = kx_head; NULL != pos; pos = pos->next) |
1908 | { | 1863 | { |
@@ -1932,25 +1887,24 @@ do_rekey (void *cls) | |||
1932 | int | 1887 | int |
1933 | GSC_KX_init (struct GNUNET_CRYPTO_EddsaPrivateKey *pk) | 1888 | GSC_KX_init (struct GNUNET_CRYPTO_EddsaPrivateKey *pk) |
1934 | { | 1889 | { |
1935 | struct GNUNET_MQ_MessageHandler handlers[] = { | 1890 | struct GNUNET_MQ_MessageHandler handlers[] = |
1936 | GNUNET_MQ_hd_fixed_size (ephemeral_key, | 1891 | {GNUNET_MQ_hd_fixed_size (ephemeral_key, |
1937 | GNUNET_MESSAGE_TYPE_CORE_EPHEMERAL_KEY, | 1892 | GNUNET_MESSAGE_TYPE_CORE_EPHEMERAL_KEY, |
1938 | struct EphemeralKeyMessage, | 1893 | struct EphemeralKeyMessage, |
1939 | NULL), | 1894 | NULL), |
1940 | GNUNET_MQ_hd_fixed_size (ping, | 1895 | GNUNET_MQ_hd_fixed_size (ping, |
1941 | GNUNET_MESSAGE_TYPE_CORE_PING, | 1896 | GNUNET_MESSAGE_TYPE_CORE_PING, |
1942 | struct PingMessage, | 1897 | struct PingMessage, |
1943 | NULL), | 1898 | NULL), |
1944 | GNUNET_MQ_hd_fixed_size (pong, | 1899 | GNUNET_MQ_hd_fixed_size (pong, |
1945 | GNUNET_MESSAGE_TYPE_CORE_PONG, | 1900 | GNUNET_MESSAGE_TYPE_CORE_PONG, |
1946 | struct PongMessage, | 1901 | struct PongMessage, |
1947 | NULL), | 1902 | NULL), |
1948 | GNUNET_MQ_hd_var_size (encrypted, | 1903 | GNUNET_MQ_hd_var_size (encrypted, |
1949 | GNUNET_MESSAGE_TYPE_CORE_ENCRYPTED_MESSAGE, | 1904 | GNUNET_MESSAGE_TYPE_CORE_ENCRYPTED_MESSAGE, |
1950 | struct EncryptedMessage, | 1905 | struct EncryptedMessage, |
1951 | NULL), | 1906 | NULL), |
1952 | GNUNET_MQ_handler_end() | 1907 | GNUNET_MQ_handler_end ()}; |
1953 | }; | ||
1954 | 1908 | ||
1955 | my_private_key = pk; | 1909 | my_private_key = pk; |
1956 | GNUNET_CRYPTO_eddsa_key_get_public (my_private_key, | 1910 | GNUNET_CRYPTO_eddsa_key_get_public (my_private_key, |
@@ -1976,17 +1930,15 @@ GSC_KX_init (struct GNUNET_CRYPTO_EddsaPrivateKey *pk) | |||
1976 | } | 1930 | } |
1977 | 1931 | ||
1978 | nc = GNUNET_notification_context_create (1); | 1932 | nc = GNUNET_notification_context_create (1); |
1979 | rekey_task = GNUNET_SCHEDULER_add_delayed (REKEY_FREQUENCY, | 1933 | rekey_task = GNUNET_SCHEDULER_add_delayed (REKEY_FREQUENCY, &do_rekey, NULL); |
1980 | &do_rekey, | 1934 | transport = |
1981 | NULL); | 1935 | GNUNET_TRANSPORT_core_connect (GSC_cfg, |
1982 | transport | 1936 | &GSC_my_identity, |
1983 | = GNUNET_TRANSPORT_core_connect (GSC_cfg, | 1937 | handlers, |
1984 | &GSC_my_identity, | 1938 | NULL, |
1985 | handlers, | 1939 | &handle_transport_notify_connect, |
1986 | NULL, | 1940 | &handle_transport_notify_disconnect, |
1987 | &handle_transport_notify_connect, | 1941 | &handle_transport_notify_excess_bw); |
1988 | &handle_transport_notify_disconnect, | ||
1989 | &handle_transport_notify_excess_bw); | ||
1990 | if (NULL == transport) | 1942 | if (NULL == transport) |
1991 | { | 1943 | { |
1992 | GSC_KX_done (); | 1944 | GSC_KX_done (); |
@@ -2030,7 +1982,7 @@ GSC_KX_done () | |||
2030 | } | 1982 | } |
2031 | 1983 | ||
2032 | 1984 | ||
2033 | /** | 1985 | /** |
2034 | * Check how many messages are queued for the given neighbour. | 1986 | * Check how many messages are queued for the given neighbour. |
2035 | * | 1987 | * |
2036 | * @param kxinfo data about neighbour to check | 1988 | * @param kxinfo data about neighbour to check |
@@ -2071,27 +2023,22 @@ GSC_KX_handle_client_monitor_peers (struct GNUNET_MQ_Handle *mq) | |||
2071 | struct MonitorNotifyMessage *done_msg; | 2023 | struct MonitorNotifyMessage *done_msg; |
2072 | struct GSC_KeyExchangeInfo *kx; | 2024 | struct GSC_KeyExchangeInfo *kx; |
2073 | 2025 | ||
2074 | GNUNET_notification_context_add (nc, | 2026 | GNUNET_notification_context_add (nc, mq); |
2075 | mq); | ||
2076 | for (kx = kx_head; NULL != kx; kx = kx->next) | 2027 | for (kx = kx_head; NULL != kx; kx = kx->next) |
2077 | { | 2028 | { |
2078 | struct GNUNET_MQ_Envelope *env; | 2029 | struct GNUNET_MQ_Envelope *env; |
2079 | struct MonitorNotifyMessage *msg; | 2030 | struct MonitorNotifyMessage *msg; |
2080 | 2031 | ||
2081 | env = GNUNET_MQ_msg (msg, | 2032 | env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_CORE_MONITOR_NOTIFY); |
2082 | GNUNET_MESSAGE_TYPE_CORE_MONITOR_NOTIFY); | ||
2083 | msg->state = htonl ((uint32_t) kx->status); | 2033 | msg->state = htonl ((uint32_t) kx->status); |
2084 | msg->peer = *kx->peer; | 2034 | msg->peer = *kx->peer; |
2085 | msg->timeout = GNUNET_TIME_absolute_hton (kx->timeout); | 2035 | msg->timeout = GNUNET_TIME_absolute_hton (kx->timeout); |
2086 | GNUNET_MQ_send (mq, | 2036 | GNUNET_MQ_send (mq, env); |
2087 | env); | ||
2088 | } | 2037 | } |
2089 | env = GNUNET_MQ_msg (done_msg, | 2038 | env = GNUNET_MQ_msg (done_msg, GNUNET_MESSAGE_TYPE_CORE_MONITOR_NOTIFY); |
2090 | GNUNET_MESSAGE_TYPE_CORE_MONITOR_NOTIFY); | ||
2091 | done_msg->state = htonl ((uint32_t) GNUNET_CORE_KX_ITERATION_FINISHED); | 2039 | done_msg->state = htonl ((uint32_t) GNUNET_CORE_KX_ITERATION_FINISHED); |
2092 | done_msg->timeout = GNUNET_TIME_absolute_hton (GNUNET_TIME_UNIT_FOREVER_ABS); | 2040 | done_msg->timeout = GNUNET_TIME_absolute_hton (GNUNET_TIME_UNIT_FOREVER_ABS); |
2093 | GNUNET_MQ_send (mq, | 2041 | GNUNET_MQ_send (mq, env); |
2094 | env); | ||
2095 | } | 2042 | } |
2096 | 2043 | ||
2097 | 2044 | ||