X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Fsecretsharing%2Fgnunet-service-secretsharing.c;h=d2e47da8b889bc78f54f240526aa4518a5efba3b;hb=7d28a76ad5f6fc5db4a207fbd81a31b70cdb3866;hp=a0e4400844a3e7183798b8a8cea97560c6f596a0;hpb=b8fc68d6cb81adb3803186359b3a30b1a4bb7b5a;p=oweals%2Fgnunet.git diff --git a/src/secretsharing/gnunet-service-secretsharing.c b/src/secretsharing/gnunet-service-secretsharing.c index a0e440084..d2e47da8b 100644 --- a/src/secretsharing/gnunet-service-secretsharing.c +++ b/src/secretsharing/gnunet-service-secretsharing.c @@ -1,22 +1,22 @@ /* This file is part of GNUnet. - (C) 2013 Christian Grothoff (and other contributing authors) + Copyright (C) 2013 GNUnet e.V. - GNUnet is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3, or (at your - option) any later version. + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. GNUnet is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. + Affero General Public License for more details. - You should have received a copy of the GNU General Public License - along with GNUnet; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. -*/ + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + + SPDX-License-Identifier: AGPL3.0-or-later + */ /** * @file secretsharing/gnunet-service-secretsharing.c @@ -53,7 +53,7 @@ struct KeygenPeerInfo struct GNUNET_CRYPTO_PaillierPublicKey paillier_public_key; /** - * The peer's commitment to his presecret. + * The peer's commitment to its presecret. */ gcry_mpi_t presecret_commitment; @@ -108,36 +108,26 @@ struct DecryptPeerInfo }; +/** + * State we keep per client. + */ +struct ClientState; + + /** * Session to establish a threshold-shared secret. */ struct KeygenSession { - /** - * Keygen sessions are held in a linked list. - */ - struct KeygenSession *next; - - /** - * Keygen sessions are held in a linked list. - */ - struct KeygenSession *prev; - /** * Current consensus, used for both DKG rounds. */ struct GNUNET_CONSENSUS_Handle *consensus; /** - * Client that is interested in the result - * of this key generation session. - */ - struct GNUNET_SERVER_Client *client; - - /** - * Message queue for 'client' + * Which client is this for? */ - struct GNUNET_MQ_Handle *client_mq; + struct ClientState *cs; /** * Randomly generated coefficients of the polynomial for sharing our @@ -223,30 +213,15 @@ struct KeygenSession */ struct DecryptSession { - /** - * Decrypt sessions are stored in a linked list. - */ - struct DecryptSession *next; - - /** - * Decrypt sessions are stored in a linked list. - */ - struct DecryptSession *prev; - /** * Handle to the consensus over partial decryptions. */ struct GNUNET_CONSENSUS_Handle *consensus; /** - * Client connected to us. + * Which client is this for? */ - struct GNUNET_SERVER_Client *client; - - /** - * Message queue for 'client'. - */ - struct GNUNET_MQ_Handle *client_mq; + struct ClientState *cs; /** * When should we start communicating for decryption? @@ -279,24 +254,31 @@ struct DecryptSession /** - * Decrypt sessions are held in a linked list. + * State we keep per client. */ -static struct DecryptSession *decrypt_sessions_head; +struct ClientState +{ + /** + * Decrypt session of the client, if any. + */ + struct DecryptSession *decrypt_session; -/** - * Decrypt sessions are held in a linked list. - */ -static struct DecryptSession *decrypt_sessions_tail; + /** + * Keygen session of the client, if any. + */ + struct KeygenSession *keygen_session; -/** - * Decrypt sessions are held in a linked list. - */ -static struct KeygenSession *keygen_sessions_head; + /** + * Client this is about. + */ + struct GNUNET_SERVICE_Client *client; + + /** + * MQ to talk to @a client. + */ + struct GNUNET_MQ_Handle *mq; +}; -/** - * Decrypt sessions are held in a linked list. - */ -static struct KeygenSession *keygen_sessions_tail; /** * The ElGamal prime field order as libgcrypt mpi. @@ -331,11 +313,6 @@ static struct GNUNET_CRYPTO_EddsaPrivateKey *my_peer_private_key; */ static const struct GNUNET_CONFIGURATION_Handle *cfg; -/** - * Server for this service. - */ -static struct GNUNET_SERVER_Handle *srv; - /** * Get the peer info belonging to a peer identity in a keygen session. @@ -349,8 +326,9 @@ get_keygen_peer_info (const struct KeygenSession *ks, const struct GNUNET_PeerIdentity *peer) { unsigned int i; + for (i = 0; i < ks->num_peers; i++) - if (0 == memcmp (peer, &ks->info[i].peer, sizeof (struct GNUNET_PeerIdentity))) + if (0 == GNUNET_memcmp (peer, &ks->info[i].peer)) return &ks->info[i]; return NULL; } @@ -368,8 +346,9 @@ get_decrypt_peer_info (const struct DecryptSession *ds, const struct GNUNET_PeerIdentity *peer) { unsigned int i; + for (i = 0; i < ds->share->num_peers; i++) - if (0 == memcmp (peer, &ds->info[i].peer, sizeof (struct GNUNET_PeerIdentity))) + if (0 == GNUNET_memcmp (peer, &ds->info[i].peer)) return &ds->info[i]; return NULL; } @@ -411,7 +390,7 @@ peer_id_cmp (const void *p1, const void *p2) { return memcmp (p1, p2, - sizeof (struct GNUNET_PeerIdentity)); + sizeof(struct GNUNET_PeerIdentity)); } @@ -431,9 +410,8 @@ peer_find (const struct GNUNET_PeerIdentity *haystack, unsigned int n, unsigned int i; for (i = 0; i < n; i++) - if (0 == memcmp (&haystack[i], - needle, - sizeof (struct GNUNET_PeerIdentity))) + if (0 == GNUNET_memcmp (&haystack[i], + needle)) return i; return -1; } @@ -468,17 +446,18 @@ normalize_peers (struct GNUNET_PeerIdentity *listed, n += 1; } - normalized = GNUNET_new_array (n, struct GNUNET_PeerIdentity); + normalized = GNUNET_new_array (n, + struct GNUNET_PeerIdentity); if (GNUNET_NO == local_peer_in_list) normalized[n - 1] = my_peer; - memcpy (normalized, - listed, - num_listed * sizeof (struct GNUNET_PeerIdentity)); + GNUNET_memcpy (normalized, + listed, + num_listed * sizeof(struct GNUNET_PeerIdentity)); qsort (normalized, n, - sizeof (struct GNUNET_PeerIdentity), + sizeof(struct GNUNET_PeerIdentity), &peer_id_cmp); if (NULL != my_peer_idx) @@ -558,10 +537,13 @@ compute_lagrange_coefficient (gcry_mpi_t coeff, unsigned int j, static void decrypt_session_destroy (struct DecryptSession *ds) { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "destroying decrypt session\n"); - - GNUNET_CONTAINER_DLL_remove (decrypt_sessions_head, decrypt_sessions_tail, ds); - + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "destroying decrypt session\n"); + if (NULL != ds->cs) + { + ds->cs->decrypt_session = NULL; + ds->cs = NULL; + } if (NULL != ds->consensus) { GNUNET_CONSENSUS_destroy (ds->consensus); @@ -570,8 +552,7 @@ decrypt_session_destroy (struct DecryptSession *ds) if (NULL != ds->info) { - unsigned int i; - for (i = 0; i < ds->share->num_peers; i++) + for (unsigned int i = 0; i < ds->share->num_peers; i++) { if (NULL != ds->info[i].partial_decryption) { @@ -582,29 +563,16 @@ decrypt_session_destroy (struct DecryptSession *ds) GNUNET_free (ds->info); ds->info = NULL; } - if (NULL != ds->share) { GNUNET_SECRETSHARING_share_destroy (ds->share); ds->share = NULL; } - if (NULL != ds->client_mq) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "destroying decrypt MQ\n"); - GNUNET_MQ_destroy (ds->client_mq); - ds->client_mq = NULL; - } - - if (NULL != ds->client) - { - GNUNET_SERVER_client_disconnect (ds->client); - ds->client = NULL; - } - GNUNET_free (ds); } + static void keygen_info_destroy (struct KeygenPeerInfo *info) { @@ -621,7 +589,7 @@ keygen_info_destroy (struct KeygenPeerInfo *info) if (NULL != info->preshare_commitment) { gcry_mpi_release (info->preshare_commitment); - info->presecret_commitment = NULL; + info->preshare_commitment = NULL; } } @@ -629,14 +597,17 @@ keygen_info_destroy (struct KeygenPeerInfo *info) static void keygen_session_destroy (struct KeygenSession *ks) { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "destroying keygen session\n"); - - GNUNET_CONTAINER_DLL_remove (keygen_sessions_head, keygen_sessions_tail, ks); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "destroying keygen session\n"); + if (NULL != ks->cs) + { + ks->cs->keygen_session = NULL; + ks->cs = NULL; + } if (NULL != ks->info) { - unsigned int i; - for (i = 0; i < ks->num_peers; i++) + for (unsigned int i = 0; i < ks->num_peers; i++) keygen_info_destroy (&ks->info[i]); GNUNET_free (ks->info); ks->info = NULL; @@ -650,8 +621,7 @@ keygen_session_destroy (struct KeygenSession *ks) if (NULL != ks->presecret_polynomial) { - unsigned int i; - for (i = 0; i < ks->threshold; i++) + for (unsigned int i = 0; i < ks->threshold; i++) { GNUNET_assert (NULL != ks->presecret_polynomial[i]); gcry_mpi_release (ks->presecret_polynomial[i]); @@ -660,38 +630,21 @@ keygen_session_destroy (struct KeygenSession *ks) GNUNET_free (ks->presecret_polynomial); ks->presecret_polynomial = NULL; } - - if (NULL != ks->client_mq) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "destroying keygen MQ\n"); - GNUNET_MQ_destroy (ks->client_mq); - ks->client_mq = NULL; - } - if (NULL != ks->my_share) { gcry_mpi_release (ks->my_share); ks->my_share = NULL; } - if (NULL != ks->public_key) { gcry_mpi_release (ks->public_key); ks->public_key = NULL; } - if (NULL != ks->peers) { GNUNET_free (ks->peers); ks->peers = NULL; } - - if (NULL != ks->client) - { - GNUNET_SERVER_client_disconnect (ks->client); - ks->client = NULL; - } - GNUNET_free (ks); } @@ -703,17 +656,12 @@ keygen_session_destroy (struct KeygenSession *ks) * @param tc unused */ static void -cleanup_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +cleanup_task (void *cls) { - while (NULL != decrypt_sessions_head) - decrypt_session_destroy (decrypt_sessions_head); - - while (NULL != keygen_sessions_head) - keygen_session_destroy (keygen_sessions_head); + /* Nothing to do! */ } - /** * Generate the random coefficients of our pre-secret polynomial * @@ -726,17 +674,21 @@ generate_presecret_polynomial (struct KeygenSession *ks) gcry_mpi_t v; GNUNET_assert (NULL == ks->presecret_polynomial); - ks->presecret_polynomial = GNUNET_new_array (ks->threshold, gcry_mpi_t); + ks->presecret_polynomial = GNUNET_new_array (ks->threshold, + gcry_mpi_t); for (i = 0; i < ks->threshold; i++) { - v = ks->presecret_polynomial[i] = gcry_mpi_new (GNUNET_SECRETSHARING_ELGAMAL_BITS); + v = ks->presecret_polynomial[i] = gcry_mpi_new ( + GNUNET_SECRETSHARING_ELGAMAL_BITS); GNUNET_assert (NULL != v); // Randomize v such that 0 < v < elgamal_q. // The '- 1' is necessary as bitlength(q) = bitlength(p) - 1. do { - gcry_mpi_randomize (v, GNUNET_SECRETSHARING_ELGAMAL_BITS - 1, GCRY_WEAK_RANDOM); - } while ((gcry_mpi_cmp_ui (v, 0) == 0) || (gcry_mpi_cmp (v, elgamal_q) >= 0)); + gcry_mpi_randomize (v, GNUNET_SECRETSHARING_ELGAMAL_BITS - 1, + GCRY_WEAK_RANDOM); + } + while ((gcry_mpi_cmp_ui (v, 0) == 0) || (gcry_mpi_cmp (v, elgamal_q) >= 0)); } } @@ -764,12 +716,13 @@ keygen_round1_new_element (void *cls, } /* elements have fixed size */ - if (element->size != sizeof (struct GNUNET_SECRETSHARING_KeygenCommitData)) + if (element->size != sizeof(struct GNUNET_SECRETSHARING_KeygenCommitData)) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "keygen commit data with wrong size (%u) in consensus, " - " %u expected\n", - element->size, sizeof (struct GNUNET_SECRETSHARING_KeygenCommitData)); + "keygen commit data with wrong size (%u) in consensus, %u expected\n", + (unsigned int) element->size, + (unsigned int) sizeof(struct + GNUNET_SECRETSHARING_KeygenCommitData)); return; } @@ -780,27 +733,35 @@ keygen_round1_new_element (void *cls, if (NULL == info) { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "keygen commit data with wrong peer identity (%s) in consensus\n", + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "keygen commit data with wrong peer identity (%s) in consensus\n", GNUNET_i2s (&d->peer)); return; } /* Check that the right amount of data has been signed. */ if (d->purpose.size != - htonl (element->size - offsetof (struct GNUNET_SECRETSHARING_KeygenCommitData, purpose))) + htonl (element->size - offsetof (struct + GNUNET_SECRETSHARING_KeygenCommitData, + purpose))) { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "keygen commit data with wrong signature purpose size in consensus\n"); + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "keygen commit data with wrong signature purpose size in consensus\n"); return; } - if (GNUNET_OK != GNUNET_CRYPTO_eddsa_verify (GNUNET_SIGNATURE_PURPOSE_SECRETSHARING_DKG1, - &d->purpose, &d->signature, &d->peer.public_key)) + if (GNUNET_OK != GNUNET_CRYPTO_eddsa_verify ( + GNUNET_SIGNATURE_PURPOSE_SECRETSHARING_DKG1, + &d->purpose, &d->signature, + &d->peer.public_key)) { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "keygen commit data with invalid signature in consensus\n"); + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "keygen commit data with invalid signature in consensus\n"); return; } info->paillier_public_key = d->pubkey; - GNUNET_CRYPTO_mpi_scan_unsigned (&info->presecret_commitment, &d->commitment, 512 / 8); + GNUNET_CRYPTO_mpi_scan_unsigned (&info->presecret_commitment, &d->commitment, + 512 / 8); info->round1_valid = GNUNET_YES; } @@ -816,7 +777,8 @@ keygen_round1_new_element (void *cls, * @param m what group are we operating in? */ static void -horner_eval (gcry_mpi_t z, gcry_mpi_t *coeff, unsigned int num_coeff, gcry_mpi_t x, gcry_mpi_t m) +horner_eval (gcry_mpi_t z, gcry_mpi_t *coeff, unsigned int num_coeff, gcry_mpi_t + x, gcry_mpi_t m) { unsigned int i; @@ -854,10 +816,13 @@ keygen_round2_conclude (void *cls) if (GNUNET_YES == ks->info[i].round2_valid) share->num_peers++; - share->peers = GNUNET_new_array (share->num_peers, struct GNUNET_PeerIdentity); + share->peers = GNUNET_new_array (share->num_peers, + struct GNUNET_PeerIdentity); share->sigmas = - GNUNET_new_array (share->num_peers, struct GNUNET_SECRETSHARING_FieldElement); - share->original_indices = GNUNET_new_array (share->num_peers, uint16_t); + GNUNET_new_array (share->num_peers, + struct GNUNET_SECRETSHARING_FieldElement); + share->original_indices = GNUNET_new_array (share->num_peers, + uint16_t); /* maybe we're not even in the list of peers? */ share->my_peer = share->num_peers; @@ -872,7 +837,7 @@ keygen_round2_conclude (void *cls) GNUNET_SECRETSHARING_ELGAMAL_BITS / 8, ks->info[i].sigma); share->original_indices[i] = j; - if (0 == memcmp (&share->peers[i], &my_peer, sizeof (struct GNUNET_PeerIdentity))) + if (0 == GNUNET_memcmp (&share->peers[i], &my_peer)) share->my_peer = j; j += 1; } @@ -880,20 +845,25 @@ keygen_round2_conclude (void *cls) if (share->my_peer == share->num_peers) { - GNUNET_log (GNUNET_ERROR_TYPE_INFO, "P%u: peer identity not in share\n", ks->local_peer_idx); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "P%u: peer identity not in share\n", + ks->local_peer_idx); } - GNUNET_CRYPTO_mpi_print_unsigned (&share->my_share, GNUNET_SECRETSHARING_ELGAMAL_BITS / 8, + GNUNET_CRYPTO_mpi_print_unsigned (&share->my_share, + GNUNET_SECRETSHARING_ELGAMAL_BITS / 8, ks->my_share); - GNUNET_CRYPTO_mpi_print_unsigned (&share->public_key, GNUNET_SECRETSHARING_ELGAMAL_BITS / 8, + GNUNET_CRYPTO_mpi_print_unsigned (&share->public_key, + GNUNET_SECRETSHARING_ELGAMAL_BITS / 8, ks->public_key); - GNUNET_log (GNUNET_ERROR_TYPE_INFO, "keygen completed with %u peers\n", share->num_peers); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "keygen completed with %u peers\n", + share->num_peers); /* Write the share. If 0 peers completed the dkg, an empty * share will be sent. */ - GNUNET_assert (GNUNET_OK == GNUNET_SECRETSHARING_share_write (share, NULL, 0, &share_size)); + GNUNET_assert (GNUNET_OK == GNUNET_SECRETSHARING_share_write (share, NULL, 0, + &share_size)); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "writing share of size %u\n", (unsigned int) share_size); @@ -901,16 +871,18 @@ keygen_round2_conclude (void *cls) ev = GNUNET_MQ_msg_extra (m, share_size, GNUNET_MESSAGE_TYPE_SECRETSHARING_CLIENT_SECRET_READY); - GNUNET_assert (GNUNET_OK == GNUNET_SECRETSHARING_share_write (share, &m[1], share_size, NULL)); + GNUNET_assert (GNUNET_OK == GNUNET_SECRETSHARING_share_write (share, &m[1], + share_size, + NULL)); GNUNET_SECRETSHARING_share_destroy (share); share = NULL; - GNUNET_MQ_send (ks->client_mq, ev); + GNUNET_MQ_send (ks->cs->mq, + ev); } - static void restore_fair (const struct GNUNET_CRYPTO_PaillierPublicKey *ppub, const struct GNUNET_SECRETSHARING_FairEncryption *fe, @@ -942,7 +914,10 @@ restore_fair (const struct GNUNET_CRYPTO_PaillierPublicKey *ppub, GNUNET_assert (NULL != (big_b = gcry_mpi_new (0))); // a = (N,0)^T - GNUNET_CRYPTO_mpi_scan_unsigned (&a_1, ppub, sizeof (struct GNUNET_CRYPTO_PaillierPublicKey)); + GNUNET_CRYPTO_mpi_scan_unsigned (&a_1, + ppub, + sizeof(struct + GNUNET_CRYPTO_PaillierPublicKey)); GNUNET_assert (NULL != (a_2 = gcry_mpi_new (0))); gcry_mpi_set_ui (a_2, 0); // b = (x,1)^T @@ -1001,15 +976,9 @@ restore_fair (const struct GNUNET_CRYPTO_PaillierPublicKey *ppub, gcry_mpi_set (big_b, big_t); } - { - gcry_mpi_t paillier_n; - - GNUNET_CRYPTO_mpi_scan_unsigned (&paillier_n, ppub, sizeof (struct GNUNET_CRYPTO_PaillierPublicKey)); - - gcry_mpi_set (xres, b_2); - gcry_mpi_invm (xres, xres, elgamal_q); - gcry_mpi_mulm (xres, xres, b_1, elgamal_q); - } + gcry_mpi_set (xres, b_2); + gcry_mpi_invm (xres, xres, elgamal_q); + gcry_mpi_mulm (xres, xres, b_1, elgamal_q); gcry_mpi_release (a_1); gcry_mpi_release (a_2); @@ -1028,9 +997,12 @@ restore_fair (const struct GNUNET_CRYPTO_PaillierPublicKey *ppub, static void -get_fair_encryption_challenge (const struct GNUNET_SECRETSHARING_FairEncryption *fe, gcry_mpi_t e) +get_fair_encryption_challenge (const struct + GNUNET_SECRETSHARING_FairEncryption *fe, + gcry_mpi_t *e) { - struct { + struct + { struct GNUNET_CRYPTO_PaillierCiphertext c; char h[GNUNET_SECRETSHARING_ELGAMAL_BITS / 8]; char t1[GNUNET_SECRETSHARING_ELGAMAL_BITS / 8]; @@ -1038,18 +1010,28 @@ get_fair_encryption_challenge (const struct GNUNET_SECRETSHARING_FairEncryption } hash_data; struct GNUNET_HashCode e_hash; - memcpy (&hash_data.c, &fe->c, sizeof (struct GNUNET_CRYPTO_PaillierCiphertext)); - memcpy (&hash_data.h, &fe->h, GNUNET_SECRETSHARING_ELGAMAL_BITS / 8); - memcpy (&hash_data.t1, &fe->t1, GNUNET_SECRETSHARING_ELGAMAL_BITS / 8); - memcpy (&hash_data.t2, &fe->t2, GNUNET_CRYPTO_PAILLIER_BITS * 2 / 8); - - GNUNET_CRYPTO_mpi_scan_unsigned (&e, &e_hash, sizeof (struct GNUNET_HashCode)); - gcry_mpi_mod (e, e, elgamal_q); + memset (&hash_data, + 0, + sizeof(hash_data)); + GNUNET_memcpy (&hash_data.c, &fe->c, sizeof(struct + GNUNET_CRYPTO_PaillierCiphertext)); + GNUNET_memcpy (&hash_data.h, &fe->h, GNUNET_SECRETSHARING_ELGAMAL_BITS / 8); + GNUNET_memcpy (&hash_data.t1, &fe->t1, GNUNET_SECRETSHARING_ELGAMAL_BITS / 8); + GNUNET_memcpy (&hash_data.t2, &fe->t2, GNUNET_CRYPTO_PAILLIER_BITS * 2 / 8); + GNUNET_CRYPTO_hash (&hash_data, + sizeof(hash_data), + &e_hash); + /* This allocates "e" */ + GNUNET_CRYPTO_mpi_scan_unsigned (e, + &e_hash, + sizeof(struct GNUNET_HashCode)); + gcry_mpi_mod (*e, *e, elgamal_q); } static int -verify_fair (const struct GNUNET_CRYPTO_PaillierPublicKey *ppub, const struct GNUNET_SECRETSHARING_FairEncryption *fe) +verify_fair (const struct GNUNET_CRYPTO_PaillierPublicKey *ppub, + const struct GNUNET_SECRETSHARING_FairEncryption *fe) { gcry_mpi_t n; gcry_mpi_t n_sq; @@ -1067,17 +1049,25 @@ verify_fair (const struct GNUNET_CRYPTO_PaillierPublicKey *ppub, const struct GN GNUNET_assert (NULL != (n_sq = gcry_mpi_new (0))); GNUNET_assert (NULL != (tmp1 = gcry_mpi_new (0))); GNUNET_assert (NULL != (tmp2 = gcry_mpi_new (0))); - GNUNET_assert (NULL != (e = gcry_mpi_new (0))); - get_fair_encryption_challenge (fe, e); + get_fair_encryption_challenge (fe, + &e /* this allocates e */); - GNUNET_CRYPTO_mpi_scan_unsigned (&n, ppub, sizeof (struct GNUNET_CRYPTO_PaillierPublicKey)); - GNUNET_CRYPTO_mpi_scan_unsigned (&t1, fe->t1, GNUNET_CRYPTO_PAILLIER_BITS / 8); - GNUNET_CRYPTO_mpi_scan_unsigned (&z, fe->z, GNUNET_SECRETSHARING_ELGAMAL_BITS / 8); - GNUNET_CRYPTO_mpi_scan_unsigned (&y, fe->h, GNUNET_SECRETSHARING_ELGAMAL_BITS / 8); + GNUNET_CRYPTO_mpi_scan_unsigned (&n, + ppub, + sizeof(struct + GNUNET_CRYPTO_PaillierPublicKey)); + GNUNET_CRYPTO_mpi_scan_unsigned (&t1, fe->t1, GNUNET_CRYPTO_PAILLIER_BITS + / 8); + GNUNET_CRYPTO_mpi_scan_unsigned (&z, fe->z, + GNUNET_SECRETSHARING_ELGAMAL_BITS / 8); + GNUNET_CRYPTO_mpi_scan_unsigned (&y, fe->h, + GNUNET_SECRETSHARING_ELGAMAL_BITS / 8); GNUNET_CRYPTO_mpi_scan_unsigned (&w, fe->w, GNUNET_CRYPTO_PAILLIER_BITS / 8); - GNUNET_CRYPTO_mpi_scan_unsigned (&big_y, fe->c.bits, GNUNET_CRYPTO_PAILLIER_BITS * 2 / 8); - GNUNET_CRYPTO_mpi_scan_unsigned (&t2, fe->t2, GNUNET_CRYPTO_PAILLIER_BITS * 2 / 8); + GNUNET_CRYPTO_mpi_scan_unsigned (&big_y, fe->c.bits, + GNUNET_CRYPTO_PAILLIER_BITS * 2 / 8); + GNUNET_CRYPTO_mpi_scan_unsigned (&t2, fe->t2, GNUNET_CRYPTO_PAILLIER_BITS + * 2 / 8); gcry_mpi_mul (n_sq, n, n); // tmp1 = g^z @@ -1140,7 +1130,9 @@ cleanup: * @param[out] fe the fair encryption */ static void -encrypt_fair (gcry_mpi_t v, const struct GNUNET_CRYPTO_PaillierPublicKey *ppub, struct GNUNET_SECRETSHARING_FairEncryption *fe) +encrypt_fair (gcry_mpi_t v, + const struct GNUNET_CRYPTO_PaillierPublicKey *ppub, + struct GNUNET_SECRETSHARING_FairEncryption *fe) { gcry_mpi_t r; gcry_mpi_t s; @@ -1155,6 +1147,7 @@ encrypt_fair (gcry_mpi_t v, const struct GNUNET_CRYPTO_PaillierPublicKey *ppub, gcry_mpi_t Y; gcry_mpi_t G; gcry_mpi_t h; + GNUNET_assert (NULL != (r = gcry_mpi_new (0))); GNUNET_assert (NULL != (s = gcry_mpi_new (0))); GNUNET_assert (NULL != (t1 = gcry_mpi_new (0))); @@ -1162,17 +1155,20 @@ encrypt_fair (gcry_mpi_t v, const struct GNUNET_CRYPTO_PaillierPublicKey *ppub, GNUNET_assert (NULL != (z = gcry_mpi_new (0))); GNUNET_assert (NULL != (w = gcry_mpi_new (0))); GNUNET_assert (NULL != (n_sq = gcry_mpi_new (0))); - GNUNET_assert (NULL != (e = gcry_mpi_new (0))); GNUNET_assert (NULL != (u = gcry_mpi_new (0))); GNUNET_assert (NULL != (Y = gcry_mpi_new (0))); GNUNET_assert (NULL != (G = gcry_mpi_new (0))); GNUNET_assert (NULL != (h = gcry_mpi_new (0))); - GNUNET_CRYPTO_mpi_scan_unsigned (&n, ppub, sizeof (struct GNUNET_CRYPTO_PaillierPublicKey)); + GNUNET_CRYPTO_mpi_scan_unsigned (&n, + ppub, + sizeof(struct + GNUNET_CRYPTO_PaillierPublicKey)); gcry_mpi_mul (n_sq, n, n); gcry_mpi_add_ui (G, n, 1); - do { + do + { gcry_mpi_randomize (u, GNUNET_CRYPTO_PAILLIER_BITS, GCRY_WEAK_RANDOM); } while (gcry_mpi_cmp (u, n) >= 0); @@ -1187,7 +1183,8 @@ encrypt_fair (gcry_mpi_t v, const struct GNUNET_CRYPTO_PaillierPublicKey *ppub, gcry_mpi_randomize (r, 2048, GCRY_WEAK_RANDOM); - do { + do + { gcry_mpi_randomize (s, GNUNET_CRYPTO_PAILLIER_BITS, GCRY_WEAK_RANDOM); } while (gcry_mpi_cmp (s, n) >= 0); @@ -1214,8 +1211,8 @@ encrypt_fair (gcry_mpi_t v, const struct GNUNET_CRYPTO_PaillierPublicKey *ppub, GNUNET_CRYPTO_PAILLIER_BITS * 2 / 8, t2); - - get_fair_encryption_challenge (fe, e); + get_fair_encryption_challenge (fe, + &e /* This allocates "e" */); // compute z gcry_mpi_mul (z, e, v); @@ -1273,14 +1270,17 @@ insert_round2_element (struct KeygenSession *ks) GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "P%u: Inserting round2 element\n", ks->local_peer_idx); - GNUNET_assert (NULL != (v = gcry_mpi_new (GNUNET_SECRETSHARING_ELGAMAL_BITS))); - GNUNET_assert (NULL != (idx = gcry_mpi_new (GNUNET_SECRETSHARING_ELGAMAL_BITS))); + GNUNET_assert (NULL != (v = gcry_mpi_new ( + GNUNET_SECRETSHARING_ELGAMAL_BITS))); + GNUNET_assert (NULL != (idx = gcry_mpi_new ( + GNUNET_SECRETSHARING_ELGAMAL_BITS))); - element_size = (sizeof (struct GNUNET_SECRETSHARING_KeygenRevealData) + - sizeof (struct GNUNET_SECRETSHARING_FairEncryption) * ks->num_peers + - GNUNET_SECRETSHARING_ELGAMAL_BITS / 8 * ks->threshold); + element_size = (sizeof(struct GNUNET_SECRETSHARING_KeygenRevealData) + + sizeof(struct GNUNET_SECRETSHARING_FairEncryption) + * ks->num_peers + + GNUNET_SECRETSHARING_ELGAMAL_BITS / 8 * ks->threshold); - element = GNUNET_malloc (sizeof (struct GNUNET_SET_Element) + element_size); + element = GNUNET_malloc (sizeof(struct GNUNET_SET_Element) + element_size); element->size = element_size; element->data = (void *) &element[1]; @@ -1309,7 +1309,8 @@ insert_round2_element (struct KeygenSession *ks) { gcry_mpi_set_ui (idx, i + 1); // evaluate the polynomial - horner_eval (v, ks->presecret_polynomial, ks->threshold, idx, elgamal_q); + horner_eval (v, ks->presecret_polynomial, ks->threshold, idx, + elgamal_q); // encrypt the result encrypt_fair (v, &ks->info[i].paillier_public_key, fe); } @@ -1326,7 +1327,8 @@ insert_round2_element (struct KeygenSession *ks) ptrdiff_t remaining = last_pos - pos; GNUNET_assert (remaining > 0); gcry_mpi_powm (v, elgamal_g, ks->presecret_polynomial[i], elgamal_p); - GNUNET_CRYPTO_mpi_print_unsigned (pos, GNUNET_SECRETSHARING_ELGAMAL_BITS / 8, v); + GNUNET_CRYPTO_mpi_print_unsigned (pos, GNUNET_SECRETSHARING_ELGAMAL_BITS + / 8, v); pos += GNUNET_SECRETSHARING_ELGAMAL_BITS / 8; } @@ -1334,7 +1336,9 @@ insert_round2_element (struct KeygenSession *ks) ks->local_peer_idx); - d->purpose.size = htonl (element_size - offsetof (struct GNUNET_SECRETSHARING_KeygenRevealData, purpose)); + d->purpose.size = htonl (element_size - offsetof (struct + GNUNET_SECRETSHARING_KeygenRevealData, + purpose)); d->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_SECRETSHARING_DKG2); GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_eddsa_sign (my_peer_private_key, @@ -1342,7 +1346,7 @@ insert_round2_element (struct KeygenSession *ks) &d->signature)); GNUNET_CONSENSUS_insert (ks->consensus, element, NULL, NULL); - GNUNET_free (element); /* FIXME: maybe stack-allocate instead? */ + GNUNET_free (element); /* FIXME: maybe stack-allocate instead? */ gcry_mpi_release (v); gcry_mpi_release (idx); @@ -1351,7 +1355,8 @@ insert_round2_element (struct KeygenSession *ks) static gcry_mpi_t keygen_reveal_get_exp_coeff (struct KeygenSession *ks, - const struct GNUNET_SECRETSHARING_KeygenRevealData *d, + const struct + GNUNET_SECRETSHARING_KeygenRevealData *d, unsigned int idx) { unsigned char *pos; @@ -1361,18 +1366,20 @@ keygen_reveal_get_exp_coeff (struct KeygenSession *ks, pos = (void *) &d[1]; // skip encrypted pre-shares - pos += sizeof (struct GNUNET_SECRETSHARING_FairEncryption) * ks->num_peers; + pos += sizeof(struct GNUNET_SECRETSHARING_FairEncryption) * ks->num_peers; // skip exp. coeffs we are not interested in pos += GNUNET_SECRETSHARING_ELGAMAL_BITS / 8 * idx; // the first exponentiated coefficient is the public key share - GNUNET_CRYPTO_mpi_scan_unsigned (&exp_coeff, pos, GNUNET_SECRETSHARING_ELGAMAL_BITS / 8); + GNUNET_CRYPTO_mpi_scan_unsigned (&exp_coeff, pos, + GNUNET_SECRETSHARING_ELGAMAL_BITS / 8); return exp_coeff; } static struct GNUNET_SECRETSHARING_FairEncryption * keygen_reveal_get_enc_preshare (struct KeygenSession *ks, - const struct GNUNET_SECRETSHARING_KeygenRevealData *d, + const struct + GNUNET_SECRETSHARING_KeygenRevealData *d, unsigned int idx) { unsigned char *pos; @@ -1381,14 +1388,15 @@ keygen_reveal_get_enc_preshare (struct KeygenSession *ks, pos = (void *) &d[1]; // skip encrypted pre-shares we're not interested in - pos += sizeof (struct GNUNET_SECRETSHARING_FairEncryption) * idx; + pos += sizeof(struct GNUNET_SECRETSHARING_FairEncryption) * idx; return (struct GNUNET_SECRETSHARING_FairEncryption *) pos; } static gcry_mpi_t keygen_reveal_get_exp_preshare (struct KeygenSession *ks, - const struct GNUNET_SECRETSHARING_KeygenRevealData *d, + const struct + GNUNET_SECRETSHARING_KeygenRevealData *d, unsigned int idx) { gcry_mpi_t exp_preshare; @@ -1396,7 +1404,8 @@ keygen_reveal_get_exp_preshare (struct KeygenSession *ks, GNUNET_assert (idx < ks->num_peers); fe = keygen_reveal_get_enc_preshare (ks, d, idx); - GNUNET_CRYPTO_mpi_scan_unsigned (&exp_preshare, fe->h, GNUNET_SECRETSHARING_ELGAMAL_BITS / 8); + GNUNET_CRYPTO_mpi_scan_unsigned (&exp_preshare, fe->h, + GNUNET_SECRETSHARING_ELGAMAL_BITS / 8); return exp_preshare; } @@ -1421,16 +1430,19 @@ keygen_round2_new_element (void *cls, return; } - expected_element_size = (sizeof (struct GNUNET_SECRETSHARING_KeygenRevealData) + - sizeof (struct GNUNET_SECRETSHARING_FairEncryption) * ks->num_peers + - GNUNET_SECRETSHARING_ELGAMAL_BITS / 8 * ks->threshold); + expected_element_size = (sizeof(struct GNUNET_SECRETSHARING_KeygenRevealData) + + sizeof(struct + GNUNET_SECRETSHARING_FairEncryption) + * ks->num_peers + + GNUNET_SECRETSHARING_ELGAMAL_BITS / 8 + * ks->threshold); if (element->size != expected_element_size) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "keygen round2 data with wrong size (%u) in consensus, " - " %u expected\n", - element->size, expected_element_size); + "keygen round2 data with wrong size (%u) in consensus, %u expected\n", + (unsigned int) element->size, + (unsigned int) expected_element_size); return; } @@ -1440,7 +1452,8 @@ keygen_round2_new_element (void *cls, if (NULL == info) { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "keygen commit data with wrong peer identity (%s) in consensus\n", + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "keygen commit data with wrong peer identity (%s) in consensus\n", GNUNET_i2s (&d->peer)); return; } @@ -1464,21 +1477,27 @@ keygen_round2_new_element (void *cls, GNUNET_log (GNUNET_ERROR_TYPE_INFO, "got round2 element\n"); if (ntohl (d->purpose.size) != - element->size - offsetof (struct GNUNET_SECRETSHARING_KeygenRevealData, purpose)) + element->size - offsetof (struct GNUNET_SECRETSHARING_KeygenRevealData, + purpose)) { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "keygen reveal data with wrong signature purpose size in consensus\n"); + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "keygen reveal data with wrong signature purpose size in consensus\n"); return; } - if (GNUNET_OK != GNUNET_CRYPTO_eddsa_verify (GNUNET_SIGNATURE_PURPOSE_SECRETSHARING_DKG2, - &d->purpose, &d->signature, &d->peer.public_key)) + if (GNUNET_OK != GNUNET_CRYPTO_eddsa_verify ( + GNUNET_SIGNATURE_PURPOSE_SECRETSHARING_DKG2, + &d->purpose, &d->signature, + &d->peer.public_key)) { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "keygen reveal data with invalid signature in consensus\n"); + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "keygen reveal data with invalid signature in consensus\n"); return; } public_key_share = keygen_reveal_get_exp_coeff (ks, d, 0); - info->preshare_commitment = keygen_reveal_get_exp_preshare (ks, d, ks->local_peer_idx); + info->preshare_commitment = keygen_reveal_get_exp_preshare (ks, d, + ks->local_peer_idx); if (NULL == ks->public_key) { @@ -1491,10 +1510,12 @@ keygen_round2_new_element (void *cls, public_key_share = NULL; { - struct GNUNET_SECRETSHARING_FairEncryption *fe = keygen_reveal_get_enc_preshare (ks, d, ks->local_peer_idx); + struct GNUNET_SECRETSHARING_FairEncryption *fe = + keygen_reveal_get_enc_preshare (ks, d, ks->local_peer_idx); GNUNET_assert (NULL != (preshare = gcry_mpi_new (0))); GNUNET_CRYPTO_paillier_decrypt (&ks->paillier_private_key, - &ks->info[ks->local_peer_idx].paillier_public_key, + &ks->info[ks->local_peer_idx]. + paillier_public_key, &fe->c, preshare); @@ -1513,8 +1534,10 @@ keygen_round2_new_element (void *cls, tmp = NULL; if (0 != cmp_result) { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "P%u: Got invalid presecret from P%u\n", - (unsigned int) ks->local_peer_idx, (unsigned int) (info - ks->info)); + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "P%u: Got invalid presecret from P%u\n", + (unsigned int) ks->local_peer_idx, (unsigned int) (info + - ks->info)); return; } @@ -1553,7 +1576,7 @@ keygen_round2_new_element (void *cls, // Using pow(double,double) is a bit sketchy. // We count players from 1, but shares from 0. gcry_mpi_t tmp; - gcry_mpi_set_ui (j_to_k, (unsigned int) pow(j+1, k)); + gcry_mpi_set_ui (j_to_k, (unsigned int) pow (j + 1, k)); tmp = keygen_reveal_get_exp_coeff (ks, d, k); gcry_mpi_powm (tmp, tmp, j_to_k, elgamal_p); gcry_mpi_mulm (prod, prod, tmp, elgamal_p); @@ -1566,7 +1589,8 @@ keygen_round2_new_element (void *cls, exp_preshare = NULL; if (0 != cmp_result) { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "P%u: reveal data from P%u incorrect\n", + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "P%u: reveal data from P%u incorrect\n", ks->local_peer_idx, j); /* no need for further verification, round2 stays invalid ... */ return; @@ -1576,14 +1600,15 @@ keygen_round2_new_element (void *cls, // TODO: verify proof of fair encryption (once implemented) for (j = 0; j < ks->num_peers; j++) { - struct GNUNET_SECRETSHARING_FairEncryption *fe = keygen_reveal_get_enc_preshare (ks, d, j); + struct GNUNET_SECRETSHARING_FairEncryption *fe = + keygen_reveal_get_enc_preshare (ks, d, j); if (GNUNET_YES != verify_fair (&ks->info[j].paillier_public_key, fe)) { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "P%u: reveal data from P%u incorrect (fair encryption)\n", + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "P%u: reveal data from P%u incorrect (fair encryption)\n", ks->local_peer_idx, j); return; } - } info->round2_valid = GNUNET_YES; @@ -1607,8 +1632,10 @@ keygen_round1_conclude (void *cls) GNUNET_CONSENSUS_destroy (ks->consensus); - ks->consensus = GNUNET_CONSENSUS_create (cfg, ks->num_peers, ks->peers, &ks->session_id, - time_between (ks->start_time, ks->deadline, 1, 2), + ks->consensus = GNUNET_CONSENSUS_create (cfg, ks->num_peers, ks->peers, + &ks->session_id, + time_between (ks->start_time, + ks->deadline, 1, 2), ks->deadline, keygen_round2_new_element, ks); @@ -1647,13 +1674,17 @@ insert_round1_element (struct KeygenSession *ks) gcry_mpi_powm (v, elgamal_g, ks->presecret_polynomial[0], elgamal_p); - GNUNET_CRYPTO_mpi_print_unsigned (v_data, GNUNET_SECRETSHARING_ELGAMAL_BITS / 8, v); + GNUNET_CRYPTO_mpi_print_unsigned (v_data, GNUNET_SECRETSHARING_ELGAMAL_BITS + / 8, v); - GNUNET_CRYPTO_hash (v_data, GNUNET_SECRETSHARING_ELGAMAL_BITS / 8, &d->commitment); + GNUNET_CRYPTO_hash (v_data, GNUNET_SECRETSHARING_ELGAMAL_BITS / 8, + &d->commitment); d->pubkey = ks->info[ks->local_peer_idx].paillier_public_key; - d->purpose.size = htonl ((sizeof *d) - offsetof (struct GNUNET_SECRETSHARING_KeygenCommitData, purpose)); + d->purpose.size = htonl ((sizeof *d) - offsetof (struct + GNUNET_SECRETSHARING_KeygenCommitData, + purpose)); d->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_SECRETSHARING_DKG1); GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_eddsa_sign (my_peer_private_key, @@ -1667,74 +1698,106 @@ insert_round1_element (struct KeygenSession *ks) } +/** + * Check that @a msg is well-formed. + * + * @param cls identification of the client + * @param msg the actual message + * @return #GNUNET_OK if @a msg is well-formed + */ +static int +check_client_keygen (void *cls, + const struct GNUNET_SECRETSHARING_CreateMessage *msg) +{ + unsigned int num_peers = ntohs (msg->num_peers); + + if (ntohs (msg->header.size) - sizeof(*msg) != + num_peers * sizeof(struct GNUNET_PeerIdentity)) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + return GNUNET_OK; +} + + /** * Functions with this signature are called whenever a message is * received. * - * @param cls closure - * @param client identification of the client - * @param message the actual message + * @param cls identification of the client + * @param msg the actual message */ -static void handle_client_keygen (void *cls, - struct GNUNET_SERVER_Client *client, - const struct GNUNET_MessageHeader - *message) +static void +handle_client_keygen (void *cls, + const struct GNUNET_SECRETSHARING_CreateMessage *msg) { - const struct GNUNET_SECRETSHARING_CreateMessage *msg = - (const struct GNUNET_SECRETSHARING_CreateMessage *) message; + struct ClientState *cs = cls; struct KeygenSession *ks; - unsigned int i; - - GNUNET_log (GNUNET_ERROR_TYPE_INFO, "client requested key generation\n"); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "client requested key generation\n"); + if (NULL != cs->keygen_session) + { + GNUNET_break (0); + GNUNET_SERVICE_client_drop (cs->client); + return; + } ks = GNUNET_new (struct KeygenSession); - - /* FIXME: check if client already has some session */ - - GNUNET_CONTAINER_DLL_insert (keygen_sessions_head, keygen_sessions_tail, ks); - - ks->client = client; - ks->client_mq = GNUNET_MQ_queue_for_server_client (client); - + ks->cs = cs; + cs->keygen_session = ks; ks->deadline = GNUNET_TIME_absolute_ntoh (msg->deadline); ks->threshold = ntohs (msg->threshold); ks->num_peers = ntohs (msg->num_peers); - ks->peers = normalize_peers ((struct GNUNET_PeerIdentity *) &msg[1], ks->num_peers, - &ks->num_peers, &ks->local_peer_idx); - - - GNUNET_log (GNUNET_ERROR_TYPE_INFO, "first round of consensus with %u peers\n", ks->num_peers); - ks->consensus = GNUNET_CONSENSUS_create (cfg, ks->num_peers, ks->peers, &msg->session_id, - GNUNET_TIME_absolute_ntoh (msg->start), - GNUNET_TIME_absolute_ntoh (msg->deadline), - keygen_round1_new_element, ks); - - ks->info = GNUNET_new_array (ks->num_peers, struct KeygenPeerInfo); - - for (i = 0; i < ks->num_peers; i++) + ks->peers = normalize_peers ((struct GNUNET_PeerIdentity *) &msg[1], + ks->num_peers, + &ks->num_peers, + &ks->local_peer_idx); + + + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "first round of consensus with %u peers\n", + ks->num_peers); + ks->consensus = GNUNET_CONSENSUS_create (cfg, + ks->num_peers, + ks->peers, + &msg->session_id, + GNUNET_TIME_absolute_ntoh ( + msg->start), + GNUNET_TIME_absolute_ntoh ( + msg->deadline), + keygen_round1_new_element, + ks); + + ks->info = GNUNET_new_array (ks->num_peers, + struct KeygenPeerInfo); + + for (unsigned int i = 0; i < ks->num_peers; i++) ks->info[i].peer = ks->peers[i]; - GNUNET_CRYPTO_paillier_create (&ks->info[ks->local_peer_idx].paillier_public_key, - &ks->paillier_private_key); - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "P%u: Generated paillier key pair\n", ks->local_peer_idx); + GNUNET_CRYPTO_paillier_create ( + &ks->info[ks->local_peer_idx].paillier_public_key, + &ks->paillier_private_key); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "P%u: Generated paillier key pair\n", + ks->local_peer_idx); generate_presecret_polynomial (ks); - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "P%u: Generated presecret polynomial\n", ks->local_peer_idx); - + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "P%u: Generated presecret polynomial\n", + ks->local_peer_idx); insert_round1_element (ks); - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "P%u: Concluding for round 1\n", ks->local_peer_idx); - + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "P%u: Concluding for round 1\n", + ks->local_peer_idx); GNUNET_CONSENSUS_conclude (ks->consensus, keygen_round1_conclude, ks); - - GNUNET_SERVER_receive_done (client, GNUNET_OK); - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "P%u: Waiting for round 1 elements ...\n", ks->local_peer_idx); + GNUNET_SERVICE_client_continue (cs->client); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "P%u: Waiting for round 1 elements ...\n", + ks->local_peer_idx); } @@ -1770,47 +1833,55 @@ decrypt_conclude (void *cls) if (NULL != ds->info[i].partial_decryption) num++; - indices = GNUNET_malloc (num * sizeof (unsigned int)); + indices = GNUNET_new_array (num, + unsigned int); j = 0; for (i = 0; i < ds->share->num_peers; i++) if (NULL != ds->info[i].partial_decryption) indices[j++] = ds->info[i].original_index; - GNUNET_log (GNUNET_ERROR_TYPE_INFO, "P%u: decrypt conclude, with %u peers\n", - ds->share->my_peer, num); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "P%u: decrypt conclude, with %u peers\n", + ds->share->my_peer, + num); gcry_mpi_set_ui (prod, 1); for (i = 0; i < num; i++) { - - GNUNET_log (GNUNET_ERROR_TYPE_INFO, "P%u: index of %u: %u\n", + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "P%u: index of %u: %u\n", ds->share->my_peer, i, indices[i]); compute_lagrange_coefficient (lagrange, indices[i], indices, num); // w_i^{\lambda_i} - gcry_mpi_powm (tmp, ds->info[indices[i]].partial_decryption, lagrange, elgamal_p); + gcry_mpi_powm (tmp, ds->info[indices[i]].partial_decryption, lagrange, + elgamal_p); // product of all exponentiated partiel decryptions ... gcry_mpi_mulm (prod, prod, tmp, elgamal_p); } - GNUNET_CRYPTO_mpi_scan_unsigned (&c_2, ds->ciphertext.c2_bits, GNUNET_SECRETSHARING_ELGAMAL_BITS / 8); + GNUNET_CRYPTO_mpi_scan_unsigned (&c_2, ds->ciphertext.c2_bits, + GNUNET_SECRETSHARING_ELGAMAL_BITS / 8); GNUNET_assert (0 != gcry_mpi_invm (prod, prod, elgamal_p)); gcry_mpi_mulm (m, c_2, prod, elgamal_p); - ev = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_SECRETSHARING_CLIENT_DECRYPT_DONE); - GNUNET_CRYPTO_mpi_print_unsigned (&msg->plaintext, GNUNET_SECRETSHARING_ELGAMAL_BITS / 8, m); + ev = GNUNET_MQ_msg (msg, + GNUNET_MESSAGE_TYPE_SECRETSHARING_CLIENT_DECRYPT_DONE); + GNUNET_CRYPTO_mpi_print_unsigned (&msg->plaintext, + GNUNET_SECRETSHARING_ELGAMAL_BITS / 8, m); msg->success = htonl (1); - GNUNET_MQ_send (ds->client_mq, ev); + GNUNET_MQ_send (ds->cs->mq, + ev); GNUNET_log (GNUNET_ERROR_TYPE_INFO, "sent decrypt done to client\n"); GNUNET_free (indices); - gcry_mpi_release(lagrange); - gcry_mpi_release(m); - gcry_mpi_release(tmp); - gcry_mpi_release(prod); - gcry_mpi_release(c_2); + gcry_mpi_release (lagrange); + gcry_mpi_release (m); + gcry_mpi_release (tmp); + gcry_mpi_release (prod); + gcry_mpi_release (c_2); // FIXME: what if not enough peers participated? } @@ -1874,7 +1945,8 @@ decrypt_new_element (void *cls, if (element->size != sizeof *d) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "element of wrong size in decrypt consensus\n"); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "element of wrong size in decrypt consensus\n"); return; } @@ -1884,52 +1956,67 @@ decrypt_new_element (void *cls, if (NULL == info) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "decrypt element from invalid peer (%s)\n", + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "decrypt element from invalid peer (%s)\n", GNUNET_i2s (&d->peer)); return; } if (NULL != info->partial_decryption) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "decrypt element duplicate\n", - GNUNET_i2s (&d->peer)); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "decrypt element duplicate\n"); return; } - if (0 != memcmp (&d->ciphertext, &session->ciphertext, sizeof (struct GNUNET_SECRETSHARING_Ciphertext))) + if (0 != GNUNET_memcmp (&d->ciphertext, &session->ciphertext)) { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "P%u: got decrypt element with non-matching ciphertext from P%u\n", - (unsigned int) session->share->my_peer, (unsigned int) (info - session->info)); + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "P%u: got decrypt element with non-matching ciphertext from P%u\n", + (unsigned int) session->share->my_peer, (unsigned int) (info + - + session + ->info)); return; } - GNUNET_CRYPTO_hash (offsetof (struct GNUNET_SECRETSHARING_DecryptData, ciphertext) + (char *) d, - offsetof (struct GNUNET_SECRETSHARING_DecryptData, nizk_response) - - offsetof (struct GNUNET_SECRETSHARING_DecryptData, ciphertext), + GNUNET_CRYPTO_hash (offsetof (struct GNUNET_SECRETSHARING_DecryptData, + ciphertext) + (char *) d, + offsetof (struct GNUNET_SECRETSHARING_DecryptData, + nizk_response) + - offsetof (struct GNUNET_SECRETSHARING_DecryptData, + ciphertext), &challenge_hash); GNUNET_CRYPTO_mpi_scan_unsigned (&challenge, &challenge_hash, - sizeof (struct GNUNET_HashCode)); + sizeof(struct GNUNET_HashCode)); - GNUNET_CRYPTO_mpi_scan_unsigned (&sigma, &session->share->sigmas[info - session->info], - sizeof (struct GNUNET_SECRETSHARING_FieldElement)); + GNUNET_CRYPTO_mpi_scan_unsigned (&sigma, &session->share->sigmas[info + - session-> + info], + sizeof(struct + GNUNET_SECRETSHARING_FieldElement)); GNUNET_CRYPTO_mpi_scan_unsigned (&c1, session->ciphertext.c1_bits, - sizeof (struct GNUNET_SECRETSHARING_FieldElement)); + sizeof(struct + GNUNET_SECRETSHARING_FieldElement)); GNUNET_CRYPTO_mpi_scan_unsigned (&commit1, &d->nizk_commit1, - sizeof (struct GNUNET_SECRETSHARING_FieldElement)); + sizeof(struct + GNUNET_SECRETSHARING_FieldElement)); GNUNET_CRYPTO_mpi_scan_unsigned (&commit2, &d->nizk_commit2, - sizeof (struct GNUNET_SECRETSHARING_FieldElement)); + sizeof(struct + GNUNET_SECRETSHARING_FieldElement)); GNUNET_CRYPTO_mpi_scan_unsigned (&r, &d->nizk_response, - sizeof (struct GNUNET_SECRETSHARING_FieldElement)); + sizeof(struct + GNUNET_SECRETSHARING_FieldElement)); GNUNET_CRYPTO_mpi_scan_unsigned (&w, &d->partial_decryption, - sizeof (struct GNUNET_SECRETSHARING_FieldElement)); + sizeof(struct + GNUNET_SECRETSHARING_FieldElement)); GNUNET_assert (NULL != (tmp1 = gcry_mpi_new (0))); GNUNET_assert (NULL != (tmp2 = gcry_mpi_new (0))); @@ -1945,10 +2032,15 @@ decrypt_new_element (void *cls, { char *tmp1_str; char *tmp2_str; + tmp1_str = mpi_to_str (tmp1); tmp2_str = mpi_to_str (tmp2); - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "P%u: Received invalid partial decryption from P%u (eqn 1), expected %s got %s\n", - session->share->my_peer, info - session->info, tmp1_str, tmp2_str); + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "P%u: Received invalid partial decryption from P%u (eqn 1), expected %s got %s\n", + session->share->my_peer, + (unsigned int) (info - session->info), + tmp1_str, + tmp2_str); GNUNET_free (tmp1_str); GNUNET_free (tmp2_str); goto cleanup; @@ -1963,13 +2055,16 @@ decrypt_new_element (void *cls, if (0 != gcry_mpi_cmp (tmp1, tmp2)) { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "P%u: Received invalid partial decryption from P%u (eqn 2)\n", - session->share->my_peer, info - session->info); + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "P%u: Received invalid partial decryption from P%u (eqn 2)\n", + session->share->my_peer, + (unsigned int) (info - session->info)); goto cleanup; } - GNUNET_CRYPTO_mpi_scan_unsigned (&info->partial_decryption, &d->partial_decryption, + GNUNET_CRYPTO_mpi_scan_unsigned (&info->partial_decryption, + &d->partial_decryption, GNUNET_SECRETSHARING_ELGAMAL_BITS / 8); cleanup: gcry_mpi_release (tmp1); @@ -2014,7 +2109,8 @@ insert_decrypt_element (struct DecryptSession *ds) GNUNET_SECRETSHARING_ELGAMAL_BITS / 8); GNUNET_CRYPTO_mpi_scan_unsigned (&s, &ds->share->my_share, GNUNET_SECRETSHARING_ELGAMAL_BITS / 8); - GNUNET_CRYPTO_mpi_scan_unsigned (&sigma, &ds->share->sigmas[ds->share->my_peer], + GNUNET_CRYPTO_mpi_scan_unsigned (&sigma, + &ds->share->sigmas[ds->share->my_peer], GNUNET_SECRETSHARING_ELGAMAL_BITS / 8); GNUNET_assert (NULL != (w = gcry_mpi_new (0))); @@ -2028,7 +2124,8 @@ insert_decrypt_element (struct DecryptSession *ds) char *sigma_str = mpi_to_str (sigma); char *tmp_str = mpi_to_str (tmp); char *s_str = mpi_to_str (s); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Share of P%u is invalid, ref sigma %s, " + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Share of P%u is invalid, ref sigma %s, " "computed sigma %s, s %s\n", ds->share->my_peer, sigma_str, tmp_str, s_str); @@ -2040,43 +2137,55 @@ insert_decrypt_element (struct DecryptSession *ds) gcry_mpi_powm (w, c1, s, elgamal_p); element.data = (void *) &d; - element.size = sizeof (struct GNUNET_SECRETSHARING_DecryptData); + element.size = sizeof(struct GNUNET_SECRETSHARING_DecryptData); element.element_type = 0; d.ciphertext = ds->ciphertext; d.peer = my_peer; - GNUNET_CRYPTO_mpi_print_unsigned (&d.partial_decryption, GNUNET_SECRETSHARING_ELGAMAL_BITS / 8, w); + GNUNET_CRYPTO_mpi_print_unsigned (&d.partial_decryption, + GNUNET_SECRETSHARING_ELGAMAL_BITS / 8, w); // create the zero knowledge proof // randomly choose beta such that 0 < beta < q do { - gcry_mpi_randomize (beta, GNUNET_SECRETSHARING_ELGAMAL_BITS - 1, GCRY_WEAK_RANDOM); - } while ((gcry_mpi_cmp_ui (beta, 0) == 0) || (gcry_mpi_cmp (beta, elgamal_q) >= 0)); + gcry_mpi_randomize (beta, GNUNET_SECRETSHARING_ELGAMAL_BITS - 1, + GCRY_WEAK_RANDOM); + } + while ((gcry_mpi_cmp_ui (beta, 0) == 0) || (gcry_mpi_cmp (beta, elgamal_q) >= + 0)); // tmp = g^beta gcry_mpi_powm (tmp, elgamal_g, beta, elgamal_p); - GNUNET_CRYPTO_mpi_print_unsigned (&d.nizk_commit1, GNUNET_SECRETSHARING_ELGAMAL_BITS / 8, tmp); + GNUNET_CRYPTO_mpi_print_unsigned (&d.nizk_commit1, + GNUNET_SECRETSHARING_ELGAMAL_BITS / 8, tmp); // tmp = (c_1)^beta gcry_mpi_powm (tmp, c1, beta, elgamal_p); - GNUNET_CRYPTO_mpi_print_unsigned (&d.nizk_commit2, GNUNET_SECRETSHARING_ELGAMAL_BITS / 8, tmp); + GNUNET_CRYPTO_mpi_print_unsigned (&d.nizk_commit2, + GNUNET_SECRETSHARING_ELGAMAL_BITS / 8, tmp); // the challenge is the hash of everything up to the response - GNUNET_CRYPTO_hash (offsetof (struct GNUNET_SECRETSHARING_DecryptData, ciphertext) + (char *) &d, - offsetof (struct GNUNET_SECRETSHARING_DecryptData, nizk_response) - - offsetof (struct GNUNET_SECRETSHARING_DecryptData, ciphertext), + GNUNET_CRYPTO_hash (offsetof (struct GNUNET_SECRETSHARING_DecryptData, + ciphertext) + (char *) &d, + offsetof (struct GNUNET_SECRETSHARING_DecryptData, + nizk_response) + - offsetof (struct GNUNET_SECRETSHARING_DecryptData, + ciphertext), &challenge_hash); GNUNET_CRYPTO_mpi_scan_unsigned (&challenge, &challenge_hash, - sizeof (struct GNUNET_HashCode)); + sizeof(struct GNUNET_HashCode)); // compute the response in tmp, // tmp = (c * s + beta) mod q gcry_mpi_mulm (tmp, challenge, s, elgamal_q); gcry_mpi_addm (tmp, tmp, beta, elgamal_q); - GNUNET_CRYPTO_mpi_print_unsigned (&d.nizk_response, GNUNET_SECRETSHARING_ELGAMAL_BITS / 8, tmp); + GNUNET_CRYPTO_mpi_print_unsigned (&d.nizk_response, + GNUNET_SECRETSHARING_ELGAMAL_BITS / 8, tmp); - d.purpose.size = htonl (element.size - offsetof (struct GNUNET_SECRETSHARING_DecryptData, purpose)); + d.purpose.size = htonl (element.size - offsetof (struct + GNUNET_SECRETSHARING_DecryptData, + purpose)); d.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_SECRETSHARING_DECRYPTION); GNUNET_assert (GNUNET_OK == @@ -2099,41 +2208,67 @@ insert_decrypt_element (struct DecryptSession *ds) } +/** + * Check that @a msg is well-formed. + * + * @param cls identification of the client + * @param msg the actual message + * @return #GNUNET_OK (check deferred a bit) + */ +static int +check_client_decrypt (void *cls, + const struct + GNUNET_SECRETSHARING_DecryptRequestMessage *msg) +{ + /* we check later, it's complicated */ + return GNUNET_OK; +} + + /** * Functions with this signature are called whenever a message is * received. * - * @param cls closure - * @param client identification of the client - * @param message the actual message + * @param cls identification of the client + * @param msg the actual message */ -static void handle_client_decrypt (void *cls, - struct GNUNET_SERVER_Client *client, - const struct GNUNET_MessageHeader - *message) +static void +handle_client_decrypt (void *cls, + const struct + GNUNET_SECRETSHARING_DecryptRequestMessage *msg) { - const struct GNUNET_SECRETSHARING_DecryptRequestMessage *msg = - (const void *) message; + struct ClientState *cs = cls; struct DecryptSession *ds; struct GNUNET_HashCode session_id; - unsigned int i; + if (NULL != cs->decrypt_session) + { + GNUNET_break (0); + GNUNET_SERVICE_client_drop (cs->client); + return; + } ds = GNUNET_new (struct DecryptSession); - // FIXME: check if session already exists - GNUNET_CONTAINER_DLL_insert (decrypt_sessions_head, decrypt_sessions_tail, ds); - ds->client = client; - ds->client_mq = GNUNET_MQ_queue_for_server_client (client); + cs->decrypt_session = ds; + ds->cs = cs; ds->start = GNUNET_TIME_absolute_ntoh (msg->start); ds->deadline = GNUNET_TIME_absolute_ntoh (msg->deadline); ds->ciphertext = msg->ciphertext; - ds->share = GNUNET_SECRETSHARING_share_read (&msg[1], ntohs (msg->header.size) - sizeof *msg, NULL); - // FIXME: probably should be break rather than assert - GNUNET_assert (NULL != ds->share); - - // FIXME: this is probably sufficient, but kdf/hash with all values would be nicer ... - GNUNET_CRYPTO_hash (&msg->ciphertext, sizeof (struct GNUNET_SECRETSHARING_Ciphertext), &session_id); + ds->share = GNUNET_SECRETSHARING_share_read (&msg[1], + ntohs (msg->header.size) + - sizeof(*msg), + NULL); + if (NULL == ds->share) + { + GNUNET_break (0); + GNUNET_SERVICE_client_drop (cs->client); + return; + } + /* FIXME: this is probably sufficient, but kdf/hash with all values would be nicer ... */ + GNUNET_CRYPTO_hash (&msg->ciphertext, + sizeof(struct GNUNET_SECRETSHARING_Ciphertext), + &session_id); ds->consensus = GNUNET_CONSENSUS_create (cfg, ds->share->num_peers, ds->share->peers, @@ -2144,20 +2279,20 @@ static void handle_client_decrypt (void *cls, ds); - ds->info = GNUNET_new_array (ds->share->num_peers, struct DecryptPeerInfo); - for (i = 0; i < ds->share->num_peers; i++) + ds->info = GNUNET_new_array (ds->share->num_peers, + struct DecryptPeerInfo); + for (unsigned int i = 0; i < ds->share->num_peers; i++) { ds->info[i].peer = ds->share->peers[i]; ds->info[i].original_index = ds->share->original_indices[i]; } - insert_decrypt_element (ds); - - GNUNET_CONSENSUS_conclude (ds->consensus, decrypt_conclude, ds); - - GNUNET_SERVER_receive_done (client, GNUNET_OK); - - GNUNET_log (GNUNET_ERROR_TYPE_INFO, "decrypting with %u peers\n", + GNUNET_CONSENSUS_conclude (ds->consensus, + decrypt_conclude, + ds); + GNUNET_SERVICE_client_continue (cs->client); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "decrypting with %u peers\n", ds->share->num_peers); } @@ -2166,112 +2301,115 @@ static void init_crypto_constants (void) { GNUNET_assert (0 == gcry_mpi_scan (&elgamal_q, GCRYMPI_FMT_HEX, - GNUNET_SECRETSHARING_ELGAMAL_Q_HEX, 0, NULL)); + GNUNET_SECRETSHARING_ELGAMAL_Q_HEX, 0, + NULL)); GNUNET_assert (0 == gcry_mpi_scan (&elgamal_p, GCRYMPI_FMT_HEX, - GNUNET_SECRETSHARING_ELGAMAL_P_HEX, 0, NULL)); + GNUNET_SECRETSHARING_ELGAMAL_P_HEX, 0, + NULL)); GNUNET_assert (0 == gcry_mpi_scan (&elgamal_g, GCRYMPI_FMT_HEX, - GNUNET_SECRETSHARING_ELGAMAL_G_HEX, 0, NULL)); -} - - -static struct KeygenSession * -keygen_session_get (struct GNUNET_SERVER_Client *client) -{ - struct KeygenSession *ks; - for (ks = keygen_sessions_head; NULL != ks; ks = ks->next) - if (ks->client == client) - return ks; - return NULL; -} - -static struct DecryptSession * -decrypt_session_get (struct GNUNET_SERVER_Client *client) -{ - struct DecryptSession *ds; - for (ds = decrypt_sessions_head; NULL != ds; ds = ds->next) - if (ds->client == client) - return ds; - return NULL; + GNUNET_SECRETSHARING_ELGAMAL_G_HEX, 0, + NULL)); } /** - * Clean up after a client has disconnected - * - * @param cls closure, unused - * @param client the client to clean up after - */ -static void -handle_client_disconnect (void *cls, struct GNUNET_SERVER_Client *client) -{ - struct KeygenSession *ks; - struct DecryptSession *ds; - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "handling client disconnect\n"); - - ks = keygen_session_get (client); - if (NULL != ks) - keygen_session_destroy (ks); - - ds = decrypt_session_get (client); - if (NULL != ds) - decrypt_session_destroy (ds); -} - - -/** - * Process template requests. + * Initialize secretsharing service. * * @param cls closure - * @param server the initialized server * @param c configuration to use + * @param service the initialized service */ static void -run (void *cls, struct GNUNET_SERVER_Handle *server, - const struct GNUNET_CONFIGURATION_Handle *c) +run (void *cls, + const struct GNUNET_CONFIGURATION_Handle *c, + struct GNUNET_SERVICE_Handle *service) { - static const struct GNUNET_SERVER_MessageHandler handlers[] = { - {handle_client_keygen, NULL, GNUNET_MESSAGE_TYPE_SECRETSHARING_CLIENT_GENERATE, 0}, - {handle_client_decrypt, NULL, GNUNET_MESSAGE_TYPE_SECRETSHARING_CLIENT_DECRYPT, 0}, - {NULL, NULL, 0, 0} - }; cfg = c; - srv = server; my_peer_private_key = GNUNET_CRYPTO_eddsa_key_create_from_configuration (c); if (NULL == my_peer_private_key) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "could not access host private key\n"); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "could not access host private key\n"); GNUNET_break (0); GNUNET_SCHEDULER_shutdown (); return; } init_crypto_constants (); - if (GNUNET_OK != GNUNET_CRYPTO_get_peer_identity (cfg, &my_peer)) + if (GNUNET_OK != + GNUNET_CRYPTO_get_peer_identity (cfg, + &my_peer)) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "could not retrieve host identity\n"); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "could not retrieve host identity\n"); GNUNET_break (0); GNUNET_SCHEDULER_shutdown (); return; } - GNUNET_SERVER_add_handlers (server, handlers); - GNUNET_SERVER_disconnect_notify (server, &handle_client_disconnect, NULL); - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleanup_task, - NULL); + GNUNET_SCHEDULER_add_shutdown (&cleanup_task, + NULL); } /** - * The main function for the template service. + * Callback called when a client connects to the service. * - * @param argc number of arguments from the command line - * @param argv command line arguments - * @return 0 ok, 1 on error + * @param cls closure for the service + * @param c the new client that connected to the service + * @param mq the message queue used to send messages to the client + * @return @a c */ -int -main (int argc, char *const *argv) +static void * +client_connect_cb (void *cls, + struct GNUNET_SERVICE_Client *c, + struct GNUNET_MQ_Handle *mq) { - return (GNUNET_OK == - GNUNET_SERVICE_run (argc, argv, "secretsharing", - GNUNET_SERVICE_OPTION_NONE, &run, NULL)) ? 0 : 1; + struct ClientState *cs = GNUNET_new (struct ClientState);; + + cs->client = c; + cs->mq = mq; + return cs; } + +/** + * Callback called when a client disconnected from the service + * + * @param cls closure for the service + * @param c the client that disconnected + * @param internal_cls should be equal to @a c + */ +static void +client_disconnect_cb (void *cls, + struct GNUNET_SERVICE_Client *c, + void *internal_cls) +{ + struct ClientState *cs = internal_cls; + + if (NULL != cs->keygen_session) + keygen_session_destroy (cs->keygen_session); + + if (NULL != cs->decrypt_session) + decrypt_session_destroy (cs->decrypt_session); + GNUNET_free (cs); +} + + +/** + * Define "main" method using service macro. + */ +GNUNET_SERVICE_MAIN + ("secretsharing", + GNUNET_SERVICE_OPTION_NONE, + &run, + &client_connect_cb, + &client_disconnect_cb, + NULL, + GNUNET_MQ_hd_var_size (client_keygen, + GNUNET_MESSAGE_TYPE_SECRETSHARING_CLIENT_GENERATE, + struct GNUNET_SECRETSHARING_CreateMessage, + NULL), + GNUNET_MQ_hd_var_size (client_decrypt, + GNUNET_MESSAGE_TYPE_SECRETSHARING_CLIENT_DECRYPT, + struct GNUNET_SECRETSHARING_DecryptRequestMessage, + NULL), + GNUNET_MQ_handler_end ());