GNUnet  0.19.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 
36 #include "platform.h"
37 #include "gnunet_util_lib.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 
51 static int ret;
52 
56 static int replace;
57 
61 static int remove_did;
62 
66 static int get;
67 
71 static int create;
72 
76 static int show;
77 
81 static int show_all;
82 
86 static char *did;
87 
91 static char *didd;
92 
96 static char *egoname;
97 
101 static char *expire;
102 
103 /*
104  * Handle to the GNS service
105  */
107 
108 /*
109  * Handle to the NAMESTORE service
110  */
112 
113 /*
114  * Handle to the IDENTITY service
115  */
117 
118 
119 /*
120  * The configuration
121  */
122 const static struct GNUNET_CONFIGURATION_Handle *my_cfg;
123 
127 static int ego_exists = 0;
128 
133 static void
134 cleanup (void *cls)
135 {
136  if (NULL != gns_handle)
138  if (NULL != namestore_handle)
140  if (NULL != identity_handle)
142 
143  GNUNET_free (did);
144  GNUNET_free (didd);
147 
149 }
150 
159 static void
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 
172  ret = 0;
173  return;
174 }
175 
179 static void
181 {
182 
183  if (did == NULL)
184  {
185  printf ("Set DID option to resolve DID\n");
187  ret = 1;
188  return;
189  }
190 
192  {
193  printf ("An error occured while resoling the DID\n");
195  ret = 0;
196  return;
197  }
198 }
199 
200 
204 typedef void
205 (*remove_did_document_callback) (void *cls);
206 
211 struct Event
212 {
214  void *cls;
215 };
216 
225 static void
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);
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 
252  ret = 0;
253  return;
254  }
255 }
256 
263 static void
265 {
266  const struct GNUNET_IDENTITY_PrivateKey *skey =
268 
270  skey,
272  0,
273  NULL,
275  cls);
276 }
277 
281 static void
283 {
284  struct Event *event;
285 
286  if (egoname == NULL)
287  {
288  printf ("Remove requieres an ego option\n");
290  ret = 1;
291  return;
292  }
293  else {
294  event = malloc (sizeof(*event));
295  event->cont = cont;
296  event->cls = cls;
297 
299  egoname,
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
308 
314 static void
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 
330  return;
331 }
332 
336 static void
338  const struct GNUNET_IDENTITY_PrivateKey *pk,
339  enum GNUNET_ErrorCode ec)
340 {
341  if (GNUNET_EC_NONE != ec)
342  {
343  printf ("%s\n", GNUNET_ErrorCode_get_hint (ec));
345  ret = 1;
346  return;
347  }
348 
350  egoname,
352  NULL);
353 }
354 
359 static void
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");
367  egoname,
368  NULL,
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  {
382  DID_DOCUMENT_DEFAULT_EXPIRATION_TIME, &expire_relative);
383  }
385  &
386  expire_relative))
387  {
388  printf ("Failed to read given expiration time\n");
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,
401  cls))
402  {
403  printf ("An error occured while creating the DID.\n");
404  ret = 1;
406  return;
407  }
408  }
409 }
410 
415 static void
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");
423  ret = 1;
424  return;
425  }
426 
428  egoname,
430  NULL);
431 }
432 
433 
440 static void
442 {
443  // create_did_store (didd, ego);
444 }
445 
451 static void
453 {
455  egoname,
457  NULL);
458 }
459 
464 static void
466 {
467  if ((didd != NULL) && (expire != NULL))
468  {
470  }
471  else {
472  printf (
473  "Set the DID Document and expiration time argument to replace the DID Document\n");
475  ret = 1;
476  return;
477  }
478 }
479 
480 static void
482 {
483  // TODO: Check that only one argument is set
484 
485  if (1 == replace)
486  {
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
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  {
519  return;
520  }
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 {
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  {
567  ret = 1;
568  return;
569  }
570 
572  if (identity_handle == NULL)
573  {
575  ret = 1;
576  return;
577  }
578 }
579 
580 int
581 main (int argc, char *const argv[])
582 {
585  "create",
586  gettext_noop (
587  "Create a DID Document and display its DID"),
588  &create),
590  "get",
591  gettext_noop (
592  "Get the DID Document associated with the given DID"),
593  &get),
595  "remove",
596  gettext_noop (
597  "Remove the DID"),
598  &remove_did),
600  "replace",
601  gettext_noop ("Replace the DID Document."),
602  &replace),
604  "show",
605  gettext_noop ("Show the DID for a given ego"),
606  &show),
608  "show-all",
609  gettext_noop ("Show egos with DIDs"),
610  &show_all),
612  "did",
613  "DID",
614  gettext_noop (
615  "The Decentralized Identity (DID)"),
616  &did),
618  "did-document",
619  "JSON",
620  gettext_noop (
621  "The DID Document to store in GNUNET"),
622  &didd),
624  "ego",
625  "EGO",
626  gettext_noop ("The name of the EGO"),
627  &egoname),
629  "expiration-time",
630  "TIME",
631  gettext_noop (
632  "The time until the DID Document is going to expire (e.g. 5d)"),
633  &expire),
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 }
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_OPTION_END
Definition: 002.c:13
struct GNUNET_GETOPT_CommandLineOption options[]
Definition: 002.c:5
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).
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:88
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:221
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
helper library for DID related functions
#define gettext_noop(String)
Definition: gettext.h:70
static int replace
Replace DID Document Flag.
Definition: gnunet-did.c:56
static void create_did_ego_lockup_cb()
static struct GNUNET_GNS_Handle * gns_handle
Definition: gnunet-did.c:106
static char * egoname
Ego Attribut String.
Definition: gnunet-did.c:96
static char * didd
DID Document Attribut String.
Definition: gnunet-did.c:91
static void print_did_document(enum GNUNET_GenericReturnValue status, char *did_document, void *cls)
GNS lookup callback.
Definition: gnunet-did.c:160
static void replace_did_document_remove_cb(void *cls)
Replace a DID Document.
Definition: gnunet-did.c:452
static int show_all
Show DID for Ego Flag.
Definition: gnunet-did.c:81
static char * expire
DID Document expiration Date Attribut String.
Definition: gnunet-did.c:101
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:264
static void cleanup(void *cls)
Disconnect and shutdown.
Definition: gnunet-did.c:134
static void create_did_cb(enum GNUNET_GenericReturnValue status, void *cls)
Create a DID(-Document).
Definition: gnunet-did.c:315
static int remove_did
Remove DID Document Flag.
Definition: gnunet-did.c:61
static int ego_exists
Give ego exists.
Definition: gnunet-did.c:127
static struct GNUNET_NAMESTORE_Handle * namestore_handle
Definition: gnunet-did.c:111
static const struct GNUNET_CONFIGURATION_Handle * my_cfg
Definition: gnunet-did.c:122
static int ret
return value
Definition: gnunet-did.c:51
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:226
static void create_did_ego_create_cb(void *cls, const struct GNUNET_IDENTITY_PrivateKey *pk, enum GNUNET_ErrorCode ec)
Create a DID(-Document) - Called after a new Identity has been created.
Definition: gnunet-did.c:337
static void post_ego_iteration(void *cls)
Definition: gnunet-did.c:481
static void remove_did_document(remove_did_document_callback cont, void *cls)
Remove a DID Document.
Definition: gnunet-did.c:282
static void replace_did_document_ego_lookup_cb(void *cls, struct GNUNET_IDENTITY_Ego *ego)
Replace a DID Docuemnt.
Definition: gnunet-did.c:441
static void run(void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *c)
Definition: gnunet-did.c:547
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:205
static int show
Show DID for Ego Flag.
Definition: gnunet-did.c:76
static int get
Get DID Documement for DID Flag.
Definition: gnunet-did.c:66
static int create
Create DID Document Flag.
Definition: gnunet-did.c:71
static void resolve_did()
Resolve a DID given by the user.
Definition: gnunet-did.c:180
static void replace_did_document()
Replace a DID Docuemnt.
Definition: gnunet-did.c:465
static struct GNUNET_IDENTITY_Handle * identity_handle
Definition: gnunet-did.c:116
static void process_dids(void *cls, struct GNUNET_IDENTITY_Ego *ego, void **ctx, const char *name)
Definition: gnunet-did.c:509
static void create_did()
Create a DID(-Document).
Definition: gnunet-did.c:416
static char * did
DID Attribut String.
Definition: gnunet-did.c:86
int main(int argc, char *const argv[])
Definition: gnunet-did.c:581
uint16_t status
See PRISM_STATUS_*-constants.
struct GNUNET_IDENTITY_PrivateKey pk
Private key from command line option, or NULL.
static struct GNUNET_DNSSTUB_Context * ctx
Context for DNS resolution.
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:290
struct GNUNET_GNS_Handle * GNUNET_GNS_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Initialize the connection with the GNS service.
Definition: gns_api.c:268
#define GNUNET_GNS_EMPTY_LABEL_AT
String we use to indicate an empty label (top-level entry in the zone).
const struct GNUNET_IDENTITY_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:560
struct GNUNET_IDENTITY_Operation * GNUNET_IDENTITY_create(struct GNUNET_IDENTITY_Handle *h, const char *name, const struct GNUNET_IDENTITY_PrivateKey *privkey, enum GNUNET_IDENTITY_KeyType ktype, GNUNET_IDENTITY_CreateContinuation cont, void *cont_cls)
Create a new ego with the given name.
Definition: identity_api.c:586
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:531
void GNUNET_IDENTITY_disconnect(struct GNUNET_IDENTITY_Handle *h)
Disconnect from identity service.
Definition: identity_api.c:757
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.
@ GNUNET_IDENTITY_TYPE_EDDSA
EDDSA identity.
GNUNET_GenericReturnValue
Named constants for return values.
@ GNUNET_OK
#define GNUNET_free(ptr)
Wrapper around free.
void GNUNET_NAMESTORE_disconnect(struct GNUNET_NAMESTORE_Handle *h)
Disconnect from the namestore service (and free associated resources).
struct GNUNET_NAMESTORE_QueueEntry * GNUNET_NAMESTORE_records_store(struct GNUNET_NAMESTORE_Handle *h, const struct GNUNET_IDENTITY_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.
struct GNUNET_NAMESTORE_Handle * GNUNET_NAMESTORE_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the namestore service.
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
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:534
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:1268
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:260
const char * name
A Structure containing a cont and cls.
Definition: gnunet-did.c:212
remove_did_document_callback cont
Definition: gnunet-did.c:213
void * cls
Definition: gnunet-did.c:214
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
A private key for an identity as per LSD0001.
Connection to the NAMESTORE service.
Time for relative time used by GNUnet, in microseconds.