aboutsummaryrefslogtreecommitdiff
path: root/src/revocation/gnunet-revocation.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/revocation/gnunet-revocation.c')
-rw-r--r--src/revocation/gnunet-revocation.c210
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 */
34static 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;
55static char *test_ego; 59static char *test_ego;
56 60
57/** 61/**
62 * -e option.
63 */
64static unsigned int epochs = 1;
65
66/**
58 * Handle for revocation query. 67 * Handle for revocation query.
59 */ 68 */
60static struct GNUNET_REVOCATION_Query *q; 69static struct GNUNET_REVOCATION_Query *q;
@@ -80,10 +89,19 @@ static const struct GNUNET_CONFIGURATION_Handle *cfg;
80static unsigned long long matching_bits; 89static unsigned long long matching_bits;
81 90
82/** 91/**
92 * Epoch length
93 */
94static 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 */
85static struct GNUNET_SCHEDULER_Task *pow_task; 99static struct GNUNET_SCHEDULER_Task *pow_task;
86 100
101/**
102 * Proof-of-work object
103 */
104static 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;
93static void 111static void
94do_shutdown (void *cls) 112do_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 */
193struct 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 */
215static void 212static void
216perform_revocation (const struct RevocationData *rd) 213perform_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 */
233static void 228static void
234sync_rd (const struct RevocationData *rd) 229sync_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)
252static void 247static void
253calculate_pow_shutdown (void *cls) 248calculate_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)
272static void 268static void
273calculate_pow (void *cls) 269calculate_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)
329static void 325static void
330ego_callback (void *cls, const struct GNUNET_IDENTITY_Ego *ego) 326ego_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 };