- fixes
[oweals/gnunet.git] / src / secretsharing / secretsharing_api.c
1 /*
2      This file is part of GNUnet.
3      (C) 2012 Christian Grothoff (and other contributing authors)
4
5      GNUnet is free software; you can redistribute it and/or modify
6      it under the terms of the GNU General Public License as published
7      by the Free Software Foundation; either version 3, or (at your
8      option) any later version.
9
10      GNUnet is distributed in the hope that it will be useful, but
11      WITHOUT ANY WARRANTY; without even the implied warranty of
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13      General Public License for more details.
14
15      You should have received a copy of the GNU General Public License
16      along with GNUnet; see the file COPYING.  If not, write to the
17      Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18      Boston, MA 02111-1307, USA.
19 */
20
21 /**
22  * @file secretsharing/secretsharing_api.c
23  * @brief
24  * @author Florian Dold
25  */
26 #include "platform.h"
27 #include "gnunet_util_lib.h"
28 #include "gnunet_secretsharing_service.h"
29 #include "secretsharing.h"
30
31
32 #define LOG(kind,...) GNUNET_log_from (kind, "secretsharing-api",__VA_ARGS__)
33
34 /**
35  * Session that will eventually establish a shared secred between
36  * the involved peers and allow encryption and cooperative decryption.
37  */
38 struct GNUNET_SECRETSHARING_Session
39 {
40   /**
41    * Client connected to the secretsharing service.
42    */
43   struct GNUNET_CLIENT_Connection *client;
44
45   /**
46    * Message queue for 'client'.
47    */
48   struct GNUNET_MQ_Handle *mq;
49
50   /**
51    * Called when the secret sharing is done.
52    */
53   GNUNET_SECRETSHARING_SecretReadyCallback secret_ready_cb;
54
55   /**
56    * Closure for 'secret_ready_cb'.
57    */
58   void *secret_ready_cls;
59 };
60
61
62 struct GNUNET_SECRETSHARING_DecryptionHandle
63 {
64   /**
65    * Client connected to the secretsharing service.
66    */
67   struct GNUNET_CLIENT_Connection *client;
68
69   /**
70    * Message queue for 'client'.
71    */
72   struct GNUNET_MQ_Handle *mq;
73
74   /**
75    * Called when the secret sharing is done.
76    */
77   GNUNET_SECRETSHARING_DecryptCallback decrypt_cb;
78
79   /**
80    * Closure for 'decrypt_cb'.
81    */
82   void *decrypt_cls;
83 };
84
85
86 static void
87 handle_session_client_error (void *cls, enum GNUNET_MQ_Error error)
88 {
89   struct GNUNET_SECRETSHARING_Session *s = cls;
90
91   s->secret_ready_cb (s->secret_ready_cls, NULL, NULL, 0, NULL);
92 }
93
94
95 static void
96 handle_decrypt_client_error (void *cls, enum GNUNET_MQ_Error error)
97 {
98   GNUNET_assert (0);
99 }
100
101 static void
102 handle_secret_ready (void *cls, const struct GNUNET_MessageHeader *msg)
103 {
104   struct GNUNET_SECRETSHARING_Session *session = cls;
105   struct GNUNET_SECRETSHARING_Share *share;
106   const struct GNUNET_SECRETSHARING_SecretReadyMessage *m = (const void *) msg;
107   size_t share_size;
108
109   share_size = ntohs (m->header.size) - sizeof *m;
110
111   share = GNUNET_SECRETSHARING_share_read (&m[1], share_size, NULL);
112
113   session->secret_ready_cb (session->secret_ready_cls,
114                       share, /* FIXME */
115                       &share->public_key,
116                       share->num_peers,
117                       (struct GNUNET_PeerIdentity *) &m[1]);
118
119 }
120
121
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,
130                                      void *cls)
131 {
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
138   };
139
140
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);
146
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);
150
151   ev = GNUNET_MQ_msg_extra (msg,
152                             num_peers * sizeof (struct GNUNET_PeerIdentity),
153                             GNUNET_MESSAGE_TYPE_SECRETSHARING_CLIENT_GENERATE);
154
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));
160
161   GNUNET_MQ_send (s->mq, ev);
162
163   LOG (GNUNET_ERROR_TYPE_DEBUG, "secretsharing session created with %u peers\n",
164        num_peers);
165   return s;
166 }
167
168
169 static void
170 handle_decrypt_done (void *cls, const struct GNUNET_MessageHeader *msg)
171 {
172   GNUNET_assert (0);
173 }
174
175
176 /**
177  * Publish the given ciphertext for decryption.  Once a sufficient (>=k) number of peers has
178  * published the same value, it will be decrypted.
179  *
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.
182  *
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
188  */
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)
196 {
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
203   };
204   size_t share_size;
205
206
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);
212
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);
216
217   GNUNET_assert (GNUNET_OK == GNUNET_SECRETSHARING_share_write (share, NULL, 0, &share_size));
218
219   ev = GNUNET_MQ_msg_extra (msg,
220                             share_size,
221                             GNUNET_MESSAGE_TYPE_SECRETSHARING_CLIENT_DECRYPT);
222
223   GNUNET_assert (GNUNET_OK == GNUNET_SECRETSHARING_share_write (share, &msg[1], share_size, NULL));
224
225   msg->deadline = GNUNET_TIME_absolute_hton (deadline);
226
227   GNUNET_MQ_send (s->mq, ev);
228
229   LOG (GNUNET_ERROR_TYPE_DEBUG, "decrypt session created\n");
230   return s;
231 }
232
233