aboutsummaryrefslogtreecommitdiff
path: root/src/cli/revocation
diff options
context:
space:
mode:
Diffstat (limited to 'src/cli/revocation')
-rw-r--r--src/cli/revocation/Makefile.am52
-rw-r--r--src/cli/revocation/gnunet-revocation-tvg.c230
-rw-r--r--src/cli/revocation/gnunet-revocation.c581
-rw-r--r--src/cli/revocation/meson.build22
-rw-r--r--src/cli/revocation/test_local_revocation.py.in129
5 files changed, 1014 insertions, 0 deletions
diff --git a/src/cli/revocation/Makefile.am b/src/cli/revocation/Makefile.am
new file mode 100644
index 000000000..ffd76effa
--- /dev/null
+++ b/src/cli/revocation/Makefile.am
@@ -0,0 +1,52 @@
1# This Makefile.am is in the public domain
2AM_CPPFLAGS = -I$(top_srcdir)/src/include
3
4plugindir = $(libdir)/gnunet
5
6if USE_COVERAGE
7 AM_CFLAGS = --coverage -O0
8 XLIB = -lgcov
9endif
10
11pkgcfgdir= $(pkgdatadir)/config.d/
12
13libexecdir= $(pkglibdir)/libexec/
14
15bin_PROGRAMS = \
16 gnunet-revocation
17
18gnunet_revocation_SOURCES = \
19 gnunet-revocation.c
20gnunet_revocation_LDADD = \
21 $(top_builddir)/src/service/revocation/libgnunetrevocation.la \
22 $(top_builddir)/src/service/identity/libgnunetidentity.la \
23 $(top_builddir)/src/lib/gnsrecord/libgnunetgnsrecord.la \
24 $(top_builddir)/src/lib/util/libgnunetutil.la \
25 $(GN_LIBINTL)
26
27gnunet_revocation_tvg_SOURCES = \
28 gnunet-revocation-tvg.c
29gnunet_revocation_tvg_LDADD = \
30 $(top_builddir)/src/service/revocation/libgnunetrevocation.la \
31 $(top_builddir)/src/lib/gnsrecord/libgnunetgnsrecord.la \
32 $(top_builddir)/src/lib/util/libgnunetutil.la \
33 $(GN_LIBINTL)
34
35noinst_PROGRAMS = \
36 gnunet-revocation-tvg
37
38check_SCRIPTS = \
39 #test_local_revocation.py
40
41if ENABLE_TEST_RUN
42 AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH;unset XDG_DATA_HOME;unset XDG_CONFIG_HOME;
43 TESTS = \
44 $(check_SCRIPTS) \
45 $(check_PROGRAMS)
46endif
47
48test_local_revocation.py: test_local_revocation.py.in Makefile
49 $(AWK) -v bdir="$(bindir)" -v py="$(PYTHON)" -v awkay="$(AWK_BINARY)" -v pfx="$(prefix)" -v prl="$(PERL)" -v sysconfdirectory="$(sysconfdir)" -v pkgdatadirectory="$(pkgdatadir)" -f $(top_srcdir)/scripts/dosubst.awk < $(srcdir)/test_local_revocation.py.in > test_local_revocation.py
50 chmod +x test_local_revocation.py
51
52EXTRA_DIST = test_local_revocation.py.in
diff --git a/src/cli/revocation/gnunet-revocation-tvg.c b/src/cli/revocation/gnunet-revocation-tvg.c
new file mode 100644
index 000000000..5c2bfbe45
--- /dev/null
+++ b/src/cli/revocation/gnunet-revocation-tvg.c
@@ -0,0 +1,230 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2020 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 util/gnunet-revocation-tvg.c
23 * @brief Generate test vectors for revocation.
24 * @author Martin Schanzenbach
25 */
26#include "platform.h"
27#include "gnunet_util_lib.h"
28#include "gnunet_signatures.h"
29#include "gnunet_revocation_service.h"
30#include "gnunet_testing_lib.h"
31// FIXME try to avoid this include somehow
32#include "../../lib/gnsrecord/gnsrecord_crypto.h"
33#include <inttypes.h>
34
35#define TEST_EPOCHS 2
36#define TEST_DIFFICULTY 5
37
38static char*d_pkey =
39 "6fea32c05af58bfa979553d188605fd57d8bf9cc263b78d5f7478c07b998ed70";
40
41static char *d_edkey =
42 "5af7020ee19160328832352bbc6a68a8d71a7cbe1b929969a7c66d415a0d8f65";
43
44int
45parsehex (char *src, char *dst, size_t dstlen, int invert)
46{
47 char *line = src;
48 char *data = line;
49 int off;
50 int read_byte;
51 int data_len = 0;
52
53 while (sscanf (data, " %02x%n", &read_byte, &off) == 1)
54 {
55 if (invert)
56 dst[dstlen - 1 - data_len++] = read_byte;
57 else
58 dst[data_len++] = read_byte;
59 data += off;
60 }
61 return data_len;
62}
63
64
65static void
66print_bytes_ (void *buf,
67 size_t buf_len,
68 int fold,
69 int in_be)
70{
71 int i;
72
73 for (i = 0; i < buf_len; i++)
74 {
75 if (0 != i)
76 {
77 if ((0 != fold) && (i % fold == 0))
78 printf ("\n ");
79 else
80 printf (" ");
81 }
82 else
83 {
84 printf (" ");
85 }
86 if (in_be)
87 printf ("%02x", ((unsigned char*) buf)[buf_len - 1 - i]);
88 else
89 printf ("%02x", ((unsigned char*) buf)[i]);
90 }
91 printf ("\n");
92}
93
94
95static void
96print_bytes (void *buf,
97 size_t buf_len,
98 int fold)
99{
100 print_bytes_ (buf, buf_len, fold, 0);
101}
102
103
104static void
105run_with_key (struct GNUNET_CRYPTO_PrivateKey *id_priv)
106{
107 struct GNUNET_CRYPTO_PublicKey id_pub;
108 struct GNUNET_GNSRECORD_PowP *pow;
109 struct GNUNET_GNSRECORD_PowCalculationHandle *ph;
110 struct GNUNET_TIME_Relative exp;
111 char ztld[128];
112 ssize_t key_len;
113
114 GNUNET_CRYPTO_key_get_public (id_priv,
115 &id_pub);
116 GNUNET_STRINGS_data_to_string (&id_pub,
117 GNUNET_CRYPTO_public_key_get_length (
118 &id_pub),
119 ztld,
120 sizeof (ztld));
121 fprintf (stdout, "\n");
122 fprintf (stdout, "Zone identifier (ztype|zkey):\n");
123 key_len = GNUNET_CRYPTO_public_key_get_length (&id_pub);
124 GNUNET_assert (0 < key_len);
125 print_bytes (&id_pub, key_len, 8);
126 fprintf (stdout, "\n");
127 fprintf (stdout, "Encoded zone identifier (zkl = zTLD):\n");
128 fprintf (stdout, "%s\n", ztld);
129 fprintf (stdout, "\n");
130 pow = GNUNET_malloc (GNUNET_MAX_POW_SIZE);
131 GNUNET_GNSRECORD_pow_init (id_priv,
132 pow);
133 ph = GNUNET_GNSRECORD_pow_start (pow,
134 TEST_EPOCHS,
135 TEST_DIFFICULTY);
136 fprintf (stdout, "Difficulty (%d base difficulty + %d epochs): %d\n\n",
137 TEST_DIFFICULTY,
138 TEST_EPOCHS,
139 TEST_DIFFICULTY + TEST_EPOCHS);
140 uint64_t pow_passes = 0;
141 while (GNUNET_YES != GNUNET_GNSRECORD_pow_round (ph))
142 {
143 pow_passes++;
144 }
145 struct GNUNET_GNSRECORD_SignaturePurposePS *purp;
146 purp = GNR_create_signature_message (pow);
147 fprintf (stdout, "Signed message:\n");
148 print_bytes (purp,
149 ntohl (purp->purpose.size),
150 8);
151 printf ("\n");
152 GNUNET_free (purp);
153
154 exp = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_YEARS,
155 TEST_EPOCHS);
156 GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_check_pow (pow,
157 TEST_DIFFICULTY,
158 exp));
159 fprintf (stdout, "Proof:\n");
160 print_bytes (pow,
161 GNUNET_GNSRECORD_proof_get_size (pow),
162 8);
163 GNUNET_free (ph);
164
165}
166
167
168/**
169 * Main function that will be run.
170 *
171 * @param cls closure
172 * @param args remaining command-line arguments
173 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
174 * @param cfg configuration
175 */
176static void
177run (void *cls,
178 char *const *args,
179 const char *cfgfile,
180 const struct GNUNET_CONFIGURATION_Handle *cfg)
181{
182 struct GNUNET_CRYPTO_PrivateKey id_priv;
183
184 id_priv.type = htonl (GNUNET_PUBLIC_KEY_TYPE_ECDSA);
185 parsehex (d_pkey,(char*) &id_priv.ecdsa_key, sizeof (id_priv.ecdsa_key), 1);
186
187 fprintf (stdout, "Zone private key (d, big-endian):\n");
188 print_bytes_ (&id_priv.ecdsa_key, sizeof(id_priv.ecdsa_key), 8, 1);
189 run_with_key (&id_priv);
190 printf ("\n");
191 id_priv.type = htonl (GNUNET_PUBLIC_KEY_TYPE_EDDSA);
192 parsehex (d_edkey,(char*) &id_priv.eddsa_key, sizeof (id_priv.eddsa_key), 0);
193
194 fprintf (stdout, "Zone private key (d):\n");
195 print_bytes (&id_priv.eddsa_key, sizeof(id_priv.eddsa_key), 8);
196 run_with_key (&id_priv);
197}
198
199
200/**
201 * The main function of the test vector generation tool.
202 *
203 * @param argc number of arguments from the command line
204 * @param argv command line arguments
205 * @return 0 ok, 1 on error
206 */
207int
208main (int argc,
209 char *const *argv)
210{
211 const struct GNUNET_GETOPT_CommandLineOption options[] = {
212 GNUNET_GETOPT_OPTION_END
213 };
214
215 GNUNET_assert (GNUNET_OK ==
216 GNUNET_log_setup ("gnunet-revocation-tvg",
217 "INFO",
218 NULL));
219 if (GNUNET_OK !=
220 GNUNET_PROGRAM_run (argc, argv,
221 "gnunet-revocation-tvg",
222 "Generate test vectors for revocation",
223 options,
224 &run, NULL))
225 return 1;
226 return 0;
227}
228
229
230/* end of gnunet-revocation-tvg.c */
diff --git a/src/cli/revocation/gnunet-revocation.c b/src/cli/revocation/gnunet-revocation.c
new file mode 100644
index 000000000..add9a003b
--- /dev/null
+++ b/src/cli/revocation/gnunet-revocation.c
@@ -0,0 +1,581 @@
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_gnsrecord_lib.h"
28#include "gnunet_util_lib.h"
29#include "gnunet_revocation_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_GNSRECORD_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_GNSRECORD_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_GNSRECORD_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_GNSRECORD_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_GNSRECORD_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_GNSRECORD_pow_round (ph))
281 {
282 psize = GNUNET_GNSRECORD_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_CRYPTO_PublicKey key;
327 const struct GNUNET_CRYPTO_PrivateKey *privkey;
328 struct GNUNET_GNSRECORD_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_MAX_POW_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_MAX_POW_SIZE))))
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 ==
363 GNUNET_GNSRECORD_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_GNSRECORD_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_GNSRECORD_pow_init (privkey,
390 proof_of_work);
391 ph = GNUNET_GNSRECORD_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_CRYPTO_PublicKey pk;
415 size_t psize;
416
417 cfg = c;
418 if (NULL != test_ego)
419 {
420 if (GNUNET_OK !=
421 GNUNET_CRYPTO_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_MAX_POW_SIZE);
476 if (0 < (bread = GNUNET_DISK_fn_read (filename,
477 proof_of_work,
478 GNUNET_MAX_POW_SIZE)))
479 {
480 fprintf (stderr,
481 _ ("Failed to read revocation certificate from `%s'\n"),
482 filename);
483 return;
484 }
485 psize = GNUNET_GNSRECORD_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_GNSRECORD_check_pow (proof_of_work,
496 (unsigned int) matching_bits,
497 epoch_duration))
498 {
499 struct GNUNET_GNSRECORD_PowCalculationHandle *ph;
500 ph = GNUNET_GNSRECORD_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 */
diff --git a/src/cli/revocation/meson.build b/src/cli/revocation/meson.build
new file mode 100644
index 000000000..090b381df
--- /dev/null
+++ b/src/cli/revocation/meson.build
@@ -0,0 +1,22 @@
1executable ('gnunet-revocation',
2 ['gnunet-revocation.c'],
3 dependencies: [libgnunetrevocation_dep,
4 libgnunetutil_dep,
5 libgnunetstatistics_dep,
6 libgnunetcore_dep,
7 libgnunetgnsrecord_dep,
8 libgnunetsetu_dep,
9 libgnunetidentity_dep],
10 include_directories: [incdir, configuration_inc],
11 install: true,
12 install_dir: get_option('bindir'))
13
14executable ('gnunet-revocation-tvg',
15 ['gnunet-revocation.c'],
16 dependencies: [libgnunetrevocation_dep,
17 libgnunetutil_dep,
18 libgnunetgnsrecord_dep,
19 libgnunetidentity_dep],
20 include_directories: [incdir, configuration_inc],
21 install: false)
22
diff --git a/src/cli/revocation/test_local_revocation.py.in b/src/cli/revocation/test_local_revocation.py.in
new file mode 100644
index 000000000..e667c10ce
--- /dev/null
+++ b/src/cli/revocation/test_local_revocation.py.in
@@ -0,0 +1,129 @@
1#!@PYTHONEXE@
2# This file is part of GNUnet.
3# (C) 2010, 2018 Christian Grothoff (and other contributing authors)
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# Testcase for ego revocation
21
22import sys
23import os
24import subprocess
25import re
26import shutil
27
28if os.name == 'posix':
29 config = 'gnunet-config'
30 gnunetarm = 'gnunet-arm'
31 ident = 'gnunet-identity'
32 revoc = './gnunet-revocation'
33elif os.name == 'nt':
34 config = 'gnunet-config.exe'
35 gnunetarm = 'gnunet-arm.exe'
36 ident = 'gnunet-identity.exe'
37 revoc = './gnunet-revocation.exe'
38
39TEST_CONFIGURATION = "test_revocation.conf"
40TEST_REVOCATION_EGO = "revoc_test"
41
42get_clean = subprocess.Popen([
43 config, '-c', TEST_CONFIGURATION, '-s', 'PATHS', '-o', 'GNUNET_HOME', '-f'
44],
45 stdout=subprocess.PIPE)
46cleandir, x = get_clean.communicate()
47cleandir = cleandir.decode("utf-8")
48cleandir = cleandir.rstrip('\n').rstrip('\r')
49
50if os.path.isdir(cleandir):
51 shutil.rmtree(cleandir, True)
52
53res = 0
54arm = subprocess.Popen([gnunetarm, '-s', '-c', TEST_CONFIGURATION])
55arm.communicate()
56
57try:
58 print("Creating an ego " + TEST_REVOCATION_EGO)
59 sys.stdout.flush()
60 sys.stderr.flush()
61 idc = subprocess.Popen([
62 ident, '-C', TEST_REVOCATION_EGO, '-c', TEST_CONFIGURATION
63 ])
64 idc.communicate()
65 if idc.returncode != 0:
66 raise Exception(
67 "gnunet-identity failed to create an ego `" + TEST_REVOCATION_EGO +
68 "'"
69 )
70
71 sys.stdout.flush()
72 sys.stderr.flush()
73 idd = subprocess.Popen([ident, '-d'], stdout=subprocess.PIPE)
74 rev_key, x = idd.communicate()
75 rev_key = rev_key.decode("utf-8")
76 if len(rev_key.split()) < 3:
77 raise Exception("can't get revocation key out of `" + rev_key + "'")
78 rev_key = rev_key.split()[2]
79
80 print("Testing key " + rev_key)
81 sys.stdout.flush()
82 sys.stderr.flush()
83 tst = subprocess.Popen([revoc, '-t', rev_key, '-c', TEST_CONFIGURATION],
84 stdout=subprocess.PIPE)
85 output_not_revoked, x = tst.communicate()
86 output_not_revoked = output_not_revoked.decode("utf-8")
87 if tst.returncode != 0:
88 raise Exception(
89 "gnunet-revocation failed to test a key - " + str(tst.returncode) +
90 ": " + output_not_revoked
91 )
92 if 'valid' not in output_not_revoked:
93 res = 1
94 print("Key was not valid")
95 else:
96 print("Key was valid")
97
98 print("Revoking key " + rev_key)
99 sys.stdout.flush()
100 sys.stderr.flush()
101 rev = subprocess.Popen([
102 revoc, '-R', TEST_REVOCATION_EGO, '-p', '-c', TEST_CONFIGURATION
103 ])
104 rev.communicate()
105 if rev.returncode != 0:
106 raise Exception("gnunet-revocation failed to revoke a key")
107
108 print("Testing revoked key " + rev_key)
109 sys.stdout.flush()
110 sys.stderr.flush()
111 tst = subprocess.Popen([revoc, '-t', rev_key, '-c', TEST_CONFIGURATION],
112 stdout=subprocess.PIPE)
113 output_revoked, x = tst.communicate()
114 output_revoked = output_revoked.decode("utf-8")
115 if tst.returncode != 0:
116 raise Exception("gnunet-revocation failed to test a revoked key")
117 if 'revoked' not in output_revoked:
118 res = 1
119 print("Key was not revoked")
120 else:
121 print("Key was revoked")
122
123finally:
124 arm = subprocess.Popen([gnunetarm, '-e', '-c', TEST_CONFIGURATION])
125 arm.communicate()
126 if os.path.isdir(cleandir):
127 shutil.rmtree(cleandir, True)
128
129sys.exit(res)