GNUnet 0.21.1
gnunet-revocation.c
Go to the documentation of this file.
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
26#include "platform.h"
28#include "gnunet_util_lib.h"
30
34static unsigned int pow_passes = 1;
35
39static int ret;
40
44static int perform;
45
49static char *filename;
50
54static char *revoke_ego;
55
59static char *test_ego;
60
64static unsigned int epochs = 1;
65
70
75
80
84static const struct GNUNET_CONFIGURATION_Handle *cfg;
85
89static unsigned long long matching_bits;
90
95
100
105
111static void
112do_shutdown (void *cls)
113{
114 fprintf (stderr, "%s", _ ("Shutting down...\n"));
115 if (NULL != el)
116 {
118 el = NULL;
119 }
120 if (NULL != q)
121 {
123 q = NULL;
124 }
125 if (NULL != h)
126 {
128 h = NULL;
129 }
130}
131
132
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 }
162}
163
164
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 }
206}
207
208
212static void
214{
218 NULL);
219}
220
221
228static void
230{
232 if ((NULL != filename) &&
233 (GNUNET_OK !=
236 psize,
240}
241
242
248static void
250{
252 fprintf (stderr, "%s", _ ("Cancelling calculation.\n"));
253 sync_pow ();
254 if (NULL != pow_task)
255 {
257 pow_task = NULL;
258 }
259 if (NULL != ph)
261}
262
263
269static void
270calculate_pow (void *cls)
271{
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 */
281 {
283 if (NULL != filename)
284 {
286 if (GNUNET_OK !=
289 psize,
293 }
294 if (perform)
295 {
297 }
298 else
299 {
300 fprintf (stderr, "%s", "\n");
301 fprintf (stderr,
302 _ ("Revocation certificate for `%s' stored in `%s'\n"),
304 filename);
306 }
307 return;
308 }
309 pow_passes++;
312 ph);
313
314}
315
316
323static void
324ego_callback (void *cls, struct GNUNET_IDENTITY_Ego *ego)
325{
327 const struct GNUNET_CRYPTO_PrivateKey *privkey;
329 size_t psize;
330
331 el = NULL;
332 if (NULL == ego)
333 {
334 fprintf (stdout, _ ("Ego `%s' not found.\n"), revoke_ego);
336 return;
337 }
341 if ((NULL != filename) && (GNUNET_YES == GNUNET_DISK_file_test (filename)) &&
342 (0 < (psize =
345 {
346 ssize_t ksize = GNUNET_CRYPTO_public_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 ==
364 (unsigned int) matching_bits,
366 {
367 fprintf (stderr, "%s", _ ("Revocation certificate ready\n"));
368 if (perform)
370 else
372 return;
373 }
377 fprintf (stderr,
378 "%s",
379 _ ("Continuing calculation where left off...\n"));
381 epochs,
383 }
384 fprintf (stderr,
385 "%s",
386 _ ("Revocation certificate not ready, calculating proof of work\n"));
387 if (NULL == ph)
388 {
392 epochs, /* Epochs */
394 }
397}
398
399
408static void
409run (void *cls,
410 char *const *args,
411 const char *cfgfile,
412 const struct GNUNET_CONFIGURATION_Handle *c)
413{
415 size_t psize;
416
417 cfg = c;
418 if (NULL != test_ego)
419 {
420 if (GNUNET_OK !=
422 &pk))
423 {
424 fprintf (stderr, _ ("Public key `%s' malformed\n"), test_ego);
425 return;
426 }
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 }
438 "REVOCATION",
439 "WORKBITS",
441 {
443 "REVOCATION",
444 "WORKBITS");
445 return;
446 }
448 "REVOCATION",
449 "EPOCH_DURATION",
451 {
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 */
470 return;
471 }
472 if ((NULL != filename) && (perform))
473 {
474 size_t bread;
476 if (0 < (bread = GNUNET_DISK_fn_read (filename,
479 {
480 fprintf (stderr,
481 _ ("Failed to read revocation certificate from `%s'\n"),
482 filename);
483 return;
484 }
486 if (bread != psize)
487 {
488 fprintf (stderr,
489 _ ("Revocation certificate corrupted in `%s'\n"),
490 filename);
491 return;
492 }
494 if (GNUNET_YES !=
496 (unsigned int) matching_bits,
498 {
501 epochs, /* Epochs */
503
506 return;
507 }
509 return;
510 }
511 fprintf (stderr, "%s", _ ("No action specified. Nothing to do.\n"));
512}
513
514
522int
523main (int argc, char *const *argv)
524{
527 "filename",
528 "NAME",
530 "use NAME for the name of the revocation file"),
531 &filename),
532
534 'R',
535 "revoke",
536 "NAME",
538 "revoke the private key associated for the the private key associated with the ego NAME "),
539 &revoke_ego),
540
542 'p',
543 "perform",
545 "actually perform revocation, otherwise we just do the precomputation"),
546 &perform),
547
549 "test",
550 "KEY",
552 "test if the public key KEY has been revoked"),
553 &test_ego),
555 "epochs",
556 "EPOCHS",
558 "number of epochs to calculate for"),
559 &epochs),
560
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 */
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_OPTION_END
Definition: 002.c:13
struct GNUNET_GETOPT_CommandLineOption options[]
Definition: 002.c:5
#define gettext_noop(String)
Definition: gettext.h:70
struct GNUNET_HashCode key
The key used in the DHT.
struct GNUNET_CRYPTO_PrivateKey pk
Private key from command line option, or NULL.
static char * test_ego
-t option.
static struct GNUNET_REVOCATION_Query * q
Handle for revocation query.
static unsigned int pow_passes
Pow passes.
static struct GNUNET_TIME_Relative epoch_duration
Epoch length.
static const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
static void print_revocation_result(void *cls, int is_valid)
Print the result from a revocation request.
static unsigned long long matching_bits
Number of matching bits required for revocation.
static void ego_callback(void *cls, struct GNUNET_IDENTITY_Ego *ego)
Function called with the result from the ego lookup.
static struct GNUNET_GNSRECORD_PowP * proof_of_work
Proof-of-work object.
static int ret
Final status code.
static void do_shutdown(void *cls)
Function run if the user aborts with CTRL-C.
static struct GNUNET_IDENTITY_EgoLookup * el
Handle for our ego lookup.
static int perform
Was "-p" specified?
static unsigned int epochs
-e option.
static void run(void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *c)
Main function that will be run by the scheduler.
static struct GNUNET_SCHEDULER_Task * pow_task
Task used for proof-of-work calculation.
static void print_query_result(void *cls, int is_valid)
Print the result from a revocation query.
static void calculate_pow(void *cls)
Perform the proof-of-work calculation.
static struct GNUNET_REVOCATION_Handle * h
Handle for revocation.
static void calculate_pow_shutdown(void *cls)
Perform the proof-of-work calculation.
int main(int argc, char *const *argv)
The main function of gnunet-revocation.
static void sync_pow()
Write the current state of the revocation data to disk.
static char * revoke_ego
-R option
static char * filename
-f option.
static void perform_revocation()
Perform the revocation.
API that can be used to manipulate GNS record data.
API to perform and access key revocations.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_number(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, unsigned long long *number)
Get a configuration value that should be a number.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_time(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, struct GNUNET_TIME_Relative *time)
Get a configuration value that should be a relative time.
enum GNUNET_GenericReturnValue GNUNET_DISK_file_test(const char *fil)
Check that fil corresponds to a filename (of a file that exists and that is not a directory).
Definition: disk.c:482
enum GNUNET_GenericReturnValue GNUNET_DISK_fn_write(const char *fn, const void *buf, size_t buf_size, enum GNUNET_DISK_AccessPermissions mode)
Write a buffer to a file atomically.
Definition: disk.c:725
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_remove(const char *filename)
Remove all files in a directory (rm -rf).
Definition: disk.c:1087
ssize_t GNUNET_DISK_fn_read(const char *fn, void *result, size_t len)
Read the contents of a binary file into a buffer.
Definition: disk.c:664
@ GNUNET_DISK_PERM_USER_READ
Owner can read.
@ GNUNET_DISK_PERM_USER_WRITE
Owner can write.
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_uint(char shortName, const char *name, const char *argumentHelp, const char *description, unsigned int *val)
Allow user to specify an unsigned int.
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_flag(char shortName, const char *name, const char *description, int *val)
Allow user to specify a flag (which internally means setting an integer to 1/GNUNET_YES/GNUNET_OK.
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_string(char shortName, const char *name, const char *argumentHelp, const char *description, char **str)
Allow user to specify a string.
size_t GNUNET_GNSRECORD_proof_get_size(const struct GNUNET_GNSRECORD_PowP *pow)
void GNUNET_GNSRECORD_pow_stop(struct GNUNET_GNSRECORD_PowCalculationHandle *pc)
Stop a PoW calculation.
enum GNUNET_GenericReturnValue GNUNET_GNSRECORD_pow_round(struct GNUNET_GNSRECORD_PowCalculationHandle *pc)
Calculate a single round in the key revocation PoW.
void GNUNET_GNSRECORD_pow_init(const struct GNUNET_CRYPTO_PrivateKey *key, struct GNUNET_GNSRECORD_PowP *pow)
Initializes a fresh PoW computation.
struct GNUNET_GNSRECORD_PowCalculationHandle * GNUNET_GNSRECORD_pow_start(struct GNUNET_GNSRECORD_PowP *pow, int epochs, unsigned int difficulty)
Starts a proof-of-work calculation given the pow object as well as target epochs and difficulty.
#define GNUNET_MAX_POW_SIZE
Maximum length of a revocation.
enum GNUNET_GenericReturnValue GNUNET_GNSRECORD_check_pow(const struct GNUNET_GNSRECORD_PowP *pow, unsigned int matching_bits, struct GNUNET_TIME_Relative epoch_duration)
Check if the given proof-of-work is valid.
const struct GNUNET_CRYPTO_PrivateKey * GNUNET_IDENTITY_ego_get_private_key(const struct GNUNET_IDENTITY_Ego *ego)
Obtain the ECC key associated with a ego.
Definition: identity_api.c:517
struct GNUNET_IDENTITY_EgoLookup * GNUNET_IDENTITY_ego_lookup(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *name, GNUNET_IDENTITY_EgoCallback cb, void *cb_cls)
Lookup an ego by name.
void GNUNET_IDENTITY_ego_lookup_cancel(struct GNUNET_IDENTITY_EgoLookup *el)
Abort ego lookup attempt.
void GNUNET_IDENTITY_ego_get_public_key(struct GNUNET_IDENTITY_Ego *ego, struct GNUNET_CRYPTO_PublicKey *pk)
Get the identifier (public key) of an ego.
Definition: identity_api.c:529
ssize_t GNUNET_CRYPTO_public_key_get_length(const struct GNUNET_CRYPTO_PublicKey *key)
Get the compacted length of a GNUNET_CRYPTO_PublicKey.
Definition: crypto_pkey.c:68
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_public_key_from_string(const char *str, struct GNUNET_CRYPTO_PublicKey *key)
Parses a (Base32) string representation of the public key.
Definition: crypto_pkey.c:571
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
void GNUNET_log_config_missing(enum GNUNET_ErrorType kind, const char *section, const char *option)
Log error message about missing configuration option.
#define GNUNET_log_strerror_file(level, cmd, filename)
Log an error message at log-level 'level' that indicates a failure of the command 'cmd' with the mess...
@ GNUNET_ERROR_TYPE_ERROR
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free_nz(ptr)
Wrapper around free.
enum GNUNET_GenericReturnValue GNUNET_PROGRAM_run(int argc, char *const *argv, const char *binaryName, const char *binaryHelp, const struct GNUNET_GETOPT_CommandLineOption *options, GNUNET_PROGRAM_Main task, void *task_cls)
Run a standard GNUnet command startup sequence (initialize loggers and configuration,...
Definition: program.c:400
struct GNUNET_REVOCATION_Handle * GNUNET_REVOCATION_revoke(const struct GNUNET_CONFIGURATION_Handle *cfg, const struct GNUNET_GNSRECORD_PowP *pow, GNUNET_REVOCATION_Callback func, void *func_cls)
Perform key revocation.
void GNUNET_REVOCATION_query_cancel(struct GNUNET_REVOCATION_Query *q)
Cancel key revocation check.
void GNUNET_REVOCATION_revoke_cancel(struct GNUNET_REVOCATION_Handle *h)
Cancel key revocation.
struct GNUNET_REVOCATION_Query * GNUNET_REVOCATION_query(const struct GNUNET_CONFIGURATION_Handle *cfg, const struct GNUNET_CRYPTO_PublicKey *key, GNUNET_REVOCATION_Callback func, void *func_cls)
Check if a key was revoked.
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:567
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_shutdown(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run on shutdown, that is when a CTRL-C signal is received,...
Definition: scheduler.c:1340
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:981
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1305
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1278
enum GNUNET_GenericReturnValue GNUNET_STRINGS_get_utf8_args(int argc, char *const *argv, int *u8argc, char *const **u8argv)
Returns utf-8 encoded arguments.
Definition: strings.c:1230
#define GNUNET_TIME_UNIT_MILLISECONDS
One millisecond.
#define _(String)
GNU gettext support macro.
Definition: platform.h:178
A private key for an identity as per LSD0001.
An identity key as per LSD0001.
Definition of a command line option.
The handle to a PoW calculation.
Definition: gnsrecord_pow.c:56
Struct for a proof of work as part of the revocation.
Handle for ego lookup.
Handle for an ego.
Definition: identity.h:37
Handle for the key revocation operation.
Handle for the key revocation query.
Entry in list of pending tasks.
Definition: scheduler.c:136
Time for relative time used by GNUnet, in microseconds.