diff options
author | Bart Polot <bart@net.in.tum.de> | 2014-05-14 16:50:45 +0000 |
---|---|---|
committer | Bart Polot <bart@net.in.tum.de> | 2014-05-14 16:50:45 +0000 |
commit | eabfd491ec972e9331a42d8106cf285c3385226f (patch) | |
tree | e0a9a38820a9e72edf30ab293e5f524605811b28 /src/cadet/gnunet-service-cadet_tunnel.c | |
parent | a7522e8dee3e33942196f43efd621e4b4d0e258e (diff) | |
download | gnunet-eabfd491ec972e9331a42d8106cf285c3385226f.tar.gz gnunet-eabfd491ec972e9331a42d8106cf285c3385226f.zip |
- don't destroy the KX context right away, wait 1 minute for possible old traffic
Diffstat (limited to 'src/cadet/gnunet-service-cadet_tunnel.c')
-rw-r--r-- | src/cadet/gnunet-service-cadet_tunnel.c | 53 |
1 files changed, 42 insertions, 11 deletions
diff --git a/src/cadet/gnunet-service-cadet_tunnel.c b/src/cadet/gnunet-service-cadet_tunnel.c index a97a05737..e5114cef0 100644 --- a/src/cadet/gnunet-service-cadet_tunnel.c +++ b/src/cadet/gnunet-service-cadet_tunnel.c | |||
@@ -107,6 +107,12 @@ struct CadetTunnelKXCtx | |||
107 | * When the rekey started. One minute after this the new key will be used. | 107 | * When the rekey started. One minute after this the new key will be used. |
108 | */ | 108 | */ |
109 | struct GNUNET_TIME_Absolute rekey_start_time; | 109 | struct GNUNET_TIME_Absolute rekey_start_time; |
110 | |||
111 | /** | ||
112 | * Task for delayed destruction of the Key eXchange context, to allow delayed | ||
113 | * messages with the old key to be decrypted successfully. | ||
114 | */ | ||
115 | GNUNET_SCHEDULER_TaskIdentifier finish_task; | ||
110 | }; | 116 | }; |
111 | 117 | ||
112 | /** | 118 | /** |
@@ -585,7 +591,7 @@ t_encrypt (struct CadetTunnel *t, | |||
585 | size_t out_size; | 591 | size_t out_size; |
586 | 592 | ||
587 | LOG (GNUNET_ERROR_TYPE_DEBUG, " t_encrypt start\n"); | 593 | LOG (GNUNET_ERROR_TYPE_DEBUG, " t_encrypt start\n"); |
588 | if (NULL != t->kx_ctx) | 594 | if (NULL != t->kx_ctx && GNUNET_SCHEDULER_NO_TASK == t->kx_ctx->finish_task) |
589 | { | 595 | { |
590 | struct GNUNET_TIME_Relative age; | 596 | struct GNUNET_TIME_Relative age; |
591 | 597 | ||
@@ -661,7 +667,6 @@ static int | |||
661 | t_decrypt (struct CadetTunnel *t, void *dst, const void *src, | 667 | t_decrypt (struct CadetTunnel *t, void *dst, const void *src, |
662 | size_t size, uint32_t iv) | 668 | size_t size, uint32_t iv) |
663 | { | 669 | { |
664 | struct GNUNET_CRYPTO_SymmetricInitializationVector siv; | ||
665 | struct GNUNET_CRYPTO_SymmetricSessionKey *key; | 670 | struct GNUNET_CRYPTO_SymmetricSessionKey *key; |
666 | size_t out_size; | 671 | size_t out_size; |
667 | 672 | ||
@@ -734,7 +739,7 @@ t_decrypt_and_validate (struct CadetTunnel *t, | |||
734 | return decrypted_size; | 739 | return decrypted_size; |
735 | 740 | ||
736 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 741 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
737 | "Failed checksum validation on tunnel %s with KX\n" place, | 742 | "Failed checksum validation on tunnel %s with KX\n", |
738 | GCT_2s (t)); | 743 | GCT_2s (t)); |
739 | GNUNET_STATISTICS_update (stats, "# wrong HMAC", 1, GNUNET_NO); | 744 | GNUNET_STATISTICS_update (stats, "# wrong HMAC", 1, GNUNET_NO); |
740 | return -1; | 745 | return -1; |
@@ -1601,7 +1606,6 @@ handle_ch_ack (struct CadetTunnel *t, | |||
1601 | } | 1606 | } |
1602 | 1607 | ||
1603 | 1608 | ||
1604 | |||
1605 | /** | 1609 | /** |
1606 | * Handle a channel destruction message. | 1610 | * Handle a channel destruction message. |
1607 | * | 1611 | * |
@@ -1704,6 +1708,23 @@ handle_ping (struct CadetTunnel *t, | |||
1704 | 1708 | ||
1705 | send_pong (t, res.nonce); | 1709 | send_pong (t, res.nonce); |
1706 | } | 1710 | } |
1711 | /** | ||
1712 | * @brief Finish the Key eXchange and destory the old keys. | ||
1713 | * | ||
1714 | * @param cls Closure (Tunnel for which to finish the KX). | ||
1715 | * @param tc Task context. | ||
1716 | */ | ||
1717 | static void | ||
1718 | finish_kx (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
1719 | { | ||
1720 | struct CadetTunnel *t = cls; | ||
1721 | |||
1722 | if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) | ||
1723 | return; | ||
1724 | |||
1725 | GNUNET_free (t->kx_ctx); | ||
1726 | t->kx_ctx = NULL; | ||
1727 | } | ||
1707 | 1728 | ||
1708 | 1729 | ||
1709 | /** | 1730 | /** |
@@ -1739,8 +1760,17 @@ handle_pong (struct CadetTunnel *t, | |||
1739 | } | 1760 | } |
1740 | GNUNET_SCHEDULER_cancel (t->rekey_task); | 1761 | GNUNET_SCHEDULER_cancel (t->rekey_task); |
1741 | t->rekey_task = GNUNET_SCHEDULER_NO_TASK; | 1762 | t->rekey_task = GNUNET_SCHEDULER_NO_TASK; |
1742 | GNUNET_free (t->kx_ctx); | 1763 | |
1743 | t->kx_ctx = NULL; | 1764 | /* Don't free the old keys right away, but after a delay. |
1765 | * Rationale: the KX could have happened over a very fast connection, | ||
1766 | * with payload traffic still signed with the old key stuck in a slower | ||
1767 | * connection. | ||
1768 | */ | ||
1769 | if (GNUNET_SCHEDULER_NO_TASK == t->kx_ctx->finish_task) | ||
1770 | { | ||
1771 | t->kx_ctx->finish_task = | ||
1772 | GNUNET_SCHEDULER_add_delayed(GNUNET_TIME_UNIT_MINUTES, finish_kx, t); | ||
1773 | } | ||
1744 | GCT_change_estate (t, CADET_TUNNEL3_KEY_OK); | 1774 | GCT_change_estate (t, CADET_TUNNEL3_KEY_OK); |
1745 | } | 1775 | } |
1746 | 1776 | ||
@@ -2397,12 +2427,13 @@ GCT_destroy (struct CadetTunnel *t) | |||
2397 | { | 2427 | { |
2398 | GNUNET_SCHEDULER_cancel (t->rekey_task); | 2428 | GNUNET_SCHEDULER_cancel (t->rekey_task); |
2399 | t->rekey_task = GNUNET_SCHEDULER_NO_TASK; | 2429 | t->rekey_task = GNUNET_SCHEDULER_NO_TASK; |
2400 | if (NULL != t->kx_ctx) | ||
2401 | GNUNET_free (t->kx_ctx); | ||
2402 | else | ||
2403 | GNUNET_break (0); | ||
2404 | } | 2430 | } |
2405 | 2431 | if (NULL != t->kx_ctx) | |
2432 | { | ||
2433 | if (GNUNET_SCHEDULER_NO_TASK != t->kx_ctx->finish_task) | ||
2434 | GNUNET_SCHEDULER_cancel (t->kx_ctx->finish_task); | ||
2435 | GNUNET_free (t->kx_ctx); | ||
2436 | } | ||
2406 | GNUNET_free (t); | 2437 | GNUNET_free (t); |
2407 | } | 2438 | } |
2408 | 2439 | ||