GNUnet  0.17.6
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 {
183 
184  if (did == NULL)
185  {
186  printf ("Set DID option to resolve DID\n");
188  ret = 1;
189  return;
190  }
191 
193  {
194  printf ("An error occured while resoling the DID\n");
196  ret = 0;
197  return;
198  }
199 }
200 
201 
205 typedef void
206 (*remove_did_document_callback) (void *cls);
207 
212 struct Event
213 {
215  void *cls;
216 };
217 
226 static void
227 remove_did_document_namestore_cb (void *cls, int32_t success, const char *emgs)
228 {
229  struct Event *event;
230 
231  if (success != GNUNET_SYSERR)
232  {
233  event = (struct Event *) cls;
234 
235  if (event->cont != NULL)
236  {
237  event->cont (event->cls);
238  free (event);
239  }
240  else {
241  free (event);
243  ret = 0;
244  return;
245  }
246  }
247  else {
248  printf ("Something went wrong when deleting the DID Document\n");
249 
250  if (emgs != NULL)
251  {
252  printf ("%s\n", emgs);
253  }
254 
256  ret = 0;
257  return;
258  }
259 }
260 
267 static void
269 {
270  const struct GNUNET_IDENTITY_PrivateKey *skey =
272 
274  skey,
276  0,
277  NULL,
279  cls);
280 }
281 
285 static void
287 {
288  struct Event *event;
289 
290  if (egoname == NULL)
291  {
292  printf ("Remove requieres an ego option\n");
294  ret = 1;
295  return;
296  }
297  else {
298  event = malloc (sizeof(*event));
299  event->cont = cont;
300  event->cls = cls;
301 
303  egoname,
305  (void *) event);
306  }
307 }
308 
309 // Needed because create_did_ego_lookup_cb() and
310 // create_did_ego_create_cb() can call each other
312 
318 static void
320 {
321  if (GNUNET_OK == status)
322  {
323  printf ("DID has been created.\n%s\n", (char *) cls);
324  free (cls);
325  ret = 0;
326  }
327  else
328  {
329  printf ("An error occured while creating the DID.\n");
330  ret = 1;
331  }
332 
334  return;
335 }
336 
340 static void
342  const struct GNUNET_IDENTITY_PrivateKey *pk,
343  const char *emsg)
344 {
345  if (emsg != NULL)
346  {
347  printf ("%s\n", emsg);
349  ret = 1;
350  return;
351  }
352 
354  egoname,
356  NULL);
357 }
358 
363 static void
365 {
366  if (ego == NULL)
367  {
368  // If Ego was not found. Create new one first
369  printf ("Ego was not found. Creating new one.\n");
371  egoname,
372  NULL,
375  egoname);
376  }
377  else
378  {
379  char *did = DID_identity_to_did (ego);
380  void *cls = malloc (strlen (did) + 1);
381  struct GNUNET_TIME_Relative expire_relative;
382 
383  if (expire == NULL)
384  {
386  DID_DOCUMENT_DEFAULT_EXPIRATION_TIME, &expire_relative);
387  }
389  &
390  expire_relative))
391  {
392  printf ("Failed to read given expiration time\n");
394  ret = 1;
395  return;
396  }
397 
398  strcpy (cls, did);
399  // TODO: Add DID_document argument
400  if (GNUNET_OK != DID_create (ego,
401  NULL,
402  &expire_relative,
405  cls))
406  {
407  printf ("An error occured while creating the DID.\n");
408  ret = 1;
410  return;
411  }
412  }
413 }
414 
419 static void
421 {
422  // Ego name to be set
423  if (egoname == NULL)
424  {
425  printf ("Set the Ego argument to create a new DID(-Document)\n");
427  ret = 1;
428  return;
429  }
430 
432  egoname,
434  NULL);
435 }
436 
437 
444 static void
446 {
447  // create_did_store (didd, ego);
448 }
449 
455 static void
457 {
459  egoname,
461  NULL);
462 }
463 
468 static void
470 {
471  if ((didd != NULL) && (expire != NULL))
472  {
474  }
475  else {
476  printf (
477  "Set the DID Document and expiration time argument to replace the DID Document\n");
479  ret = 1;
480  return;
481  }
482 }
483 
484 static void
486 {
487  // TODO: Check that only one argument is set
488 
489  if (1 == replace)
490  {
492  }
493  else if (1 == get)
494  {
495  resolve_did ();
496  }
497  else if (1 == remove_did)
498  {
499  remove_did_document (NULL, NULL);
500  }
501  else if (1 == create)
502  {
503  create_did ();
504  }
505  else {
506  // No Argument found
508  return;
509  }
510 }
511 
512 static void
513 process_dids (void *cls, struct GNUNET_IDENTITY_Ego *ego,
514  void **ctx, const char*name)
515 {
516  char *did_str;
517 
518  if (ego == NULL)
519  {
520  if (1 == ego_exists)
521  {
523  return;
524  }
526  return;
527  }
528 
529  if (1 == show_all)
530  {
531  did_str = DID_identity_to_did (ego);
532  printf ("%s:\n\t%s\n", name, did_str);
533  GNUNET_free (did_str);
534  return;
535  }
536  if (1 == show)
537  {
538  if (0 == strncmp (name, egoname, strlen (egoname)))
539  {
540  did_str = DID_identity_to_did (ego);
541  printf ("%s:\n\t%s\n", name, did_str);
542  GNUNET_free (did_str);
543  return;
544  }
545  }
546 }
547 
548 
549 
550 static void
551 run (void *cls,
552  char *const *args,
553  const char *cfgfile,
554  const struct GNUNET_CONFIGURATION_Handle *c)
555 {
558  my_cfg = c;
559 
560  // check if GNS_handle could connect
561  if (gns_handle == NULL)
562  {
563  ret = 1;
564  return;
565  }
566 
567  // check if NAMESTORE_handle could connect
568  if (namestore_handle == NULL)
569  {
571  ret = 1;
572  return;
573  }
574 
576  if (identity_handle == NULL)
577  {
579  ret = 1;
580  return;
581  }
582 }
583 
584 int
585 main (int argc, char *const argv[])
586 {
589  "create",
590  gettext_noop (
591  "Create a DID Document and display its DID"),
592  &create),
594  "get",
595  gettext_noop (
596  "Get the DID Document associated with the given DID"),
597  &get),
599  "remove",
600  gettext_noop (
601  "Remove the DID"),
602  &remove_did),
604  "replace",
605  gettext_noop ("Replace the DID Document."),
606  &replace),
608  "show",
609  gettext_noop ("Show the DID for a given ego"),
610  &show),
612  "show-all",
613  gettext_noop ("Show egos with DIDs"),
614  &show_all),
616  "did",
617  "DID",
618  gettext_noop (
619  "The Decentralized Identity (DID)"),
620  &did),
622  "did-document",
623  "JSON",
624  gettext_noop (
625  "The DID Document to store in GNUNET"),
626  &didd),
628  "ego",
629  "EGO",
630  gettext_noop ("The name of the EGO"),
631  &egoname),
633  "expiration-time",
634  "TIME",
635  gettext_noop (
636  "The time until the DID Document is going to expire (e.g. 5d)"),
637  &expire),
639  };
640 
641  if (GNUNET_OK != GNUNET_PROGRAM_run (argc,
642  argv,
643  "gnunet-did",
644  "Manage Decentralized Identities (DIDs)",
645  options,
646  &run,
647  NULL))
648  return 1;
649  else
650  return ret;
651 }
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:87
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:69
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 remove_did_document_namestore_cb(void *cls, int32_t success, const char *emgs)
Implements the GNUNET_NAMESTORE_ContinuationWithStatus Calls the callback function and cls in the eve...
Definition: gnunet-did.c:227
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:456
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:268
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:319
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 post_ego_iteration(void *cls)
Definition: gnunet-did.c:485
static void remove_did_document(remove_did_document_callback cont, void *cls)
Remove a DID Document.
Definition: gnunet-did.c:286
static void replace_did_document_ego_lookup_cb(void *cls, struct GNUNET_IDENTITY_Ego *ego)
Replace a DID Docuemnt.
Definition: gnunet-did.c:445
static void run(void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *c)
Definition: gnunet-did.c:551
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:206
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:469
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:513
static void create_did()
Create a DID(-Document).
Definition: gnunet-did.c:420
static char * did
DID Attribut String.
Definition: gnunet-did.c:86
int main(int argc, char *const argv[])
Definition: gnunet-did.c:585
static void create_did_ego_create_cb(void *cls, const struct GNUNET_IDENTITY_PrivateKey *pk, const char *emsg)
Create a DID(-Document) - Called after a new Identity has been created.
Definition: gnunet-did.c:341
uint16_t status
See PRISM_STATUS_*-constants.
struct GNUNET_IDENTITY_PrivateKey pk
Private key from command line option, or NULL.
static char * pkey
Public key of the zone to look in, in ASCII.
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:639
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:757
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:610
void GNUNET_IDENTITY_disconnect(struct GNUNET_IDENTITY_Handle *h)
Disconnect from identity service.
Definition: identity_api.c:921
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.
Definition: gnunet_common.h:96
@ GNUNET_OK
Definition: gnunet_common.h:99
@ GNUNET_SYSERR
Definition: gnunet_common.h:97
#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:399
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:533
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:1281
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:261
const char * name
A Structure containing a cont and cls.
Definition: gnunet-did.c:213
remove_did_document_callback cont
Definition: gnunet-did.c:214
void * cls
Definition: gnunet-did.c:215
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:96
A private key for an identity as per LSD0001.
An identity key as per LSD0001.
Connection to the NAMESTORE service.
Time for relative time used by GNUnet, in microseconds.