diff options
Diffstat (limited to 'src/secretsharing/secretsharing_api.c')
-rw-r--r-- | src/secretsharing/secretsharing_api.c | 170 |
1 files changed, 124 insertions, 46 deletions
diff --git a/src/secretsharing/secretsharing_api.c b/src/secretsharing/secretsharing_api.c index 6e347f6da..a1f5c336e 100644 --- a/src/secretsharing/secretsharing_api.c +++ b/src/secretsharing/secretsharing_api.c | |||
@@ -44,7 +44,7 @@ struct GNUNET_SECRETSHARING_Session | |||
44 | struct GNUNET_CLIENT_Connection *client; | 44 | struct GNUNET_CLIENT_Connection *client; |
45 | 45 | ||
46 | /** | 46 | /** |
47 | * Message queue for 'client'. | 47 | * Message queue for @e client. |
48 | */ | 48 | */ |
49 | struct GNUNET_MQ_Handle *mq; | 49 | struct GNUNET_MQ_Handle *mq; |
50 | 50 | ||
@@ -54,12 +54,15 @@ struct GNUNET_SECRETSHARING_Session | |||
54 | GNUNET_SECRETSHARING_SecretReadyCallback secret_ready_cb; | 54 | GNUNET_SECRETSHARING_SecretReadyCallback secret_ready_cb; |
55 | 55 | ||
56 | /** | 56 | /** |
57 | * Closure for 'secret_ready_cb'. | 57 | * Closure for @e secret_ready_cb. |
58 | */ | 58 | */ |
59 | void *secret_ready_cls; | 59 | void *secret_ready_cls; |
60 | }; | 60 | }; |
61 | 61 | ||
62 | 62 | ||
63 | /** | ||
64 | * Handle to cancel a cooperative decryption operation. | ||
65 | */ | ||
63 | struct GNUNET_SECRETSHARING_DecryptionHandle | 66 | struct GNUNET_SECRETSHARING_DecryptionHandle |
64 | { | 67 | { |
65 | /** | 68 | /** |
@@ -68,7 +71,7 @@ struct GNUNET_SECRETSHARING_DecryptionHandle | |||
68 | struct GNUNET_CLIENT_Connection *client; | 71 | struct GNUNET_CLIENT_Connection *client; |
69 | 72 | ||
70 | /** | 73 | /** |
71 | * Message queue for 'client'. | 74 | * Message queue for @e client. |
72 | */ | 75 | */ |
73 | struct GNUNET_MQ_Handle *mq; | 76 | struct GNUNET_MQ_Handle *mq; |
74 | 77 | ||
@@ -78,7 +81,7 @@ struct GNUNET_SECRETSHARING_DecryptionHandle | |||
78 | GNUNET_SECRETSHARING_DecryptCallback decrypt_cb; | 81 | GNUNET_SECRETSHARING_DecryptCallback decrypt_cb; |
79 | 82 | ||
80 | /** | 83 | /** |
81 | * Closure for 'decrypt_cb'. | 84 | * Closure for @e decrypt_cb. |
82 | */ | 85 | */ |
83 | void *decrypt_cls; | 86 | void *decrypt_cls; |
84 | }; | 87 | }; |
@@ -103,6 +106,9 @@ static gcry_mpi_t elgamal_p; | |||
103 | static gcry_mpi_t elgamal_g; | 106 | static gcry_mpi_t elgamal_g; |
104 | 107 | ||
105 | 108 | ||
109 | /** | ||
110 | * Function to initialize #elgamal_q, #egamal_p and #elgamal_g. | ||
111 | */ | ||
106 | static void | 112 | static void |
107 | ensure_elgamal_initialized (void) | 113 | ensure_elgamal_initialized (void) |
108 | { | 114 | { |
@@ -118,60 +124,117 @@ ensure_elgamal_initialized (void) | |||
118 | } | 124 | } |
119 | 125 | ||
120 | 126 | ||
127 | /** | ||
128 | * Callback invoked when there is an error communicating with | ||
129 | * the service. Notifies the application about the error. | ||
130 | * | ||
131 | * @param cls the `struct GNUNET_SECRETSHARING_Session` | ||
132 | * @param error error code | ||
133 | */ | ||
121 | static void | 134 | static void |
122 | handle_session_client_error (void *cls, enum GNUNET_MQ_Error error) | 135 | handle_session_client_error (void *cls, |
136 | enum GNUNET_MQ_Error error) | ||
123 | { | 137 | { |
124 | struct GNUNET_SECRETSHARING_Session *s = cls; | 138 | struct GNUNET_SECRETSHARING_Session *s = cls; |
125 | 139 | ||
126 | s->secret_ready_cb (s->secret_ready_cls, NULL, NULL, 0, NULL); | 140 | s->secret_ready_cb (s->secret_ready_cls, NULL, NULL, 0, NULL); |
141 | GNUNET_SECRETSHARING_session_destroy (s); | ||
127 | } | 142 | } |
128 | 143 | ||
129 | 144 | ||
145 | /** | ||
146 | * Callback invoked when there is an error communicating with | ||
147 | * the service. Notifies the application about the error. | ||
148 | * | ||
149 | * @param cls the `struct GNUNET_SECRETSHARING_DecryptionHandle` | ||
150 | * @param error error code | ||
151 | */ | ||
130 | static void | 152 | static void |
131 | handle_decrypt_client_error (void *cls, enum GNUNET_MQ_Error error) | 153 | handle_decrypt_client_error (void *cls, |
154 | enum GNUNET_MQ_Error error) | ||
132 | { | 155 | { |
133 | struct GNUNET_SECRETSHARING_DecryptionHandle *dh = cls; | 156 | struct GNUNET_SECRETSHARING_DecryptionHandle *dh = cls; |
134 | 157 | ||
135 | dh->decrypt_cb (dh->decrypt_cls, NULL); | 158 | dh->decrypt_cb (dh->decrypt_cls, NULL); |
159 | GNUNET_SECRETSHARING_decrypt_cancel (dh); | ||
136 | } | 160 | } |
137 | 161 | ||
138 | 162 | ||
163 | /** | ||
164 | * Handler invoked with the final result message from | ||
165 | * secret sharing. Decodes the message and passes the | ||
166 | * result to the application. | ||
167 | * | ||
168 | * @param cls the `struct GNUNET_SECRETSHARING_Session` | ||
169 | * @param msg message with the result | ||
170 | */ | ||
139 | static void | 171 | static void |
140 | handle_secret_ready (void *cls, const struct GNUNET_MessageHeader *msg) | 172 | handle_secret_ready (void *cls, |
173 | const struct GNUNET_MessageHeader *msg) | ||
141 | { | 174 | { |
142 | struct GNUNET_SECRETSHARING_Session *session = cls; | 175 | struct GNUNET_SECRETSHARING_Session *s = cls; |
176 | const struct GNUNET_SECRETSHARING_SecretReadyMessage *m; | ||
143 | struct GNUNET_SECRETSHARING_Share *share; | 177 | struct GNUNET_SECRETSHARING_Share *share; |
144 | const struct GNUNET_SECRETSHARING_SecretReadyMessage *m = (const void *) msg; | ||
145 | size_t share_size; | 178 | size_t share_size; |
146 | 179 | ||
147 | LOG (GNUNET_ERROR_TYPE_DEBUG, "got secret ready message of size %u\n", | 180 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
148 | ntohs (m->header.size)); | 181 | "Got secret ready message of size %u\n", |
149 | 182 | ntohs (msg->size)); | |
150 | share_size = ntohs (m->header.size) - sizeof *m; | 183 | if (ntohs (msg->size) < sizeof (struct GNUNET_SECRETSHARING_SecretReadyMessage)) |
151 | 184 | { | |
152 | share = GNUNET_SECRETSHARING_share_read (&m[1], share_size, NULL); | 185 | GNUNET_break (0); |
186 | s->secret_ready_cb (s->secret_ready_cls, NULL, NULL, 0, NULL); | ||
187 | GNUNET_SECRETSHARING_session_destroy (s); | ||
188 | return; | ||
189 | } | ||
190 | m = (const struct GNUNET_SECRETSHARING_SecretReadyMessage *) msg; | ||
191 | share_size = ntohs (m->header.size) - sizeof (struct GNUNET_SECRETSHARING_SecretReadyMessage); | ||
153 | 192 | ||
154 | session->secret_ready_cb (session->secret_ready_cls, | 193 | share = GNUNET_SECRETSHARING_share_read (&m[1], |
194 | share_size, | ||
195 | NULL); | ||
196 | s->secret_ready_cb (s->secret_ready_cls, | ||
155 | share, /* FIXME */ | 197 | share, /* FIXME */ |
156 | &share->public_key, | 198 | &share->public_key, |
157 | share->num_peers, | 199 | share->num_peers, |
158 | (struct GNUNET_PeerIdentity *) &m[1]); | 200 | (struct GNUNET_PeerIdentity *) &m[1]); |
159 | 201 | GNUNET_SECRETSHARING_session_destroy (s); | |
160 | GNUNET_SECRETSHARING_session_destroy (session); | ||
161 | } | 202 | } |
162 | 203 | ||
163 | 204 | ||
205 | /** | ||
206 | * Destroy a secret sharing session. | ||
207 | * The secret ready callback will not be called. | ||
208 | * | ||
209 | * @param s session to destroy | ||
210 | */ | ||
164 | void | 211 | void |
165 | GNUNET_SECRETSHARING_session_destroy (struct GNUNET_SECRETSHARING_Session *session) | 212 | GNUNET_SECRETSHARING_session_destroy (struct GNUNET_SECRETSHARING_Session *s) |
166 | { | 213 | { |
167 | GNUNET_MQ_destroy (session->mq); | 214 | GNUNET_MQ_destroy (s->mq); |
168 | session->mq = NULL; | 215 | s->mq = NULL; |
169 | GNUNET_CLIENT_disconnect (session->client); | 216 | GNUNET_CLIENT_disconnect (s->client); |
170 | session->client = NULL; | 217 | s->client = NULL; |
171 | GNUNET_free (session); | 218 | GNUNET_free (s); |
172 | } | 219 | } |
173 | 220 | ||
174 | 221 | ||
222 | /** | ||
223 | * Create a session that will eventually establish a shared secret | ||
224 | * with the other peers. | ||
225 | * | ||
226 | * @param cfg configuration to use | ||
227 | * @param num_peers number of peers in @a peers | ||
228 | * @param peers array of peers that we will share secrets with, can optionally contain the local peer | ||
229 | * @param session_id unique session id | ||
230 | * @param start When should all peers be available for sharing the secret? | ||
231 | * Random number generation can take place before the start time. | ||
232 | * @param deadline point in time where the session must be established; taken as hint | ||
233 | * by underlying consensus sessions | ||
234 | * @param threshold minimum number of peers that must cooperate to decrypt a value | ||
235 | * @param cb called when the secret has been established | ||
236 | * @param cls closure for @a cb | ||
237 | */ | ||
175 | struct GNUNET_SECRETSHARING_Session * | 238 | struct GNUNET_SECRETSHARING_Session * |
176 | GNUNET_SECRETSHARING_create_session (const struct GNUNET_CONFIGURATION_Handle *cfg, | 239 | GNUNET_SECRETSHARING_create_session (const struct GNUNET_CONFIGURATION_Handle *cfg, |
177 | unsigned int num_peers, | 240 | unsigned int num_peers, |
@@ -187,19 +250,25 @@ GNUNET_SECRETSHARING_create_session (const struct GNUNET_CONFIGURATION_Handle *c | |||
187 | struct GNUNET_MQ_Envelope *ev; | 250 | struct GNUNET_MQ_Envelope *ev; |
188 | struct GNUNET_SECRETSHARING_CreateMessage *msg; | 251 | struct GNUNET_SECRETSHARING_CreateMessage *msg; |
189 | static const struct GNUNET_MQ_MessageHandler mq_handlers[] = { | 252 | static const struct GNUNET_MQ_MessageHandler mq_handlers[] = { |
190 | {handle_secret_ready, GNUNET_MESSAGE_TYPE_SECRETSHARING_CLIENT_SECRET_READY, 0}, | 253 | { &handle_secret_ready, |
254 | GNUNET_MESSAGE_TYPE_SECRETSHARING_CLIENT_SECRET_READY, 0}, | ||
191 | GNUNET_MQ_HANDLERS_END | 255 | GNUNET_MQ_HANDLERS_END |
192 | }; | 256 | }; |
193 | 257 | ||
194 | |||
195 | s = GNUNET_new (struct GNUNET_SECRETSHARING_Session); | 258 | s = GNUNET_new (struct GNUNET_SECRETSHARING_Session); |
196 | s->client = GNUNET_CLIENT_connect ("secretsharing", cfg); | 259 | s->client = GNUNET_CLIENT_connect ("secretsharing", cfg); |
260 | if (NULL == s->client) | ||
261 | { | ||
262 | /* secretsharing not configured correctly */ | ||
263 | GNUNET_break (0); | ||
264 | GNUNET_free (s); | ||
265 | return NULL; | ||
266 | } | ||
197 | s->secret_ready_cb = cb; | 267 | s->secret_ready_cb = cb; |
198 | s->secret_ready_cls = cls; | 268 | s->secret_ready_cls = cls; |
199 | GNUNET_assert (NULL != s->client); | ||
200 | |||
201 | s->mq = GNUNET_MQ_queue_for_connection_client (s->client, mq_handlers, | 269 | s->mq = GNUNET_MQ_queue_for_connection_client (s->client, mq_handlers, |
202 | handle_session_client_error, s); | 270 | &handle_session_client_error, |
271 | s); | ||
203 | GNUNET_assert (NULL != s->mq); | 272 | GNUNET_assert (NULL != s->mq); |
204 | 273 | ||
205 | ev = GNUNET_MQ_msg_extra (msg, | 274 | ev = GNUNET_MQ_msg_extra (msg, |
@@ -215,19 +284,20 @@ GNUNET_SECRETSHARING_create_session (const struct GNUNET_CONFIGURATION_Handle *c | |||
215 | 284 | ||
216 | GNUNET_MQ_send (s->mq, ev); | 285 | GNUNET_MQ_send (s->mq, ev); |
217 | 286 | ||
218 | LOG (GNUNET_ERROR_TYPE_DEBUG, "secretsharing session created with %u peers\n", | 287 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
288 | "Secretsharing session created with %u peers\n", | ||
219 | num_peers); | 289 | num_peers); |
220 | return s; | 290 | return s; |
221 | } | 291 | } |
222 | 292 | ||
223 | 293 | ||
224 | static void | 294 | static void |
225 | handle_decrypt_done (void *cls, const struct GNUNET_MessageHeader *msg) | 295 | handle_decrypt_done (void *cls, |
296 | const struct GNUNET_MessageHeader *msg) | ||
226 | { | 297 | { |
227 | struct GNUNET_SECRETSHARING_DecryptionHandle *dh = cls; | 298 | struct GNUNET_SECRETSHARING_DecryptionHandle *dh = cls; |
228 | const struct GNUNET_SECRETSHARING_DecryptResponseMessage *m = | 299 | const struct GNUNET_SECRETSHARING_DecryptResponseMessage *m = |
229 | (const void *) msg; | 300 | (const void *) msg; // FIXME: size check!? |
230 | |||
231 | const struct GNUNET_SECRETSHARING_Plaintext *plaintext; | 301 | const struct GNUNET_SECRETSHARING_Plaintext *plaintext; |
232 | 302 | ||
233 | if (m->success == 0) | 303 | if (m->success == 0) |
@@ -280,7 +350,8 @@ GNUNET_SECRETSHARING_decrypt (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
280 | GNUNET_assert (NULL != s->client); | 350 | GNUNET_assert (NULL != s->client); |
281 | 351 | ||
282 | s->mq = GNUNET_MQ_queue_for_connection_client (s->client, mq_handlers, | 352 | s->mq = GNUNET_MQ_queue_for_connection_client (s->client, mq_handlers, |
283 | handle_decrypt_client_error, s); | 353 | &handle_decrypt_client_error, |
354 | s); | ||
284 | GNUNET_assert (NULL != s->mq); | 355 | GNUNET_assert (NULL != s->mq); |
285 | 356 | ||
286 | GNUNET_assert (GNUNET_OK == GNUNET_SECRETSHARING_share_write (share, NULL, 0, &share_size)); | 357 | GNUNET_assert (GNUNET_OK == GNUNET_SECRETSHARING_share_write (share, NULL, 0, &share_size)); |
@@ -376,7 +447,7 @@ GNUNET_SECRETSHARING_encrypt (const struct GNUNET_SECRETSHARING_PublicKey *publi | |||
376 | 447 | ||
377 | // Randomize y such that 0 < y < elgamal_q. | 448 | // Randomize y such that 0 < y < elgamal_q. |
378 | // The '- 1' is necessary as bitlength(q) = bitlength(p) - 1. | 449 | // The '- 1' is necessary as bitlength(q) = bitlength(p) - 1. |
379 | do | 450 | do |
380 | { | 451 | { |
381 | gcry_mpi_randomize (y, GNUNET_SECRETSHARING_ELGAMAL_BITS - 1, GCRY_WEAK_RANDOM); | 452 | gcry_mpi_randomize (y, GNUNET_SECRETSHARING_ELGAMAL_BITS - 1, GCRY_WEAK_RANDOM); |
382 | } while ((gcry_mpi_cmp_ui (y, 0) == 0) || (gcry_mpi_cmp (y, elgamal_q) >= 0)); | 453 | } while ((gcry_mpi_cmp_ui (y, 0) == 0) || (gcry_mpi_cmp (y, elgamal_q) >= 0)); |
@@ -386,10 +457,10 @@ GNUNET_SECRETSHARING_encrypt (const struct GNUNET_SECRETSHARING_PublicKey *publi | |||
386 | // write tmp to c1 | 457 | // write tmp to c1 |
387 | GNUNET_CRYPTO_mpi_print_unsigned (&result_ciphertext->c1_bits, | 458 | GNUNET_CRYPTO_mpi_print_unsigned (&result_ciphertext->c1_bits, |
388 | GNUNET_SECRETSHARING_ELGAMAL_BITS / 8, tmp); | 459 | GNUNET_SECRETSHARING_ELGAMAL_BITS / 8, tmp); |
389 | 460 | ||
390 | // tmp <- h^y | 461 | // tmp <- h^y |
391 | gcry_mpi_powm (tmp, h, y, elgamal_p); | 462 | gcry_mpi_powm (tmp, h, y, elgamal_p); |
392 | // tmp <- tmp * m | 463 | // tmp <- tmp * m |
393 | gcry_mpi_mulm (tmp, tmp, m, elgamal_p); | 464 | gcry_mpi_mulm (tmp, tmp, m, elgamal_p); |
394 | // write tmp to c2 | 465 | // write tmp to c2 |
395 | GNUNET_CRYPTO_mpi_print_unsigned (&result_ciphertext->c2_bits, | 466 | GNUNET_CRYPTO_mpi_print_unsigned (&result_ciphertext->c2_bits, |
@@ -399,15 +470,22 @@ GNUNET_SECRETSHARING_encrypt (const struct GNUNET_SECRETSHARING_PublicKey *publi | |||
399 | } | 470 | } |
400 | 471 | ||
401 | 472 | ||
473 | /** | ||
474 | * Cancel a decryption. | ||
475 | * | ||
476 | * The decrypt_cb is not called anymore, but the calling | ||
477 | * peer may already have irrevocably contributed his share for the decryption of the value. | ||
478 | * | ||
479 | * @param dh to cancel | ||
480 | */ | ||
402 | void | 481 | void |
403 | GNUNET_SECRETSHARING_decrypt_cancel (struct GNUNET_SECRETSHARING_DecryptionHandle *h) | 482 | GNUNET_SECRETSHARING_decrypt_cancel (struct GNUNET_SECRETSHARING_DecryptionHandle *dh) |
404 | { | 483 | { |
405 | GNUNET_MQ_destroy (h->mq); | 484 | GNUNET_MQ_destroy (dh->mq); |
406 | h->mq = NULL; | 485 | dh->mq = NULL; |
407 | GNUNET_CLIENT_disconnect (h->client); | 486 | GNUNET_CLIENT_disconnect (dh->client); |
408 | h->client = NULL; | 487 | dh->client = NULL; |
409 | GNUNET_free (h); | 488 | GNUNET_free (dh); |
410 | } | 489 | } |
411 | 490 | ||
412 | 491 | /* end of secretsharing_api.c */ | |
413 | |||