aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNils Gillmann <ng0@n0.is>2018-05-17 13:39:09 +0000
committerNils Gillmann <ng0@n0.is>2018-05-17 13:39:09 +0000
commit9f722a29b9f7abbb9d8d1de63a72d09588c02f91 (patch)
tree32913cdeb7364ad71a58d239be224ae29d900aaf /src
parentc7e03281601aa687030fe3d561e1d693a46bba21 (diff)
parentdd8289771b35e5ea36ebdcbfd5b09b599bd59c67 (diff)
downloadgnunet-9f722a29b9f7abbb9d8d1de63a72d09588c02f91.tar.gz
gnunet-9f722a29b9f7abbb9d8d1de63a72d09588c02f91.zip
Merge branch 'master' of gnunet.org:gnunet
Diffstat (limited to 'src')
-rw-r--r--src/cadet/gnunet-service-cadet_tunnels.c339
-rw-r--r--src/dns/.gitignore1
-rw-r--r--src/gns/gnunet-gns-benchmark.c2
-rw-r--r--src/gns/gnunet-gns-proxy.c34
-rw-r--r--src/gns/gnunet-service-gns.c19
-rw-r--r--src/include/gnunet_common.h70
-rw-r--r--src/rps/test_rps.c42
-rw-r--r--src/util/Makefile.am3
-rw-r--r--src/util/common_logging.c100
-rw-r--r--src/util/crypto_bug.c79
-rw-r--r--src/util/crypto_ecc.c171
-rw-r--r--src/util/crypto_ecc_setup.c14
-rw-r--r--src/util/test_crypto_ecdh_eddsa.c52
-rw-r--r--src/util/test_crypto_ecdhe.c25
14 files changed, 665 insertions, 286 deletions
diff --git a/src/cadet/gnunet-service-cadet_tunnels.c b/src/cadet/gnunet-service-cadet_tunnels.c
index fb91a4a6a..75d454522 100644
--- a/src/cadet/gnunet-service-cadet_tunnels.c
+++ b/src/cadet/gnunet-service-cadet_tunnels.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2013, 2017 GNUnet e.V. 3 Copyright (C) 2013, 2017, 2018 GNUnet e.V.
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published 6 it under the terms of the GNU General Public License as published
@@ -187,6 +187,12 @@ struct CadetTunnelAxolotl
187 struct GNUNET_CRYPTO_EcdhePublicKey DHRr; 187 struct GNUNET_CRYPTO_EcdhePublicKey DHRr;
188 188
189 /** 189 /**
190 * Last ephemeral public key received from the other peer,
191 * for duplicate detection.
192 */
193 struct GNUNET_CRYPTO_EcdhePublicKey last_ephemeral;
194
195 /**
190 * Time when the current ratchet expires and a new one is triggered 196 * Time when the current ratchet expires and a new one is triggered
191 * (if @e ratchet_allowed is #GNUNET_YES). 197 * (if @e ratchet_allowed is #GNUNET_YES).
192 */ 198 */
@@ -453,6 +459,29 @@ struct CadetTunnel
453 459
454 460
455/** 461/**
462 * Am I Alice or Bob, or talking to myself?
463 *
464 * @param other the other peer
465 * @return #GNUNET_YES for Alice, #GNUNET_NO for Bob, #GNUNET_SYSERR if talking to myself
466 */
467static int
468alice_or_bob (const struct GNUNET_PeerIdentity *other)
469{
470 if (0 > GNUNET_CRYPTO_cmp_peer_identity (&my_full_id,
471 other))
472 return GNUNET_YES;
473 else if (0 < GNUNET_CRYPTO_cmp_peer_identity (&my_full_id,
474 other))
475 return GNUNET_NO;
476 else
477 {
478 GNUNET_break_op (0);
479 return GNUNET_SYSERR;
480 }
481}
482
483
484/**
456 * Connection @a ct is now unready, clear it's ready flag 485 * Connection @a ct is now unready, clear it's ready flag
457 * and move it from the ready DLL to the busy DLL. 486 * and move it from the ready DLL to the busy DLL.
458 * 487 *
@@ -1318,6 +1347,8 @@ send_kx (struct CadetTunnel *t,
1318 struct GNUNET_CADET_TunnelKeyExchangeMessage *msg; 1347 struct GNUNET_CADET_TunnelKeyExchangeMessage *msg;
1319 enum GNUNET_CADET_KX_Flags flags; 1348 enum GNUNET_CADET_KX_Flags flags;
1320 1349
1350 if (GNUNET_YES != alice_or_bob (GCP_get_id (t->destination)))
1351 return; /* only Alice may send KX */
1321 if ( (NULL == ct) || 1352 if ( (NULL == ct) ||
1322 (GNUNET_NO == ct->is_ready) ) 1353 (GNUNET_NO == ct->is_ready) )
1323 ct = get_ready_connection (t); 1354 ct = get_ready_connection (t);
@@ -1331,11 +1362,6 @@ send_kx (struct CadetTunnel *t,
1331 return; 1362 return;
1332 } 1363 }
1333 cc = ct->cc; 1364 cc = ct->cc;
1334 LOG (GNUNET_ERROR_TYPE_DEBUG,
1335 "Sending KX on %s via %s in state %s\n",
1336 GCT_2s (t),
1337 GCC_2s (cc),
1338 estate2s (t->estate));
1339 env = GNUNET_MQ_msg (msg, 1365 env = GNUNET_MQ_msg (msg,
1340 GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX); 1366 GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX);
1341 flags = GNUNET_CADET_KX_FLAG_FORCE_REPLY; /* always for KX */ 1367 flags = GNUNET_CADET_KX_FLAG_FORCE_REPLY; /* always for KX */
@@ -1356,6 +1382,10 @@ send_kx (struct CadetTunnel *t,
1356 CADET_TUNNEL_KEY_AX_SENT_AND_RECV); 1382 CADET_TUNNEL_KEY_AX_SENT_AND_RECV);
1357 GCC_transmit (cc, 1383 GCC_transmit (cc,
1358 env); 1384 env);
1385 GNUNET_STATISTICS_update (stats,
1386 "# KX transmitted",
1387 1,
1388 GNUNET_NO);
1359} 1389}
1360 1390
1361 1391
@@ -1394,11 +1424,6 @@ send_kx_auth (struct CadetTunnel *t,
1394 } 1424 }
1395 t->kx_auth_requested = GNUNET_NO; /* clear flag */ 1425 t->kx_auth_requested = GNUNET_NO; /* clear flag */
1396 cc = ct->cc; 1426 cc = ct->cc;
1397 LOG (GNUNET_ERROR_TYPE_DEBUG,
1398 "Sending KX_AUTH on %s using %s\n",
1399 GCT_2s (t),
1400 GCC_2s (ct->cc));
1401
1402 env = GNUNET_MQ_msg (msg, 1427 env = GNUNET_MQ_msg (msg,
1403 GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX_AUTH); 1428 GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX_AUTH);
1404 flags = GNUNET_CADET_KX_FLAG_NONE; 1429 flags = GNUNET_CADET_KX_FLAG_NONE;
@@ -1414,7 +1439,6 @@ send_kx_auth (struct CadetTunnel *t,
1414 GNUNET_CRYPTO_hash (&ax->RK, 1439 GNUNET_CRYPTO_hash (&ax->RK,
1415 sizeof (ax->RK), 1440 sizeof (ax->RK),
1416 &msg->auth); 1441 &msg->auth);
1417
1418 /* Compute when to be triggered again; actual job will 1442 /* Compute when to be triggered again; actual job will
1419 be scheduled via #connection_ready_cb() */ 1443 be scheduled via #connection_ready_cb() */
1420 t->kx_retry_delay 1444 t->kx_retry_delay
@@ -1429,9 +1453,12 @@ send_kx_auth (struct CadetTunnel *t,
1429 if (CADET_TUNNEL_KEY_OK != t->estate) 1453 if (CADET_TUNNEL_KEY_OK != t->estate)
1430 GCT_change_estate (t, 1454 GCT_change_estate (t,
1431 CADET_TUNNEL_KEY_AX_AUTH_SENT); 1455 CADET_TUNNEL_KEY_AX_AUTH_SENT);
1432
1433 GCC_transmit (cc, 1456 GCC_transmit (cc,
1434 env); 1457 env);
1458 GNUNET_STATISTICS_update (stats,
1459 "# KX_AUTH transmitted",
1460 1,
1461 GNUNET_NO);
1435} 1462}
1436 1463
1437 1464
@@ -1476,66 +1503,57 @@ update_ax_by_kx (struct CadetTunnelAxolotl *ax,
1476 const char salt[] = "CADET Axolotl salt"; 1503 const char salt[] = "CADET Axolotl salt";
1477 int am_I_alice; 1504 int am_I_alice;
1478 1505
1479 if (0 > GNUNET_CRYPTO_cmp_peer_identity (&my_full_id, 1506 if (GNUNET_SYSERR == (am_I_alice = alice_or_bob (pid)))
1480 pid))
1481 am_I_alice = GNUNET_YES;
1482 else if (0 < GNUNET_CRYPTO_cmp_peer_identity (&my_full_id,
1483 pid))
1484 am_I_alice = GNUNET_NO;
1485 else
1486 { 1507 {
1487 GNUNET_break_op (0); 1508 GNUNET_break_op (0);
1488 return GNUNET_SYSERR; 1509 return GNUNET_SYSERR;
1489 } 1510 }
1490
1491 if (0 == memcmp (&ax->DHRr, 1511 if (0 == memcmp (&ax->DHRr,
1492 ratchet_key, 1512 ratchet_key,
1493 sizeof (*ratchet_key))) 1513 sizeof (*ratchet_key)))
1494 { 1514 {
1515 GNUNET_STATISTICS_update (stats,
1516 "# Ratchet key already known",
1517 1,
1518 GNUNET_NO);
1495 LOG (GNUNET_ERROR_TYPE_DEBUG, 1519 LOG (GNUNET_ERROR_TYPE_DEBUG,
1496 "Ratchet key already known. Ignoring KX.\n"); 1520 "Ratchet key already known. Ignoring KX.\n");
1497 return GNUNET_NO; 1521 return GNUNET_NO;
1498 } 1522 }
1499 1523
1500 ax->DHRr = *ratchet_key; 1524 ax->DHRr = *ratchet_key;
1501 1525 ax->last_ephemeral = *ephemeral_key;
1502 /* ECDH A B0 */ 1526 /* ECDH A B0 */
1503 if (GNUNET_YES == am_I_alice) 1527 if (GNUNET_YES == am_I_alice)
1504 { 1528 {
1505 GNUNET_CRYPTO_eddsa_ecdh (my_private_key, /* A */ 1529 GNUNET_CRYPTO_eddsa_ecdh (my_private_key, /* a */
1506 ephemeral_key, /* B0 */ 1530 ephemeral_key, /* B0 */
1507 &key_material[0]); 1531 &key_material[0]);
1508 } 1532 }
1509 else 1533 else
1510 { 1534 {
1511 GNUNET_CRYPTO_ecdh_eddsa (&ax->kx_0, /* B0 */ 1535 GNUNET_CRYPTO_ecdh_eddsa (&ax->kx_0, /* b0 */
1512 &pid->public_key, /* A */ 1536 &pid->public_key, /* A */
1513 &key_material[0]); 1537 &key_material[0]);
1514 } 1538 }
1515
1516 /* ECDH A0 B */ 1539 /* ECDH A0 B */
1517 if (GNUNET_YES == am_I_alice) 1540 if (GNUNET_YES == am_I_alice)
1518 { 1541 {
1519 GNUNET_CRYPTO_ecdh_eddsa (&ax->kx_0, /* A0 */ 1542 GNUNET_CRYPTO_ecdh_eddsa (&ax->kx_0, /* a0 */
1520 &pid->public_key, /* B */ 1543 &pid->public_key, /* B */
1521 &key_material[1]); 1544 &key_material[1]);
1522 } 1545 }
1523 else 1546 else
1524 { 1547 {
1525 GNUNET_CRYPTO_eddsa_ecdh (my_private_key, /* A */ 1548 GNUNET_CRYPTO_eddsa_ecdh (my_private_key, /* b */
1526 ephemeral_key, /* B0 */ 1549 ephemeral_key, /* A0 */
1527 &key_material[1]); 1550 &key_material[1]);
1528
1529
1530 } 1551 }
1531 1552
1532 /* ECDH A0 B0 */ 1553 /* ECDH A0 B0 */
1533 /* (This is the triple-DH, we could probably safely skip this, 1554 GNUNET_CRYPTO_ecc_ecdh (&ax->kx_0, /* a0 or b0 */
1534 as A0/B0 are already in the key material.) */ 1555 ephemeral_key, /* B0 or A0 */
1535 GNUNET_CRYPTO_ecc_ecdh (&ax->kx_0, /* A0 or B0 */
1536 ephemeral_key, /* B0 or A0 */
1537 &key_material[2]); 1556 &key_material[2]);
1538
1539 /* KDF */ 1557 /* KDF */
1540 GNUNET_CRYPTO_kdf (keys, sizeof (keys), 1558 GNUNET_CRYPTO_kdf (keys, sizeof (keys),
1541 salt, sizeof (salt), 1559 salt, sizeof (salt),
@@ -1547,7 +1565,11 @@ update_ax_by_kx (struct CadetTunnelAxolotl *ax,
1547 sizeof (ax->RK))) 1565 sizeof (ax->RK)))
1548 { 1566 {
1549 LOG (GNUNET_ERROR_TYPE_DEBUG, 1567 LOG (GNUNET_ERROR_TYPE_DEBUG,
1550 "Root key of handshake already known. Ignoring KX.\n"); 1568 "Root key already known. Ignoring KX.\n");
1569 GNUNET_STATISTICS_update (stats,
1570 "# Root key already known",
1571 1,
1572 GNUNET_NO);
1551 return GNUNET_NO; 1573 return GNUNET_NO;
1552 } 1574 }
1553 1575
@@ -1592,75 +1614,75 @@ retry_kx (void *cls)
1592 GCT_2s (t), 1614 GCT_2s (t),
1593 estate2s (t->estate)); 1615 estate2s (t->estate));
1594 switch (t->estate) 1616 switch (t->estate)
1595 {
1596 case CADET_TUNNEL_KEY_UNINITIALIZED: /* first attempt */
1597 case CADET_TUNNEL_KEY_AX_SENT: /* trying again */
1598 send_kx (t,
1599 NULL,
1600 &t->ax);
1601 break;
1602 case CADET_TUNNEL_KEY_AX_RECV:
1603 case CADET_TUNNEL_KEY_AX_SENT_AND_RECV:
1604 /* We are responding, so only require reply
1605 if WE have a channel waiting. */
1606 if (NULL != t->unverified_ax)
1607 { 1617 {
1608 /* Send AX_AUTH so we might get this one verified */ 1618 case CADET_TUNNEL_KEY_UNINITIALIZED: /* first attempt */
1609 ax = t->unverified_ax; 1619 case CADET_TUNNEL_KEY_AX_SENT: /* trying again */
1610 } 1620 send_kx (t,
1611 else 1621 NULL,
1612 { 1622 &t->ax);
1613 /* How can this be? */ 1623 break;
1614 GNUNET_break (0); 1624 case CADET_TUNNEL_KEY_AX_RECV:
1615 ax = &t->ax; 1625 case CADET_TUNNEL_KEY_AX_SENT_AND_RECV:
1616 } 1626 /* We are responding, so only require reply
1617 send_kx_auth (t, 1627 if WE have a channel waiting. */
1618 NULL, 1628 if (NULL != t->unverified_ax)
1619 ax, 1629 {
1620 (0 == GCT_count_channels (t)) 1630 /* Send AX_AUTH so we might get this one verified */
1621 ? GNUNET_NO 1631 ax = t->unverified_ax;
1622 : GNUNET_YES); 1632 }
1623 break; 1633 else
1624 case CADET_TUNNEL_KEY_AX_AUTH_SENT: 1634 {
1625 /* We are responding, so only require reply 1635 /* How can this be? */
1626 if WE have a channel waiting. */ 1636 GNUNET_break (0);
1627 if (NULL != t->unverified_ax) 1637 ax = &t->ax;
1628 { 1638 }
1629 /* Send AX_AUTH so we might get this one verified */ 1639 send_kx_auth (t,
1630 ax = t->unverified_ax; 1640 NULL,
1631 } 1641 ax,
1632 else 1642 (0 == GCT_count_channels (t))
1633 { 1643 ? GNUNET_NO
1634 /* How can this be? */ 1644 : GNUNET_YES);
1635 GNUNET_break (0); 1645 break;
1636 ax = &t->ax; 1646 case CADET_TUNNEL_KEY_AX_AUTH_SENT:
1637 } 1647 /* We are responding, so only require reply
1638 send_kx_auth (t, 1648 if WE have a channel waiting. */
1639 NULL, 1649 if (NULL != t->unverified_ax)
1640 ax, 1650 {
1641 (0 == GCT_count_channels (t)) 1651 /* Send AX_AUTH so we might get this one verified */
1642 ? GNUNET_NO 1652 ax = t->unverified_ax;
1643 : GNUNET_YES); 1653 }
1644 break; 1654 else
1645 case CADET_TUNNEL_KEY_OK: 1655 {
1646 /* Must have been the *other* peer asking us to 1656 /* How can this be? */
1647 respond with a KX_AUTH. */ 1657 GNUNET_break (0);
1648 if (NULL != t->unverified_ax) 1658 ax = &t->ax;
1649 { 1659 }
1650 /* Sending AX_AUTH in response to AX so we might get this one verified */ 1660 send_kx_auth (t,
1651 ax = t->unverified_ax; 1661 NULL,
1652 } 1662 ax,
1653 else 1663 (0 == GCT_count_channels (t))
1654 { 1664 ? GNUNET_NO
1655 /* Sending AX_AUTH in response to AX_AUTH */ 1665 : GNUNET_YES);
1656 ax = &t->ax; 1666 break;
1667 case CADET_TUNNEL_KEY_OK:
1668 /* Must have been the *other* peer asking us to
1669 respond with a KX_AUTH. */
1670 if (NULL != t->unverified_ax)
1671 {
1672 /* Sending AX_AUTH in response to AX so we might get this one verified */
1673 ax = t->unverified_ax;
1674 }
1675 else
1676 {
1677 /* Sending AX_AUTH in response to AX_AUTH */
1678 ax = &t->ax;
1679 }
1680 send_kx_auth (t,
1681 NULL,
1682 ax,
1683 GNUNET_NO);
1684 break;
1657 } 1685 }
1658 send_kx_auth (t,
1659 NULL,
1660 ax,
1661 GNUNET_NO);
1662 break;
1663 }
1664} 1686}
1665 1687
1666 1688
@@ -1677,76 +1699,110 @@ GCT_handle_kx (struct CadetTConnection *ct,
1677 const struct GNUNET_CADET_TunnelKeyExchangeMessage *msg) 1699 const struct GNUNET_CADET_TunnelKeyExchangeMessage *msg)
1678{ 1700{
1679 struct CadetTunnel *t = ct->t; 1701 struct CadetTunnel *t = ct->t;
1680 struct CadetTunnelAxolotl *ax;
1681 int ret; 1702 int ret;
1682 1703
1683 if (0 == 1704 GNUNET_STATISTICS_update (stats,
1684 memcmp (&t->ax.DHRr, 1705 "# KX received",
1685 &msg->ratchet_key, 1706 1,
1686 sizeof (msg->ratchet_key))) 1707 GNUNET_NO);
1708 if (GNUNET_YES == alice_or_bob (GCP_get_id (t->destination)))
1687 { 1709 {
1688 LOG (GNUNET_ERROR_TYPE_DEBUG, 1710 /* Bob is not allowed to send KX! */
1689 "Got duplicate KX. Firing back KX_AUTH.\n"); 1711 GNUNET_break_op (0);
1690 send_kx_auth (t,
1691 ct,
1692 &t->ax,
1693 GNUNET_NO);
1694 return; 1712 return;
1695 } 1713 }
1714#if 1
1715 if ( (0 ==
1716 memcmp (&t->ax.DHRr,
1717 &msg->ratchet_key,
1718 sizeof (msg->ratchet_key))) &&
1719 (0 ==
1720 memcmp (&t->ax.last_ephemeral,
1721 &msg->ephemeral_key,
1722 sizeof (msg->ephemeral_key))) )
1696 1723
1724 {
1725 GNUNET_STATISTICS_update (stats,
1726 "# Duplicate KX received",
1727 1,
1728 GNUNET_NO);
1729 send_kx_auth (t,
1730 ct,
1731 &t->ax,
1732 GNUNET_NO);
1733 return;
1734 }
1735#endif
1697 /* We only keep ONE unverified KX around, so if there is an existing one, 1736 /* We only keep ONE unverified KX around, so if there is an existing one,
1698 clean it up. */ 1737 clean it up. */
1699 if (NULL != t->unverified_ax) 1738 if (NULL != t->unverified_ax)
1700 { 1739 {
1701 if (0 == 1740 if ( (0 ==
1702 memcmp (&t->unverified_ax->DHRr, 1741 memcmp (&t->unverified_ax->DHRr,
1703 &msg->ratchet_key, 1742 &msg->ratchet_key,
1704 sizeof (msg->ratchet_key))) 1743 sizeof (msg->ratchet_key))) &&
1744 (0 ==
1745 memcmp (&t->unverified_ax->last_ephemeral,
1746 &msg->ephemeral_key,
1747 sizeof (msg->ephemeral_key))) )
1705 { 1748 {
1706 LOG (GNUNET_ERROR_TYPE_DEBUG, 1749 GNUNET_STATISTICS_update (stats,
1707 "Got duplicate unverified KX on %s. Fire back KX_AUTH again.\n", 1750 "# Duplicate unverified KX received",
1708 GCT_2s (t)); 1751 1,
1752 GNUNET_NO);
1753#if 1
1709 send_kx_auth (t, 1754 send_kx_auth (t,
1710 ct, 1755 ct,
1711 t->unverified_ax, 1756 t->unverified_ax,
1712 GNUNET_NO); 1757 GNUNET_NO);
1713 return; 1758 return;
1759#endif
1714 } 1760 }
1715 LOG (GNUNET_ERROR_TYPE_DEBUG, 1761 LOG (GNUNET_ERROR_TYPE_DEBUG,
1716 "Dropping old unverified KX state. Got a fresh KX for %s.\n", 1762 "Dropping old unverified KX state.\n");
1717 GCT_2s (t)); 1763 GNUNET_STATISTICS_update (stats,
1764 "# Unverified KX dropped for fresh KX",
1765 1,
1766 GNUNET_NO);
1767 GNUNET_break (NULL == t->unverified_ax->skipped_head);
1718 memset (t->unverified_ax, 1768 memset (t->unverified_ax,
1719 0, 1769 0,
1720 sizeof (struct CadetTunnelAxolotl)); 1770 sizeof (struct CadetTunnelAxolotl));
1721 t->unverified_ax->DHRs = t->ax.DHRs;
1722 t->unverified_ax->kx_0 = t->ax.kx_0;
1723 } 1771 }
1724 else 1772 else
1725 { 1773 {
1726 LOG (GNUNET_ERROR_TYPE_DEBUG, 1774 LOG (GNUNET_ERROR_TYPE_DEBUG,
1727 "Creating fresh unverified KX for %s.\n", 1775 "Creating fresh unverified KX for %s\n",
1728 GCT_2s (t)); 1776 GCT_2s (t));
1777 GNUNET_STATISTICS_update (stats,
1778 "# Fresh KX setup",
1779 1,
1780 GNUNET_NO);
1729 t->unverified_ax = GNUNET_new (struct CadetTunnelAxolotl); 1781 t->unverified_ax = GNUNET_new (struct CadetTunnelAxolotl);
1730 t->unverified_ax->DHRs = t->ax.DHRs;
1731 t->unverified_ax->kx_0 = t->ax.kx_0;
1732 } 1782 }
1733 /* Set as the 'current' RK/DHRr the one we are currently using, 1783 /* Set as the 'current' RK/DHRr the one we are currently using,
1734 so that the duplicate-detection logic of 1784 so that the duplicate-detection logic of
1735 #update_ax_by_kx can work. */ 1785 #update_ax_by_kx can work. */
1736 t->unverified_ax->RK = t->ax.RK; 1786 t->unverified_ax->RK = t->ax.RK;
1737 t->unverified_ax->DHRr = t->ax.DHRr; 1787 t->unverified_ax->DHRr = t->ax.DHRr;
1788 t->unverified_ax->DHRs = t->ax.DHRs;
1789 t->unverified_ax->kx_0 = t->ax.kx_0;
1738 t->unverified_attempts = 0; 1790 t->unverified_attempts = 0;
1739 ax = t->unverified_ax;
1740 1791
1741 /* Update 'ax' by the new key material */ 1792 /* Update 'ax' by the new key material */
1742 ret = update_ax_by_kx (ax, 1793 ret = update_ax_by_kx (t->unverified_ax,
1743 GCP_get_id (t->destination), 1794 GCP_get_id (t->destination),
1744 &msg->ephemeral_key, 1795 &msg->ephemeral_key,
1745 &msg->ratchet_key); 1796 &msg->ratchet_key);
1746 GNUNET_break (GNUNET_SYSERR != ret); 1797 GNUNET_break (GNUNET_SYSERR != ret);
1747 if (GNUNET_OK != ret) 1798 if (GNUNET_OK != ret)
1799 {
1800 GNUNET_STATISTICS_update (stats,
1801 "# Useless KX",
1802 1,
1803 GNUNET_NO);
1748 return; /* duplicate KX, nothing to do */ 1804 return; /* duplicate KX, nothing to do */
1749 1805 }
1750 /* move ahead in our state machine */ 1806 /* move ahead in our state machine */
1751 if (CADET_TUNNEL_KEY_UNINITIALIZED == t->estate) 1807 if (CADET_TUNNEL_KEY_UNINITIALIZED == t->estate)
1752 GCT_change_estate (t, 1808 GCT_change_estate (t,
@@ -1782,6 +1838,10 @@ GCT_handle_kx_auth (struct CadetTConnection *ct,
1782 struct GNUNET_HashCode kx_auth; 1838 struct GNUNET_HashCode kx_auth;
1783 int ret; 1839 int ret;
1784 1840
1841 GNUNET_STATISTICS_update (stats,
1842 "# KX_AUTH received",
1843 1,
1844 GNUNET_NO);
1785 if ( (CADET_TUNNEL_KEY_UNINITIALIZED == t->estate) || 1845 if ( (CADET_TUNNEL_KEY_UNINITIALIZED == t->estate) ||
1786 (CADET_TUNNEL_KEY_AX_RECV == t->estate) ) 1846 (CADET_TUNNEL_KEY_AX_RECV == t->estate) )
1787 { 1847 {
@@ -1794,7 +1854,6 @@ GCT_handle_kx_auth (struct CadetTConnection *ct,
1794 LOG (GNUNET_ERROR_TYPE_DEBUG, 1854 LOG (GNUNET_ERROR_TYPE_DEBUG,
1795 "Handling KX_AUTH message for %s\n", 1855 "Handling KX_AUTH message for %s\n",
1796 GCT_2s (t)); 1856 GCT_2s (t));
1797
1798 /* We do everything in ax_tmp until we've checked the authentication 1857 /* We do everything in ax_tmp until we've checked the authentication
1799 so we don't clobber anything we care about by accident. */ 1858 so we don't clobber anything we care about by accident. */
1800 ax_tmp = t->ax; 1859 ax_tmp = t->ax;
@@ -1828,9 +1887,13 @@ GCT_handle_kx_auth (struct CadetTConnection *ct,
1828 "# KX_AUTH not using our last KX received (auth failure)", 1887 "# KX_AUTH not using our last KX received (auth failure)",
1829 1, 1888 1,
1830 GNUNET_NO); 1889 GNUNET_NO);
1831 send_kx (t, 1890 LOG (GNUNET_ERROR_TYPE_WARNING,
1832 ct, 1891 "KX AUTH missmatch!\n");
1833 &t->ax); 1892 if (NULL == t->kx_task)
1893 t->kx_task
1894 = GNUNET_SCHEDULER_add_at (t->next_kx_attempt,
1895 &retry_kx,
1896 t);
1834 return; 1897 return;
1835 } 1898 }
1836 /* Yep, we're good. */ 1899 /* Yep, we're good. */
diff --git a/src/dns/.gitignore b/src/dns/.gitignore
index f045f806a..d3a62470e 100644
--- a/src/dns/.gitignore
+++ b/src/dns/.gitignore
@@ -4,3 +4,4 @@ gnunet-dns-redirector
4gnunet-helper-dns 4gnunet-helper-dns
5test_hexcoder 5test_hexcoder
6gnunet-zoneimport 6gnunet-zoneimport
7gnunet-zonewalk
diff --git a/src/gns/gnunet-gns-benchmark.c b/src/gns/gnunet-gns-benchmark.c
index afa540c85..d5afae9f6 100644
--- a/src/gns/gnunet-gns-benchmark.c
+++ b/src/gns/gnunet-gns-benchmark.c
@@ -492,7 +492,7 @@ process_stdin (void *cls)
492 delta = GNUNET_TIME_absolute_get_duration (last); 492 delta = GNUNET_TIME_absolute_get_duration (last);
493 last = GNUNET_TIME_absolute_get (); 493 last = GNUNET_TIME_absolute_get ();
494 fprintf (stderr, 494 fprintf (stderr,
495 "Read 10000 domain names in %s\n", 495 "Read 100000 domain names in %s\n",
496 GNUNET_STRINGS_relative_time_to_string (delta, 496 GNUNET_STRINGS_relative_time_to_string (delta,
497 GNUNET_YES)); 497 GNUNET_YES));
498 } 498 }
diff --git a/src/gns/gnunet-gns-proxy.c b/src/gns/gnunet-gns-proxy.c
index 08663a57e..02ebcf0f1 100644
--- a/src/gns/gnunet-gns-proxy.c
+++ b/src/gns/gnunet-gns-proxy.c
@@ -1801,6 +1801,23 @@ create_response (void *cls,
1801 curl_easy_setopt (s5r->curl, CURLOPT_WRITEDATA, s5r); 1801 curl_easy_setopt (s5r->curl, CURLOPT_WRITEDATA, s5r);
1802 curl_easy_setopt (s5r->curl, CURLOPT_READFUNCTION, &curl_upload_cb); 1802 curl_easy_setopt (s5r->curl, CURLOPT_READFUNCTION, &curl_upload_cb);
1803 curl_easy_setopt (s5r->curl, CURLOPT_READDATA, s5r); 1803 curl_easy_setopt (s5r->curl, CURLOPT_READDATA, s5r);
1804 {
1805 const char *us;
1806 long upload_size;
1807
1808 us = MHD_lookup_connection_value (con,
1809 MHD_HEADER_KIND,
1810 MHD_HTTP_HEADER_CONTENT_LENGTH);
1811 if ( (1 == sscanf (us,
1812 "%ld",
1813 &upload_size)) &&
1814 (upload_size >= 0) )
1815 {
1816 curl_easy_setopt (s5r->curl,
1817 CURLOPT_INFILESIZE,
1818 upload_size);
1819 }
1820 }
1804 } 1821 }
1805 else if (0 == strcasecmp (meth, MHD_HTTP_METHOD_POST)) 1822 else if (0 == strcasecmp (meth, MHD_HTTP_METHOD_POST))
1806 { 1823 {
@@ -1810,6 +1827,23 @@ create_response (void *cls,
1810 curl_easy_setopt (s5r->curl, CURLOPT_WRITEDATA, s5r); 1827 curl_easy_setopt (s5r->curl, CURLOPT_WRITEDATA, s5r);
1811 curl_easy_setopt (s5r->curl, CURLOPT_READFUNCTION, &curl_upload_cb); 1828 curl_easy_setopt (s5r->curl, CURLOPT_READFUNCTION, &curl_upload_cb);
1812 curl_easy_setopt (s5r->curl, CURLOPT_READDATA, s5r); 1829 curl_easy_setopt (s5r->curl, CURLOPT_READDATA, s5r);
1830 {
1831 const char *us;
1832 long upload_size;
1833
1834 us = MHD_lookup_connection_value (con,
1835 MHD_HEADER_KIND,
1836 MHD_HTTP_HEADER_CONTENT_LENGTH);
1837 if ( (1 == sscanf (us,
1838 "%ld",
1839 &upload_size)) &&
1840 (upload_size >= 0) )
1841 {
1842 curl_easy_setopt (s5r->curl,
1843 CURLOPT_INFILESIZE,
1844 upload_size);
1845 }
1846 }
1813 } 1847 }
1814 else if (0 == strcasecmp (meth, MHD_HTTP_METHOD_HEAD)) 1848 else if (0 == strcasecmp (meth, MHD_HTTP_METHOD_HEAD))
1815 { 1849 {
diff --git a/src/gns/gnunet-service-gns.c b/src/gns/gnunet-service-gns.c
index c376ddfcc..cffae824d 100644
--- a/src/gns/gnunet-service-gns.c
+++ b/src/gns/gnunet-service-gns.c
@@ -296,7 +296,6 @@ client_disconnect_cb (void *cls,
296 clh); 296 clh);
297 GNUNET_free (clh); 297 GNUNET_free (clh);
298 } 298 }
299
300 GNUNET_free (gc); 299 GNUNET_free (gc);
301} 300}
302 301
@@ -340,26 +339,29 @@ send_lookup_response (void* cls,
340 const struct GNUNET_GNSRECORD_Data *rd) 339 const struct GNUNET_GNSRECORD_Data *rd)
341{ 340{
342 struct ClientLookupHandle *clh = cls; 341 struct ClientLookupHandle *clh = cls;
343 struct GNUNET_MQ_Envelope *env; 342 struct GnsClient *gc = clh->gc;
343 struct GNUNET_MQ_Envelope *env;
344 struct LookupResultMessage *rmsg; 344 struct LookupResultMessage *rmsg;
345 size_t len; 345 size_t len;
346 346
347 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 347 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
348 "Sending LOOKUP_RESULT message with %u results\n", 348 "Sending LOOKUP_RESULT message with %u results\n",
349 (unsigned int) rd_count); 349 (unsigned int) rd_count);
350 350 len = GNUNET_GNSRECORD_records_get_size (rd_count,
351 len = GNUNET_GNSRECORD_records_get_size (rd_count, rd); 351 rd);
352 env = GNUNET_MQ_msg_extra (rmsg, 352 env = GNUNET_MQ_msg_extra (rmsg,
353 len, 353 len,
354 GNUNET_MESSAGE_TYPE_GNS_LOOKUP_RESULT); 354 GNUNET_MESSAGE_TYPE_GNS_LOOKUP_RESULT);
355 rmsg->id = clh->request_id; 355 rmsg->id = clh->request_id;
356 rmsg->rd_count = htonl (rd_count); 356 rmsg->rd_count = htonl (rd_count);
357 GNUNET_GNSRECORD_records_serialize (rd_count, rd, len, 357 GNUNET_GNSRECORD_records_serialize (rd_count,
358 rd,
359 len,
358 (char*) &rmsg[1]); 360 (char*) &rmsg[1]);
359 GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq(clh->gc->client), 361 GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (gc->client),
360 env); 362 env);
361 GNUNET_CONTAINER_DLL_remove (clh->gc->clh_head, 363 GNUNET_CONTAINER_DLL_remove (gc->clh_head,
362 clh->gc->clh_tail, 364 gc->clh_tail,
363 clh); 365 clh);
364 GNUNET_free (clh); 366 GNUNET_free (clh);
365 GNUNET_STATISTICS_update (statistics, 367 GNUNET_STATISTICS_update (statistics,
@@ -428,7 +430,6 @@ handle_lookup (void *cls,
428 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 430 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
429 "Received LOOKUP `%s' message\n", 431 "Received LOOKUP `%s' message\n",
430 name); 432 name);
431
432 clh = GNUNET_new (struct ClientLookupHandle); 433 clh = GNUNET_new (struct ClientLookupHandle);
433 GNUNET_CONTAINER_DLL_insert (gc->clh_head, 434 GNUNET_CONTAINER_DLL_insert (gc->clh_head,
434 gc->clh_tail, 435 gc->clh_tail,
diff --git a/src/include/gnunet_common.h b/src/include/gnunet_common.h
index 0fb39575c..0c527e774 100644
--- a/src/include/gnunet_common.h
+++ b/src/include/gnunet_common.h
@@ -592,7 +592,7 @@ GNUNET_sh2s (const struct GNUNET_ShortHashCode *shc);
592 * @return string 592 * @return string
593 */ 593 */
594const char * 594const char *
595GNUNET_h2s (const struct GNUNET_HashCode * hc); 595GNUNET_h2s (const struct GNUNET_HashCode *hc);
596 596
597 597
598/** 598/**
@@ -607,7 +607,7 @@ GNUNET_h2s (const struct GNUNET_HashCode * hc);
607 * @return string 607 * @return string
608 */ 608 */
609const char * 609const char *
610GNUNET_h2s2 (const struct GNUNET_HashCode * hc); 610GNUNET_h2s2 (const struct GNUNET_HashCode *hc);
611 611
612 612
613/** 613/**
@@ -621,7 +621,71 @@ GNUNET_h2s2 (const struct GNUNET_HashCode * hc);
621 * @return string 621 * @return string
622 */ 622 */
623const char * 623const char *
624GNUNET_h2s_full (const struct GNUNET_HashCode * hc); 624GNUNET_h2s_full (const struct GNUNET_HashCode *hc);
625
626
627/**
628 * Public key. Details in gnunet_util_crypto.h.
629 */
630struct GNUNET_CRYPTO_EddsaPublicKey;
631
632
633/**
634 * Public key. Details in gnunet_util_crypto.h.
635 */
636struct GNUNET_CRYPTO_EcdhePublicKey;
637
638
639/**
640 * @ingroup logging
641 * Convert a public key value to a string (for printing debug messages).
642 * This is one of the very few calls in the entire API that is
643 * NOT reentrant!
644 *
645 * @param hc the hash code
646 * @return string
647 */
648const char *
649GNUNET_p2s (const struct GNUNET_CRYPTO_EddsaPublicKey *p);
650
651
652/**
653 * @ingroup logging
654 * Convert a public key value to a string (for printing debug messages).
655 * This is one of the very few calls in the entire API that is
656 * NOT reentrant!
657 *
658 * @param hc the hash code
659 * @return string
660 */
661const char *
662GNUNET_p2s2 (const struct GNUNET_CRYPTO_EddsaPublicKey *p);
663
664
665/**
666 * @ingroup logging
667 * Convert a public key value to a string (for printing debug messages).
668 * This is one of the very few calls in the entire API that is
669 * NOT reentrant!
670 *
671 * @param hc the hash code
672 * @return string
673 */
674const char *
675GNUNET_e2s (const struct GNUNET_CRYPTO_EcdhePublicKey *p);
676
677
678/**
679 * @ingroup logging
680 * Convert a public key value to a string (for printing debug messages).
681 * This is one of the very few calls in the entire API that is
682 * NOT reentrant!
683 *
684 * @param hc the hash code
685 * @return string
686 */
687const char *
688GNUNET_e2s2 (const struct GNUNET_CRYPTO_EcdhePublicKey *p);
625 689
626 690
627/** 691/**
diff --git a/src/rps/test_rps.c b/src/rps/test_rps.c
index b433a51d4..bae28428f 100644
--- a/src/rps/test_rps.c
+++ b/src/rps/test_rps.c
@@ -2180,22 +2180,25 @@ void view_update_cb (void *cls,
2180 rps_peer->index, 2180 rps_peer->index,
2181 count_peer_in_views_2 (rps_peer->index)); 2181 count_peer_in_views_2 (rps_peer->index));
2182 cumulated_view_sizes(); 2182 cumulated_view_sizes();
2183 to_file ("/tmp/rps/repr.txt", 2183 if (0 != view_size)
2184 "%" PRIu64 /* index */ 2184 {
2185 " %" PRIu32 /* occurrence in views */ 2185 to_file ("/tmp/rps/repr.txt",
2186 " %" PRIu32 /* view sizes */ 2186 "%" PRIu64 /* index */
2187 " %f" /* fraction of repr in views */ 2187 " %" PRIu32 /* occurrence in views */
2188 " %f" /* average view size */ 2188 " %" PRIu32 /* view sizes */
2189 " %f" /* prob of occurrence in view slot */ 2189 " %f" /* fraction of repr in views */
2190 " %f" "", /* exp frac of repr in views */ 2190 " %f" /* average view size */
2191 rps_peer->index, 2191 " %f" /* prob of occurrence in view slot */
2192 count_peer_in_views_2 (rps_peer->index), 2192 " %f" "", /* exp frac of repr in views */
2193 view_sizes, 2193 rps_peer->index,
2194 count_peer_in_views_2 (rps_peer->index) / (view_size * 1.0), /* fraction of representation in views */ 2194 count_peer_in_views_2 (rps_peer->index),
2195 view_sizes / (view_size * 1.0), /* average view size */ 2195 view_sizes,
2196 1.0 /view_size, /* prob of occurrence in view slot */ 2196 count_peer_in_views_2 (rps_peer->index) / (view_size * 1.0), /* fraction of representation in views */
2197 (1.0/view_size) * (view_sizes/view_size) /* expected fraction of repr in views */ 2197 view_sizes / (view_size * 1.0), /* average view size */
2198 ); 2198 1.0 /view_size, /* prob of occurrence in view slot */
2199 (1.0/view_size) * (view_sizes/view_size) /* expected fraction of repr in views */
2200 );
2201 }
2199 compute_probabilities (rps_peer->index); 2202 compute_probabilities (rps_peer->index);
2200 all_views_updated_cb(); 2203 all_views_updated_cb();
2201} 2204}
@@ -2770,7 +2773,7 @@ main (int argc, char *argv[])
2770 cur_test_run.main_test = churn_test_cb; 2773 cur_test_run.main_test = churn_test_cb;
2771 cur_test_run.reply_handle = default_reply_handle; 2774 cur_test_run.reply_handle = default_reply_handle;
2772 cur_test_run.eval_cb = default_eval_cb; 2775 cur_test_run.eval_cb = default_eval_cb;
2773 cur_test_run.have_churn = HAVE_CHURN; 2776 cur_test_run.have_churn = HAVE_NO_CHURN;
2774 cur_test_run.have_quick_quit = HAVE_NO_QUICK_QUIT; 2777 cur_test_run.have_quick_quit = HAVE_NO_QUICK_QUIT;
2775 timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10); 2778 timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10);
2776 } 2779 }
@@ -2779,7 +2782,7 @@ main (int argc, char *argv[])
2779 { 2782 {
2780 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "This is the profiler\n"); 2783 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "This is the profiler\n");
2781 cur_test_run.name = "test-rps-profiler"; 2784 cur_test_run.name = "test-rps-profiler";
2782 num_peers = 10; 2785 num_peers = 100;
2783 mal_type = 3; 2786 mal_type = 3;
2784 cur_test_run.init_peer = profiler_init_peer; 2787 cur_test_run.init_peer = profiler_init_peer;
2785 //cur_test_run.pre_test = mal_pre; 2788 //cur_test_run.pre_test = mal_pre;
@@ -2790,7 +2793,8 @@ main (int argc, char *argv[])
2790 cur_test_run.post_test = post_profiler; 2793 cur_test_run.post_test = post_profiler;
2791 cur_test_run.request_interval = 2; 2794 cur_test_run.request_interval = 2;
2792 cur_test_run.num_requests = 5; 2795 cur_test_run.num_requests = 5;
2793 cur_test_run.have_churn = HAVE_CHURN; 2796 //cur_test_run.have_churn = HAVE_CHURN;
2797 cur_test_run.have_churn = HAVE_NO_CHURN;
2794 cur_test_run.have_quick_quit = HAVE_NO_QUICK_QUIT; 2798 cur_test_run.have_quick_quit = HAVE_NO_QUICK_QUIT;
2795 cur_test_run.have_collect_statistics = COLLECT_STATISTICS; 2799 cur_test_run.have_collect_statistics = COLLECT_STATISTICS;
2796 cur_test_run.stat_collect_flags = STAT_TYPE_ROUNDS | 2800 cur_test_run.stat_collect_flags = STAT_TYPE_ROUNDS |
diff --git a/src/util/Makefile.am b/src/util/Makefile.am
index eb655157d..407f482df 100644
--- a/src/util/Makefile.am
+++ b/src/util/Makefile.am
@@ -598,4 +598,5 @@ EXTRA_DIST = \
598 test_resolver_api_data.conf \ 598 test_resolver_api_data.conf \
599 test_service_data.conf \ 599 test_service_data.conf \
600 test_speedup_data.conf \ 600 test_speedup_data.conf \
601 gnunet-qr.py.in 601 gnunet-qr.py.in \
602 crypto_bug.c
diff --git a/src/util/common_logging.c b/src/util/common_logging.c
index ea5430191..df501fbcd 100644
--- a/src/util/common_logging.c
+++ b/src/util/common_logging.c
@@ -1192,6 +1192,106 @@ GNUNET_h2s2 (const struct GNUNET_HashCode * hc)
1192 1192
1193/** 1193/**
1194 * @ingroup logging 1194 * @ingroup logging
1195 * Convert a public key value to a string (for printing debug messages).
1196 * This is one of the very few calls in the entire API that is
1197 * NOT reentrant!
1198 *
1199 * @param hc the hash code
1200 * @return string
1201 */
1202const char *
1203GNUNET_p2s (const struct GNUNET_CRYPTO_EddsaPublicKey *p)
1204{
1205 static struct GNUNET_CRYPTO_HashAsciiEncoded ret;
1206 struct GNUNET_HashCode hc;
1207
1208 GNUNET_CRYPTO_hash (p,
1209 sizeof (*p),
1210 &hc);
1211 GNUNET_CRYPTO_hash_to_enc (&hc,
1212 &ret);
1213 ret.encoding[6] = '\0';
1214 return (const char *) ret.encoding;
1215}
1216
1217
1218/**
1219 * @ingroup logging
1220 * Convert a public key value to a string (for printing debug messages).
1221 * This is one of the very few calls in the entire API that is
1222 * NOT reentrant!
1223 *
1224 * @param hc the hash code
1225 * @return string
1226 */
1227const char *
1228GNUNET_p2s2 (const struct GNUNET_CRYPTO_EddsaPublicKey *p)
1229{
1230 static struct GNUNET_CRYPTO_HashAsciiEncoded ret;
1231 struct GNUNET_HashCode hc;
1232
1233 GNUNET_CRYPTO_hash (p,
1234 sizeof (*p),
1235 &hc);
1236 GNUNET_CRYPTO_hash_to_enc (&hc,
1237 &ret);
1238 ret.encoding[6] = '\0';
1239 return (const char *) ret.encoding;
1240}
1241
1242
1243/**
1244 * @ingroup logging
1245 * Convert a public key value to a string (for printing debug messages).
1246 * This is one of the very few calls in the entire API that is
1247 * NOT reentrant!
1248 *
1249 * @param hc the hash code
1250 * @return string
1251 */
1252const char *
1253GNUNET_e2s (const struct GNUNET_CRYPTO_EcdhePublicKey *p)
1254{
1255 static struct GNUNET_CRYPTO_HashAsciiEncoded ret;
1256 struct GNUNET_HashCode hc;
1257
1258 GNUNET_CRYPTO_hash (p,
1259 sizeof (*p),
1260 &hc);
1261 GNUNET_CRYPTO_hash_to_enc (&hc,
1262 &ret);
1263 ret.encoding[6] = '\0';
1264 return (const char *) ret.encoding;
1265}
1266
1267
1268/**
1269 * @ingroup logging
1270 * Convert a public key value to a string (for printing debug messages).
1271 * This is one of the very few calls in the entire API that is
1272 * NOT reentrant!
1273 *
1274 * @param hc the hash code
1275 * @return string
1276 */
1277const char *
1278GNUNET_e2s2 (const struct GNUNET_CRYPTO_EcdhePublicKey *p)
1279{
1280 static struct GNUNET_CRYPTO_HashAsciiEncoded ret;
1281 struct GNUNET_HashCode hc;
1282
1283 GNUNET_CRYPTO_hash (p,
1284 sizeof (*p),
1285 &hc);
1286 GNUNET_CRYPTO_hash_to_enc (&hc,
1287 &ret);
1288 ret.encoding[6] = '\0';
1289 return (const char *) ret.encoding;
1290}
1291
1292
1293/**
1294 * @ingroup logging
1195 * Convert a short hash value to a string (for printing debug messages). 1295 * Convert a short hash value to a string (for printing debug messages).
1196 * This is one of the very few calls in the entire API that is 1296 * This is one of the very few calls in the entire API that is
1197 * NOT reentrant! 1297 * NOT reentrant!
diff --git a/src/util/crypto_bug.c b/src/util/crypto_bug.c
new file mode 100644
index 000000000..c25e79c63
--- /dev/null
+++ b/src/util/crypto_bug.c
@@ -0,0 +1,79 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2018 GNUnet e.V.
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20
21/**
22 * @file util/crypto_bug.c
23 * @brief work around unidentified public key cryptography bug
24 * @author Christian Grothoff
25 */
26
27/**
28 * Enable work-around. Will cause code to call #check_eddsa_key() to
29 * see if we have a bad key, and if so, create a new one.
30 */
31#define CRYPTO_BUG 1
32
33
34#if CRYPTO_BUG
35/**
36 * Check if ECDH works with @a priv_dsa and this version
37 * of libgcrypt.
38 *
39 * @param priv_dsa key to check
40 * @return #GNUNET_OK if key passes
41 */
42static int
43check_eddsa_key (const struct GNUNET_CRYPTO_EddsaPrivateKey *priv_dsa)
44{
45 struct GNUNET_CRYPTO_EcdhePrivateKey *priv_ecdh;
46 struct GNUNET_CRYPTO_EddsaPublicKey id1;
47 struct GNUNET_CRYPTO_EcdhePublicKey id2;
48 struct GNUNET_HashCode dh[2];
49
50 GNUNET_CRYPTO_eddsa_key_get_public (priv_dsa,
51 &id1);
52 for (unsigned int j=0;j<4;j++)
53 {
54 priv_ecdh = GNUNET_CRYPTO_ecdhe_key_create ();
55 /* Extract public keys */
56 GNUNET_CRYPTO_ecdhe_key_get_public (priv_ecdh,
57 &id2);
58 /* Do ECDH */
59 GNUNET_assert (GNUNET_OK ==
60 GNUNET_CRYPTO_eddsa_ecdh (priv_dsa,
61 &id2,
62 &dh[0]));
63 GNUNET_assert (GNUNET_OK ==
64 GNUNET_CRYPTO_ecdh_eddsa (priv_ecdh,
65 &id1,
66 &dh[1]));
67 /* Check that both DH results are equal. */
68 if (0 != memcmp (&dh[0],
69 &dh[1],
70 sizeof (struct GNUNET_HashCode)))
71 {
72 GNUNET_break (0); /* bad EdDSA key! */
73 return GNUNET_SYSERR;
74 }
75 GNUNET_free (priv_ecdh);
76 }
77 return GNUNET_OK;
78}
79#endif
diff --git a/src/util/crypto_ecc.c b/src/util/crypto_ecc.c
index 5d5e8a9ce..1abf0fddc 100644
--- a/src/util/crypto_ecc.c
+++ b/src/util/crypto_ecc.c
@@ -52,6 +52,9 @@
52#define LOG_GCRY(level, cmd, rc) do { LOG(level, _("`%s' failed at %s:%d with error: %s\n"), cmd, __FILE__, __LINE__, gcry_strerror(rc)); } while(0) 52#define LOG_GCRY(level, cmd, rc) do { LOG(level, _("`%s' failed at %s:%d with error: %s\n"), cmd, __FILE__, __LINE__, gcry_strerror(rc)); } while(0)
53 53
54 54
55#include "crypto_bug.c"
56
57
55/** 58/**
56 * Extract values from an S-expression. 59 * Extract values from an S-expression.
57 * 60 *
@@ -455,7 +458,7 @@ GNUNET_CRYPTO_eddsa_public_key_from_string (const char *enc,
455int 458int
456GNUNET_CRYPTO_eddsa_private_key_from_string (const char *enc, 459GNUNET_CRYPTO_eddsa_private_key_from_string (const char *enc,
457 size_t enclen, 460 size_t enclen,
458 struct GNUNET_CRYPTO_EddsaPrivateKey *pub) 461 struct GNUNET_CRYPTO_EddsaPrivateKey *priv)
459{ 462{
460 size_t keylen = (sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey)) * 8; 463 size_t keylen = (sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey)) * 8;
461 464
@@ -465,10 +468,19 @@ GNUNET_CRYPTO_eddsa_private_key_from_string (const char *enc,
465 if (enclen != keylen) 468 if (enclen != keylen)
466 return GNUNET_SYSERR; 469 return GNUNET_SYSERR;
467 470
468 if (GNUNET_OK != GNUNET_STRINGS_string_to_data (enc, enclen, 471 if (GNUNET_OK !=
469 pub, 472 GNUNET_STRINGS_string_to_data (enc, enclen,
470 sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey))) 473 priv,
474 sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey)))
471 return GNUNET_SYSERR; 475 return GNUNET_SYSERR;
476#if CRYPTO_BUG
477 if (GNUNET_OK !=
478 check_eddsa_key (priv))
479 {
480 GNUNET_break (0);
481 return GNUNET_OK;
482 }
483#endif
472 return GNUNET_OK; 484 return GNUNET_OK;
473} 485}
474 486
@@ -651,6 +663,9 @@ GNUNET_CRYPTO_eddsa_key_create ()
651 gcry_mpi_t d; 663 gcry_mpi_t d;
652 int rc; 664 int rc;
653 665
666#if CRYPTO_BUG
667 again:
668#endif
654 if (0 != (rc = gcry_sexp_build (&s_keyparam, NULL, 669 if (0 != (rc = gcry_sexp_build (&s_keyparam, NULL,
655 "(genkey(ecc(curve \"" CURVE "\")" 670 "(genkey(ecc(curve \"" CURVE "\")"
656 "(flags eddsa)))"))) 671 "(flags eddsa)))")))
@@ -683,6 +698,17 @@ GNUNET_CRYPTO_eddsa_key_create ()
683 priv = GNUNET_new (struct GNUNET_CRYPTO_EddsaPrivateKey); 698 priv = GNUNET_new (struct GNUNET_CRYPTO_EddsaPrivateKey);
684 GNUNET_CRYPTO_mpi_print_unsigned (priv->d, sizeof (priv->d), d); 699 GNUNET_CRYPTO_mpi_print_unsigned (priv->d, sizeof (priv->d), d);
685 gcry_mpi_release (d); 700 gcry_mpi_release (d);
701
702#if CRYPTO_BUG
703 if (GNUNET_OK !=
704 check_eddsa_key (priv))
705 {
706 GNUNET_break (0);
707 GNUNET_free (priv);
708 goto again;
709 }
710#endif
711
686 return priv; 712 return priv;
687} 713}
688 714
@@ -1279,6 +1305,48 @@ eddsa_d_to_a (gcry_mpi_t d)
1279 1305
1280 1306
1281/** 1307/**
1308 * Take point from ECDH and convert it to key material.
1309 *
1310 * @param result point from ECDH
1311 * @param ctx ECC context
1312 * @param key_material[out] set to derived key material
1313 * @return #GNUNET_OK on success
1314 */
1315static int
1316point_to_hash (gcry_mpi_point_t result,
1317 gcry_ctx_t ctx,
1318 struct GNUNET_HashCode *key_material)
1319{
1320 gcry_mpi_t result_x;
1321 unsigned char xbuf[256 / 8];
1322 size_t rsize;
1323
1324 /* finally, convert point to string for hashing */
1325 result_x = gcry_mpi_new (256);
1326 if (gcry_mpi_ec_get_affine (result_x, NULL, result, ctx))
1327 {
1328 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "get_affine failed", 0);
1329 return GNUNET_SYSERR;
1330 }
1331
1332 rsize = sizeof (xbuf);
1333 GNUNET_assert (! gcry_mpi_get_flag (result_x, GCRYMPI_FLAG_OPAQUE));
1334 /* result_x can be negative here, so we do not use 'GNUNET_CRYPTO_mpi_print_unsigned'
1335 as that does not include the sign bit; x should be a 255-bit
1336 value, so with the sign it should fit snugly into the 256-bit
1337 xbuf */
1338 GNUNET_assert (0 ==
1339 gcry_mpi_print (GCRYMPI_FMT_STD, xbuf, rsize, &rsize,
1340 result_x));
1341 GNUNET_CRYPTO_hash (xbuf,
1342 rsize,
1343 key_material);
1344 gcry_mpi_release (result_x);
1345 return GNUNET_OK;
1346}
1347
1348
1349/**
1282 * @ingroup crypto 1350 * @ingroup crypto
1283 * Derive key material from a ECDH public key and a private EdDSA key. 1351 * Derive key material from a ECDH public key and a private EdDSA key.
1284 * Dual to #GNUNET_CRRYPTO_ecdh_eddsa. 1352 * Dual to #GNUNET_CRRYPTO_ecdh_eddsa.
@@ -1299,9 +1367,7 @@ GNUNET_CRYPTO_eddsa_ecdh (const struct GNUNET_CRYPTO_EddsaPrivateKey *priv,
1299 gcry_mpi_t a; 1367 gcry_mpi_t a;
1300 gcry_ctx_t ctx; 1368 gcry_ctx_t ctx;
1301 gcry_sexp_t pub_sexpr; 1369 gcry_sexp_t pub_sexpr;
1302 gcry_mpi_t result_x; 1370 int ret;
1303 unsigned char xbuf[256 / 8];
1304 size_t rsize;
1305 1371
1306 /* first, extract the q = dP value from the public key */ 1372 /* first, extract the q = dP value from the public key */
1307 if (0 != gcry_sexp_build (&pub_sexpr, NULL, 1373 if (0 != gcry_sexp_build (&pub_sexpr, NULL,
@@ -1325,34 +1391,15 @@ GNUNET_CRYPTO_eddsa_ecdh (const struct GNUNET_CRYPTO_EddsaPrivateKey *priv,
1325 gcry_mpi_point_release (q); 1391 gcry_mpi_point_release (q);
1326 gcry_mpi_release (a); 1392 gcry_mpi_release (a);
1327 1393
1328 /* finally, convert point to string for hashing */ 1394 ret = point_to_hash (result,
1329 result_x = gcry_mpi_new (256); 1395 ctx,
1330 if (gcry_mpi_ec_get_affine (result_x, NULL, result, ctx)) 1396 key_material);
1331 {
1332 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "get_affine failed", 0);
1333 gcry_mpi_point_release (result);
1334 gcry_ctx_release (ctx);
1335 return GNUNET_SYSERR;
1336 }
1337 gcry_mpi_point_release (result); 1397 gcry_mpi_point_release (result);
1338 gcry_ctx_release (ctx); 1398 gcry_ctx_release (ctx);
1339 1399 return ret;
1340 rsize = sizeof (xbuf);
1341 GNUNET_assert (! gcry_mpi_get_flag (result_x, GCRYMPI_FLAG_OPAQUE));
1342 /* result_x can be negative here, so we do not use 'GNUNET_CRYPTO_mpi_print_unsigned'
1343 as that does not include the sign bit; x should be a 255-bit
1344 value, so with the sign it should fit snugly into the 256-bit
1345 xbuf */
1346 GNUNET_assert (0 ==
1347 gcry_mpi_print (GCRYMPI_FMT_STD, xbuf, rsize, &rsize,
1348 result_x));
1349 GNUNET_CRYPTO_hash (xbuf,
1350 rsize,
1351 key_material);
1352 gcry_mpi_release (result_x);
1353 return GNUNET_OK;
1354} 1400}
1355 1401
1402
1356/** 1403/**
1357 * @ingroup crypto 1404 * @ingroup crypto
1358 * Derive key material from a ECDH public key and a private ECDSA key. 1405 * Derive key material from a ECDH public key and a private ECDSA key.
@@ -1373,9 +1420,7 @@ GNUNET_CRYPTO_ecdsa_ecdh (const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv,
1373 gcry_mpi_t d; 1420 gcry_mpi_t d;
1374 gcry_ctx_t ctx; 1421 gcry_ctx_t ctx;
1375 gcry_sexp_t pub_sexpr; 1422 gcry_sexp_t pub_sexpr;
1376 gcry_mpi_t result_x; 1423 int ret;
1377 unsigned char xbuf[256 / 8];
1378 size_t rsize;
1379 1424
1380 /* first, extract the q = dP value from the public key */ 1425 /* first, extract the q = dP value from the public key */
1381 if (0 != gcry_sexp_build (&pub_sexpr, NULL, 1426 if (0 != gcry_sexp_build (&pub_sexpr, NULL,
@@ -1396,31 +1441,12 @@ GNUNET_CRYPTO_ecdsa_ecdh (const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv,
1396 gcry_mpi_release (d); 1441 gcry_mpi_release (d);
1397 1442
1398 /* finally, convert point to string for hashing */ 1443 /* finally, convert point to string for hashing */
1399 result_x = gcry_mpi_new (256); 1444 ret = point_to_hash (result,
1400 if (gcry_mpi_ec_get_affine (result_x, NULL, result, ctx)) 1445 ctx,
1401 { 1446 key_material);
1402 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "get_affine failed", 0);
1403 gcry_mpi_point_release (result);
1404 gcry_ctx_release (ctx);
1405 return GNUNET_SYSERR;
1406 }
1407 gcry_mpi_point_release (result); 1447 gcry_mpi_point_release (result);
1408 gcry_ctx_release (ctx); 1448 gcry_ctx_release (ctx);
1409 1449 return ret;
1410 rsize = sizeof (xbuf);
1411 GNUNET_assert (! gcry_mpi_get_flag (result_x, GCRYMPI_FLAG_OPAQUE));
1412 /* result_x can be negative here, so we do not use 'GNUNET_CRYPTO_mpi_print_unsigned'
1413 as that does not include the sign bit; x should be a 255-bit
1414 value, so with the sign it should fit snugly into the 256-bit
1415 xbuf */
1416 GNUNET_assert (0 ==
1417 gcry_mpi_print (GCRYMPI_FMT_STD, xbuf, rsize, &rsize,
1418 result_x));
1419 GNUNET_CRYPTO_hash (xbuf,
1420 rsize,
1421 key_material);
1422 gcry_mpi_release (result_x);
1423 return GNUNET_OK;
1424} 1450}
1425 1451
1426 1452
@@ -1445,9 +1471,7 @@ GNUNET_CRYPTO_ecdh_eddsa (const struct GNUNET_CRYPTO_EcdhePrivateKey *priv,
1445 gcry_mpi_t d; 1471 gcry_mpi_t d;
1446 gcry_ctx_t ctx; 1472 gcry_ctx_t ctx;
1447 gcry_sexp_t pub_sexpr; 1473 gcry_sexp_t pub_sexpr;
1448 gcry_mpi_t result_x; 1474 int ret;
1449 unsigned char xbuf[256 / 8];
1450 size_t rsize;
1451 1475
1452 /* first, extract the q = dP value from the public key */ 1476 /* first, extract the q = dP value from the public key */
1453 if (0 != gcry_sexp_build (&pub_sexpr, NULL, 1477 if (0 != gcry_sexp_build (&pub_sexpr, NULL,
@@ -1468,31 +1492,12 @@ GNUNET_CRYPTO_ecdh_eddsa (const struct GNUNET_CRYPTO_EcdhePrivateKey *priv,
1468 gcry_mpi_release (d); 1492 gcry_mpi_release (d);
1469 1493
1470 /* finally, convert point to string for hashing */ 1494 /* finally, convert point to string for hashing */
1471 result_x = gcry_mpi_new (256); 1495 ret = point_to_hash (result,
1472 if (gcry_mpi_ec_get_affine (result_x, NULL, result, ctx)) 1496 ctx,
1473 { 1497 key_material);
1474 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "get_affine failed", 0);
1475 gcry_mpi_point_release (result);
1476 gcry_ctx_release (ctx);
1477 return GNUNET_SYSERR;
1478 }
1479 gcry_mpi_point_release (result); 1498 gcry_mpi_point_release (result);
1480 gcry_ctx_release (ctx); 1499 gcry_ctx_release (ctx);
1481 1500 return ret;
1482 rsize = sizeof (xbuf);
1483 GNUNET_assert (! gcry_mpi_get_flag (result_x, GCRYMPI_FLAG_OPAQUE));
1484 /* result_x can be negative here, so we do not use 'GNUNET_CRYPTO_mpi_print_unsigned'
1485 as that does not include the sign bit; x should be a 255-bit
1486 value, so with the sign it should fit snugly into the 256-bit
1487 xbuf */
1488 GNUNET_assert (0 ==
1489 gcry_mpi_print (GCRYMPI_FMT_STD, xbuf, rsize, &rsize,
1490 result_x));
1491 GNUNET_CRYPTO_hash (xbuf,
1492 rsize,
1493 key_material);
1494 gcry_mpi_release (result_x);
1495 return GNUNET_OK;
1496} 1501}
1497 1502
1498/** 1503/**
diff --git a/src/util/crypto_ecc_setup.c b/src/util/crypto_ecc_setup.c
index e7caf9ded..76c25dc70 100644
--- a/src/util/crypto_ecc_setup.c
+++ b/src/util/crypto_ecc_setup.c
@@ -41,6 +41,9 @@
41#define LOG_GCRY(level, cmd, rc) do { LOG(level, _("`%s' failed at %s:%d with error: %s\n"), cmd, __FILE__, __LINE__, gcry_strerror(rc)); } while(0) 41#define LOG_GCRY(level, cmd, rc) do { LOG(level, _("`%s' failed at %s:%d with error: %s\n"), cmd, __FILE__, __LINE__, gcry_strerror(rc)); } while(0)
42 42
43 43
44#include "crypto_bug.c"
45
46
44/** 47/**
45 * Wait for a short time (we're trying to lock a file or want 48 * Wait for a short time (we're trying to lock a file or want
46 * to give another process a shot at finishing a disk write, etc.). 49 * to give another process a shot at finishing a disk write, etc.).
@@ -221,6 +224,15 @@ GNUNET_CRYPTO_eddsa_key_create_from_file (const char *filename)
221 filename); 224 filename);
222 GNUNET_assert (GNUNET_YES == 225 GNUNET_assert (GNUNET_YES ==
223 GNUNET_DISK_file_close (fd)); 226 GNUNET_DISK_file_close (fd));
227#if CRYPTO_BUG
228 if (GNUNET_OK !=
229 check_eddsa_key (priv))
230 {
231 GNUNET_break (0);
232 GNUNET_free (priv);
233 return NULL;
234 }
235#endif
224 return priv; 236 return priv;
225} 237}
226 238
@@ -248,7 +260,7 @@ GNUNET_CRYPTO_ecdsa_key_create_from_file (const char *filename)
248 int ec; 260 int ec;
249 uint64_t fs; 261 uint64_t fs;
250 ssize_t sret; 262 ssize_t sret;
251 263
252 if (GNUNET_SYSERR == 264 if (GNUNET_SYSERR ==
253 GNUNET_DISK_directory_create_for_file (filename)) 265 GNUNET_DISK_directory_create_for_file (filename))
254 return NULL; 266 return NULL;
diff --git a/src/util/test_crypto_ecdh_eddsa.c b/src/util/test_crypto_ecdh_eddsa.c
index ec7819c3b..356c64bf1 100644
--- a/src/util/test_crypto_ecdh_eddsa.c
+++ b/src/util/test_crypto_ecdh_eddsa.c
@@ -36,30 +36,35 @@ test_ecdh()
36 struct GNUNET_CRYPTO_EcdhePrivateKey *priv_ecdh; 36 struct GNUNET_CRYPTO_EcdhePrivateKey *priv_ecdh;
37 struct GNUNET_CRYPTO_EddsaPublicKey id1; 37 struct GNUNET_CRYPTO_EddsaPublicKey id1;
38 struct GNUNET_CRYPTO_EcdhePublicKey id2; 38 struct GNUNET_CRYPTO_EcdhePublicKey id2;
39 struct GNUNET_HashCode dh[3]; 39 struct GNUNET_HashCode dh[2];
40 40
41 /* Generate keys */ 41 /* Generate keys */
42 priv_dsa = GNUNET_CRYPTO_eddsa_key_create (); 42 priv_dsa = GNUNET_CRYPTO_eddsa_key_create ();
43 priv_ecdh = GNUNET_CRYPTO_ecdhe_key_create ();
44 /* Extract public keys */
45 GNUNET_CRYPTO_eddsa_key_get_public (priv_dsa, 43 GNUNET_CRYPTO_eddsa_key_get_public (priv_dsa,
46 &id1); 44 &id1);
47 GNUNET_CRYPTO_ecdhe_key_get_public (priv_ecdh, 45 for (unsigned int j=0;j<10;j++)
48 &id2); 46 {
49 /* Do ECDH */ 47 fprintf (stderr, ",");
50 GNUNET_assert (GNUNET_OK == 48 priv_ecdh = GNUNET_CRYPTO_ecdhe_key_create ();
51 GNUNET_CRYPTO_eddsa_ecdh (priv_dsa, 49 /* Extract public keys */
52 &id2, 50 GNUNET_CRYPTO_ecdhe_key_get_public (priv_ecdh,
53 &dh[0])); 51 &id2);
54 GNUNET_assert (GNUNET_OK == 52 /* Do ECDH */
55 GNUNET_CRYPTO_ecdh_eddsa (priv_ecdh, 53 GNUNET_assert (GNUNET_OK ==
56 &id1, 54 GNUNET_CRYPTO_eddsa_ecdh (priv_dsa,
57 &dh[1])); 55 &id2,
58 /* Check that both DH results are equal. */ 56 &dh[0]));
59 GNUNET_assert (0 == memcmp (&dh[0], &dh[1], 57 GNUNET_assert (GNUNET_OK ==
60 sizeof (struct GNUNET_HashCode))); 58 GNUNET_CRYPTO_ecdh_eddsa (priv_ecdh,
59 &id1,
60 &dh[1]));
61 /* Check that both DH results are equal. */
62 GNUNET_assert (0 == memcmp (&dh[0],
63 &dh[1],
64 sizeof (struct GNUNET_HashCode)));
65 GNUNET_free (priv_ecdh);
66 }
61 GNUNET_free (priv_dsa); 67 GNUNET_free (priv_dsa);
62 GNUNET_free (priv_ecdh);
63 return 0; 68 return 0;
64} 69}
65 70
@@ -75,10 +80,15 @@ main (int argc, char *argv[])
75 return 0; 80 return 0;
76 } 81 }
77 if (getenv ("GNUNET_GCRYPT_DEBUG")) 82 if (getenv ("GNUNET_GCRYPT_DEBUG"))
78 gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u , 0); 83 gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0);
79 GNUNET_log_setup ("test-crypto-ecdh-eddsa", "WARNING", NULL); 84 GNUNET_log_setup ("test-crypto-ecdh-eddsa", "WARNING", NULL);
80 if (0 != test_ecdh()) 85 for (unsigned int i=0;i<100;i++)
81 return 1; 86 {
87 fprintf (stderr,
88 ".");
89 if (0 != test_ecdh())
90 return 1;
91 }
82 return 0; 92 return 0;
83} 93}
84 94
diff --git a/src/util/test_crypto_ecdhe.c b/src/util/test_crypto_ecdhe.c
index 0cfb7f2c3..d59562552 100644
--- a/src/util/test_crypto_ecdhe.c
+++ b/src/util/test_crypto_ecdhe.c
@@ -50,16 +50,21 @@ main (int argc, char *argv[])
50 gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u , 0); 50 gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u , 0);
51 GNUNET_log_setup ("test-crypto-ecdhe", "WARNING", NULL); 51 GNUNET_log_setup ("test-crypto-ecdhe", "WARNING", NULL);
52 52
53 priv1 = GNUNET_CRYPTO_ecdhe_key_create (); 53 for (unsigned int i=0;i<100;i++)
54 priv2 = GNUNET_CRYPTO_ecdhe_key_create (); 54 {
55 GNUNET_CRYPTO_ecdhe_key_get_public (priv1, &pub1); 55 fprintf (stderr,
56 GNUNET_CRYPTO_ecdhe_key_get_public (priv2, &pub2); 56 ".");
57 GNUNET_CRYPTO_ecc_ecdh (priv1, &pub2, &ecdh1); 57 priv1 = GNUNET_CRYPTO_ecdhe_key_create ();
58 GNUNET_CRYPTO_ecc_ecdh (priv2, &pub1, &ecdh2); 58 priv2 = GNUNET_CRYPTO_ecdhe_key_create ();
59 GNUNET_assert (0 == memcmp (&ecdh1, &ecdh2, 59 GNUNET_CRYPTO_ecdhe_key_get_public (priv1, &pub1);
60 sizeof (struct GNUNET_HashCode))); 60 GNUNET_CRYPTO_ecdhe_key_get_public (priv2, &pub2);
61 GNUNET_free (priv1); 61 GNUNET_CRYPTO_ecc_ecdh (priv1, &pub2, &ecdh1);
62 GNUNET_free (priv2); 62 GNUNET_CRYPTO_ecc_ecdh (priv2, &pub1, &ecdh2);
63 GNUNET_assert (0 == memcmp (&ecdh1, &ecdh2,
64 sizeof (struct GNUNET_HashCode)));
65 GNUNET_free (priv1);
66 GNUNET_free (priv2);
67 }
63 return 0; 68 return 0;
64} 69}
65 70