diff options
Diffstat (limited to 'src/revocation/gnunet-revocation.c')
-rw-r--r-- | src/revocation/gnunet-revocation.c | 210 |
1 files changed, 119 insertions, 91 deletions
diff --git a/src/revocation/gnunet-revocation.c b/src/revocation/gnunet-revocation.c index 14e23b244..8b7cf33c6 100644 --- a/src/revocation/gnunet-revocation.c +++ b/src/revocation/gnunet-revocation.c | |||
@@ -28,6 +28,10 @@ | |||
28 | #include "gnunet_revocation_service.h" | 28 | #include "gnunet_revocation_service.h" |
29 | #include "gnunet_identity_service.h" | 29 | #include "gnunet_identity_service.h" |
30 | 30 | ||
31 | /** | ||
32 | * Pow passes | ||
33 | */ | ||
34 | static unsigned int pow_passes = 1; | ||
31 | 35 | ||
32 | /** | 36 | /** |
33 | * Final status code. | 37 | * Final status code. |
@@ -55,6 +59,11 @@ static char *revoke_ego; | |||
55 | static char *test_ego; | 59 | static char *test_ego; |
56 | 60 | ||
57 | /** | 61 | /** |
62 | * -e option. | ||
63 | */ | ||
64 | static unsigned int epochs = 1; | ||
65 | |||
66 | /** | ||
58 | * Handle for revocation query. | 67 | * Handle for revocation query. |
59 | */ | 68 | */ |
60 | static struct GNUNET_REVOCATION_Query *q; | 69 | static struct GNUNET_REVOCATION_Query *q; |
@@ -80,10 +89,19 @@ static const struct GNUNET_CONFIGURATION_Handle *cfg; | |||
80 | static unsigned long long matching_bits; | 89 | static unsigned long long matching_bits; |
81 | 90 | ||
82 | /** | 91 | /** |
92 | * Epoch length | ||
93 | */ | ||
94 | static struct GNUNET_TIME_Relative epoch_duration; | ||
95 | |||
96 | /** | ||
83 | * Task used for proof-of-work calculation. | 97 | * Task used for proof-of-work calculation. |
84 | */ | 98 | */ |
85 | static struct GNUNET_SCHEDULER_Task *pow_task; | 99 | static struct GNUNET_SCHEDULER_Task *pow_task; |
86 | 100 | ||
101 | /** | ||
102 | * Proof-of-work object | ||
103 | */ | ||
104 | static struct GNUNET_REVOCATION_Pow proof_of_work; | ||
87 | 105 | ||
88 | /** | 106 | /** |
89 | * Function run if the user aborts with CTRL-C. | 107 | * Function run if the user aborts with CTRL-C. |
@@ -93,6 +111,7 @@ static struct GNUNET_SCHEDULER_Task *pow_task; | |||
93 | static void | 111 | static void |
94 | do_shutdown (void *cls) | 112 | do_shutdown (void *cls) |
95 | { | 113 | { |
114 | fprintf (stderr, "%s", _ ("Shutting down...\n")); | ||
96 | if (NULL != el) | 115 | if (NULL != el) |
97 | { | 116 | { |
98 | GNUNET_IDENTITY_ego_lookup_cancel (el); | 117 | GNUNET_IDENTITY_ego_lookup_cancel (el); |
@@ -188,37 +207,13 @@ print_revocation_result (void *cls, int is_valid) | |||
188 | 207 | ||
189 | 208 | ||
190 | /** | 209 | /** |
191 | * Data needed to perform a revocation. | ||
192 | */ | ||
193 | struct RevocationData | ||
194 | { | ||
195 | /** | ||
196 | * Public key. | ||
197 | */ | ||
198 | struct GNUNET_CRYPTO_EcdsaPublicKey key; | ||
199 | |||
200 | /** | ||
201 | * Revocation signature data. | ||
202 | */ | ||
203 | struct GNUNET_CRYPTO_EcdsaSignature sig; | ||
204 | |||
205 | /** | ||
206 | * Proof of work (in NBO). | ||
207 | */ | ||
208 | uint64_t pow GNUNET_PACKED; | ||
209 | }; | ||
210 | |||
211 | |||
212 | /** | ||
213 | * Perform the revocation. | 210 | * Perform the revocation. |
214 | */ | 211 | */ |
215 | static void | 212 | static void |
216 | perform_revocation (const struct RevocationData *rd) | 213 | perform_revocation () |
217 | { | 214 | { |
218 | h = GNUNET_REVOCATION_revoke (cfg, | 215 | h = GNUNET_REVOCATION_revoke (cfg, |
219 | &rd->key, | 216 | &proof_of_work, |
220 | &rd->sig, | ||
221 | rd->pow, | ||
222 | &print_revocation_result, | 217 | &print_revocation_result, |
223 | NULL); | 218 | NULL); |
224 | } | 219 | } |
@@ -231,13 +226,13 @@ perform_revocation (const struct RevocationData *rd) | |||
231 | * @param rd data to sync | 226 | * @param rd data to sync |
232 | */ | 227 | */ |
233 | static void | 228 | static void |
234 | sync_rd (const struct RevocationData *rd) | 229 | sync_pow () |
235 | { | 230 | { |
236 | if ((NULL != filename) && | 231 | if ((NULL != filename) && |
237 | (sizeof(struct RevocationData) == | 232 | (sizeof(struct GNUNET_REVOCATION_Pow) != |
238 | GNUNET_DISK_fn_write (filename, | 233 | GNUNET_DISK_fn_write (filename, |
239 | &rd, | 234 | &proof_of_work, |
240 | sizeof(rd), | 235 | sizeof(struct GNUNET_REVOCATION_Pow), |
241 | GNUNET_DISK_PERM_USER_READ | 236 | GNUNET_DISK_PERM_USER_READ |
242 | | GNUNET_DISK_PERM_USER_WRITE))) | 237 | | GNUNET_DISK_PERM_USER_WRITE))) |
243 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "write", filename); | 238 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "write", filename); |
@@ -252,15 +247,16 @@ sync_rd (const struct RevocationData *rd) | |||
252 | static void | 247 | static void |
253 | calculate_pow_shutdown (void *cls) | 248 | calculate_pow_shutdown (void *cls) |
254 | { | 249 | { |
255 | struct RevocationData *rd = cls; | 250 | struct GNUNET_REVOCATION_PowCalculationHandle *ph = cls; |
256 | 251 | fprintf (stderr, "%s", _ ("Cancelling calculation.\n")); | |
252 | sync_pow (); | ||
257 | if (NULL != pow_task) | 253 | if (NULL != pow_task) |
258 | { | 254 | { |
259 | GNUNET_SCHEDULER_cancel (pow_task); | 255 | GNUNET_SCHEDULER_cancel (pow_task); |
260 | pow_task = NULL; | 256 | pow_task = NULL; |
261 | } | 257 | } |
262 | sync_rd (rd); | 258 | if (NULL != ph) |
263 | GNUNET_free (rd); | 259 | GNUNET_REVOCATION_pow_stop (ph); |
264 | } | 260 | } |
265 | 261 | ||
266 | 262 | ||
@@ -272,38 +268,26 @@ calculate_pow_shutdown (void *cls) | |||
272 | static void | 268 | static void |
273 | calculate_pow (void *cls) | 269 | calculate_pow (void *cls) |
274 | { | 270 | { |
275 | struct RevocationData *rd = cls; | 271 | struct GNUNET_REVOCATION_PowCalculationHandle *ph = cls; |
276 | 272 | ||
277 | /* store temporary results */ | 273 | /* store temporary results */ |
278 | pow_task = NULL; | 274 | pow_task = NULL; |
279 | if (0 == (rd->pow % 128)) | 275 | if (0 == (pow_passes % 128)) |
280 | sync_rd (rd); | 276 | sync_pow (); |
281 | /* display progress estimate */ | ||
282 | if ((0 == ((1 << matching_bits) / 100 / 50)) || | ||
283 | (0 == (rd->pow % ((1 << matching_bits) / 100 / 50)))) | ||
284 | fprintf (stderr, "%s", "."); | ||
285 | if ((0 != rd->pow) && ((0 == ((1 << matching_bits) / 100)) || | ||
286 | (0 == (rd->pow % ((1 << matching_bits) / 100))))) | ||
287 | fprintf (stderr, | ||
288 | " - @ %3u%% (estimate)\n", | ||
289 | (unsigned int) (rd->pow * 100) / (1 << matching_bits)); | ||
290 | /* actually do POW calculation */ | 277 | /* actually do POW calculation */ |
291 | rd->pow++; | 278 | if (GNUNET_OK == GNUNET_REVOCATION_pow_round (ph)) |
292 | if (GNUNET_OK == GNUNET_REVOCATION_check_pow (&rd->key, | ||
293 | rd->pow, | ||
294 | (unsigned int) matching_bits)) | ||
295 | { | 279 | { |
296 | if ((NULL != filename) && | 280 | if ((NULL != filename) && |
297 | (sizeof(struct RevocationData) != | 281 | (sizeof(struct GNUNET_REVOCATION_Pow) != |
298 | GNUNET_DISK_fn_write (filename, | 282 | GNUNET_DISK_fn_write (filename, |
299 | rd, | 283 | &proof_of_work, |
300 | sizeof(struct RevocationData), | 284 | sizeof(struct GNUNET_REVOCATION_Pow), |
301 | GNUNET_DISK_PERM_USER_READ | 285 | GNUNET_DISK_PERM_USER_READ |
302 | | GNUNET_DISK_PERM_USER_WRITE))) | 286 | | GNUNET_DISK_PERM_USER_WRITE))) |
303 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "write", filename); | 287 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "write", filename); |
304 | if (perform) | 288 | if (perform) |
305 | { | 289 | { |
306 | perform_revocation (rd); | 290 | perform_revocation (); |
307 | } | 291 | } |
308 | else | 292 | else |
309 | { | 293 | { |
@@ -316,7 +300,19 @@ calculate_pow (void *cls) | |||
316 | } | 300 | } |
317 | return; | 301 | return; |
318 | } | 302 | } |
319 | pow_task = GNUNET_SCHEDULER_add_now (&calculate_pow, rd); | 303 | pow_passes++; |
304 | /** | ||
305 | * Otherwise CTRL-C does not work | ||
306 | */ | ||
307 | if (0 == pow_passes % 128) | ||
308 | pow_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MILLISECONDS, | ||
309 | &calculate_pow, | ||
310 | ph); | ||
311 | else | ||
312 | pow_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MILLISECONDS, | ||
313 | &calculate_pow, | ||
314 | ph); | ||
315 | |||
320 | } | 316 | } |
321 | 317 | ||
322 | 318 | ||
@@ -329,8 +325,9 @@ calculate_pow (void *cls) | |||
329 | static void | 325 | static void |
330 | ego_callback (void *cls, const struct GNUNET_IDENTITY_Ego *ego) | 326 | ego_callback (void *cls, const struct GNUNET_IDENTITY_Ego *ego) |
331 | { | 327 | { |
332 | struct RevocationData *rd; | ||
333 | struct GNUNET_CRYPTO_EcdsaPublicKey key; | 328 | struct GNUNET_CRYPTO_EcdsaPublicKey key; |
329 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *privkey; | ||
330 | struct GNUNET_REVOCATION_PowCalculationHandle *ph = NULL; | ||
334 | 331 | ||
335 | el = NULL; | 332 | el = NULL; |
336 | if (NULL == ego) | 333 | if (NULL == ego) |
@@ -340,44 +337,55 @@ ego_callback (void *cls, const struct GNUNET_IDENTITY_Ego *ego) | |||
340 | return; | 337 | return; |
341 | } | 338 | } |
342 | GNUNET_IDENTITY_ego_get_public_key (ego, &key); | 339 | GNUNET_IDENTITY_ego_get_public_key (ego, &key); |
343 | rd = GNUNET_new (struct RevocationData); | 340 | privkey = GNUNET_IDENTITY_ego_get_private_key (ego); |
341 | memset (&proof_of_work, 0, sizeof (proof_of_work)); | ||
344 | if ((NULL != filename) && (GNUNET_YES == GNUNET_DISK_file_test (filename)) && | 342 | if ((NULL != filename) && (GNUNET_YES == GNUNET_DISK_file_test (filename)) && |
345 | (sizeof(struct RevocationData) == | 343 | (sizeof(proof_of_work) == |
346 | GNUNET_DISK_fn_read (filename, rd, sizeof(struct RevocationData)))) | 344 | GNUNET_DISK_fn_read (filename, &proof_of_work, sizeof(proof_of_work)))) |
347 | { | 345 | { |
348 | if (0 != GNUNET_memcmp (&rd->key, &key)) | 346 | if (0 != GNUNET_memcmp (&proof_of_work.key, &key)) |
349 | { | 347 | { |
350 | fprintf (stderr, | 348 | fprintf (stderr, |
351 | _ ("Error: revocation certificate in `%s' is not for `%s'\n"), | 349 | _ ("Error: revocation certificate in `%s' is not for `%s'\n"), |
352 | filename, | 350 | filename, |
353 | revoke_ego); | 351 | revoke_ego); |
354 | GNUNET_free (rd); | ||
355 | return; | 352 | return; |
356 | } | 353 | } |
357 | } | 354 | if (GNUNET_YES == |
358 | else | 355 | GNUNET_REVOCATION_check_pow (&proof_of_work, |
359 | { | 356 | (unsigned int) matching_bits, |
360 | GNUNET_REVOCATION_sign_revocation (GNUNET_IDENTITY_ego_get_private_key ( | 357 | epoch_duration)) |
361 | ego), | 358 | { |
362 | &rd->sig); | 359 | fprintf (stderr, "%s", _ ("Revocation certificate ready\n")); |
363 | rd->key = key; | 360 | if (perform) |
364 | } | 361 | perform_revocation (); |
365 | if (GNUNET_YES == | 362 | else |
366 | GNUNET_REVOCATION_check_pow (&key, rd->pow, (unsigned int) matching_bits)) | 363 | GNUNET_SCHEDULER_shutdown (); |
367 | { | 364 | return; |
368 | fprintf (stderr, "%s", _ ("Revocation certificate ready\n")); | 365 | } |
369 | if (perform) | 366 | /** |
370 | perform_revocation (rd); | 367 | * Certificate not yet ready |
371 | else | 368 | */ |
372 | GNUNET_SCHEDULER_shutdown (); | 369 | fprintf (stderr, |
373 | GNUNET_free (rd); | 370 | "%s", |
374 | return; | 371 | _ ("Continuing calculation where left off...\n")); |
372 | ph = GNUNET_REVOCATION_pow_start (&proof_of_work, | ||
373 | epochs, | ||
374 | matching_bits); | ||
375 | } | 375 | } |
376 | fprintf (stderr, | 376 | fprintf (stderr, |
377 | "%s", | 377 | "%s", |
378 | _ ("Revocation certificate not ready, calculating proof of work\n")); | 378 | _ ("Revocation certificate not ready, calculating proof of work\n")); |
379 | pow_task = GNUNET_SCHEDULER_add_now (&calculate_pow, rd); | 379 | if (NULL == ph) |
380 | GNUNET_SCHEDULER_add_shutdown (&calculate_pow_shutdown, rd); | 380 | { |
381 | GNUNET_REVOCATION_pow_init (privkey, | ||
382 | &proof_of_work); | ||
383 | ph = GNUNET_REVOCATION_pow_start (&proof_of_work, | ||
384 | epochs, /* Epochs */ | ||
385 | matching_bits); | ||
386 | } | ||
387 | pow_task = GNUNET_SCHEDULER_add_now (&calculate_pow, ph); | ||
388 | GNUNET_SCHEDULER_add_shutdown (&calculate_pow_shutdown, ph); | ||
381 | } | 389 | } |
382 | 390 | ||
383 | 391 | ||
@@ -396,7 +404,6 @@ run (void *cls, | |||
396 | const struct GNUNET_CONFIGURATION_Handle *c) | 404 | const struct GNUNET_CONFIGURATION_Handle *c) |
397 | { | 405 | { |
398 | struct GNUNET_CRYPTO_EcdsaPublicKey pk; | 406 | struct GNUNET_CRYPTO_EcdsaPublicKey pk; |
399 | struct RevocationData rd; | ||
400 | 407 | ||
401 | cfg = c; | 408 | cfg = c; |
402 | if (NULL != test_ego) | 409 | if (NULL != test_ego) |
@@ -429,6 +436,17 @@ run (void *cls, | |||
429 | "WORKBITS"); | 436 | "WORKBITS"); |
430 | return; | 437 | return; |
431 | } | 438 | } |
439 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_time (cfg, | ||
440 | "REVOCATION", | ||
441 | "EPOCH_DURATION", | ||
442 | &epoch_duration)) | ||
443 | { | ||
444 | GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, | ||
445 | "REVOCATION", | ||
446 | "EPOCH_DURATION"); | ||
447 | return; | ||
448 | } | ||
449 | |||
432 | if (NULL != revoke_ego) | 450 | if (NULL != revoke_ego) |
433 | { | 451 | { |
434 | if (! perform && (NULL == filename)) | 452 | if (! perform && (NULL == filename)) |
@@ -445,7 +463,9 @@ run (void *cls, | |||
445 | } | 463 | } |
446 | if ((NULL != filename) && (perform)) | 464 | if ((NULL != filename) && (perform)) |
447 | { | 465 | { |
448 | if (sizeof(rd) != GNUNET_DISK_fn_read (filename, &rd, sizeof(rd))) | 466 | if (sizeof(proof_of_work) != GNUNET_DISK_fn_read (filename, |
467 | &proof_of_work, | ||
468 | sizeof(proof_of_work))) | ||
449 | { | 469 | { |
450 | fprintf (stderr, | 470 | fprintf (stderr, |
451 | _ ("Failed to read revocation certificate from `%s'\n"), | 471 | _ ("Failed to read revocation certificate from `%s'\n"), |
@@ -454,18 +474,20 @@ run (void *cls, | |||
454 | } | 474 | } |
455 | GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL); | 475 | GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL); |
456 | if (GNUNET_YES != | 476 | if (GNUNET_YES != |
457 | GNUNET_REVOCATION_check_pow (&rd.key, | 477 | GNUNET_REVOCATION_check_pow (&proof_of_work, |
458 | rd.pow, | 478 | (unsigned int) matching_bits, |
459 | (unsigned int) matching_bits)) | 479 | epoch_duration)) |
460 | { | 480 | { |
461 | struct RevocationData *cp = GNUNET_new (struct RevocationData); | 481 | struct GNUNET_REVOCATION_PowCalculationHandle *ph; |
482 | ph = GNUNET_REVOCATION_pow_start (&proof_of_work, | ||
483 | epochs, /* Epochs */ | ||
484 | matching_bits); | ||
462 | 485 | ||
463 | *cp = rd; | 486 | pow_task = GNUNET_SCHEDULER_add_now (&calculate_pow, ph); |
464 | pow_task = GNUNET_SCHEDULER_add_now (&calculate_pow, cp); | 487 | GNUNET_SCHEDULER_add_shutdown (&calculate_pow_shutdown, ph); |
465 | GNUNET_SCHEDULER_add_shutdown (&calculate_pow_shutdown, cp); | ||
466 | return; | 488 | return; |
467 | } | 489 | } |
468 | perform_revocation (&rd); | 490 | perform_revocation (); |
469 | return; | 491 | return; |
470 | } | 492 | } |
471 | fprintf (stderr, "%s", _ ("No action specified. Nothing to do.\n")); | 493 | fprintf (stderr, "%s", _ ("No action specified. Nothing to do.\n")); |
@@ -511,6 +533,12 @@ main (int argc, char *const *argv) | |||
511 | gettext_noop ( | 533 | gettext_noop ( |
512 | "test if the public key KEY has been revoked"), | 534 | "test if the public key KEY has been revoked"), |
513 | &test_ego), | 535 | &test_ego), |
536 | GNUNET_GETOPT_option_uint ('e', | ||
537 | "epochs", | ||
538 | "EPOCHS", | ||
539 | gettext_noop ( | ||
540 | "number of epochs to calculate for"), | ||
541 | &epochs), | ||
514 | 542 | ||
515 | GNUNET_GETOPT_OPTION_END | 543 | GNUNET_GETOPT_OPTION_END |
516 | }; | 544 | }; |