diff options
author | Christian Grothoff <christian@grothoff.org> | 2018-05-20 00:35:13 +0200 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2018-05-20 00:36:20 +0200 |
commit | 0be37e812d034754eb725701f237fbc81b973904 (patch) | |
tree | c50481209ec97b5dbbd075489255477c5e761d3d /src/cadet/gnunet-service-cadet_tunnels.c | |
parent | c227e3f00efb4b3677e9b85c0273a7bf5fbcb4a9 (diff) | |
download | gnunet-0be37e812d034754eb725701f237fbc81b973904.tar.gz gnunet-0be37e812d034754eb725701f237fbc81b973904.zip |
fix off-by-one error in cadet connection construction, also enforce better timeouts for retransmissions of handshake
Diffstat (limited to 'src/cadet/gnunet-service-cadet_tunnels.c')
-rw-r--r-- | src/cadet/gnunet-service-cadet_tunnels.c | 190 |
1 files changed, 182 insertions, 8 deletions
diff --git a/src/cadet/gnunet-service-cadet_tunnels.c b/src/cadet/gnunet-service-cadet_tunnels.c index 75d454522..dbd84a818 100644 --- a/src/cadet/gnunet-service-cadet_tunnels.c +++ b/src/cadet/gnunet-service-cadet_tunnels.c | |||
@@ -1369,6 +1369,15 @@ send_kx (struct CadetTunnel *t, | |||
1369 | msg->cid = *GCC_get_id (cc); | 1369 | msg->cid = *GCC_get_id (cc); |
1370 | GNUNET_CRYPTO_ecdhe_key_get_public (&ax->kx_0, | 1370 | GNUNET_CRYPTO_ecdhe_key_get_public (&ax->kx_0, |
1371 | &msg->ephemeral_key); | 1371 | &msg->ephemeral_key); |
1372 | #if DEBUG_KX | ||
1373 | msg->ephemeral_key_XXX = ax->kx_0; | ||
1374 | msg->private_key_XXX = *my_private_key; | ||
1375 | #endif | ||
1376 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1377 | "Sending KX message to %s with ephemeral %s on CID %s\n", | ||
1378 | GCT_2s (t), | ||
1379 | GNUNET_e2s (&msg->ephemeral_key), | ||
1380 | GNUNET_sh2s (&msg->cid.connection_of_tunnel)); | ||
1372 | GNUNET_CRYPTO_ecdhe_key_get_public (&ax->DHRs, | 1381 | GNUNET_CRYPTO_ecdhe_key_get_public (&ax->DHRs, |
1373 | &msg->ratchet_key); | 1382 | &msg->ratchet_key); |
1374 | mark_connection_unready (ct); | 1383 | mark_connection_unready (ct); |
@@ -1435,6 +1444,17 @@ send_kx_auth (struct CadetTunnel *t, | |||
1435 | &msg->kx.ephemeral_key); | 1444 | &msg->kx.ephemeral_key); |
1436 | GNUNET_CRYPTO_ecdhe_key_get_public (&ax->DHRs, | 1445 | GNUNET_CRYPTO_ecdhe_key_get_public (&ax->DHRs, |
1437 | &msg->kx.ratchet_key); | 1446 | &msg->kx.ratchet_key); |
1447 | #if DEBUG_KX | ||
1448 | msg->kx.ephemeral_key_XXX = ax->kx_0; | ||
1449 | msg->kx.private_key_XXX = *my_private_key; | ||
1450 | msg->r_ephemeral_key_XXX = ax->last_ephemeral; | ||
1451 | #endif | ||
1452 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1453 | "Sending KX_AUTH message to %s with ephemeral %s on CID %s\n", | ||
1454 | GCT_2s (t), | ||
1455 | GNUNET_e2s (&msg->kx.ephemeral_key), | ||
1456 | GNUNET_sh2s (&msg->kx.cid.connection_of_tunnel)); | ||
1457 | |||
1438 | /* Compute authenticator (this is the main difference to #send_kx()) */ | 1458 | /* Compute authenticator (this is the main difference to #send_kx()) */ |
1439 | GNUNET_CRYPTO_hash (&ax->RK, | 1459 | GNUNET_CRYPTO_hash (&ax->RK, |
1440 | sizeof (ax->RK), | 1460 | sizeof (ax->RK), |
@@ -1705,12 +1725,19 @@ GCT_handle_kx (struct CadetTConnection *ct, | |||
1705 | "# KX received", | 1725 | "# KX received", |
1706 | 1, | 1726 | 1, |
1707 | GNUNET_NO); | 1727 | GNUNET_NO); |
1708 | if (GNUNET_YES == alice_or_bob (GCP_get_id (t->destination))) | 1728 | if (GNUNET_YES == |
1729 | alice_or_bob (GCP_get_id (t->destination))) | ||
1709 | { | 1730 | { |
1710 | /* Bob is not allowed to send KX! */ | 1731 | /* Bob is not allowed to send KX! */ |
1711 | GNUNET_break_op (0); | 1732 | GNUNET_break_op (0); |
1712 | return; | 1733 | return; |
1713 | } | 1734 | } |
1735 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1736 | "Received KX message from %s with ephemeral %s from %s on connection %s\n", | ||
1737 | GCT_2s (t), | ||
1738 | GNUNET_e2s (&msg->ephemeral_key), | ||
1739 | GNUNET_i2s (GCP_get_id (t->destination)), | ||
1740 | GCC_2s (ct->cc)); | ||
1714 | #if 1 | 1741 | #if 1 |
1715 | if ( (0 == | 1742 | if ( (0 == |
1716 | memcmp (&t->ax.DHRr, | 1743 | memcmp (&t->ax.DHRr, |
@@ -1823,6 +1850,75 @@ GCT_handle_kx (struct CadetTConnection *ct, | |||
1823 | } | 1850 | } |
1824 | 1851 | ||
1825 | 1852 | ||
1853 | #if DEBUG_KX | ||
1854 | static void | ||
1855 | check_ee (const struct GNUNET_CRYPTO_EcdhePrivateKey *e1, | ||
1856 | const struct GNUNET_CRYPTO_EcdhePrivateKey *e2) | ||
1857 | { | ||
1858 | struct GNUNET_CRYPTO_EcdhePublicKey p1; | ||
1859 | struct GNUNET_CRYPTO_EcdhePublicKey p2; | ||
1860 | struct GNUNET_HashCode hc1; | ||
1861 | struct GNUNET_HashCode hc2; | ||
1862 | |||
1863 | GNUNET_CRYPTO_ecdhe_key_get_public (e1, | ||
1864 | &p1); | ||
1865 | GNUNET_CRYPTO_ecdhe_key_get_public (e2, | ||
1866 | &p2); | ||
1867 | GNUNET_assert (GNUNET_OK == | ||
1868 | GNUNET_CRYPTO_ecc_ecdh (e1, | ||
1869 | &p2, | ||
1870 | &hc1)); | ||
1871 | GNUNET_assert (GNUNET_OK == | ||
1872 | GNUNET_CRYPTO_ecc_ecdh (e2, | ||
1873 | &p1, | ||
1874 | &hc2)); | ||
1875 | GNUNET_break (0 == memcmp (&hc1, | ||
1876 | &hc2, | ||
1877 | sizeof (hc1))); | ||
1878 | } | ||
1879 | |||
1880 | |||
1881 | static void | ||
1882 | check_ed (const struct GNUNET_CRYPTO_EcdhePrivateKey *e1, | ||
1883 | const struct GNUNET_CRYPTO_EddsaPrivateKey *e2) | ||
1884 | { | ||
1885 | struct GNUNET_CRYPTO_EcdhePublicKey p1; | ||
1886 | struct GNUNET_CRYPTO_EddsaPublicKey p2; | ||
1887 | struct GNUNET_HashCode hc1; | ||
1888 | struct GNUNET_HashCode hc2; | ||
1889 | |||
1890 | GNUNET_CRYPTO_ecdhe_key_get_public (e1, | ||
1891 | &p1); | ||
1892 | GNUNET_CRYPTO_eddsa_key_get_public (e2, | ||
1893 | &p2); | ||
1894 | GNUNET_assert (GNUNET_OK == | ||
1895 | GNUNET_CRYPTO_ecdh_eddsa (e1, | ||
1896 | &p2, | ||
1897 | &hc1)); | ||
1898 | GNUNET_assert (GNUNET_OK == | ||
1899 | GNUNET_CRYPTO_eddsa_ecdh (e2, | ||
1900 | &p1, | ||
1901 | &hc2)); | ||
1902 | GNUNET_break (0 == memcmp (&hc1, | ||
1903 | &hc2, | ||
1904 | sizeof (hc1))); | ||
1905 | } | ||
1906 | |||
1907 | |||
1908 | static void | ||
1909 | test_crypto_bug (const struct GNUNET_CRYPTO_EcdhePrivateKey *e1, | ||
1910 | const struct GNUNET_CRYPTO_EcdhePrivateKey *e2, | ||
1911 | const struct GNUNET_CRYPTO_EddsaPrivateKey *d1, | ||
1912 | const struct GNUNET_CRYPTO_EddsaPrivateKey *d2) | ||
1913 | { | ||
1914 | check_ee (e1, e2); | ||
1915 | check_ed (e1, d2); | ||
1916 | check_ed (e2, d1); | ||
1917 | } | ||
1918 | |||
1919 | #endif | ||
1920 | |||
1921 | |||
1826 | /** | 1922 | /** |
1827 | * Handle KX_AUTH message. | 1923 | * Handle KX_AUTH message. |
1828 | * | 1924 | * |
@@ -1852,8 +1948,9 @@ GCT_handle_kx_auth (struct CadetTConnection *ct, | |||
1852 | return; | 1948 | return; |
1853 | } | 1949 | } |
1854 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1950 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1855 | "Handling KX_AUTH message for %s\n", | 1951 | "Handling KX_AUTH message from %s with ephemeral %s\n", |
1856 | GCT_2s (t)); | 1952 | GCT_2s (t), |
1953 | GNUNET_e2s (&msg->kx.ephemeral_key)); | ||
1857 | /* We do everything in ax_tmp until we've checked the authentication | 1954 | /* We do everything in ax_tmp until we've checked the authentication |
1858 | so we don't clobber anything we care about by accident. */ | 1955 | so we don't clobber anything we care about by accident. */ |
1859 | ax_tmp = t->ax; | 1956 | ax_tmp = t->ax; |
@@ -1889,6 +1986,32 @@ GCT_handle_kx_auth (struct CadetTConnection *ct, | |||
1889 | GNUNET_NO); | 1986 | GNUNET_NO); |
1890 | LOG (GNUNET_ERROR_TYPE_WARNING, | 1987 | LOG (GNUNET_ERROR_TYPE_WARNING, |
1891 | "KX AUTH missmatch!\n"); | 1988 | "KX AUTH missmatch!\n"); |
1989 | #if DEBUG_KX | ||
1990 | { | ||
1991 | struct GNUNET_CRYPTO_EcdhePublicKey ephemeral_key; | ||
1992 | |||
1993 | GNUNET_CRYPTO_ecdhe_key_get_public (&ax_tmp.kx_0, | ||
1994 | &ephemeral_key); | ||
1995 | if (0 != memcmp (&ephemeral_key, | ||
1996 | &msg->r_ephemeral_key_XXX, | ||
1997 | sizeof (ephemeral_key))) | ||
1998 | { | ||
1999 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
2000 | "My ephemeral is %s!\n", | ||
2001 | GNUNET_e2s (&ephemeral_key)); | ||
2002 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
2003 | "Response is for ephemeral %s!\n", | ||
2004 | GNUNET_e2s (&msg->r_ephemeral_key_XXX)); | ||
2005 | } | ||
2006 | else | ||
2007 | { | ||
2008 | test_crypto_bug (&ax_tmp.kx_0, | ||
2009 | &msg->kx.ephemeral_key_XXX, | ||
2010 | my_private_key, | ||
2011 | &msg->kx.private_key_XXX); | ||
2012 | } | ||
2013 | } | ||
2014 | #endif | ||
1892 | if (NULL == t->kx_task) | 2015 | if (NULL == t->kx_task) |
1893 | t->kx_task | 2016 | t->kx_task |
1894 | = GNUNET_SCHEDULER_add_at (t->next_kx_attempt, | 2017 | = GNUNET_SCHEDULER_add_at (t->next_kx_attempt, |
@@ -2301,6 +2424,8 @@ connection_ready_cb (void *cls, | |||
2301 | /* Do not begin KX if WE have no channels waiting! */ | 2424 | /* Do not begin KX if WE have no channels waiting! */ |
2302 | if (0 == GCT_count_channels (t)) | 2425 | if (0 == GCT_count_channels (t)) |
2303 | return; | 2426 | return; |
2427 | if (0 != GNUNET_TIME_absolute_get_remaining (t->next_kx_attempt).rel_value_us) | ||
2428 | return; /* wait for timeout before retrying */ | ||
2304 | /* We are uninitialized, just transmit immediately, | 2429 | /* We are uninitialized, just transmit immediately, |
2305 | without undue delay. */ | 2430 | without undue delay. */ |
2306 | if (NULL != t->kx_task) | 2431 | if (NULL != t->kx_task) |
@@ -2326,6 +2451,8 @@ connection_ready_cb (void *cls, | |||
2326 | case CADET_TUNNEL_KEY_OK: | 2451 | case CADET_TUNNEL_KEY_OK: |
2327 | if (GNUNET_YES == t->kx_auth_requested) | 2452 | if (GNUNET_YES == t->kx_auth_requested) |
2328 | { | 2453 | { |
2454 | if (0 != GNUNET_TIME_absolute_get_remaining (t->next_kx_attempt).rel_value_us) | ||
2455 | return; /* wait for timeout */ | ||
2329 | if (NULL != t->kx_task) | 2456 | if (NULL != t->kx_task) |
2330 | { | 2457 | { |
2331 | GNUNET_SCHEDULER_cancel (t->kx_task); | 2458 | GNUNET_SCHEDULER_cancel (t->kx_task); |
@@ -2433,15 +2560,21 @@ evaluate_connection (void *cls, | |||
2433 | { | 2560 | { |
2434 | struct EvaluationSummary *es = cls; | 2561 | struct EvaluationSummary *es = cls; |
2435 | struct CadetConnection *cc = ct->cc; | 2562 | struct CadetConnection *cc = ct->cc; |
2436 | struct CadetPeerPath *ps = GCC_get_path (cc); | 2563 | unsigned int ct_length; |
2564 | struct CadetPeerPath *ps; | ||
2437 | const struct CadetConnectionMetrics *metrics; | 2565 | const struct CadetConnectionMetrics *metrics; |
2438 | GNUNET_CONTAINER_HeapCostType ct_desirability; | 2566 | GNUNET_CONTAINER_HeapCostType ct_desirability; |
2439 | struct GNUNET_TIME_Relative uptime; | 2567 | struct GNUNET_TIME_Relative uptime; |
2440 | struct GNUNET_TIME_Relative last_use; | 2568 | struct GNUNET_TIME_Relative last_use; |
2441 | uint32_t ct_length; | ||
2442 | double score; | 2569 | double score; |
2443 | double success_rate; | 2570 | double success_rate; |
2444 | 2571 | ||
2572 | ps = GCC_get_path (cc, | ||
2573 | &ct_length); | ||
2574 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2575 | "Evaluating path %s of existing %s\n", | ||
2576 | GCPP_2s (ps), | ||
2577 | GCC_2s (cc)); | ||
2445 | if (ps == es->path) | 2578 | if (ps == es->path) |
2446 | { | 2579 | { |
2447 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 2580 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
@@ -2450,8 +2583,39 @@ evaluate_connection (void *cls, | |||
2450 | es->duplicate = GNUNET_YES; | 2583 | es->duplicate = GNUNET_YES; |
2451 | return; | 2584 | return; |
2452 | } | 2585 | } |
2586 | if (NULL != es->path) | ||
2587 | { | ||
2588 | int duplicate = GNUNET_YES; | ||
2589 | |||
2590 | for (unsigned int i=0;i<ct_length;i++) | ||
2591 | { | ||
2592 | GNUNET_assert (GCPP_get_length (es->path) > i); | ||
2593 | if (GCPP_get_peer_at_offset (es->path, | ||
2594 | i) != | ||
2595 | GCPP_get_peer_at_offset (ps, | ||
2596 | i)) | ||
2597 | { | ||
2598 | duplicate = GNUNET_NO; | ||
2599 | break; | ||
2600 | } | ||
2601 | } | ||
2602 | if (GNUNET_YES == duplicate) | ||
2603 | { | ||
2604 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2605 | "Ignoring overlapping path %s.\n", | ||
2606 | GCPP_2s (es->path)); | ||
2607 | es->duplicate = GNUNET_YES; | ||
2608 | return; | ||
2609 | } | ||
2610 | else | ||
2611 | { | ||
2612 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2613 | "Known path %s differs from proposed path\n", | ||
2614 | GCPP_2s (ps)); | ||
2615 | } | ||
2616 | } | ||
2617 | |||
2453 | ct_desirability = GCPP_get_desirability (ps); | 2618 | ct_desirability = GCPP_get_desirability (ps); |
2454 | ct_length = GCPP_get_length (ps); | ||
2455 | metrics = GCC_get_metrics (cc); | 2619 | metrics = GCC_get_metrics (cc); |
2456 | uptime = GNUNET_TIME_absolute_get_duration (metrics->age); | 2620 | uptime = GNUNET_TIME_absolute_get_duration (metrics->age); |
2457 | last_use = GNUNET_TIME_absolute_get_duration (metrics->last_use); | 2621 | last_use = GNUNET_TIME_absolute_get_duration (metrics->last_use); |
@@ -2500,6 +2664,8 @@ consider_path_cb (void *cls, | |||
2500 | struct CadetTConnection *ct; | 2664 | struct CadetTConnection *ct; |
2501 | 2665 | ||
2502 | GNUNET_assert (off < GCPP_get_length (path)); | 2666 | GNUNET_assert (off < GCPP_get_length (path)); |
2667 | GNUNET_assert (GCPP_get_peer_at_offset (path, | ||
2668 | off) == t->destination); | ||
2503 | es.min_length = UINT_MAX; | 2669 | es.min_length = UINT_MAX; |
2504 | es.max_length = 0; | 2670 | es.max_length = 0; |
2505 | es.max_desire = 0; | 2671 | es.max_desire = 0; |
@@ -2509,6 +2675,13 @@ consider_path_cb (void *cls, | |||
2509 | es.worst = NULL; | 2675 | es.worst = NULL; |
2510 | 2676 | ||
2511 | /* Compute evaluation summary over existing connections. */ | 2677 | /* Compute evaluation summary over existing connections. */ |
2678 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2679 | "Evaluating proposed path %s for target %s\n", | ||
2680 | GCPP_2s (path), | ||
2681 | GCT_2s (t)); | ||
2682 | /* FIXME: suspect this does not ACTUALLY iterate | ||
2683 | over all existing paths, otherwise dup detection | ||
2684 | should work!!! */ | ||
2512 | GCT_iterate_connections (t, | 2685 | GCT_iterate_connections (t, |
2513 | &evaluate_connection, | 2686 | &evaluate_connection, |
2514 | &es); | 2687 | &es); |
@@ -2653,9 +2826,10 @@ GCT_consider_path (struct CadetTunnel *t, | |||
2653 | unsigned int off) | 2826 | unsigned int off) |
2654 | { | 2827 | { |
2655 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 2828 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
2656 | "Considering %s for %s\n", | 2829 | "Considering %s for %s (offset %u)\n", |
2657 | GCPP_2s (p), | 2830 | GCPP_2s (p), |
2658 | GCT_2s (t)); | 2831 | GCT_2s (t), |
2832 | off); | ||
2659 | (void) consider_path_cb (t, | 2833 | (void) consider_path_cb (t, |
2660 | p, | 2834 | p, |
2661 | off); | 2835 | off); |