GNUnet 0.22.2
gnunet-did.c
Go to the documentation of this file.
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
35#include "did_core.h"
36
37#include "gnunet_util_lib.h"
40#include "gnunet_gns_service.h"
42
43#define GNUNET_DID_DEFAULT_DID_DOCUMENT_EXPIRATION_TIME "1d"
44
48static int ret;
49
53static int replace;
54
58static int remove_did;
59
63static int get;
64
68static int create;
69
73static int show;
74
78static int show_all;
79
83static char *did;
84
88static char *didd;
89
93static char *egoname;
94
98static char *expire;
99
100/*
101 * Handle to the GNS service
102 */
104
105/*
106 * Handle to the NAMESTORE service
107 */
109
110/*
111 * Handle to the IDENTITY service
112 */
114
115
116/*
117 * The configuration
118 */
120
124static int ego_exists = 0;
125
130static void
131cleanup (void *cls)
132{
133 if (NULL != gns_handle)
135 if (NULL != namestore_handle)
137 if (NULL != identity_handle)
139
144
146}
147
148
157static void
160 const char *did_document,
161 void *cls
162 )
163{
164 if (GNUNET_OK == status)
165 printf ("%s\n", did_document);
166 else
167 printf ("An error occurred: %s\n", did_document);
168
170 ret = 0;
171 return;
172}
173
174
178static void
180{
181
182 if (did == NULL)
183 {
184 printf ("Set DID option to resolve DID\n");
186 ret = 1;
187 return;
188 }
189
191 {
192 printf ("An error occurred while resoling the DID\n");
194 ret = 0;
195 return;
196 }
197}
198
199
203typedef void
204(*remove_did_document_callback) (void *cls);
205
210struct Event
211{
213 void *cls;
214};
215
224static void
226{
227 struct Event *event;
228
229 if (GNUNET_EC_NONE == ec)
230 {
231 event = (struct Event *) cls;
232
233 if (event->cont != NULL)
234 {
235 event->cont (event->cls);
236 free (event);
237 }
238 else
239 {
240 free (event);
242 ret = 0;
243 return;
244 }
245 }
246 else
247 {
248 printf ("Something went wrong when deleting the DID Document\n");
249
250 printf ("%s\n", GNUNET_ErrorCode_get_hint (ec));
251
253 ret = 0;
254 return;
255 }
256}
257
258
265static void
267{
268 const struct GNUNET_CRYPTO_PrivateKey *skey =
270
272 skey,
274 0,
275 NULL,
277 cls);
278}
279
280
284static void
286{
287 struct Event *event;
288
289 if (egoname == NULL)
290 {
291 printf ("Remove requires an ego option\n");
293 ret = 1;
294 return;
295 }
296 else
297 {
298 event = malloc (sizeof(*event));
299 event->cont = cont;
300 event->cls = cls;
301
303 egoname,
305 (void *) event);
306 }
307}
308
309
310// Needed because create_did_ego_lookup_cb() and
311// create_did_ego_create_cb() can call each other
312static void
314
320static void
322{
323 if (GNUNET_OK == status)
324 {
325 printf ("DID has been created.\n%s\n", (char *) cls);
326 free (cls);
327 ret = 0;
328 }
329 else
330 {
331 printf ("An error occurred while creating the DID.\n");
332 ret = 1;
333 }
334
336 return;
337}
338
339
343static void
345 const struct GNUNET_CRYPTO_PrivateKey *pk,
346 enum GNUNET_ErrorCode ec)
347{
348 if (GNUNET_EC_NONE != ec)
349 {
350 printf ("%s\n", GNUNET_ErrorCode_get_hint (ec));
352 ret = 1;
353 return;
354 }
355
357 egoname,
359 NULL);
360}
361
362
367static void
369{
370 if (ego == NULL)
371 {
372 // If Ego was not found. Create new one first
373 printf ("Ego was not found. Creating new one.\n");
375 egoname,
376 NULL,
379 egoname);
380 }
381 else
382 {
383 char *did_tmp = DID_identity_to_did (ego);
384 void *cls_tmp = GNUNET_malloc (strlen (did_tmp) + 1);
385 struct GNUNET_TIME_Relative expire_relative;
386
387 if (expire == NULL)
388 {
392 &expire_relative));
393 }
395 &
396 expire_relative))
397 {
398 printf ("Failed to read given expiration time\n");
400 ret = 1;
401 GNUNET_free (cls_tmp);
402 return;
403 }
404
405 strcpy (cls_tmp, did_tmp);
406 // TODO: Add DID_document argument
407 if (GNUNET_OK != DID_create (ego,
408 NULL,
409 &expire_relative,
412 cls_tmp))
413 {
414 printf ("An error occurred while creating the DID.\n");
415 ret = 1;
417 GNUNET_free (cls_tmp);
418 return;
419 }
420 GNUNET_free (cls_tmp);
421 }
422}
423
424
429static void
431{
432 // Ego name to be set
433 if (egoname == NULL)
434 {
435 printf ("Set the Ego argument to create a new DID(-Document)\n");
437 ret = 1;
438 return;
439 }
440
442 egoname,
444 NULL);
445}
446
447
454static void
456{
457 // create_did_store (didd, ego);
458}
459
460
466static void
468{
470 egoname,
472 NULL);
473}
474
475
480static void
482{
483 if ((didd != NULL) && (expire != NULL))
484 {
486 }
487 else
488 {
489 printf (
490 "Set the DID Document and expiration time argument to replace the DID Document\n");
492 ret = 1;
493 return;
494 }
495}
496
497
498static void
500{
501 // TODO: Check that only one argument is set
502
503 if (1 == replace)
504 {
506 }
507 else if (1 == get)
508 {
509 resolve_did ();
510 }
511 else if (1 == remove_did)
512 {
513 remove_did_document (NULL, NULL);
514 }
515 else if (1 == create)
516 {
517 create_did ();
518 }
519 else
520 {
521 // No Argument found
523 return;
524 }
525}
526
527
528static void
529process_dids (void *cls, struct GNUNET_IDENTITY_Ego *ego,
530 void **ctx, const char*name)
531{
532 char *did_str;
533
534 if (ego == NULL)
535 {
536 if (1 == ego_exists)
537 {
539 return;
540 }
542 return;
543 }
544
545 if (1 == show_all)
546 {
547 did_str = DID_identity_to_did (ego);
548 printf ("%s:\n\t%s\n", name, did_str);
549 GNUNET_free (did_str);
550 return;
551 }
552 if (1 == show)
553 {
554 if (0 == strncmp (name, egoname, strlen (egoname)))
555 {
556 did_str = DID_identity_to_did (ego);
557 printf ("%s:\n\t%s\n", name, did_str);
558 GNUNET_free (did_str);
559 return;
560 }
561 }
562}
563
564
565static void
566run (void *cls,
567 char *const *args,
568 const char *cfgfile,
569 const struct GNUNET_CONFIGURATION_Handle *c)
570{
573 my_cfg = c;
574
575 // check if GNS_handle could connect
576 if (gns_handle == NULL)
577 {
578 ret = 1;
579 return;
580 }
581
582 // check if NAMESTORE_handle could connect
583 if (namestore_handle == NULL)
584 {
586 ret = 1;
587 return;
588 }
589
591 if (identity_handle == NULL)
592 {
594 ret = 1;
595 return;
596 }
597}
598
599
600int
601main (int argc, char *const argv[])
602{
605 "create",
607 "Create a DID Document and display its DID"),
608 &create),
610 "get",
612 "Get the DID Document associated with the given DID"),
613 &get),
615 "remove",
617 "Remove the DID"),
618 &remove_did),
620 "replace",
621 gettext_noop ("Replace the DID Document."),
622 &replace),
624 "show",
625 gettext_noop ("Show the DID for a given ego"),
626 &show),
628 "show-all",
629 gettext_noop ("Show egos with DIDs"),
630 &show_all),
632 "did",
633 "DID",
635 "The Decentralized Identity (DID)"),
636 &did),
638 "did-document",
639 "JSON",
641 "The DID Document to store in GNUNET"),
642 &didd),
644 "ego",
645 "EGO",
646 gettext_noop ("The name of the EGO"),
647 &egoname),
649 "expiration-time",
650 "TIME",
652 "The time until the DID Document is going to expire (e.g. 5d)"),
653 &expire),
655 };
656
657 if (GNUNET_OK !=
660 argc,
661 argv,
662 "gnunet-did",
663 "Manage Decentralized Identities (DIDs)",
664 options,
665 &run,
666 NULL))
667 return 1;
668 else
669 return ret;
670}
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_OPTION_END
Definition: 002.c:13
struct GNUNET_GETOPT_CommandLineOption options[]
Definition: 002.c:5
enum GNUNET_GenericReturnValue DID_resolve(const char *did, struct GNUNET_GNS_Handle *gns_handle, DID_resolve_callback *cont, void *cls)
Resolve a DID.
Definition: did_core.c:89
enum GNUNET_GenericReturnValue DID_create(const struct GNUNET_IDENTITY_Ego *ego, const char *did_document, const struct GNUNET_TIME_Relative *expire_time, struct GNUNET_NAMESTORE_Handle *namestore_handle, DID_action_callback *cont, void *cls)
Creates a DID and saves DID Document in Namestore.
Definition: did_core.c:226
Core functionality for GNUNET Decentralized Identifier.
#define DID_DOCUMENT_DEFAULT_EXPIRATION_TIME
Definition: did_core.h:38
char * DID_identity_to_did(struct GNUNET_IDENTITY_Ego *ego)
Generate a DID for a given gnunet EGO.
Definition: did_helper.c:67
#define gettext_noop(String)
Definition: gettext.h:74
static int replace
Replace DID Document Flag.
Definition: gnunet-did.c:53
static struct GNUNET_GNS_Handle * gns_handle
Definition: gnunet-did.c:103
static char * egoname
Ego Attribute String.
Definition: gnunet-did.c:93
static char * didd
DID Document Attribute String.
Definition: gnunet-did.c:88
static void replace_did_document_remove_cb(void *cls)
Replace a DID Document.
Definition: gnunet-did.c:467
static int show_all
Show DID for Ego Flag.
Definition: gnunet-did.c:78
static char * expire
DID Document expiration Date Attribute String.
Definition: gnunet-did.c:98
static void remove_did_document_ego_lookup_cb(void *cls, struct GNUNET_IDENTITY_Ego *ego)
Callback called after the ego has been locked up.
Definition: gnunet-did.c:266
static void cleanup(void *cls)
Disconnect and shutdown.
Definition: gnunet-did.c:131
static void create_did_cb(enum GNUNET_GenericReturnValue status, void *cls)
Create a DID(-Document).
Definition: gnunet-did.c:321
static int remove_did
Remove DID Document Flag.
Definition: gnunet-did.c:58
static int ego_exists
Give ego exists.
Definition: gnunet-did.c:124
static struct GNUNET_NAMESTORE_Handle * namestore_handle
Definition: gnunet-did.c:108
static const struct GNUNET_CONFIGURATION_Handle * my_cfg
Definition: gnunet-did.c:119
static int ret
return value
Definition: gnunet-did.c:48
static void remove_did_document_namestore_cb(void *cls, enum GNUNET_ErrorCode ec)
Implements the GNUNET_NAMESTORE_ContinuationWithStatus Calls the callback function and cls in the eve...
Definition: gnunet-did.c:225
static void post_ego_iteration(void *cls)
Definition: gnunet-did.c:499
static void remove_did_document(remove_did_document_callback cont, void *cls)
Remove a DID Document.
Definition: gnunet-did.c:285
static void replace_did_document_ego_lookup_cb(void *cls, struct GNUNET_IDENTITY_Ego *ego)
Replace a DID Document.
Definition: gnunet-did.c:455
static void run(void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *c)
Definition: gnunet-did.c:566
void(* remove_did_document_callback)(void *cls)
Signature of a callback function that is called after a did has been removed.
Definition: gnunet-did.c:204
static int show
Show DID for Ego Flag.
Definition: gnunet-did.c:73
static int get
Get DID Documement for DID Flag.
Definition: gnunet-did.c:63
static int create
Create DID Document Flag.
Definition: gnunet-did.c:68
static void resolve_did()
Resolve a DID given by the user.
Definition: gnunet-did.c:179
static void replace_did_document()
Replace a DID Document.
Definition: gnunet-did.c:481
static void create_did_ego_create_cb(void *cls, const struct GNUNET_CRYPTO_PrivateKey *pk, enum GNUNET_ErrorCode ec)
Create a DID(-Document) - Called after a new Identity has been created.
Definition: gnunet-did.c:344
static struct GNUNET_IDENTITY_Handle * identity_handle
Definition: gnunet-did.c:113
static void print_did_document(enum GNUNET_GenericReturnValue status, const char *did_document, void *cls)
GNS lookup callback.
Definition: gnunet-did.c:158
static void process_dids(void *cls, struct GNUNET_IDENTITY_Ego *ego, void **ctx, const char *name)
Definition: gnunet-did.c:529
static void create_did()
Create a DID(-Document).
Definition: gnunet-did.c:430
static char * did
DID Attribute String.
Definition: gnunet-did.c:83
static void create_did_ego_lockup_cb(void *cls, struct GNUNET_IDENTITY_Ego *ego)
Create a DID(-Document).
Definition: gnunet-did.c:368
int main(int argc, char *const argv[])
Definition: gnunet-did.c:601
static struct GNUNET_FS_Handle * ctx
struct GNUNET_CRYPTO_PrivateKey pk
Private key from command line option, or NULL.
static char * name
Name (label) of the records to list.
static int status
The program status; 0 for success.
Definition: gnunet-nse.c:39
const char * GNUNET_ErrorCode_get_hint(enum GNUNET_ErrorCode ec)
Returns a hint for a given error code.
GNUNET_ErrorCode
Taler error codes.
@ GNUNET_EC_NONE
No error (success).
API to the GNS service.
API that can be used to manipulate GNS record data.
Identity service; implements identity management for GNUnet.
API that can be used to store naming information on a GNUnet node;.
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.
void GNUNET_GNS_disconnect(struct GNUNET_GNS_Handle *handle)
Shutdown connection with the GNS service.
Definition: gns_api.c:289
struct GNUNET_GNS_Handle * GNUNET_GNS_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Initialize the connection with the GNS service.
Definition: gns_api.c:267
#define GNUNET_GNS_EMPTY_LABEL_AT
String we use to indicate an empty label (top-level entry in the zone).
struct GNUNET_IDENTITY_Operation * GNUNET_IDENTITY_create(struct GNUNET_IDENTITY_Handle *id, const char *name, const struct GNUNET_CRYPTO_PrivateKey *privkey, enum GNUNET_CRYPTO_KeyType ktype, GNUNET_IDENTITY_CreateContinuation cont, void *cont_cls)
Create a new ego with the given name.
Definition: identity_api.c:561
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.
struct GNUNET_IDENTITY_Handle * GNUNET_IDENTITY_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_IDENTITY_Callback cb, void *cb_cls)
Connect to the identity service.
Definition: identity_api.c:487
void GNUNET_IDENTITY_disconnect(struct GNUNET_IDENTITY_Handle *h)
Disconnect from identity service.
Definition: identity_api.c:732
GNUNET_GenericReturnValue
Named constants for return values.
@ GNUNET_PUBLIC_KEY_TYPE_EDDSA
EDDSA identity.
@ GNUNET_OK
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
struct GNUNET_NAMESTORE_QueueEntry * GNUNET_NAMESTORE_record_set_store(struct GNUNET_NAMESTORE_Handle *h, const struct GNUNET_CRYPTO_PrivateKey *pkey, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd, GNUNET_NAMESTORE_ContinuationWithStatus cont, void *cont_cls)
Store an item in the namestore.
void GNUNET_NAMESTORE_disconnect(struct GNUNET_NAMESTORE_Handle *h)
Disconnect from the namestore service (and free associated resources).
struct GNUNET_NAMESTORE_Handle * GNUNET_NAMESTORE_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the namestore service.
const struct GNUNET_OS_ProjectData * GNUNET_OS_project_data_gnunet(void)
Return default project data used by 'libgnunetutil' for GNUnet.
enum GNUNET_GenericReturnValue GNUNET_PROGRAM_run(const struct GNUNET_OS_ProjectData *pd, 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:407
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:567
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:1304
enum GNUNET_GenericReturnValue GNUNET_STRINGS_fancy_time_to_relative(const char *fancy_time, struct GNUNET_TIME_Relative *rtime)
Convert a given fancy human-readable time to our internal representation.
Definition: strings.c:259
A Structure containing a cont and cls.
Definition: gnunet-did.c:211
remove_did_document_callback cont
Definition: gnunet-did.c:212
void * cls
Definition: gnunet-did.c:213
A private key for an identity as per LSD0001.
Definition of a command line option.
Connection to the GNS service.
Definition: gns_api.h:36
Handle for an ego.
Definition: identity.h:37
Handle for the service.
Definition: identity_api.c:97
Connection to the NAMESTORE service.
Time for relative time used by GNUnet, in microseconds.