diff options
Diffstat (limited to 'src/secretsharing/gnunet-service-secretsharing.c')
-rw-r--r-- | src/secretsharing/gnunet-service-secretsharing.c | 538 |
1 files changed, 279 insertions, 259 deletions
diff --git a/src/secretsharing/gnunet-service-secretsharing.c b/src/secretsharing/gnunet-service-secretsharing.c index ddbe81576..ccdba12c2 100644 --- a/src/secretsharing/gnunet-service-secretsharing.c +++ b/src/secretsharing/gnunet-service-secretsharing.c | |||
@@ -109,19 +109,16 @@ struct DecryptPeerInfo | |||
109 | 109 | ||
110 | 110 | ||
111 | /** | 111 | /** |
112 | * State we keep per client. | ||
113 | */ | ||
114 | struct ClientState; | ||
115 | |||
116 | |||
117 | /** | ||
112 | * Session to establish a threshold-shared secret. | 118 | * Session to establish a threshold-shared secret. |
113 | */ | 119 | */ |
114 | struct KeygenSession | 120 | struct KeygenSession |
115 | { | 121 | { |
116 | /** | ||
117 | * Keygen sessions are held in a linked list. | ||
118 | */ | ||
119 | struct KeygenSession *next; | ||
120 | |||
121 | /** | ||
122 | * Keygen sessions are held in a linked list. | ||
123 | */ | ||
124 | struct KeygenSession *prev; | ||
125 | 122 | ||
126 | /** | 123 | /** |
127 | * Current consensus, used for both DKG rounds. | 124 | * Current consensus, used for both DKG rounds. |
@@ -129,15 +126,9 @@ struct KeygenSession | |||
129 | struct GNUNET_CONSENSUS_Handle *consensus; | 126 | struct GNUNET_CONSENSUS_Handle *consensus; |
130 | 127 | ||
131 | /** | 128 | /** |
132 | * Client that is interested in the result | 129 | * Which client is this for? |
133 | * of this key generation session. | ||
134 | */ | ||
135 | struct GNUNET_SERVER_Client *client; | ||
136 | |||
137 | /** | ||
138 | * Message queue for 'client' | ||
139 | */ | 130 | */ |
140 | struct GNUNET_MQ_Handle *client_mq; | 131 | struct ClientState *cs; |
141 | 132 | ||
142 | /** | 133 | /** |
143 | * Randomly generated coefficients of the polynomial for sharing our | 134 | * Randomly generated coefficients of the polynomial for sharing our |
@@ -223,15 +214,6 @@ struct KeygenSession | |||
223 | */ | 214 | */ |
224 | struct DecryptSession | 215 | struct DecryptSession |
225 | { | 216 | { |
226 | /** | ||
227 | * Decrypt sessions are stored in a linked list. | ||
228 | */ | ||
229 | struct DecryptSession *next; | ||
230 | |||
231 | /** | ||
232 | * Decrypt sessions are stored in a linked list. | ||
233 | */ | ||
234 | struct DecryptSession *prev; | ||
235 | 217 | ||
236 | /** | 218 | /** |
237 | * Handle to the consensus over partial decryptions. | 219 | * Handle to the consensus over partial decryptions. |
@@ -239,14 +221,9 @@ struct DecryptSession | |||
239 | struct GNUNET_CONSENSUS_Handle *consensus; | 221 | struct GNUNET_CONSENSUS_Handle *consensus; |
240 | 222 | ||
241 | /** | 223 | /** |
242 | * Client connected to us. | 224 | * Which client is this for? |
243 | */ | 225 | */ |
244 | struct GNUNET_SERVER_Client *client; | 226 | struct ClientState *cs; |
245 | |||
246 | /** | ||
247 | * Message queue for 'client'. | ||
248 | */ | ||
249 | struct GNUNET_MQ_Handle *client_mq; | ||
250 | 227 | ||
251 | /** | 228 | /** |
252 | * When should we start communicating for decryption? | 229 | * When should we start communicating for decryption? |
@@ -279,24 +256,32 @@ struct DecryptSession | |||
279 | 256 | ||
280 | 257 | ||
281 | /** | 258 | /** |
282 | * Decrypt sessions are held in a linked list. | 259 | * State we keep per client. |
283 | */ | 260 | */ |
284 | static struct DecryptSession *decrypt_sessions_head; | 261 | struct ClientState |
262 | { | ||
263 | /** | ||
264 | * Decrypt session of the client, if any. | ||
265 | */ | ||
266 | struct DecryptSession *decrypt_session; | ||
285 | 267 | ||
286 | /** | 268 | /** |
287 | * Decrypt sessions are held in a linked list. | 269 | * Keygen session of the client, if any. |
288 | */ | 270 | */ |
289 | static struct DecryptSession *decrypt_sessions_tail; | 271 | struct KeygenSession *keygen_session; |
290 | 272 | ||
291 | /** | 273 | /** |
292 | * Decrypt sessions are held in a linked list. | 274 | * Client this is about. |
293 | */ | 275 | */ |
294 | static struct KeygenSession *keygen_sessions_head; | 276 | struct GNUNET_SERVICE_Client *client; |
277 | |||
278 | /** | ||
279 | * MQ to talk to @a client. | ||
280 | */ | ||
281 | struct GNUNET_MQ_Handle *mq; | ||
282 | |||
283 | }; | ||
295 | 284 | ||
296 | /** | ||
297 | * Decrypt sessions are held in a linked list. | ||
298 | */ | ||
299 | static struct KeygenSession *keygen_sessions_tail; | ||
300 | 285 | ||
301 | /** | 286 | /** |
302 | * The ElGamal prime field order as libgcrypt mpi. | 287 | * The ElGamal prime field order as libgcrypt mpi. |
@@ -331,11 +316,6 @@ static struct GNUNET_CRYPTO_EddsaPrivateKey *my_peer_private_key; | |||
331 | */ | 316 | */ |
332 | static const struct GNUNET_CONFIGURATION_Handle *cfg; | 317 | static const struct GNUNET_CONFIGURATION_Handle *cfg; |
333 | 318 | ||
334 | /** | ||
335 | * Server for this service. | ||
336 | */ | ||
337 | static struct GNUNET_SERVER_Handle *srv; | ||
338 | |||
339 | 319 | ||
340 | /** | 320 | /** |
341 | * Get the peer info belonging to a peer identity in a keygen session. | 321 | * Get the peer info belonging to a peer identity in a keygen session. |
@@ -468,7 +448,8 @@ normalize_peers (struct GNUNET_PeerIdentity *listed, | |||
468 | n += 1; | 448 | n += 1; |
469 | } | 449 | } |
470 | 450 | ||
471 | normalized = GNUNET_new_array (n, struct GNUNET_PeerIdentity); | 451 | normalized = GNUNET_new_array (n, |
452 | struct GNUNET_PeerIdentity); | ||
472 | 453 | ||
473 | if (GNUNET_NO == local_peer_in_list) | 454 | if (GNUNET_NO == local_peer_in_list) |
474 | normalized[n - 1] = my_peer; | 455 | normalized[n - 1] = my_peer; |
@@ -558,10 +539,13 @@ compute_lagrange_coefficient (gcry_mpi_t coeff, unsigned int j, | |||
558 | static void | 539 | static void |
559 | decrypt_session_destroy (struct DecryptSession *ds) | 540 | decrypt_session_destroy (struct DecryptSession *ds) |
560 | { | 541 | { |
561 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "destroying decrypt session\n"); | 542 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
562 | 543 | "destroying decrypt session\n"); | |
563 | GNUNET_CONTAINER_DLL_remove (decrypt_sessions_head, decrypt_sessions_tail, ds); | 544 | if (NULL != ds->cs) |
564 | 545 | { | |
546 | ds->cs->decrypt_session = NULL; | ||
547 | ds->cs = NULL; | ||
548 | } | ||
565 | if (NULL != ds->consensus) | 549 | if (NULL != ds->consensus) |
566 | { | 550 | { |
567 | GNUNET_CONSENSUS_destroy (ds->consensus); | 551 | GNUNET_CONSENSUS_destroy (ds->consensus); |
@@ -570,8 +554,7 @@ decrypt_session_destroy (struct DecryptSession *ds) | |||
570 | 554 | ||
571 | if (NULL != ds->info) | 555 | if (NULL != ds->info) |
572 | { | 556 | { |
573 | unsigned int i; | 557 | for (unsigned int i = 0; i < ds->share->num_peers; i++) |
574 | for (i = 0; i < ds->share->num_peers; i++) | ||
575 | { | 558 | { |
576 | if (NULL != ds->info[i].partial_decryption) | 559 | if (NULL != ds->info[i].partial_decryption) |
577 | { | 560 | { |
@@ -582,26 +565,12 @@ decrypt_session_destroy (struct DecryptSession *ds) | |||
582 | GNUNET_free (ds->info); | 565 | GNUNET_free (ds->info); |
583 | ds->info = NULL; | 566 | ds->info = NULL; |
584 | } | 567 | } |
585 | |||
586 | if (NULL != ds->share) | 568 | if (NULL != ds->share) |
587 | { | 569 | { |
588 | GNUNET_SECRETSHARING_share_destroy (ds->share); | 570 | GNUNET_SECRETSHARING_share_destroy (ds->share); |
589 | ds->share = NULL; | 571 | ds->share = NULL; |
590 | } | 572 | } |
591 | 573 | ||
592 | if (NULL != ds->client_mq) | ||
593 | { | ||
594 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "destroying decrypt MQ\n"); | ||
595 | GNUNET_MQ_destroy (ds->client_mq); | ||
596 | ds->client_mq = NULL; | ||
597 | } | ||
598 | |||
599 | if (NULL != ds->client) | ||
600 | { | ||
601 | GNUNET_SERVER_client_disconnect (ds->client); | ||
602 | ds->client = NULL; | ||
603 | } | ||
604 | |||
605 | GNUNET_free (ds); | 574 | GNUNET_free (ds); |
606 | } | 575 | } |
607 | 576 | ||
@@ -630,14 +599,17 @@ keygen_info_destroy (struct KeygenPeerInfo *info) | |||
630 | static void | 599 | static void |
631 | keygen_session_destroy (struct KeygenSession *ks) | 600 | keygen_session_destroy (struct KeygenSession *ks) |
632 | { | 601 | { |
633 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "destroying keygen session\n"); | 602 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
634 | 603 | "destroying keygen session\n"); | |
635 | GNUNET_CONTAINER_DLL_remove (keygen_sessions_head, keygen_sessions_tail, ks); | ||
636 | 604 | ||
605 | if (NULL != ks->cs) | ||
606 | { | ||
607 | ks->cs->keygen_session = NULL; | ||
608 | ks->cs = NULL; | ||
609 | } | ||
637 | if (NULL != ks->info) | 610 | if (NULL != ks->info) |
638 | { | 611 | { |
639 | unsigned int i; | 612 | for (unsigned int i = 0; i < ks->num_peers; i++) |
640 | for (i = 0; i < ks->num_peers; i++) | ||
641 | keygen_info_destroy (&ks->info[i]); | 613 | keygen_info_destroy (&ks->info[i]); |
642 | GNUNET_free (ks->info); | 614 | GNUNET_free (ks->info); |
643 | ks->info = NULL; | 615 | ks->info = NULL; |
@@ -651,8 +623,7 @@ keygen_session_destroy (struct KeygenSession *ks) | |||
651 | 623 | ||
652 | if (NULL != ks->presecret_polynomial) | 624 | if (NULL != ks->presecret_polynomial) |
653 | { | 625 | { |
654 | unsigned int i; | 626 | for (unsigned int i = 0; i < ks->threshold; i++) |
655 | for (i = 0; i < ks->threshold; i++) | ||
656 | { | 627 | { |
657 | GNUNET_assert (NULL != ks->presecret_polynomial[i]); | 628 | GNUNET_assert (NULL != ks->presecret_polynomial[i]); |
658 | gcry_mpi_release (ks->presecret_polynomial[i]); | 629 | gcry_mpi_release (ks->presecret_polynomial[i]); |
@@ -661,38 +632,21 @@ keygen_session_destroy (struct KeygenSession *ks) | |||
661 | GNUNET_free (ks->presecret_polynomial); | 632 | GNUNET_free (ks->presecret_polynomial); |
662 | ks->presecret_polynomial = NULL; | 633 | ks->presecret_polynomial = NULL; |
663 | } | 634 | } |
664 | |||
665 | if (NULL != ks->client_mq) | ||
666 | { | ||
667 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "destroying keygen MQ\n"); | ||
668 | GNUNET_MQ_destroy (ks->client_mq); | ||
669 | ks->client_mq = NULL; | ||
670 | } | ||
671 | |||
672 | if (NULL != ks->my_share) | 635 | if (NULL != ks->my_share) |
673 | { | 636 | { |
674 | gcry_mpi_release (ks->my_share); | 637 | gcry_mpi_release (ks->my_share); |
675 | ks->my_share = NULL; | 638 | ks->my_share = NULL; |
676 | } | 639 | } |
677 | |||
678 | if (NULL != ks->public_key) | 640 | if (NULL != ks->public_key) |
679 | { | 641 | { |
680 | gcry_mpi_release (ks->public_key); | 642 | gcry_mpi_release (ks->public_key); |
681 | ks->public_key = NULL; | 643 | ks->public_key = NULL; |
682 | } | 644 | } |
683 | |||
684 | if (NULL != ks->peers) | 645 | if (NULL != ks->peers) |
685 | { | 646 | { |
686 | GNUNET_free (ks->peers); | 647 | GNUNET_free (ks->peers); |
687 | ks->peers = NULL; | 648 | ks->peers = NULL; |
688 | } | 649 | } |
689 | |||
690 | if (NULL != ks->client) | ||
691 | { | ||
692 | GNUNET_SERVER_client_disconnect (ks->client); | ||
693 | ks->client = NULL; | ||
694 | } | ||
695 | |||
696 | GNUNET_free (ks); | 650 | GNUNET_free (ks); |
697 | } | 651 | } |
698 | 652 | ||
@@ -706,11 +660,7 @@ keygen_session_destroy (struct KeygenSession *ks) | |||
706 | static void | 660 | static void |
707 | cleanup_task (void *cls) | 661 | cleanup_task (void *cls) |
708 | { | 662 | { |
709 | while (NULL != decrypt_sessions_head) | 663 | /* Nothing to do! */ |
710 | decrypt_session_destroy (decrypt_sessions_head); | ||
711 | |||
712 | while (NULL != keygen_sessions_head) | ||
713 | keygen_session_destroy (keygen_sessions_head); | ||
714 | } | 664 | } |
715 | 665 | ||
716 | 666 | ||
@@ -727,7 +677,8 @@ generate_presecret_polynomial (struct KeygenSession *ks) | |||
727 | gcry_mpi_t v; | 677 | gcry_mpi_t v; |
728 | 678 | ||
729 | GNUNET_assert (NULL == ks->presecret_polynomial); | 679 | GNUNET_assert (NULL == ks->presecret_polynomial); |
730 | ks->presecret_polynomial = GNUNET_new_array (ks->threshold, gcry_mpi_t); | 680 | ks->presecret_polynomial = GNUNET_new_array (ks->threshold, |
681 | gcry_mpi_t); | ||
731 | for (i = 0; i < ks->threshold; i++) | 682 | for (i = 0; i < ks->threshold; i++) |
732 | { | 683 | { |
733 | v = ks->presecret_polynomial[i] = gcry_mpi_new (GNUNET_SECRETSHARING_ELGAMAL_BITS); | 684 | v = ks->presecret_polynomial[i] = gcry_mpi_new (GNUNET_SECRETSHARING_ELGAMAL_BITS); |
@@ -768,9 +719,9 @@ keygen_round1_new_element (void *cls, | |||
768 | if (element->size != sizeof (struct GNUNET_SECRETSHARING_KeygenCommitData)) | 719 | if (element->size != sizeof (struct GNUNET_SECRETSHARING_KeygenCommitData)) |
769 | { | 720 | { |
770 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 721 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
771 | "keygen commit data with wrong size (%u) in consensus, " | 722 | "keygen commit data with wrong size (%u) in consensus, %u expected\n", |
772 | " %lu expected\n", | 723 | (unsigned int) element->size, |
773 | element->size, sizeof (struct GNUNET_SECRETSHARING_KeygenCommitData)); | 724 | (unsigned int) sizeof (struct GNUNET_SECRETSHARING_KeygenCommitData)); |
774 | return; | 725 | return; |
775 | } | 726 | } |
776 | 727 | ||
@@ -855,10 +806,13 @@ keygen_round2_conclude (void *cls) | |||
855 | if (GNUNET_YES == ks->info[i].round2_valid) | 806 | if (GNUNET_YES == ks->info[i].round2_valid) |
856 | share->num_peers++; | 807 | share->num_peers++; |
857 | 808 | ||
858 | share->peers = GNUNET_new_array (share->num_peers, struct GNUNET_PeerIdentity); | 809 | share->peers = GNUNET_new_array (share->num_peers, |
810 | struct GNUNET_PeerIdentity); | ||
859 | share->sigmas = | 811 | share->sigmas = |
860 | GNUNET_new_array (share->num_peers, struct GNUNET_SECRETSHARING_FieldElement); | 812 | GNUNET_new_array (share->num_peers, |
861 | share->original_indices = GNUNET_new_array (share->num_peers, uint16_t); | 813 | struct GNUNET_SECRETSHARING_FieldElement); |
814 | share->original_indices = GNUNET_new_array (share->num_peers, | ||
815 | uint16_t); | ||
862 | 816 | ||
863 | /* maybe we're not even in the list of peers? */ | 817 | /* maybe we're not even in the list of peers? */ |
864 | share->my_peer = share->num_peers; | 818 | share->my_peer = share->num_peers; |
@@ -907,7 +861,8 @@ keygen_round2_conclude (void *cls) | |||
907 | GNUNET_SECRETSHARING_share_destroy (share); | 861 | GNUNET_SECRETSHARING_share_destroy (share); |
908 | share = NULL; | 862 | share = NULL; |
909 | 863 | ||
910 | GNUNET_MQ_send (ks->client_mq, ev); | 864 | GNUNET_MQ_send (ks->cs->mq, |
865 | ev); | ||
911 | } | 866 | } |
912 | 867 | ||
913 | 868 | ||
@@ -1429,9 +1384,9 @@ keygen_round2_new_element (void *cls, | |||
1429 | if (element->size != expected_element_size) | 1384 | if (element->size != expected_element_size) |
1430 | { | 1385 | { |
1431 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 1386 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
1432 | "keygen round2 data with wrong size (%u) in consensus, " | 1387 | "keygen round2 data with wrong size (%u) in consensus, %u expected\n", |
1433 | " %lu expected\n", | 1388 | (unsigned int) element->size, |
1434 | element->size, expected_element_size); | 1389 | (unsigned int) expected_element_size); |
1435 | return; | 1390 | return; |
1436 | } | 1391 | } |
1437 | 1392 | ||
@@ -1669,73 +1624,102 @@ insert_round1_element (struct KeygenSession *ks) | |||
1669 | 1624 | ||
1670 | 1625 | ||
1671 | /** | 1626 | /** |
1627 | * Check that @a msg is well-formed. | ||
1628 | * | ||
1629 | * @param cls identification of the client | ||
1630 | * @param msg the actual message | ||
1631 | * @return #GNUNET_OK if @a msg is well-formed | ||
1632 | */ | ||
1633 | static int | ||
1634 | check_client_keygen (void *cls, | ||
1635 | const struct GNUNET_SECRETSHARING_CreateMessage *msg) | ||
1636 | { | ||
1637 | unsigned int num_peers = ntohs (msg->num_peers); | ||
1638 | |||
1639 | if (ntohs (msg->header.size) - sizeof (*msg) != | ||
1640 | num_peers * sizeof (struct GNUNET_PeerIdentity)) | ||
1641 | { | ||
1642 | GNUNET_break (0); | ||
1643 | return GNUNET_SYSERR; | ||
1644 | } | ||
1645 | return GNUNET_OK; | ||
1646 | } | ||
1647 | |||
1648 | |||
1649 | /** | ||
1672 | * Functions with this signature are called whenever a message is | 1650 | * Functions with this signature are called whenever a message is |
1673 | * received. | 1651 | * received. |
1674 | * | 1652 | * |
1675 | * @param cls closure | 1653 | * @param cls identification of the client |
1676 | * @param client identification of the client | 1654 | * @param msg the actual message |
1677 | * @param message the actual message | ||
1678 | */ | 1655 | */ |
1679 | static void handle_client_keygen (void *cls, | 1656 | static void |
1680 | struct GNUNET_SERVER_Client *client, | 1657 | handle_client_keygen (void *cls, |
1681 | const struct GNUNET_MessageHeader | 1658 | const struct GNUNET_SECRETSHARING_CreateMessage *msg) |
1682 | *message) | ||
1683 | { | 1659 | { |
1684 | const struct GNUNET_SECRETSHARING_CreateMessage *msg = | 1660 | struct ClientState *cs = cls; |
1685 | (const struct GNUNET_SECRETSHARING_CreateMessage *) message; | ||
1686 | struct KeygenSession *ks; | 1661 | struct KeygenSession *ks; |
1687 | unsigned int i; | ||
1688 | |||
1689 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "client requested key generation\n"); | ||
1690 | 1662 | ||
1663 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
1664 | "client requested key generation\n"); | ||
1665 | if (NULL != cs->keygen_session) | ||
1666 | { | ||
1667 | GNUNET_break (0); | ||
1668 | GNUNET_SERVICE_client_drop (cs->client); | ||
1669 | return; | ||
1670 | } | ||
1691 | ks = GNUNET_new (struct KeygenSession); | 1671 | ks = GNUNET_new (struct KeygenSession); |
1692 | 1672 | ks->cs = cs; | |
1693 | /* FIXME: check if client already has some session */ | 1673 | cs->keygen_session = ks; |
1694 | |||
1695 | GNUNET_CONTAINER_DLL_insert (keygen_sessions_head, keygen_sessions_tail, ks); | ||
1696 | |||
1697 | ks->client = client; | ||
1698 | ks->client_mq = GNUNET_MQ_queue_for_server_client (client); | ||
1699 | |||
1700 | ks->deadline = GNUNET_TIME_absolute_ntoh (msg->deadline); | 1674 | ks->deadline = GNUNET_TIME_absolute_ntoh (msg->deadline); |
1701 | ks->threshold = ntohs (msg->threshold); | 1675 | ks->threshold = ntohs (msg->threshold); |
1702 | ks->num_peers = ntohs (msg->num_peers); | 1676 | ks->num_peers = ntohs (msg->num_peers); |
1703 | 1677 | ||
1704 | ks->peers = normalize_peers ((struct GNUNET_PeerIdentity *) &msg[1], ks->num_peers, | 1678 | ks->peers = normalize_peers ((struct GNUNET_PeerIdentity *) &msg[1], |
1705 | &ks->num_peers, &ks->local_peer_idx); | 1679 | ks->num_peers, |
1680 | &ks->num_peers, | ||
1681 | &ks->local_peer_idx); | ||
1706 | 1682 | ||
1707 | 1683 | ||
1708 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "first round of consensus with %u peers\n", ks->num_peers); | 1684 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
1709 | ks->consensus = GNUNET_CONSENSUS_create (cfg, ks->num_peers, ks->peers, &msg->session_id, | 1685 | "first round of consensus with %u peers\n", |
1686 | ks->num_peers); | ||
1687 | ks->consensus = GNUNET_CONSENSUS_create (cfg, | ||
1688 | ks->num_peers, | ||
1689 | ks->peers, | ||
1690 | &msg->session_id, | ||
1710 | GNUNET_TIME_absolute_ntoh (msg->start), | 1691 | GNUNET_TIME_absolute_ntoh (msg->start), |
1711 | GNUNET_TIME_absolute_ntoh (msg->deadline), | 1692 | GNUNET_TIME_absolute_ntoh (msg->deadline), |
1712 | keygen_round1_new_element, ks); | 1693 | keygen_round1_new_element, |
1694 | ks); | ||
1713 | 1695 | ||
1714 | ks->info = GNUNET_new_array (ks->num_peers, struct KeygenPeerInfo); | 1696 | ks->info = GNUNET_new_array (ks->num_peers, |
1697 | struct KeygenPeerInfo); | ||
1715 | 1698 | ||
1716 | for (i = 0; i < ks->num_peers; i++) | 1699 | for (unsigned int i = 0; i < ks->num_peers; i++) |
1717 | ks->info[i].peer = ks->peers[i]; | 1700 | ks->info[i].peer = ks->peers[i]; |
1718 | 1701 | ||
1719 | GNUNET_CRYPTO_paillier_create (&ks->info[ks->local_peer_idx].paillier_public_key, | 1702 | GNUNET_CRYPTO_paillier_create (&ks->info[ks->local_peer_idx].paillier_public_key, |
1720 | &ks->paillier_private_key); | 1703 | &ks->paillier_private_key); |
1721 | 1704 | ||
1722 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "P%u: Generated paillier key pair\n", ks->local_peer_idx); | 1705 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1723 | 1706 | "P%u: Generated paillier key pair\n", | |
1707 | ks->local_peer_idx); | ||
1724 | generate_presecret_polynomial (ks); | 1708 | generate_presecret_polynomial (ks); |
1725 | 1709 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | |
1726 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "P%u: Generated presecret polynomial\n", ks->local_peer_idx); | 1710 | "P%u: Generated presecret polynomial\n", |
1727 | 1711 | ks->local_peer_idx); | |
1728 | insert_round1_element (ks); | 1712 | insert_round1_element (ks); |
1729 | 1713 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | |
1730 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "P%u: Concluding for round 1\n", ks->local_peer_idx); | 1714 | "P%u: Concluding for round 1\n", |
1731 | 1715 | ks->local_peer_idx); | |
1732 | GNUNET_CONSENSUS_conclude (ks->consensus, | 1716 | GNUNET_CONSENSUS_conclude (ks->consensus, |
1733 | keygen_round1_conclude, | 1717 | keygen_round1_conclude, |
1734 | ks); | 1718 | ks); |
1735 | 1719 | GNUNET_SERVICE_client_continue (cs->client); | |
1736 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 1720 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1737 | 1721 | "P%u: Waiting for round 1 elements ...\n", | |
1738 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "P%u: Waiting for round 1 elements ...\n", ks->local_peer_idx); | 1722 | ks->local_peer_idx); |
1739 | } | 1723 | } |
1740 | 1724 | ||
1741 | 1725 | ||
@@ -1771,20 +1755,24 @@ decrypt_conclude (void *cls) | |||
1771 | if (NULL != ds->info[i].partial_decryption) | 1755 | if (NULL != ds->info[i].partial_decryption) |
1772 | num++; | 1756 | num++; |
1773 | 1757 | ||
1774 | indices = GNUNET_malloc (num * sizeof (unsigned int)); | 1758 | indices = GNUNET_new_array (num, |
1759 | unsigned int); | ||
1775 | j = 0; | 1760 | j = 0; |
1776 | for (i = 0; i < ds->share->num_peers; i++) | 1761 | for (i = 0; i < ds->share->num_peers; i++) |
1777 | if (NULL != ds->info[i].partial_decryption) | 1762 | if (NULL != ds->info[i].partial_decryption) |
1778 | indices[j++] = ds->info[i].original_index; | 1763 | indices[j++] = ds->info[i].original_index; |
1779 | 1764 | ||
1780 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "P%u: decrypt conclude, with %u peers\n", | 1765 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
1781 | ds->share->my_peer, num); | 1766 | "P%u: decrypt conclude, with %u peers\n", |
1767 | ds->share->my_peer, | ||
1768 | num); | ||
1782 | 1769 | ||
1783 | gcry_mpi_set_ui (prod, 1); | 1770 | gcry_mpi_set_ui (prod, 1); |
1784 | for (i = 0; i < num; i++) | 1771 | for (i = 0; i < num; i++) |
1785 | { | 1772 | { |
1786 | 1773 | ||
1787 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "P%u: index of %u: %u\n", | 1774 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
1775 | "P%u: index of %u: %u\n", | ||
1788 | ds->share->my_peer, i, indices[i]); | 1776 | ds->share->my_peer, i, indices[i]); |
1789 | compute_lagrange_coefficient (lagrange, indices[i], indices, num); | 1777 | compute_lagrange_coefficient (lagrange, indices[i], indices, num); |
1790 | // w_i^{\lambda_i} | 1778 | // w_i^{\lambda_i} |
@@ -1801,7 +1789,8 @@ decrypt_conclude (void *cls) | |||
1801 | ev = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_SECRETSHARING_CLIENT_DECRYPT_DONE); | 1789 | ev = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_SECRETSHARING_CLIENT_DECRYPT_DONE); |
1802 | GNUNET_CRYPTO_mpi_print_unsigned (&msg->plaintext, GNUNET_SECRETSHARING_ELGAMAL_BITS / 8, m); | 1790 | GNUNET_CRYPTO_mpi_print_unsigned (&msg->plaintext, GNUNET_SECRETSHARING_ELGAMAL_BITS / 8, m); |
1803 | msg->success = htonl (1); | 1791 | msg->success = htonl (1); |
1804 | GNUNET_MQ_send (ds->client_mq, ev); | 1792 | GNUNET_MQ_send (ds->cs->mq, |
1793 | ev); | ||
1805 | 1794 | ||
1806 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "sent decrypt done to client\n"); | 1795 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "sent decrypt done to client\n"); |
1807 | 1796 | ||
@@ -1945,10 +1934,15 @@ decrypt_new_element (void *cls, | |||
1945 | { | 1934 | { |
1946 | char *tmp1_str; | 1935 | char *tmp1_str; |
1947 | char *tmp2_str; | 1936 | char *tmp2_str; |
1937 | |||
1948 | tmp1_str = mpi_to_str (tmp1); | 1938 | tmp1_str = mpi_to_str (tmp1); |
1949 | tmp2_str = mpi_to_str (tmp2); | 1939 | tmp2_str = mpi_to_str (tmp2); |
1950 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "P%u: Received invalid partial decryption from P%ld (eqn 1), expected %s got %s\n", | 1940 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
1951 | session->share->my_peer, info - session->info, tmp1_str, tmp2_str); | 1941 | "P%u: Received invalid partial decryption from P%u (eqn 1), expected %s got %s\n", |
1942 | session->share->my_peer, | ||
1943 | (unsigned int) (info - session->info), | ||
1944 | tmp1_str, | ||
1945 | tmp2_str); | ||
1952 | GNUNET_free (tmp1_str); | 1946 | GNUNET_free (tmp1_str); |
1953 | GNUNET_free (tmp2_str); | 1947 | GNUNET_free (tmp2_str); |
1954 | goto cleanup; | 1948 | goto cleanup; |
@@ -1963,8 +1957,10 @@ decrypt_new_element (void *cls, | |||
1963 | 1957 | ||
1964 | if (0 != gcry_mpi_cmp (tmp1, tmp2)) | 1958 | if (0 != gcry_mpi_cmp (tmp1, tmp2)) |
1965 | { | 1959 | { |
1966 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "P%u: Received invalid partial decryption from P%ld (eqn 2)\n", | 1960 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
1967 | session->share->my_peer, info - session->info); | 1961 | "P%u: Received invalid partial decryption from P%u (eqn 2)\n", |
1962 | session->share->my_peer, | ||
1963 | (unsigned int) (info - session->info)); | ||
1968 | goto cleanup; | 1964 | goto cleanup; |
1969 | } | 1965 | } |
1970 | 1966 | ||
@@ -2100,40 +2096,63 @@ insert_decrypt_element (struct DecryptSession *ds) | |||
2100 | 2096 | ||
2101 | 2097 | ||
2102 | /** | 2098 | /** |
2099 | * Check that @a msg is well-formed. | ||
2100 | * | ||
2101 | * @param cls identification of the client | ||
2102 | * @param msg the actual message | ||
2103 | * @return #GNUNET_OK (check deferred a bit) | ||
2104 | */ | ||
2105 | static int | ||
2106 | check_client_decrypt (void *cls, | ||
2107 | const struct GNUNET_SECRETSHARING_DecryptRequestMessage *msg) | ||
2108 | { | ||
2109 | /* we check later, it's complicated */ | ||
2110 | return GNUNET_OK; | ||
2111 | } | ||
2112 | |||
2113 | |||
2114 | /** | ||
2103 | * Functions with this signature are called whenever a message is | 2115 | * Functions with this signature are called whenever a message is |
2104 | * received. | 2116 | * received. |
2105 | * | 2117 | * |
2106 | * @param cls closure | 2118 | * @param cls identification of the client |
2107 | * @param client identification of the client | 2119 | * @param msg the actual message |
2108 | * @param message the actual message | ||
2109 | */ | 2120 | */ |
2110 | static void handle_client_decrypt (void *cls, | 2121 | static void |
2111 | struct GNUNET_SERVER_Client *client, | 2122 | handle_client_decrypt (void *cls, |
2112 | const struct GNUNET_MessageHeader | 2123 | const struct GNUNET_SECRETSHARING_DecryptRequestMessage *msg) |
2113 | *message) | ||
2114 | { | 2124 | { |
2115 | const struct GNUNET_SECRETSHARING_DecryptRequestMessage *msg = | 2125 | struct ClientState *cs = cls; |
2116 | (const void *) message; | ||
2117 | struct DecryptSession *ds; | 2126 | struct DecryptSession *ds; |
2118 | struct GNUNET_HashCode session_id; | 2127 | struct GNUNET_HashCode session_id; |
2119 | unsigned int i; | ||
2120 | 2128 | ||
2129 | if (NULL != cs->decrypt_session) | ||
2130 | { | ||
2131 | GNUNET_break (0); | ||
2132 | GNUNET_SERVICE_client_drop (cs->client); | ||
2133 | return; | ||
2134 | } | ||
2121 | ds = GNUNET_new (struct DecryptSession); | 2135 | ds = GNUNET_new (struct DecryptSession); |
2122 | // FIXME: check if session already exists | 2136 | cs->decrypt_session = ds; |
2123 | GNUNET_CONTAINER_DLL_insert (decrypt_sessions_head, decrypt_sessions_tail, ds); | 2137 | ds->cs = cs; |
2124 | ds->client = client; | ||
2125 | ds->client_mq = GNUNET_MQ_queue_for_server_client (client); | ||
2126 | ds->start = GNUNET_TIME_absolute_ntoh (msg->start); | 2138 | ds->start = GNUNET_TIME_absolute_ntoh (msg->start); |
2127 | ds->deadline = GNUNET_TIME_absolute_ntoh (msg->deadline); | 2139 | ds->deadline = GNUNET_TIME_absolute_ntoh (msg->deadline); |
2128 | ds->ciphertext = msg->ciphertext; | 2140 | ds->ciphertext = msg->ciphertext; |
2129 | 2141 | ||
2130 | ds->share = GNUNET_SECRETSHARING_share_read (&msg[1], ntohs (msg->header.size) - sizeof *msg, NULL); | 2142 | ds->share = GNUNET_SECRETSHARING_share_read (&msg[1], |
2131 | // FIXME: probably should be break rather than assert | 2143 | ntohs (msg->header.size) - sizeof (*msg), |
2132 | GNUNET_assert (NULL != ds->share); | 2144 | NULL); |
2133 | 2145 | if (NULL == ds->share) | |
2134 | // FIXME: this is probably sufficient, but kdf/hash with all values would be nicer ... | 2146 | { |
2135 | GNUNET_CRYPTO_hash (&msg->ciphertext, sizeof (struct GNUNET_SECRETSHARING_Ciphertext), &session_id); | 2147 | GNUNET_break (0); |
2148 | GNUNET_SERVICE_client_drop (cs->client); | ||
2149 | return; | ||
2150 | } | ||
2136 | 2151 | ||
2152 | /* FIXME: this is probably sufficient, but kdf/hash with all values would be nicer ... */ | ||
2153 | GNUNET_CRYPTO_hash (&msg->ciphertext, | ||
2154 | sizeof (struct GNUNET_SECRETSHARING_Ciphertext), | ||
2155 | &session_id); | ||
2137 | ds->consensus = GNUNET_CONSENSUS_create (cfg, | 2156 | ds->consensus = GNUNET_CONSENSUS_create (cfg, |
2138 | ds->share->num_peers, | 2157 | ds->share->num_peers, |
2139 | ds->share->peers, | 2158 | ds->share->peers, |
@@ -2144,20 +2163,20 @@ static void handle_client_decrypt (void *cls, | |||
2144 | ds); | 2163 | ds); |
2145 | 2164 | ||
2146 | 2165 | ||
2147 | ds->info = GNUNET_new_array (ds->share->num_peers, struct DecryptPeerInfo); | 2166 | ds->info = GNUNET_new_array (ds->share->num_peers, |
2148 | for (i = 0; i < ds->share->num_peers; i++) | 2167 | struct DecryptPeerInfo); |
2168 | for (unsigned int i = 0; i < ds->share->num_peers; i++) | ||
2149 | { | 2169 | { |
2150 | ds->info[i].peer = ds->share->peers[i]; | 2170 | ds->info[i].peer = ds->share->peers[i]; |
2151 | ds->info[i].original_index = ds->share->original_indices[i]; | 2171 | ds->info[i].original_index = ds->share->original_indices[i]; |
2152 | } | 2172 | } |
2153 | |||
2154 | insert_decrypt_element (ds); | 2173 | insert_decrypt_element (ds); |
2155 | 2174 | GNUNET_CONSENSUS_conclude (ds->consensus, | |
2156 | GNUNET_CONSENSUS_conclude (ds->consensus, decrypt_conclude, ds); | 2175 | decrypt_conclude, |
2157 | 2176 | ds); | |
2158 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 2177 | GNUNET_SERVICE_client_continue (cs->client); |
2159 | 2178 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | |
2160 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "decrypting with %u peers\n", | 2179 | "decrypting with %u peers\n", |
2161 | ds->share->num_peers); | 2180 | ds->share->num_peers); |
2162 | } | 2181 | } |
2163 | 2182 | ||
@@ -2174,103 +2193,104 @@ init_crypto_constants (void) | |||
2174 | } | 2193 | } |
2175 | 2194 | ||
2176 | 2195 | ||
2177 | static struct KeygenSession * | ||
2178 | keygen_session_get (struct GNUNET_SERVER_Client *client) | ||
2179 | { | ||
2180 | struct KeygenSession *ks; | ||
2181 | for (ks = keygen_sessions_head; NULL != ks; ks = ks->next) | ||
2182 | if (ks->client == client) | ||
2183 | return ks; | ||
2184 | return NULL; | ||
2185 | } | ||
2186 | |||
2187 | static struct DecryptSession * | ||
2188 | decrypt_session_get (struct GNUNET_SERVER_Client *client) | ||
2189 | { | ||
2190 | struct DecryptSession *ds; | ||
2191 | for (ds = decrypt_sessions_head; NULL != ds; ds = ds->next) | ||
2192 | if (ds->client == client) | ||
2193 | return ds; | ||
2194 | return NULL; | ||
2195 | } | ||
2196 | |||
2197 | |||
2198 | /** | ||
2199 | * Clean up after a client has disconnected | ||
2200 | * | ||
2201 | * @param cls closure, unused | ||
2202 | * @param client the client to clean up after | ||
2203 | */ | ||
2204 | static void | ||
2205 | handle_client_disconnect (void *cls, struct GNUNET_SERVER_Client *client) | ||
2206 | { | ||
2207 | struct KeygenSession *ks; | ||
2208 | struct DecryptSession *ds; | ||
2209 | |||
2210 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "handling client disconnect\n"); | ||
2211 | |||
2212 | ks = keygen_session_get (client); | ||
2213 | if (NULL != ks) | ||
2214 | keygen_session_destroy (ks); | ||
2215 | |||
2216 | ds = decrypt_session_get (client); | ||
2217 | if (NULL != ds) | ||
2218 | decrypt_session_destroy (ds); | ||
2219 | } | ||
2220 | |||
2221 | |||
2222 | /** | 2196 | /** |
2223 | * Process template requests. | 2197 | * Initialize secretsharing service. |
2224 | * | 2198 | * |
2225 | * @param cls closure | 2199 | * @param cls closure |
2226 | * @param server the initialized server | ||
2227 | * @param c configuration to use | 2200 | * @param c configuration to use |
2201 | * @param service the initialized service | ||
2228 | */ | 2202 | */ |
2229 | static void | 2203 | static void |
2230 | run (void *cls, struct GNUNET_SERVER_Handle *server, | 2204 | run (void *cls, |
2231 | const struct GNUNET_CONFIGURATION_Handle *c) | 2205 | const struct GNUNET_CONFIGURATION_Handle *c, |
2206 | struct GNUNET_SERVICE_Handle *service) | ||
2232 | { | 2207 | { |
2233 | static const struct GNUNET_SERVER_MessageHandler handlers[] = { | ||
2234 | {handle_client_keygen, NULL, GNUNET_MESSAGE_TYPE_SECRETSHARING_CLIENT_GENERATE, 0}, | ||
2235 | {handle_client_decrypt, NULL, GNUNET_MESSAGE_TYPE_SECRETSHARING_CLIENT_DECRYPT, 0}, | ||
2236 | {NULL, NULL, 0, 0} | ||
2237 | }; | ||
2238 | cfg = c; | 2208 | cfg = c; |
2239 | srv = server; | ||
2240 | my_peer_private_key = GNUNET_CRYPTO_eddsa_key_create_from_configuration (c); | 2209 | my_peer_private_key = GNUNET_CRYPTO_eddsa_key_create_from_configuration (c); |
2241 | if (NULL == my_peer_private_key) | 2210 | if (NULL == my_peer_private_key) |
2242 | { | 2211 | { |
2243 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "could not access host private key\n"); | 2212 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
2213 | "could not access host private key\n"); | ||
2244 | GNUNET_break (0); | 2214 | GNUNET_break (0); |
2245 | GNUNET_SCHEDULER_shutdown (); | 2215 | GNUNET_SCHEDULER_shutdown (); |
2246 | return; | 2216 | return; |
2247 | } | 2217 | } |
2248 | init_crypto_constants (); | 2218 | init_crypto_constants (); |
2249 | if (GNUNET_OK != GNUNET_CRYPTO_get_peer_identity (cfg, &my_peer)) | 2219 | if (GNUNET_OK != |
2220 | GNUNET_CRYPTO_get_peer_identity (cfg, | ||
2221 | &my_peer)) | ||
2250 | { | 2222 | { |
2251 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "could not retrieve host identity\n"); | 2223 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
2224 | "could not retrieve host identity\n"); | ||
2252 | GNUNET_break (0); | 2225 | GNUNET_break (0); |
2253 | GNUNET_SCHEDULER_shutdown (); | 2226 | GNUNET_SCHEDULER_shutdown (); |
2254 | return; | 2227 | return; |
2255 | } | 2228 | } |
2256 | GNUNET_SERVER_add_handlers (server, handlers); | ||
2257 | GNUNET_SERVER_disconnect_notify (server, &handle_client_disconnect, NULL); | ||
2258 | GNUNET_SCHEDULER_add_shutdown (&cleanup_task, | 2229 | GNUNET_SCHEDULER_add_shutdown (&cleanup_task, |
2259 | NULL); | 2230 | NULL); |
2260 | } | 2231 | } |
2261 | 2232 | ||
2262 | 2233 | ||
2263 | /** | 2234 | /** |
2264 | * The main function for the template service. | 2235 | * Callback called when a client connects to the service. |
2236 | * | ||
2237 | * @param cls closure for the service | ||
2238 | * @param c the new client that connected to the service | ||
2239 | * @param mq the message queue used to send messages to the client | ||
2240 | * @return @a c | ||
2241 | */ | ||
2242 | static void * | ||
2243 | client_connect_cb (void *cls, | ||
2244 | struct GNUNET_SERVICE_Client *c, | ||
2245 | struct GNUNET_MQ_Handle *mq) | ||
2246 | { | ||
2247 | struct ClientState *cs = GNUNET_new (struct ClientState);; | ||
2248 | |||
2249 | cs->client = c; | ||
2250 | cs->mq = mq; | ||
2251 | return cs; | ||
2252 | } | ||
2253 | |||
2254 | |||
2255 | /** | ||
2256 | * Callback called when a client disconnected from the service | ||
2265 | * | 2257 | * |
2266 | * @param argc number of arguments from the command line | 2258 | * @param cls closure for the service |
2267 | * @param argv command line arguments | 2259 | * @param c the client that disconnected |
2268 | * @return 0 ok, 1 on error | 2260 | * @param internal_cls should be equal to @a c |
2269 | */ | 2261 | */ |
2270 | int | 2262 | static void |
2271 | main (int argc, char *const *argv) | 2263 | client_disconnect_cb (void *cls, |
2264 | struct GNUNET_SERVICE_Client *c, | ||
2265 | void *internal_cls) | ||
2272 | { | 2266 | { |
2273 | return (GNUNET_OK == | 2267 | struct ClientState *cs = internal_cls; |
2274 | GNUNET_SERVICE_run (argc, argv, "secretsharing", | 2268 | |
2275 | GNUNET_SERVICE_OPTION_NONE, &run, NULL)) ? 0 : 1; | 2269 | if (NULL != cs->keygen_session) |
2270 | keygen_session_destroy (cs->keygen_session); | ||
2271 | |||
2272 | if (NULL != cs->decrypt_session) | ||
2273 | decrypt_session_destroy (cs->decrypt_session); | ||
2274 | GNUNET_free (cs); | ||
2276 | } | 2275 | } |
2276 | |||
2277 | |||
2278 | /** | ||
2279 | * Define "main" method using service macro. | ||
2280 | */ | ||
2281 | GNUNET_SERVICE_MAIN | ||
2282 | ("secretsharing", | ||
2283 | GNUNET_SERVICE_OPTION_NONE, | ||
2284 | &run, | ||
2285 | &client_connect_cb, | ||
2286 | &client_disconnect_cb, | ||
2287 | NULL, | ||
2288 | GNUNET_MQ_hd_var_size (client_keygen, | ||
2289 | GNUNET_MESSAGE_TYPE_SECRETSHARING_CLIENT_GENERATE, | ||
2290 | struct GNUNET_SECRETSHARING_CreateMessage, | ||
2291 | NULL), | ||
2292 | GNUNET_MQ_hd_var_size (client_decrypt, | ||
2293 | GNUNET_MESSAGE_TYPE_SECRETSHARING_CLIENT_DECRYPT, | ||
2294 | struct GNUNET_SECRETSHARING_DecryptRequestMessage, | ||
2295 | NULL), | ||
2296 | GNUNET_MQ_handler_end ()); | ||