diff options
author | Nils Gillmann <ng0@n0.is> | 2018-05-17 13:39:09 +0000 |
---|---|---|
committer | Nils Gillmann <ng0@n0.is> | 2018-05-17 13:39:09 +0000 |
commit | 9f722a29b9f7abbb9d8d1de63a72d09588c02f91 (patch) | |
tree | 32913cdeb7364ad71a58d239be224ae29d900aaf /src | |
parent | c7e03281601aa687030fe3d561e1d693a46bba21 (diff) | |
parent | dd8289771b35e5ea36ebdcbfd5b09b599bd59c67 (diff) | |
download | gnunet-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.c | 339 | ||||
-rw-r--r-- | src/dns/.gitignore | 1 | ||||
-rw-r--r-- | src/gns/gnunet-gns-benchmark.c | 2 | ||||
-rw-r--r-- | src/gns/gnunet-gns-proxy.c | 34 | ||||
-rw-r--r-- | src/gns/gnunet-service-gns.c | 19 | ||||
-rw-r--r-- | src/include/gnunet_common.h | 70 | ||||
-rw-r--r-- | src/rps/test_rps.c | 42 | ||||
-rw-r--r-- | src/util/Makefile.am | 3 | ||||
-rw-r--r-- | src/util/common_logging.c | 100 | ||||
-rw-r--r-- | src/util/crypto_bug.c | 79 | ||||
-rw-r--r-- | src/util/crypto_ecc.c | 171 | ||||
-rw-r--r-- | src/util/crypto_ecc_setup.c | 14 | ||||
-rw-r--r-- | src/util/test_crypto_ecdh_eddsa.c | 52 | ||||
-rw-r--r-- | src/util/test_crypto_ecdhe.c | 25 |
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 | */ | ||
467 | static int | ||
468 | alice_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 | |||
4 | gnunet-helper-dns | 4 | gnunet-helper-dns |
5 | test_hexcoder | 5 | test_hexcoder |
6 | gnunet-zoneimport | 6 | gnunet-zoneimport |
7 | gnunet-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 | */ |
594 | const char * | 594 | const char * |
595 | GNUNET_h2s (const struct GNUNET_HashCode * hc); | 595 | GNUNET_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 | */ |
609 | const char * | 609 | const char * |
610 | GNUNET_h2s2 (const struct GNUNET_HashCode * hc); | 610 | GNUNET_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 | */ |
623 | const char * | 623 | const char * |
624 | GNUNET_h2s_full (const struct GNUNET_HashCode * hc); | 624 | GNUNET_h2s_full (const struct GNUNET_HashCode *hc); |
625 | |||
626 | |||
627 | /** | ||
628 | * Public key. Details in gnunet_util_crypto.h. | ||
629 | */ | ||
630 | struct GNUNET_CRYPTO_EddsaPublicKey; | ||
631 | |||
632 | |||
633 | /** | ||
634 | * Public key. Details in gnunet_util_crypto.h. | ||
635 | */ | ||
636 | struct 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 | */ | ||
648 | const char * | ||
649 | GNUNET_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 | */ | ||
661 | const char * | ||
662 | GNUNET_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 | */ | ||
674 | const char * | ||
675 | GNUNET_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 | */ | ||
687 | const char * | ||
688 | GNUNET_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 | */ | ||
1202 | const char * | ||
1203 | GNUNET_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 | */ | ||
1227 | const char * | ||
1228 | GNUNET_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 | */ | ||
1252 | const char * | ||
1253 | GNUNET_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 | */ | ||
1277 | const char * | ||
1278 | GNUNET_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 | */ | ||
42 | static int | ||
43 | check_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, | |||
455 | int | 458 | int |
456 | GNUNET_CRYPTO_eddsa_private_key_from_string (const char *enc, | 459 | GNUNET_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 | */ | ||
1315 | static int | ||
1316 | point_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 | ||