aboutsummaryrefslogtreecommitdiff
path: root/src/cadet/gnunet-service-cadet_tunnels.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2018-05-20 00:35:13 +0200
committerChristian Grothoff <christian@grothoff.org>2018-05-20 00:36:20 +0200
commit0be37e812d034754eb725701f237fbc81b973904 (patch)
treec50481209ec97b5dbbd075489255477c5e761d3d /src/cadet/gnunet-service-cadet_tunnels.c
parentc227e3f00efb4b3677e9b85c0273a7bf5fbcb4a9 (diff)
downloadgnunet-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.c190
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
1854static void
1855check_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
1881static void
1882check_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
1908static void
1909test_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);