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.c581
1 files changed, 0 insertions, 581 deletions
diff --git a/src/revocation/gnunet-revocation.c b/src/revocation/gnunet-revocation.c
deleted file mode 100644
index a7f96385c..000000000
--- a/src/revocation/gnunet-revocation.c
+++ /dev/null
@@ -1,581 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2013 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your 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 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
21/**
22 * @file revocation/gnunet-revocation.c
23 * @brief tool for revoking public keys
24 * @author Christian Grothoff
25 */
26#include "platform.h"
27#include "gnunet_util_lib.h"
28#include "gnunet_revocation_service.h"
29#include "gnunet_identity_service.h"
30
31/**
32 * Pow passes
33 */
34static unsigned int pow_passes = 1;
35
36/**
37 * Final status code.
38 */
39static int ret;
40
41/**
42 * Was "-p" specified?
43 */
44static int perform;
45
46/**
47 * -f option.
48 */
49static char *filename;
50
51/**
52 * -R option
53 */
54static char *revoke_ego;
55
56/**
57 * -t option.
58 */
59static char *test_ego;
60
61/**
62 * -e option.
63 */
64static unsigned int epochs = 1;
65
66/**
67 * Handle for revocation query.
68 */
69static struct GNUNET_REVOCATION_Query *q;
70
71/**
72 * Handle for revocation.
73 */
74static struct GNUNET_REVOCATION_Handle *h;
75
76/**
77 * Handle for our ego lookup.
78 */
79static struct GNUNET_IDENTITY_EgoLookup *el;
80
81/**
82 * Our configuration.
83 */
84static const struct GNUNET_CONFIGURATION_Handle *cfg;
85
86/**
87 * Number of matching bits required for revocation.
88 */
89static unsigned long long matching_bits;
90
91/**
92 * Epoch length
93 */
94static struct GNUNET_TIME_Relative epoch_duration;
95
96/**
97 * Task used for proof-of-work calculation.
98 */
99static struct GNUNET_SCHEDULER_Task *pow_task;
100
101/**
102 * Proof-of-work object
103 */
104static struct GNUNET_REVOCATION_PowP *proof_of_work;
105
106/**
107 * Function run if the user aborts with CTRL-C.
108 *
109 * @param cls closure
110 */
111static void
112do_shutdown (void *cls)
113{
114 fprintf (stderr, "%s", _ ("Shutting down...\n"));
115 if (NULL != el)
116 {
117 GNUNET_IDENTITY_ego_lookup_cancel (el);
118 el = NULL;
119 }
120 if (NULL != q)
121 {
122 GNUNET_REVOCATION_query_cancel (q);
123 q = NULL;
124 }
125 if (NULL != h)
126 {
127 GNUNET_REVOCATION_revoke_cancel (h);
128 h = NULL;
129 }
130}
131
132
133/**
134 * Print the result from a revocation query.
135 *
136 * @param cls NULL
137 * @param is_valid #GNUNET_YES if the key is still valid, #GNUNET_NO if not, #GNUNET_SYSERR on error
138 */
139static void
140print_query_result (void *cls, int is_valid)
141{
142 q = NULL;
143 switch (is_valid)
144 {
145 case GNUNET_YES:
146 fprintf (stdout, _ ("Key `%s' is valid\n"), test_ego);
147 break;
148
149 case GNUNET_NO:
150 fprintf (stdout, _ ("Key `%s' has been revoked\n"), test_ego);
151 break;
152
153 case GNUNET_SYSERR:
154 fprintf (stdout, "%s", _ ("Internal error\n"));
155 break;
156
157 default:
158 GNUNET_break (0);
159 break;
160 }
161 GNUNET_SCHEDULER_shutdown ();
162}
163
164
165/**
166 * Print the result from a revocation request.
167 *
168 * @param cls NULL
169 * @param is_valid #GNUNET_YES if the key is still valid, #GNUNET_NO if not, #GNUNET_SYSERR on error
170 */
171static void
172print_revocation_result (void *cls, int is_valid)
173{
174 h = NULL;
175 switch (is_valid)
176 {
177 case GNUNET_YES:
178 if (NULL != revoke_ego)
179 fprintf (stdout,
180 _ ("Key for ego `%s' is still valid, revocation failed (!)\n"),
181 revoke_ego);
182 else
183 fprintf (stdout, "%s", _ ("Revocation failed (!)\n"));
184 break;
185
186 case GNUNET_NO:
187 if (NULL != revoke_ego)
188 fprintf (stdout,
189 _ ("Key for ego `%s' has been successfully revoked\n"),
190 revoke_ego);
191 else
192 fprintf (stdout, "%s", _ ("Revocation successful.\n"));
193 break;
194
195 case GNUNET_SYSERR:
196 fprintf (stdout,
197 "%s",
198 _ ("Internal error, key revocation might have failed\n"));
199 break;
200
201 default:
202 GNUNET_break (0);
203 break;
204 }
205 GNUNET_SCHEDULER_shutdown ();
206}
207
208
209/**
210 * Perform the revocation.
211 */
212static void
213perform_revocation ()
214{
215 h = GNUNET_REVOCATION_revoke (cfg,
216 proof_of_work,
217 &print_revocation_result,
218 NULL);
219}
220
221
222/**
223 * Write the current state of the revocation data
224 * to disk.
225 *
226 * @param rd data to sync
227 */
228static void
229sync_pow ()
230{
231 size_t psize = GNUNET_REVOCATION_proof_get_size (proof_of_work);
232 if ((NULL != filename) &&
233 (GNUNET_OK !=
234 GNUNET_DISK_fn_write (filename,
235 proof_of_work,
236 psize,
237 GNUNET_DISK_PERM_USER_READ
238 | GNUNET_DISK_PERM_USER_WRITE)))
239 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "write", filename);
240}
241
242
243/**
244 * Perform the proof-of-work calculation.
245 *
246 * @param cls the `struct RevocationData`
247 */
248static void
249calculate_pow_shutdown (void *cls)
250{
251 struct GNUNET_REVOCATION_PowCalculationHandle *ph = cls;
252 fprintf (stderr, "%s", _ ("Cancelling calculation.\n"));
253 sync_pow ();
254 if (NULL != pow_task)
255 {
256 GNUNET_SCHEDULER_cancel (pow_task);
257 pow_task = NULL;
258 }
259 if (NULL != ph)
260 GNUNET_REVOCATION_pow_stop (ph);
261}
262
263
264/**
265 * Perform the proof-of-work calculation.
266 *
267 * @param cls the `struct RevocationData`
268 */
269static void
270calculate_pow (void *cls)
271{
272 struct GNUNET_REVOCATION_PowCalculationHandle *ph = cls;
273 size_t psize;
274
275 /* store temporary results */
276 pow_task = NULL;
277 if (0 == (pow_passes % 128))
278 sync_pow ();
279 /* actually do POW calculation */
280 if (GNUNET_OK == GNUNET_REVOCATION_pow_round (ph))
281 {
282 psize = GNUNET_REVOCATION_proof_get_size (proof_of_work);
283 if (NULL != filename)
284 {
285 (void) GNUNET_DISK_directory_remove (filename);
286 if (GNUNET_OK !=
287 GNUNET_DISK_fn_write (filename,
288 proof_of_work,
289 psize,
290 GNUNET_DISK_PERM_USER_READ
291 | GNUNET_DISK_PERM_USER_WRITE))
292 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "write", filename);
293 }
294 if (perform)
295 {
296 perform_revocation ();
297 }
298 else
299 {
300 fprintf (stderr, "%s", "\n");
301 fprintf (stderr,
302 _ ("Revocation certificate for `%s' stored in `%s'\n"),
303 revoke_ego,
304 filename);
305 GNUNET_SCHEDULER_shutdown ();
306 }
307 return;
308 }
309 pow_passes++;
310 pow_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MILLISECONDS,
311 &calculate_pow,
312 ph);
313
314}
315
316
317/**
318 * Function called with the result from the ego lookup.
319 *
320 * @param cls closure
321 * @param ego the ego, NULL if not found
322 */
323static void
324ego_callback (void *cls, struct GNUNET_IDENTITY_Ego *ego)
325{
326 struct GNUNET_IDENTITY_PublicKey key;
327 const struct GNUNET_IDENTITY_PrivateKey *privkey;
328 struct GNUNET_REVOCATION_PowCalculationHandle *ph = NULL;
329 size_t psize;
330
331 el = NULL;
332 if (NULL == ego)
333 {
334 fprintf (stdout, _ ("Ego `%s' not found.\n"), revoke_ego);
335 GNUNET_SCHEDULER_shutdown ();
336 return;
337 }
338 GNUNET_IDENTITY_ego_get_public_key (ego, &key);
339 privkey = GNUNET_IDENTITY_ego_get_private_key (ego);
340 proof_of_work = GNUNET_malloc (GNUNET_REVOCATION_MAX_PROOF_SIZE);
341 if ((NULL != filename) && (GNUNET_YES == GNUNET_DISK_file_test (filename)) &&
342 (0 < (psize =
343 GNUNET_DISK_fn_read (filename, proof_of_work,
344 GNUNET_REVOCATION_MAX_PROOF_SIZE))))
345 {
346 ssize_t ksize = GNUNET_IDENTITY_key_get_length (&key);
347 if (0 > ksize)
348 {
349 fprintf (stderr,
350 _ ("Error: Key is invalid\n"));
351 return;
352 }
353 if (((psize - sizeof (*proof_of_work)) < ksize) || // Key too small
354 (0 != memcmp (&proof_of_work[1], &key, ksize))) // Keys do not match
355 {
356 fprintf (stderr,
357 _ ("Error: revocation certificate in `%s' is not for `%s'\n"),
358 filename,
359 revoke_ego);
360 return;
361 }
362 if (GNUNET_YES ==
363 GNUNET_REVOCATION_check_pow (proof_of_work,
364 (unsigned int) matching_bits,
365 epoch_duration))
366 {
367 fprintf (stderr, "%s", _ ("Revocation certificate ready\n"));
368 if (perform)
369 perform_revocation ();
370 else
371 GNUNET_SCHEDULER_shutdown ();
372 return;
373 }
374 /**
375 * Certificate not yet ready
376 */
377 fprintf (stderr,
378 "%s",
379 _ ("Continuing calculation where left off...\n"));
380 ph = GNUNET_REVOCATION_pow_start (proof_of_work,
381 epochs,
382 matching_bits);
383 }
384 fprintf (stderr,
385 "%s",
386 _ ("Revocation certificate not ready, calculating proof of work\n"));
387 if (NULL == ph)
388 {
389 GNUNET_REVOCATION_pow_init (privkey,
390 proof_of_work);
391 ph = GNUNET_REVOCATION_pow_start (proof_of_work,
392 epochs, /* Epochs */
393 matching_bits);
394 }
395 pow_task = GNUNET_SCHEDULER_add_now (&calculate_pow, ph);
396 GNUNET_SCHEDULER_add_shutdown (&calculate_pow_shutdown, ph);
397}
398
399
400/**
401 * Main function that will be run by the scheduler.
402 *
403 * @param cls closure
404 * @param args remaining command-line arguments
405 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
406 * @param c configuration
407 */
408static void
409run (void *cls,
410 char *const *args,
411 const char *cfgfile,
412 const struct GNUNET_CONFIGURATION_Handle *c)
413{
414 struct GNUNET_IDENTITY_PublicKey pk;
415 size_t psize;
416
417 cfg = c;
418 if (NULL != test_ego)
419 {
420 if (GNUNET_OK !=
421 GNUNET_IDENTITY_public_key_from_string (test_ego,
422 &pk))
423 {
424 fprintf (stderr, _ ("Public key `%s' malformed\n"), test_ego);
425 return;
426 }
427 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL);
428 q = GNUNET_REVOCATION_query (cfg, &pk, &print_query_result, NULL);
429 if (NULL != revoke_ego)
430 fprintf (
431 stderr,
432 "%s",
433 _ (
434 "Testing and revoking at the same time is not allowed, only executing test.\n"));
435 return;
436 }
437 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (cfg,
438 "REVOCATION",
439 "WORKBITS",
440 &matching_bits))
441 {
442 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
443 "REVOCATION",
444 "WORKBITS");
445 return;
446 }
447 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_time (cfg,
448 "REVOCATION",
449 "EPOCH_DURATION",
450 &epoch_duration))
451 {
452 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
453 "REVOCATION",
454 "EPOCH_DURATION");
455 return;
456 }
457
458 if (NULL != revoke_ego)
459 {
460 if (! perform && (NULL == filename))
461 {
462 fprintf (stderr,
463 "%s",
464 _ ("No filename to store revocation certificate given.\n"));
465 return;
466 }
467 /* main code here */
468 el = GNUNET_IDENTITY_ego_lookup (cfg, revoke_ego, &ego_callback, NULL);
469 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL);
470 return;
471 }
472 if ((NULL != filename) && (perform))
473 {
474 size_t bread;
475 proof_of_work = GNUNET_malloc (GNUNET_REVOCATION_MAX_PROOF_SIZE);
476 if (0 < (bread = GNUNET_DISK_fn_read (filename,
477 proof_of_work,
478 GNUNET_REVOCATION_MAX_PROOF_SIZE)))
479 {
480 fprintf (stderr,
481 _ ("Failed to read revocation certificate from `%s'\n"),
482 filename);
483 return;
484 }
485 psize = GNUNET_REVOCATION_proof_get_size (proof_of_work);
486 if (bread != psize)
487 {
488 fprintf (stderr,
489 _ ("Revocation certificate corrupted in `%s'\n"),
490 filename);
491 return;
492 }
493 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL);
494 if (GNUNET_YES !=
495 GNUNET_REVOCATION_check_pow (proof_of_work,
496 (unsigned int) matching_bits,
497 epoch_duration))
498 {
499 struct GNUNET_REVOCATION_PowCalculationHandle *ph;
500 ph = GNUNET_REVOCATION_pow_start (proof_of_work,
501 epochs, /* Epochs */
502 matching_bits);
503
504 pow_task = GNUNET_SCHEDULER_add_now (&calculate_pow, ph);
505 GNUNET_SCHEDULER_add_shutdown (&calculate_pow_shutdown, ph);
506 return;
507 }
508 perform_revocation ();
509 return;
510 }
511 fprintf (stderr, "%s", _ ("No action specified. Nothing to do.\n"));
512}
513
514
515/**
516 * The main function of gnunet-revocation.
517 *
518 * @param argc number of arguments from the command line
519 * @param argv command line arguments
520 * @return 0 ok, 1 on error
521 */
522int
523main (int argc, char *const *argv)
524{
525 struct GNUNET_GETOPT_CommandLineOption options[] = {
526 GNUNET_GETOPT_option_string ('f',
527 "filename",
528 "NAME",
529 gettext_noop (
530 "use NAME for the name of the revocation file"),
531 &filename),
532
533 GNUNET_GETOPT_option_string (
534 'R',
535 "revoke",
536 "NAME",
537 gettext_noop (
538 "revoke the private key associated for the the private key associated with the ego NAME "),
539 &revoke_ego),
540
541 GNUNET_GETOPT_option_flag (
542 'p',
543 "perform",
544 gettext_noop (
545 "actually perform revocation, otherwise we just do the precomputation"),
546 &perform),
547
548 GNUNET_GETOPT_option_string ('t',
549 "test",
550 "KEY",
551 gettext_noop (
552 "test if the public key KEY has been revoked"),
553 &test_ego),
554 GNUNET_GETOPT_option_uint ('e',
555 "epochs",
556 "EPOCHS",
557 gettext_noop (
558 "number of epochs to calculate for"),
559 &epochs),
560
561 GNUNET_GETOPT_OPTION_END
562 };
563
564 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
565 return 2;
566
567 ret = (GNUNET_OK == GNUNET_PROGRAM_run (argc,
568 argv,
569 "gnunet-revocation",
570 gettext_noop ("help text"),
571 options,
572 &run,
573 NULL))
574 ? ret
575 : 1;
576 GNUNET_free_nz ((void *) argv);
577 return ret;
578}
579
580
581/* end of gnunet-revocation.c */