GNUnet 0.22.0
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 "gnunet_util_lib.h"
38#include "gnunet_gns_service.h"
40#include "did_core.h"
41
42#define GNUNET_DID_DEFAULT_DID_DOCUMENT_EXPIRATION_TIME "1d"
43
47static int ret;
48
52static int replace;
53
57static int remove_did;
58
62static int get;
63
67static int create;
68
72static int show;
73
77static int show_all;
78
82static char *did;
83
87static char *didd;
88
92static char *egoname;
93
97static char *expire;
98
99/*
100 * Handle to the GNS service
101 */
103
104/*
105 * Handle to the NAMESTORE service
106 */
108
109/*
110 * Handle to the IDENTITY service
111 */
113
114
115/*
116 * The configuration
117 */
119
123static int ego_exists = 0;
124
129static void
130cleanup (void *cls)
131{
132 if (NULL != gns_handle)
134 if (NULL != namestore_handle)
136 if (NULL != identity_handle)
138
143
145}
146
147
156static void
159 const char *did_document,
160 void *cls
161 )
162{
163 if (GNUNET_OK == status)
164 printf ("%s\n", did_document);
165 else
166 printf ("An error occurred: %s\n", did_document);
167
169 ret = 0;
170 return;
171}
172
173
177static void
179{
180
181 if (did == NULL)
182 {
183 printf ("Set DID option to resolve DID\n");
185 ret = 1;
186 return;
187 }
188
190 {
191 printf ("An error occurred while resoling the DID\n");
193 ret = 0;
194 return;
195 }
196}
197
198
202typedef void
203(*remove_did_document_callback) (void *cls);
204
209struct Event
210{
212 void *cls;
213};
214
223static void
225{
226 struct Event *event;
227
228 if (GNUNET_EC_NONE == ec)
229 {
230 event = (struct Event *) cls;
231
232 if (event->cont != NULL)
233 {
234 event->cont (event->cls);
235 free (event);
236 }
237 else
238 {
239 free (event);
241 ret = 0;
242 return;
243 }
244 }
245 else
246 {
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
257
264static void
266{
267 const struct GNUNET_CRYPTO_PrivateKey *skey =
269
271 skey,
273 0,
274 NULL,
276 cls);
277}
278
279
283static void
285{
286 struct Event *event;
287
288 if (egoname == NULL)
289 {
290 printf ("Remove requires an ego option\n");
292 ret = 1;
293 return;
294 }
295 else
296 {
297 event = malloc (sizeof(*event));
298 event->cont = cont;
299 event->cls = cls;
300
302 egoname,
304 (void *) event);
305 }
306}
307
308
309// Needed because create_did_ego_lookup_cb() and
310// create_did_ego_create_cb() can call each other
311static void
313
319static void
321{
322 if (GNUNET_OK == status)
323 {
324 printf ("DID has been created.\n%s\n", (char *) cls);
325 free (cls);
326 ret = 0;
327 }
328 else
329 {
330 printf ("An error occurred while creating the DID.\n");
331 ret = 1;
332 }
333
335 return;
336}
337
338
342static void
344 const struct GNUNET_CRYPTO_PrivateKey *pk,
345 enum GNUNET_ErrorCode ec)
346{
347 if (GNUNET_EC_NONE != ec)
348 {
349 printf ("%s\n", GNUNET_ErrorCode_get_hint (ec));
351 ret = 1;
352 return;
353 }
354
356 egoname,
358 NULL);
359}
360
361
366static void
368{
369 if (ego == NULL)
370 {
371 // If Ego was not found. Create new one first
372 printf ("Ego was not found. Creating new one.\n");
374 egoname,
375 NULL,
378 egoname);
379 }
380 else
381 {
382 char *did_tmp = DID_identity_to_did (ego);
383 void *cls_tmp = GNUNET_malloc (strlen (did_tmp) + 1);
384 struct GNUNET_TIME_Relative expire_relative;
385
386 if (expire == NULL)
387 {
391 &expire_relative));
392 }
394 &
395 expire_relative))
396 {
397 printf ("Failed to read given expiration time\n");
399 ret = 1;
400 GNUNET_free (cls_tmp);
401 return;
402 }
403
404 strcpy (cls_tmp, did_tmp);
405 // TODO: Add DID_document argument
406 if (GNUNET_OK != DID_create (ego,
407 NULL,
408 &expire_relative,
411 cls_tmp))
412 {
413 printf ("An error occurred while creating the DID.\n");
414 ret = 1;
416 GNUNET_free (cls_tmp);
417 return;
418 }
419 GNUNET_free (cls_tmp);
420 }
421}
422
423
428static void
430{
431 // Ego name to be set
432 if (egoname == NULL)
433 {
434 printf ("Set the Ego argument to create a new DID(-Document)\n");
436 ret = 1;
437 return;
438 }
439
441 egoname,
443 NULL);
444}
445
446
453static void
455{
456 // create_did_store (didd, ego);
457}
458
459
465static void
467{
469 egoname,
471 NULL);
472}
473
474
479static void
481{
482 if ((didd != NULL) && (expire != NULL))
483 {
485 }
486 else
487 {
488 printf (
489 "Set the DID Document and expiration time argument to replace the DID Document\n");
491 ret = 1;
492 return;
493 }
494}
495
496
497static void
499{
500 // TODO: Check that only one argument is set
501
502 if (1 == replace)
503 {
505 }
506 else if (1 == get)
507 {
508 resolve_did ();
509 }
510 else if (1 == remove_did)
511 {
512 remove_did_document (NULL, NULL);
513 }
514 else if (1 == create)
515 {
516 create_did ();
517 }
518 else
519 {
520 // No Argument found
522 return;
523 }
524}
525
526
527static void
528process_dids (void *cls, struct GNUNET_IDENTITY_Ego *ego,
529 void **ctx, const char*name)
530{
531 char *did_str;
532
533 if (ego == NULL)
534 {
535 if (1 == ego_exists)
536 {
538 return;
539 }
541 return;
542 }
543
544 if (1 == show_all)
545 {
546 did_str = DID_identity_to_did (ego);
547 printf ("%s:\n\t%s\n", name, did_str);
548 GNUNET_free (did_str);
549 return;
550 }
551 if (1 == show)
552 {
553 if (0 == strncmp (name, egoname, strlen (egoname)))
554 {
555 did_str = DID_identity_to_did (ego);
556 printf ("%s:\n\t%s\n", name, did_str);
557 GNUNET_free (did_str);
558 return;
559 }
560 }
561}
562
563
564static void
565run (void *cls,
566 char *const *args,
567 const char *cfgfile,
568 const struct GNUNET_CONFIGURATION_Handle *c)
569{
572 my_cfg = c;
573
574 // check if GNS_handle could connect
575 if (gns_handle == NULL)
576 {
577 ret = 1;
578 return;
579 }
580
581 // check if NAMESTORE_handle could connect
582 if (namestore_handle == NULL)
583 {
585 ret = 1;
586 return;
587 }
588
590 if (identity_handle == NULL)
591 {
593 ret = 1;
594 return;
595 }
596}
597
598
599int
600main (int argc, char *const argv[])
601{
604 "create",
606 "Create a DID Document and display its DID"),
607 &create),
609 "get",
611 "Get the DID Document associated with the given DID"),
612 &get),
614 "remove",
616 "Remove the DID"),
617 &remove_did),
619 "replace",
620 gettext_noop ("Replace the DID Document."),
621 &replace),
623 "show",
624 gettext_noop ("Show the DID for a given ego"),
625 &show),
627 "show-all",
628 gettext_noop ("Show egos with DIDs"),
629 &show_all),
631 "did",
632 "DID",
634 "The Decentralized Identity (DID)"),
635 &did),
637 "did-document",
638 "JSON",
640 "The DID Document to store in GNUNET"),
641 &didd),
643 "ego",
644 "EGO",
645 gettext_noop ("The name of the EGO"),
646 &egoname),
648 "expiration-time",
649 "TIME",
651 "The time until the DID Document is going to expire (e.g. 5d)"),
652 &expire),
654 };
655
656 if (GNUNET_OK != GNUNET_PROGRAM_run (argc,
657 argv,
658 "gnunet-did",
659 "Manage Decentralized Identities (DIDs)",
660 options,
661 &run,
662 NULL))
663 return 1;
664 else
665 return ret;
666}
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:52
static struct GNUNET_GNS_Handle * gns_handle
Definition: gnunet-did.c:102
static char * egoname
Ego Attribute String.
Definition: gnunet-did.c:92
static char * didd
DID Document Attribute String.
Definition: gnunet-did.c:87
static void replace_did_document_remove_cb(void *cls)
Replace a DID Document.
Definition: gnunet-did.c:466
static int show_all
Show DID for Ego Flag.
Definition: gnunet-did.c:77
static char * expire
DID Document expiration Date Attribute String.
Definition: gnunet-did.c:97
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:265
static void cleanup(void *cls)
Disconnect and shutdown.
Definition: gnunet-did.c:130
static void create_did_cb(enum GNUNET_GenericReturnValue status, void *cls)
Create a DID(-Document).
Definition: gnunet-did.c:320
static int remove_did
Remove DID Document Flag.
Definition: gnunet-did.c:57
static int ego_exists
Give ego exists.
Definition: gnunet-did.c:123
static struct GNUNET_NAMESTORE_Handle * namestore_handle
Definition: gnunet-did.c:107
static const struct GNUNET_CONFIGURATION_Handle * my_cfg
Definition: gnunet-did.c:118
static int ret
return value
Definition: gnunet-did.c:47
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:224
static void post_ego_iteration(void *cls)
Definition: gnunet-did.c:498
static void remove_did_document(remove_did_document_callback cont, void *cls)
Remove a DID Document.
Definition: gnunet-did.c:284
static void replace_did_document_ego_lookup_cb(void *cls, struct GNUNET_IDENTITY_Ego *ego)
Replace a DID Document.
Definition: gnunet-did.c:454
static void run(void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *c)
Definition: gnunet-did.c:565
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:203
static int show
Show DID for Ego Flag.
Definition: gnunet-did.c:72
static int get
Get DID Documement for DID Flag.
Definition: gnunet-did.c:62
static int create
Create DID Document Flag.
Definition: gnunet-did.c:67
static void resolve_did()
Resolve a DID given by the user.
Definition: gnunet-did.c:178
static void replace_did_document()
Replace a DID Document.
Definition: gnunet-did.c:480
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:343
static struct GNUNET_IDENTITY_Handle * identity_handle
Definition: gnunet-did.c:112
static void print_did_document(enum GNUNET_GenericReturnValue status, const char *did_document, void *cls)
GNS lookup callback.
Definition: gnunet-did.c:157
static void process_dids(void *cls, struct GNUNET_IDENTITY_Ego *ego, void **ctx, const char *name)
Definition: gnunet-did.c:528
static void create_did()
Create a DID(-Document).
Definition: gnunet-did.c:429
static char * did
DID Attribute String.
Definition: gnunet-did.c:82
static void create_did_ego_lockup_cb(void *cls, struct GNUNET_IDENTITY_Ego *ego)
Create a DID(-Document).
Definition: gnunet-did.c:367
int main(int argc, char *const argv[])
Definition: gnunet-did.c:600
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
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.
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:566
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:1303
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
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).
A Structure containing a cont and cls.
Definition: gnunet-did.c:210
remove_did_document_callback cont
Definition: gnunet-did.c:211
void * cls
Definition: gnunet-did.c:212
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.