diff options
Diffstat (limited to 'src/reclaim/gnunet-did.c')
-rw-r--r-- | src/reclaim/gnunet-did.c | 647 |
1 files changed, 0 insertions, 647 deletions
diff --git a/src/reclaim/gnunet-did.c b/src/reclaim/gnunet-did.c deleted file mode 100644 index e88a3671e..000000000 --- a/src/reclaim/gnunet-did.c +++ /dev/null | |||
@@ -1,647 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2012-2022 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 | * FIXME: Do we only want to handle EdDSA identities? | ||
23 | * TODO: Own GNS record type | ||
24 | * TODO: Fix overwrite of records in @ if present look for other with same sub | ||
25 | * TODO. Tests | ||
26 | * TODO: Move constants to did.h | ||
27 | * FIXME: Remove and lookup require differnt representations (did vs egoname) | ||
28 | */ | ||
29 | |||
30 | /** | ||
31 | * @author Tristan Schwieren | ||
32 | * @file src/did/gnunet-did.c | ||
33 | * @brief DID Method Wrapper | ||
34 | * | ||
35 | */ | ||
36 | #include "platform.h" | ||
37 | #include "gnunet_util_lib.h" | ||
38 | #include "gnunet_namestore_service.h" | ||
39 | #include "gnunet_identity_service.h" | ||
40 | #include "gnunet_gns_service.h" | ||
41 | #include "gnunet_gnsrecord_lib.h" | ||
42 | #include "did_helper.h" | ||
43 | #include "did_core.h" | ||
44 | #include "jansson.h" | ||
45 | |||
46 | #define GNUNET_DID_DEFAULT_DID_DOCUMENT_EXPIRATION_TIME "1d" | ||
47 | |||
48 | /** | ||
49 | * return value | ||
50 | */ | ||
51 | static int ret; | ||
52 | |||
53 | /** | ||
54 | * Replace DID Document Flag | ||
55 | */ | ||
56 | static int replace; | ||
57 | |||
58 | /** | ||
59 | * Remove DID Document Flag | ||
60 | */ | ||
61 | static int remove_did; | ||
62 | |||
63 | /** | ||
64 | * Get DID Documement for DID Flag | ||
65 | */ | ||
66 | static int get; | ||
67 | |||
68 | /** | ||
69 | * Create DID Document Flag | ||
70 | */ | ||
71 | static int create; | ||
72 | |||
73 | /** | ||
74 | * Show DID for Ego Flag | ||
75 | */ | ||
76 | static int show; | ||
77 | |||
78 | /** | ||
79 | * Show DID for Ego Flag | ||
80 | */ | ||
81 | static int show_all; | ||
82 | |||
83 | /** | ||
84 | * DID Attribut String | ||
85 | */ | ||
86 | static char *did; | ||
87 | |||
88 | /** | ||
89 | * DID Document Attribut String | ||
90 | */ | ||
91 | static char *didd; | ||
92 | |||
93 | /** | ||
94 | * Ego Attribut String | ||
95 | */ | ||
96 | static char *egoname; | ||
97 | |||
98 | /** | ||
99 | * DID Document expiration Date Attribut String | ||
100 | */ | ||
101 | static char *expire; | ||
102 | |||
103 | /* | ||
104 | * Handle to the GNS service | ||
105 | */ | ||
106 | static struct GNUNET_GNS_Handle *gns_handle; | ||
107 | |||
108 | /* | ||
109 | * Handle to the NAMESTORE service | ||
110 | */ | ||
111 | static struct GNUNET_NAMESTORE_Handle *namestore_handle; | ||
112 | |||
113 | /* | ||
114 | * Handle to the IDENTITY service | ||
115 | */ | ||
116 | static struct GNUNET_IDENTITY_Handle *identity_handle; | ||
117 | |||
118 | |||
119 | /* | ||
120 | * The configuration | ||
121 | */ | ||
122 | const static struct GNUNET_CONFIGURATION_Handle *my_cfg; | ||
123 | |||
124 | /** | ||
125 | * Give ego exists | ||
126 | */ | ||
127 | static int ego_exists = 0; | ||
128 | |||
129 | /** | ||
130 | * @brief Disconnect and shutdown | ||
131 | * @param cls closure | ||
132 | */ | ||
133 | static void | ||
134 | cleanup (void *cls) | ||
135 | { | ||
136 | if (NULL != gns_handle) | ||
137 | GNUNET_GNS_disconnect (gns_handle); | ||
138 | if (NULL != namestore_handle) | ||
139 | GNUNET_NAMESTORE_disconnect (namestore_handle); | ||
140 | if (NULL != identity_handle) | ||
141 | GNUNET_IDENTITY_disconnect (identity_handle); | ||
142 | |||
143 | GNUNET_free (did); | ||
144 | GNUNET_free (didd); | ||
145 | GNUNET_free (egoname); | ||
146 | GNUNET_free (expire); | ||
147 | |||
148 | GNUNET_SCHEDULER_shutdown (); | ||
149 | } | ||
150 | |||
151 | /** | ||
152 | * @brief GNS lookup callback. Prints the DID Document to standard out. | ||
153 | * Fails if there is more than one DID record. | ||
154 | * | ||
155 | * @param cls closure | ||
156 | * @param rd_count number of records in @a rd | ||
157 | * @param rd the records in the reply | ||
158 | */ | ||
159 | static void | ||
160 | print_did_document ( | ||
161 | enum GNUNET_GenericReturnValue status, | ||
162 | char *did_document, | ||
163 | void *cls | ||
164 | ) | ||
165 | { | ||
166 | if (GNUNET_OK == status) | ||
167 | printf ("%s\n", did_document); | ||
168 | else | ||
169 | printf ("An error occured: %s\n", did_document); | ||
170 | |||
171 | GNUNET_SCHEDULER_add_now (cleanup, NULL); | ||
172 | ret = 0; | ||
173 | return; | ||
174 | } | ||
175 | |||
176 | /** | ||
177 | * @brief Resolve a DID given by the user. | ||
178 | */ | ||
179 | static void | ||
180 | resolve_did () | ||
181 | { | ||
182 | |||
183 | if (did == NULL) | ||
184 | { | ||
185 | printf ("Set DID option to resolve DID\n"); | ||
186 | GNUNET_SCHEDULER_add_now (cleanup, NULL); | ||
187 | ret = 1; | ||
188 | return; | ||
189 | } | ||
190 | |||
191 | if (GNUNET_OK != DID_resolve (did, gns_handle, print_did_document, NULL)) | ||
192 | { | ||
193 | printf ("An error occured while resoling the DID\n"); | ||
194 | GNUNET_SCHEDULER_add_now (cleanup, NULL); | ||
195 | ret = 0; | ||
196 | return; | ||
197 | } | ||
198 | } | ||
199 | |||
200 | |||
201 | /** | ||
202 | * @brief Signature of a callback function that is called after a did has been removed | ||
203 | */ | ||
204 | typedef void | ||
205 | (*remove_did_document_callback) (void *cls); | ||
206 | |||
207 | /** | ||
208 | * @brief A Structure containing a cont and cls. Can be passed as a cls to a callback function | ||
209 | * | ||
210 | */ | ||
211 | struct Event | ||
212 | { | ||
213 | remove_did_document_callback cont; | ||
214 | void *cls; | ||
215 | }; | ||
216 | |||
217 | /** | ||
218 | * @brief Implements the GNUNET_NAMESTORE_ContinuationWithStatus | ||
219 | * Calls the callback function and cls in the event struct | ||
220 | * | ||
221 | * @param cls closure containing the event struct | ||
222 | * @param success | ||
223 | * @param emgs | ||
224 | */ | ||
225 | static void | ||
226 | remove_did_document_namestore_cb (void *cls, enum GNUNET_ErrorCode ec) | ||
227 | { | ||
228 | struct Event *event; | ||
229 | |||
230 | if (GNUNET_EC_NONE == ec) | ||
231 | { | ||
232 | event = (struct Event *) cls; | ||
233 | |||
234 | if (event->cont != NULL) | ||
235 | { | ||
236 | event->cont (event->cls); | ||
237 | free (event); | ||
238 | } | ||
239 | else { | ||
240 | free (event); | ||
241 | GNUNET_SCHEDULER_add_now (cleanup, NULL); | ||
242 | ret = 0; | ||
243 | return; | ||
244 | } | ||
245 | } | ||
246 | else { | ||
247 | printf ("Something went wrong when deleting the DID Document\n"); | ||
248 | |||
249 | printf ("%s\n", GNUNET_ErrorCode_get_hint (ec)); | ||
250 | |||
251 | GNUNET_SCHEDULER_add_now (cleanup, NULL); | ||
252 | ret = 0; | ||
253 | return; | ||
254 | } | ||
255 | } | ||
256 | |||
257 | /** | ||
258 | * @brief Callback called after the ego has been locked up | ||
259 | * | ||
260 | * @param cls closure | ||
261 | * @param ego the ego returned by the identity service | ||
262 | */ | ||
263 | static void | ||
264 | remove_did_document_ego_lookup_cb (void *cls, struct GNUNET_IDENTITY_Ego *ego) | ||
265 | { | ||
266 | const struct GNUNET_CRYPTO_PrivateKey *skey = | ||
267 | GNUNET_IDENTITY_ego_get_private_key (ego); | ||
268 | |||
269 | GNUNET_NAMESTORE_records_store (namestore_handle, | ||
270 | skey, | ||
271 | GNUNET_GNS_EMPTY_LABEL_AT, | ||
272 | 0, | ||
273 | NULL, | ||
274 | &remove_did_document_namestore_cb, | ||
275 | cls); | ||
276 | } | ||
277 | |||
278 | /** | ||
279 | * @brief Remove a DID Document | ||
280 | */ | ||
281 | static void | ||
282 | remove_did_document (remove_did_document_callback cont, void *cls) | ||
283 | { | ||
284 | struct Event *event; | ||
285 | |||
286 | if (egoname == NULL) | ||
287 | { | ||
288 | printf ("Remove requieres an ego option\n"); | ||
289 | GNUNET_SCHEDULER_add_now (cleanup, NULL); | ||
290 | ret = 1; | ||
291 | return; | ||
292 | } | ||
293 | else { | ||
294 | event = malloc (sizeof(*event)); | ||
295 | event->cont = cont; | ||
296 | event->cls = cls; | ||
297 | |||
298 | GNUNET_IDENTITY_ego_lookup (my_cfg, | ||
299 | egoname, | ||
300 | &remove_did_document_ego_lookup_cb, | ||
301 | (void *) event); | ||
302 | } | ||
303 | } | ||
304 | |||
305 | // Needed because create_did_ego_lookup_cb() and | ||
306 | // create_did_ego_create_cb() can call each other | ||
307 | static void create_did_ego_lockup_cb (); | ||
308 | |||
309 | /** | ||
310 | * @brief Create a DID(-Document). Called after DID has been created | ||
311 | * Prints status and the DID. | ||
312 | * | ||
313 | */ | ||
314 | static void | ||
315 | create_did_cb (enum GNUNET_GenericReturnValue status, void *cls) | ||
316 | { | ||
317 | if (GNUNET_OK == status) | ||
318 | { | ||
319 | printf ("DID has been created.\n%s\n", (char *) cls); | ||
320 | free (cls); | ||
321 | ret = 0; | ||
322 | } | ||
323 | else | ||
324 | { | ||
325 | printf ("An error occured while creating the DID.\n"); | ||
326 | ret = 1; | ||
327 | } | ||
328 | |||
329 | GNUNET_SCHEDULER_add_now (&cleanup, NULL); | ||
330 | return; | ||
331 | } | ||
332 | |||
333 | /** | ||
334 | * @brief Create a DID(-Document) - Called after a new Identity has been created. | ||
335 | */ | ||
336 | static void | ||
337 | create_did_ego_create_cb (void *cls, | ||
338 | const struct GNUNET_CRYPTO_PrivateKey *pk, | ||
339 | enum GNUNET_ErrorCode ec) | ||
340 | { | ||
341 | if (GNUNET_EC_NONE != ec) | ||
342 | { | ||
343 | printf ("%s\n", GNUNET_ErrorCode_get_hint (ec)); | ||
344 | GNUNET_SCHEDULER_add_now (&cleanup, NULL); | ||
345 | ret = 1; | ||
346 | return; | ||
347 | } | ||
348 | |||
349 | GNUNET_IDENTITY_ego_lookup (my_cfg, | ||
350 | egoname, | ||
351 | &create_did_ego_lockup_cb, | ||
352 | NULL); | ||
353 | } | ||
354 | |||
355 | /** | ||
356 | * @brief Create a DID(-Document). Called after ego lookup | ||
357 | * | ||
358 | */ | ||
359 | static void | ||
360 | create_did_ego_lockup_cb (void *cls, struct GNUNET_IDENTITY_Ego *ego) | ||
361 | { | ||
362 | if (ego == NULL) | ||
363 | { | ||
364 | // If Ego was not found. Create new one first | ||
365 | printf ("Ego was not found. Creating new one.\n"); | ||
366 | GNUNET_IDENTITY_create (identity_handle, | ||
367 | egoname, | ||
368 | NULL, | ||
369 | GNUNET_PUBLIC_KEY_TYPE_EDDSA, | ||
370 | &create_did_ego_create_cb, | ||
371 | egoname); | ||
372 | } | ||
373 | else | ||
374 | { | ||
375 | char *did = DID_identity_to_did (ego); | ||
376 | void *cls = malloc (strlen (did) + 1); | ||
377 | struct GNUNET_TIME_Relative expire_relative; | ||
378 | |||
379 | if (expire == NULL) | ||
380 | { | ||
381 | GNUNET_STRINGS_fancy_time_to_relative ( | ||
382 | DID_DOCUMENT_DEFAULT_EXPIRATION_TIME, &expire_relative); | ||
383 | } | ||
384 | else if (GNUNET_OK != GNUNET_STRINGS_fancy_time_to_relative (expire, | ||
385 | & | ||
386 | expire_relative)) | ||
387 | { | ||
388 | printf ("Failed to read given expiration time\n"); | ||
389 | GNUNET_SCHEDULER_add_now (cleanup, NULL); | ||
390 | ret = 1; | ||
391 | return; | ||
392 | } | ||
393 | |||
394 | strcpy (cls, did); | ||
395 | // TODO: Add DID_document argument | ||
396 | if (GNUNET_OK != DID_create (ego, | ||
397 | NULL, | ||
398 | &expire_relative, | ||
399 | namestore_handle, | ||
400 | create_did_cb, | ||
401 | cls)) | ||
402 | { | ||
403 | printf ("An error occured while creating the DID.\n"); | ||
404 | ret = 1; | ||
405 | GNUNET_SCHEDULER_add_now (&cleanup, NULL); | ||
406 | return; | ||
407 | } | ||
408 | } | ||
409 | } | ||
410 | |||
411 | /** | ||
412 | * @brief Create a DID(-Document). | ||
413 | * | ||
414 | */ | ||
415 | static void | ||
416 | create_did () | ||
417 | { | ||
418 | // Ego name to be set | ||
419 | if (egoname == NULL) | ||
420 | { | ||
421 | printf ("Set the Ego argument to create a new DID(-Document)\n"); | ||
422 | GNUNET_SCHEDULER_add_now (&cleanup, NULL); | ||
423 | ret = 1; | ||
424 | return; | ||
425 | } | ||
426 | |||
427 | GNUNET_IDENTITY_ego_lookup (my_cfg, | ||
428 | egoname, | ||
429 | &create_did_ego_lockup_cb, | ||
430 | NULL); | ||
431 | } | ||
432 | |||
433 | |||
434 | /** | ||
435 | * @brief Replace a DID Docuemnt. Callback function after ego lockup | ||
436 | * | ||
437 | * @param cls | ||
438 | * @param ego | ||
439 | */ | ||
440 | static void | ||
441 | replace_did_document_ego_lookup_cb (void *cls, struct GNUNET_IDENTITY_Ego *ego) | ||
442 | { | ||
443 | // create_did_store (didd, ego); | ||
444 | } | ||
445 | |||
446 | /** | ||
447 | * @brief Replace a DID Document. Callback functiona after remove | ||
448 | * | ||
449 | * @param cls | ||
450 | */ | ||
451 | static void | ||
452 | replace_did_document_remove_cb (void *cls) | ||
453 | { | ||
454 | GNUNET_IDENTITY_ego_lookup (my_cfg, | ||
455 | egoname, | ||
456 | &replace_did_document_ego_lookup_cb, | ||
457 | NULL); | ||
458 | } | ||
459 | |||
460 | /** | ||
461 | * @brief Replace a DID Docuemnt | ||
462 | * | ||
463 | */ | ||
464 | static void | ||
465 | replace_did_document () | ||
466 | { | ||
467 | if ((didd != NULL) && (expire != NULL)) | ||
468 | { | ||
469 | remove_did_document (&replace_did_document_remove_cb, NULL); | ||
470 | } | ||
471 | else { | ||
472 | printf ( | ||
473 | "Set the DID Document and expiration time argument to replace the DID Document\n"); | ||
474 | GNUNET_SCHEDULER_add_now (&cleanup, NULL); | ||
475 | ret = 1; | ||
476 | return; | ||
477 | } | ||
478 | } | ||
479 | |||
480 | static void | ||
481 | post_ego_iteration (void *cls) | ||
482 | { | ||
483 | // TODO: Check that only one argument is set | ||
484 | |||
485 | if (1 == replace) | ||
486 | { | ||
487 | replace_did_document (); | ||
488 | } | ||
489 | else if (1 == get) | ||
490 | { | ||
491 | resolve_did (); | ||
492 | } | ||
493 | else if (1 == remove_did) | ||
494 | { | ||
495 | remove_did_document (NULL, NULL); | ||
496 | } | ||
497 | else if (1 == create) | ||
498 | { | ||
499 | create_did (); | ||
500 | } | ||
501 | else { | ||
502 | // No Argument found | ||
503 | GNUNET_SCHEDULER_add_now (&cleanup, NULL); | ||
504 | return; | ||
505 | } | ||
506 | } | ||
507 | |||
508 | static void | ||
509 | process_dids (void *cls, struct GNUNET_IDENTITY_Ego *ego, | ||
510 | void **ctx, const char*name) | ||
511 | { | ||
512 | char *did_str; | ||
513 | |||
514 | if (ego == NULL) | ||
515 | { | ||
516 | if (1 == ego_exists) | ||
517 | { | ||
518 | GNUNET_SCHEDULER_add_now (&cleanup, NULL); | ||
519 | return; | ||
520 | } | ||
521 | GNUNET_SCHEDULER_add_now (&post_ego_iteration, NULL); | ||
522 | return; | ||
523 | } | ||
524 | |||
525 | if (1 == show_all) | ||
526 | { | ||
527 | did_str = DID_identity_to_did (ego); | ||
528 | printf ("%s:\n\t%s\n", name, did_str); | ||
529 | GNUNET_free (did_str); | ||
530 | return; | ||
531 | } | ||
532 | if (1 == show) | ||
533 | { | ||
534 | if (0 == strncmp (name, egoname, strlen (egoname))) | ||
535 | { | ||
536 | did_str = DID_identity_to_did (ego); | ||
537 | printf ("%s:\n\t%s\n", name, did_str); | ||
538 | GNUNET_free (did_str); | ||
539 | return; | ||
540 | } | ||
541 | } | ||
542 | } | ||
543 | |||
544 | |||
545 | |||
546 | static void | ||
547 | run (void *cls, | ||
548 | char *const *args, | ||
549 | const char *cfgfile, | ||
550 | const struct GNUNET_CONFIGURATION_Handle *c) | ||
551 | { | ||
552 | gns_handle = GNUNET_GNS_connect (c); | ||
553 | namestore_handle = GNUNET_NAMESTORE_connect (c); | ||
554 | my_cfg = c; | ||
555 | |||
556 | // check if GNS_handle could connect | ||
557 | if (gns_handle == NULL) | ||
558 | { | ||
559 | ret = 1; | ||
560 | return; | ||
561 | } | ||
562 | |||
563 | // check if NAMESTORE_handle could connect | ||
564 | if (namestore_handle == NULL) | ||
565 | { | ||
566 | GNUNET_SCHEDULER_add_now (&cleanup, NULL); | ||
567 | ret = 1; | ||
568 | return; | ||
569 | } | ||
570 | |||
571 | identity_handle = GNUNET_IDENTITY_connect (c, &process_dids, NULL); | ||
572 | if (identity_handle == NULL) | ||
573 | { | ||
574 | GNUNET_SCHEDULER_add_now (&cleanup, NULL); | ||
575 | ret = 1; | ||
576 | return; | ||
577 | } | ||
578 | } | ||
579 | |||
580 | int | ||
581 | main (int argc, char *const argv[]) | ||
582 | { | ||
583 | struct GNUNET_GETOPT_CommandLineOption options[] = { | ||
584 | GNUNET_GETOPT_option_flag ('C', | ||
585 | "create", | ||
586 | gettext_noop ( | ||
587 | "Create a DID Document and display its DID"), | ||
588 | &create), | ||
589 | GNUNET_GETOPT_option_flag ('g', | ||
590 | "get", | ||
591 | gettext_noop ( | ||
592 | "Get the DID Document associated with the given DID"), | ||
593 | &get), | ||
594 | GNUNET_GETOPT_option_flag ('r', | ||
595 | "remove", | ||
596 | gettext_noop ( | ||
597 | "Remove the DID"), | ||
598 | &remove_did), | ||
599 | GNUNET_GETOPT_option_flag ('R', | ||
600 | "replace", | ||
601 | gettext_noop ("Replace the DID Document."), | ||
602 | &replace), | ||
603 | GNUNET_GETOPT_option_flag ('s', | ||
604 | "show", | ||
605 | gettext_noop ("Show the DID for a given ego"), | ||
606 | &show), | ||
607 | GNUNET_GETOPT_option_flag ('A', | ||
608 | "show-all", | ||
609 | gettext_noop ("Show egos with DIDs"), | ||
610 | &show_all), | ||
611 | GNUNET_GETOPT_option_string ('d', | ||
612 | "did", | ||
613 | "DID", | ||
614 | gettext_noop ( | ||
615 | "The Decentralized Identity (DID)"), | ||
616 | &did), | ||
617 | GNUNET_GETOPT_option_string ('D', | ||
618 | "did-document", | ||
619 | "JSON", | ||
620 | gettext_noop ( | ||
621 | "The DID Document to store in GNUNET"), | ||
622 | &didd), | ||
623 | GNUNET_GETOPT_option_string ('e', | ||
624 | "ego", | ||
625 | "EGO", | ||
626 | gettext_noop ("The name of the EGO"), | ||
627 | &egoname), | ||
628 | GNUNET_GETOPT_option_string ('t', | ||
629 | "expiration-time", | ||
630 | "TIME", | ||
631 | gettext_noop ( | ||
632 | "The time until the DID Document is going to expire (e.g. 5d)"), | ||
633 | &expire), | ||
634 | GNUNET_GETOPT_OPTION_END | ||
635 | }; | ||
636 | |||
637 | if (GNUNET_OK != GNUNET_PROGRAM_run (argc, | ||
638 | argv, | ||
639 | "gnunet-did", | ||
640 | "Manage Decentralized Identities (DIDs)", | ||
641 | options, | ||
642 | &run, | ||
643 | NULL)) | ||
644 | return 1; | ||
645 | else | ||
646 | return ret; | ||
647 | } | ||