2 This file is part of GNUnet.
3 (C) 2012 Christian Grothoff (and other contributing authors)
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
22 * @file secretsharing/secretsharing_api.c
24 * @author Florian Dold
27 #include "gnunet_util_lib.h"
28 #include "gnunet_secretsharing_service.h"
29 #include "secretsharing.h"
32 #define LOG(kind,...) GNUNET_log_from (kind, "secretsharing-api",__VA_ARGS__)
35 * Session that will eventually establish a shared secred between
36 * the involved peers and allow encryption and cooperative decryption.
38 struct GNUNET_SECRETSHARING_Session
41 * Client connected to the secretsharing service.
43 struct GNUNET_CLIENT_Connection *client;
46 * Message queue for 'client'.
48 struct GNUNET_MQ_Handle *mq;
51 * Called when the secret sharing is done.
53 GNUNET_SECRETSHARING_SecretReadyCallback secret_ready_cb;
56 * Closure for 'secret_ready_cb'.
58 void *secret_ready_cls;
62 struct GNUNET_SECRETSHARING_DecryptionHandle
65 * Client connected to the secretsharing service.
67 struct GNUNET_CLIENT_Connection *client;
70 * Message queue for 'client'.
72 struct GNUNET_MQ_Handle *mq;
75 * Called when the secret sharing is done.
77 GNUNET_SECRETSHARING_DecryptCallback decrypt_cb;
80 * Closure for 'decrypt_cb'.
87 handle_session_client_error (void *cls, enum GNUNET_MQ_Error error)
89 struct GNUNET_SECRETSHARING_Session *s = cls;
91 s->secret_ready_cb (s->secret_ready_cls, NULL, NULL, 0, NULL);
96 handle_decrypt_client_error (void *cls, enum GNUNET_MQ_Error error)
102 handle_secret_ready (void *cls, const struct GNUNET_MessageHeader *msg)
104 struct GNUNET_SECRETSHARING_Session *session = cls;
105 struct GNUNET_SECRETSHARING_Share *share;
106 const struct GNUNET_SECRETSHARING_SecretReadyMessage *m = (const void *) msg;
109 share_size = ntohs (m->header.size) - sizeof *m;
111 share = GNUNET_SECRETSHARING_share_read (&m[1], share_size, NULL);
113 session->secret_ready_cb (session->secret_ready_cls,
117 (struct GNUNET_PeerIdentity *) &m[1]);
122 struct GNUNET_SECRETSHARING_Session *
123 GNUNET_SECRETSHARING_create_session (const struct GNUNET_CONFIGURATION_Handle *cfg,
124 unsigned int num_peers,
125 const struct GNUNET_PeerIdentity *peers,
126 const struct GNUNET_HashCode *session_id,
127 struct GNUNET_TIME_Absolute deadline,
128 unsigned int threshold,
129 GNUNET_SECRETSHARING_SecretReadyCallback cb,
132 struct GNUNET_SECRETSHARING_Session *s;
133 struct GNUNET_MQ_Envelope *ev;
134 struct GNUNET_SECRETSHARING_CreateMessage *msg;
135 static const struct GNUNET_MQ_MessageHandler mq_handlers[] = {
136 {handle_secret_ready, GNUNET_MESSAGE_TYPE_SECRETSHARING_CLIENT_SECRET_READY, 0},
137 GNUNET_MQ_HANDLERS_END
141 s = GNUNET_new (struct GNUNET_SECRETSHARING_Session);
142 s->client = GNUNET_CLIENT_connect ("secretsharing", cfg);
143 s->secret_ready_cb = cb;
144 s->secret_ready_cls = cls;
145 GNUNET_assert (NULL != s->client);
147 s->mq = GNUNET_MQ_queue_for_connection_client (s->client, mq_handlers,
148 handle_session_client_error, s);
149 GNUNET_assert (NULL != s->mq);
151 ev = GNUNET_MQ_msg_extra (msg,
152 num_peers * sizeof (struct GNUNET_PeerIdentity),
153 GNUNET_MESSAGE_TYPE_SECRETSHARING_CLIENT_GENERATE);
155 msg->threshold = htons (threshold);
156 msg->num_peers = htons (num_peers);
157 msg->session_id = *session_id;
158 msg->deadline = GNUNET_TIME_absolute_hton (deadline);
159 memcpy (&msg[1], peers, num_peers * sizeof (struct GNUNET_PeerIdentity));
161 GNUNET_MQ_send (s->mq, ev);
163 LOG (GNUNET_ERROR_TYPE_DEBUG, "secretsharing session created with %u peers\n",
170 handle_decrypt_done (void *cls, const struct GNUNET_MessageHeader *msg)
177 * Publish the given ciphertext for decryption. Once a sufficient (>=k) number of peers has
178 * published the same value, it will be decrypted.
180 * When the operation is canceled, the decrypt_cb is not called anymore, but the calling
181 * peer may already have irrevocably contributed his share for the decryption of the value.
183 * @param share our secret share to use for decryption
184 * @param ciphertext ciphertext to publish in order to decrypt it (if enough peers agree)
185 * @param decrypt_cb callback called once the decryption succeeded
186 * @param decrypt_cb_cls closure for @a decrypt_cb
187 * @return handle to cancel the operation
189 struct GNUNET_SECRETSHARING_DecryptionHandle *
190 GNUNET_SECRETSHARING_decrypt (struct GNUNET_CONFIGURATION_Handle *cfg,
191 struct GNUNET_SECRETSHARING_Share *share,
192 struct GNUNET_SECRETSHARING_Ciphertext *ciphertext,
193 struct GNUNET_TIME_Absolute deadline,
194 GNUNET_SECRETSHARING_DecryptCallback decrypt_cb,
195 void *decrypt_cb_cls)
197 struct GNUNET_SECRETSHARING_DecryptionHandle *s;
198 struct GNUNET_MQ_Envelope *ev;
199 struct GNUNET_SECRETSHARING_DecryptRequestMessage *msg;
200 static const struct GNUNET_MQ_MessageHandler mq_handlers[] = {
201 {handle_decrypt_done, GNUNET_MESSAGE_TYPE_SECRETSHARING_CLIENT_DECRYPT_DONE, 0},
202 GNUNET_MQ_HANDLERS_END
207 s = GNUNET_new (struct GNUNET_SECRETSHARING_DecryptionHandle);
208 s->client = GNUNET_CLIENT_connect ("secretsharing", cfg);
209 s->decrypt_cb = decrypt_cb;
210 s->decrypt_cls = decrypt_cb_cls;
211 GNUNET_assert (NULL != s->client);
213 s->mq = GNUNET_MQ_queue_for_connection_client (s->client, mq_handlers,
214 handle_decrypt_client_error, s);
215 GNUNET_assert (NULL != s->mq);
217 GNUNET_assert (GNUNET_OK == GNUNET_SECRETSHARING_share_write (share, NULL, 0, &share_size));
219 ev = GNUNET_MQ_msg_extra (msg,
221 GNUNET_MESSAGE_TYPE_SECRETSHARING_CLIENT_DECRYPT);
223 GNUNET_assert (GNUNET_OK == GNUNET_SECRETSHARING_share_write (share, &msg[1], share_size, NULL));
225 msg->deadline = GNUNET_TIME_absolute_hton (deadline);
227 GNUNET_MQ_send (s->mq, ev);
229 LOG (GNUNET_ERROR_TYPE_DEBUG, "decrypt session created\n");