gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gnunet] branch master updated: RECLAIM: Add DIDs - trizuz


From: gnunet
Subject: [gnunet] branch master updated: RECLAIM: Add DIDs - trizuz
Date: Fri, 14 Jan 2022 18:42:36 +0100

This is an automated email from the git hooks/post-receive script.

martin-schanzenbach pushed a commit to branch master
in repository gnunet.

The following commit(s) were added to refs/heads/master by this push:
     new 7e43ac554 RECLAIM: Add DIDs - trizuz
7e43ac554 is described below

commit 7e43ac55443b309d193f5c9f3dea02452205880d
Author: Martin Schanzenbach <schanzen@gnunet.org>
AuthorDate: Fri Jan 14 18:42:27 2022 +0100

    RECLAIM: Add DIDs - trizuz
---
 configure.ac                        |   1 +
 src/Makefile.am                     |   3 +-
 src/reclaim/Makefile.am             |  22 +-
 src/reclaim/gnunet-did.c            | 922 ++++++++++++++++++++++++++++++++++++
 src/reclaim/test_w3c_ed25519_2020.c |  69 +++
 5 files changed, 1014 insertions(+), 3 deletions(-)

diff --git a/configure.ac b/configure.ac
index feee06f9f..096a9f768 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1367,6 +1367,7 @@ src/dht/Makefile
 src/dht/dht.conf
 src/dhtu/Makefile
 src/dns/Makefile
+src/did/Makefile
 src/dns/dns.conf
 src/exit/Makefile
 src/fragmentation/Makefile
diff --git a/src/Makefile.am b/src/Makefile.am
index 4c665c3b3..06d018c56 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -6,7 +6,8 @@ TESTBED = testbed-logger testbed
 if HAVE_EXPERIMENTAL
  EXP_DIR = \
   rps \
-  abd
+  abd \
+  did
 if HAVE_ABE
  EXP_DIR += \
   abe
diff --git a/src/reclaim/Makefile.am b/src/reclaim/Makefile.am
index 350d77d4b..6b5934a2f 100644
--- a/src/reclaim/Makefile.am
+++ b/src/reclaim/Makefile.am
@@ -43,7 +43,8 @@ plugin_LTLIBRARIES = \
   $(REST_PLUGIN)
 
 bin_PROGRAMS = \
- gnunet-reclaim
+ gnunet-reclaim \
+ gnunet-did
 
 libexec_PROGRAMS = \
  gnunet-service-reclaim
@@ -187,13 +188,30 @@ test_reclaim_attribute_LDADD = \
   libgnunetreclaim.la \
   $(GN_LIBINTL)
 
+gnunet_did_SOURCES = \
+       gnunet-did.c
+gnunet_did_LDADD = \
+       $(top_builddir)/src/util/libgnunetutil.la \
+       $(top_builddir)/src/gns/libgnunetgns.la \
+       $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \
+       $(top_builddir)/src/identity/libgnunetidentity.la \
+       $(top_builddir)/src/namestore/libgnunetnamestore.la \
+       -ljansson
+
+
+test_w3c_ed25519_2020_SOURCES = \
+  test_w3c_ed25519_2020.c
+test_w3c_ed25519_2020_LDADD = \
+  $(top_builddir)/src/util/libgnunetutil.la
+
 check_SCRIPTS = \
   test_reclaim_attribute.sh \
   test_reclaim_issue.sh \
   test_reclaim_consume.sh
 
 check_PROGRAMS = \
-  test_reclaim_attribute
+  test_reclaim_attribute \
+  test_w3c_ed25519_2020
 
 if ENABLE_TEST_RUN
  AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export 
PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH;unset XDG_DATA_HOME;unset 
XDG_CONFIG_HOME;
diff --git a/src/reclaim/gnunet-did.c b/src/reclaim/gnunet-did.c
new file mode 100644
index 000000000..2ebef7601
--- /dev/null
+++ b/src/reclaim/gnunet-did.c
@@ -0,0 +1,922 @@
+/*
+   This file is part of GNUnet.
+   Copyright (C) 2012-2021 GNUnet e.V.
+
+   GNUnet is free software: you can redistribute it and/or modify it
+   under the terms of the GNU Affero General Public License as published
+   by the Free Software Foundation, either version 3 of the License,
+   or (at your option) any later version.
+
+   GNUnet is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Affero General Public License for more details.
+
+   You should have received a copy of the GNU Affero General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+     SPDX-License-Identifier: AGPL3.0-or-later
+ */
+
+/**
+ * FIXME: Do we only want to handle EdDSA identities?
+ * TODO: Own GNS record type
+ * TODO: Fix overwrite of records in @ if present look for other with same sub
+ * TODO. Tests
+ * TODO: Move constants to did.h
+ * FIXME: Remove and lookup require differnt representations (did vs egoname)
+ */
+
+/**
+ * @author Tristan Schwieren
+ * @file src/did/gnunet-did.c
+ * @brief DID Method Wrapper
+ *
+ */
+#include "platform.h"
+#include "gnunet_util_lib.h"
+#include "gnunet_namestore_service.h"
+#include "gnunet_gns_service.h"
+#include "gnunet_gnsrecord_lib.h"
+#include "jansson.h"
+
+#define GNUNET_DID_METHOD_RECLAIM_PREFIX "did:reclaim:"
+#define GNUNET_DID_DEFAULT_DID_DOCUMENT_EXPIRATION_TIME "1d"
+
+/**
+ * return value
+ */
+static int ret;
+
+/**
+ * Replace DID Document Flag
+ */
+static int replace;
+
+/**
+ * Remove DID Document Flag
+ */
+static int remove_did;
+
+/**
+ *  Get DID Documement for DID Flag
+ */
+static int get;
+
+/**
+ * Create DID Document Flag
+ */
+static int create;
+
+/**
+ * Show DID for Ego Flag
+ */
+static int show;
+
+/**
+ * Show DID for Ego Flag
+ */
+static int show_all;
+
+/**
+ * DID Attribut String
+ */
+static char *did;
+
+/**
+ * DID Document Attribut String
+ */
+static char *didd;
+
+/**
+ * Ego Attribut String
+ */
+static char *egoname;
+
+/**
+ * DID Document expiration Date Attribut String
+ */
+static char *expire;
+
+/*
+ * Handle to the GNS service
+ */
+static struct GNUNET_GNS_Handle *gns_handle;
+
+/*
+ * Handle to the NAMESTORE service
+ */
+static struct GNUNET_NAMESTORE_Handle *namestore_handle;
+
+/*
+ * Handle to the IDENTITY service
+ */
+static struct GNUNET_IDENTITY_Handle *identity_handle;
+
+
+/*
+ * The configuration
+ */
+const static struct GNUNET_CONFIGURATION_Handle *my_cfg;
+
+/**
+ * Give ego exists
+ */
+static int ego_exists = 0;
+
+/**
+ * @brief Disconnect and shutdown
+ * @param cls closure
+ */
+static void
+cleanup (void *cls)
+{
+  if (NULL != gns_handle)
+    GNUNET_GNS_disconnect (gns_handle);
+  if (NULL != namestore_handle)
+    GNUNET_NAMESTORE_disconnect (namestore_handle);
+  if (NULL != identity_handle)
+    GNUNET_IDENTITY_disconnect (identity_handle);
+
+  GNUNET_free (did);
+  GNUNET_free (didd);
+  GNUNET_free (egoname);
+  GNUNET_free (expire);
+
+  GNUNET_SCHEDULER_shutdown ();
+}
+
+char*
+ego_to_did (struct GNUNET_IDENTITY_Ego *ego)
+{
+  struct GNUNET_IDENTITY_PublicKey pkey; // Get Public key
+  char *pkey_str;
+  char *did_str;
+  size_t pkey_len;
+
+  GNUNET_IDENTITY_ego_get_public_key (ego, &pkey);
+
+  pkey_str = GNUNET_IDENTITY_public_key_to_string (&pkey);
+  GNUNET_asprintf (&did_str, "%s%s",
+                   GNUNET_DID_METHOD_RECLAIM_PREFIX,
+                   pkey_str);
+
+  free (pkey_str);
+  return did_str;
+}
+
+/**
+ * @brief Callback for ego loockup of get_did_for_ego()
+ *
+ * @param cls closure
+ * @param ego the returned ego
+ */
+static void
+get_did_for_ego_lookup_cb (void *cls, struct GNUNET_IDENTITY_Ego *ego)
+{
+  char *did_str;
+
+  if (ego == NULL)
+  {
+    printf ("EGO not found\n");
+    GNUNET_SCHEDULER_add_now (&cleanup, NULL);
+    ret = 1;
+    return;
+  }
+  did_str = ego_to_did (ego);
+
+  printf ("%s\n", did_str);
+
+  GNUNET_SCHEDULER_add_now (&cleanup, NULL);
+  ret = 0;
+  return;
+}
+
+/**
+ * @brief Get the DID for a given EGO
+ *
+ */
+static void
+get_did_for_ego ()
+{
+  if (egoname != NULL)
+  {
+    GNUNET_IDENTITY_ego_lookup (my_cfg,
+                                egoname,
+                                &get_did_for_ego_lookup_cb,
+                                NULL);
+  }
+  else {
+    printf ("Set the EGO argument to get the DID for a given EGO\n");
+    GNUNET_SCHEDULER_add_now (&cleanup, NULL);
+    ret = 1;
+    return;
+  }
+}
+
+
+/**
+ * @brief Get the public key from did attribute given by the user
+ *
+ * @param pkey place to write the public key to
+ */
+static void
+get_pkey_from_attr_did (struct GNUNET_IDENTITY_PublicKey *pkey)
+{
+  /* FIXME-MSC: I suggest introducing a
+   * #define MAX_DID_LENGTH <something>
+   * here and use it for parsing
+   */
+  char pkey_str[59];
+
+  if ((1 != (sscanf (did, GNUNET_DID_METHOD_RECLAIM_PREFIX"%58s", pkey_str))) 
||
+      (GNUNET_OK != GNUNET_IDENTITY_public_key_from_string (pkey_str, pkey)))
+  {
+    fprintf (stderr, _("Invalid DID `%s'\n"), pkey_str);
+    GNUNET_SCHEDULER_add_now (cleanup, NULL);
+    ret = 1;
+    return;
+  }
+}
+
+/**
+ * @brief GNS lookup callback. Prints the DID Document to standard out.
+ * Fails if there is more than one DID record.
+ *
+ * @param cls closure
+ * @param rd_count number of records in @a rd
+ * @param rd the records in the reply
+ */
+static void
+print_did_document (
+  void *cls,
+  uint32_t rd_count,
+  const struct GNUNET_GNSRECORD_Data *rd)
+{
+  /*
+   * FIXME-MSC: The user may decide to put other records here.
+   * In general I am fine with the constraint here, but not when
+   * we move it to "@"
+   */
+  if (rd_count != 1)
+  {
+    printf ("An ego should only have one DID Document\n");
+    GNUNET_SCHEDULER_add_now (cleanup, NULL);
+    ret = 1;
+    return;
+  }
+
+  if (rd[0].record_type == GNUNET_DNSPARSER_TYPE_TXT)
+  {
+    printf ("%s\n", (char *) rd[0].data);
+  }
+  else {
+    printf ("DID Document is not a TXT record\n");
+  }
+
+  GNUNET_SCHEDULER_add_now (cleanup, NULL);
+  ret = 0;
+  return;
+}
+
+/**
+ * @brief Resolve a DID given by the user.
+ */
+static void
+resolve_did_document ()
+{
+  struct GNUNET_IDENTITY_PublicKey pkey;
+
+  if (did == NULL)
+  {
+    printf ("Set DID option to resolve DID\n");
+    GNUNET_SCHEDULER_add_now (cleanup, NULL);
+    ret = 1;
+    return;
+  }
+
+  get_pkey_from_attr_did (&pkey);
+
+  GNUNET_GNS_lookup (gns_handle, GNUNET_GNS_EMPTY_LABEL_AT, &pkey, 
GNUNET_DNSPARSER_TYPE_TXT,
+                     GNUNET_GNS_LO_DEFAULT, &print_did_document, NULL);
+}
+
+
+/**
+ * @brief Signature of a callback function that is called after a did has been 
removed
+ */
+typedef void
+(*remove_did_document_callback) (void *cls);
+
+/**
+ * @brief A Structure containing a cont and cls. Can be passed as a cls to a 
callback function
+ *
+ */
+struct Event
+{
+  remove_did_document_callback cont;
+  void *cls;
+};
+
+/**
+ * @brief Implements the GNUNET_NAMESTORE_ContinuationWithStatus
+ * Calls the callback function and cls in the event struct
+ *
+ * @param cls closure containing the event struct
+ * @param success
+ * @param emgs
+ */
+static void
+remove_did_document_namestore_cb (void *cls, int32_t success, const char *emgs)
+{
+  struct Event *event;
+
+  if (success != GNUNET_SYSERR)
+  {
+    event = (struct Event *) cls;
+
+    if (event->cont != NULL)
+    {
+      event->cont (event->cls);
+      free (event);
+    }
+    else {
+      free (event);
+      GNUNET_SCHEDULER_add_now (cleanup, NULL);
+      ret = 0;
+      return;
+    }
+  } else {
+    printf ("Something went wrong when deleting the DID Document\n");
+
+    if (emgs != NULL)
+    {
+      printf ("%s\n", emgs);
+    }
+
+    GNUNET_SCHEDULER_add_now (cleanup, NULL);
+    ret = 0;
+    return;
+  }
+}
+
+/**
+ * @brief Callback called after the ego has been locked up
+ *
+ * @param cls closure
+ * @param ego the ego returned by the identity service
+ */
+static void
+remove_did_document_ego_lookup_cb (void *cls, struct GNUNET_IDENTITY_Ego *ego)
+{
+  const struct GNUNET_IDENTITY_PrivateKey *skey =
+    GNUNET_IDENTITY_ego_get_private_key (ego);
+
+  GNUNET_NAMESTORE_records_store (namestore_handle,
+                                  skey,
+                                  GNUNET_GNS_EMPTY_LABEL_AT,
+                                  0,
+                                  NULL,
+                                  &remove_did_document_namestore_cb,
+                                  cls);
+}
+
+/**
+ * @brief Remove a DID Document
+ */
+static void
+remove_did_document (remove_did_document_callback cont, void *cls)
+{
+  struct Event *event;
+
+  if (egoname == NULL)
+  {
+    printf ("Remove requieres an ego option\n");
+    GNUNET_SCHEDULER_add_now (cleanup, NULL);
+    ret = 1;
+    return;
+  }
+  else {
+    event = malloc (sizeof(*event));
+    event->cont = cont;
+    event->cls = cls;
+
+    GNUNET_IDENTITY_ego_lookup (my_cfg,
+                                egoname,
+                                &remove_did_document_ego_lookup_cb,
+                                (void *) event);
+  }
+}
+
+
+/**
+ * @brief Create a did generate did object
+ *
+ * @param pkey
+ * @return void* Return pointer to the DID Document
+ */
+char *
+create_did_generate (struct GNUNET_IDENTITY_PublicKey pkey)
+{
+  /* FIXME-MSC: I would prefer constants instead of magic numbers */
+  char *pkey_str;  // Convert public key to string
+  char did_str[71]; // 58 + 12 + 1 = 71
+  char *didd_str;
+  char verify_id_str[77]; // did_str len + "#key-1" = 71 + 6 = 77
+  char *pkey_multibase_str;
+
+  /* FIXME-MSC: This screams for a GNUNET_DID_identity_key_to_string() */
+  char *b64;
+  char pkx[34];
+  pkx[0] = 0xed;
+  pkx[1] = 0x01;
+  memcpy (pkx + 2, &(pkey.eddsa_key), sizeof(pkey.eddsa_key));
+  GNUNET_STRINGS_base64_encode (pkx, sizeof(pkx), &b64);
+
+  GNUNET_asprintf (&pkey_multibase_str, "u%s", b64);
+
+  json_t *didd;
+  json_t *did_json;
+  json_t *pkey_multibase_json;
+  json_t *context_json;
+  json_t *context_1_json;
+  json_t *context_2_json;
+  json_t *verify_json;
+  json_t *verify_1_json;
+  json_t *verify_1_type_json;
+  json_t *verify_1_id_json;
+  json_t *verify_relative_ref_json;
+  json_t *auth_json;
+  json_t *assert_json;
+
+  /* FIXME-MSC: This screams for GNUNET_DID_identity_to_did() */
+  pkey_str = GNUNET_IDENTITY_public_key_to_string (&pkey); // Convert public 
key to string
+  sprintf (did_str, "did:reclaim:%s", pkey_str); // Convert the public key to 
a DID str
+  sprintf (verify_id_str, "did:reclaim:%s#key-1", pkey_str); // Convert the 
public key to a DID str
+
+  // sprintf(pkey_multibase_str, "V%s", pkey_str); // Convert the public key 
to MultiBase data format
+
+  /* FIXME-MSC: This is effectively creating a DID Document default template 
for
+   * the initial document.
+   * Maybe this can be refactored to generate such a template for an identity?
+   * Even if higher layers add/modify it, there should probably still be a
+   * GNUNET_DID_document_template_from_identity()
+   */
+  // Create Json Strings
+  did_json = json_string (did_str);
+  pkey_multibase_json = json_string (pkey_multibase_str);
+
+  context_1_json = json_string ("https://www.w3.org/ns/did/v1";);
+  context_2_json = json_string (
+    "https://w3id.org/security/suites/ed25519-2020/v1";);
+  verify_1_id_json = json_string (verify_id_str);
+  verify_1_type_json = json_string ("Ed25519VerificationKey2020");
+
+  // Add a relative DID URL to reference a verifiation method
+  // https://www.w3.org/TR/did-core/#relative-did-urls`
+  verify_relative_ref_json = json_string ("#key-1");
+
+  // Create DID Document
+  didd = json_object ();
+
+  // Add context
+  context_json = json_array ();
+  json_array_append (context_json, context_1_json);
+  json_array_append (context_json, context_2_json);
+  json_object_set (didd, "@context", context_json);
+
+  // Add id
+  json_object_set (didd, "id", did_json);
+
+  // Add verification method
+  verify_json = json_array ();
+  verify_1_json = json_object ();
+  json_object_set (verify_1_json, "id", verify_1_id_json);
+  json_object_set (verify_1_json, "type", verify_1_type_json);
+  json_object_set (verify_1_json, "controller", did_json);
+  json_object_set (verify_1_json, "publicKeyMultiBase", pkey_multibase_json);
+  json_array_append (verify_json, verify_1_json);
+  json_object_set (didd, "verificationMethod", verify_json);
+
+  // Add authentication method
+  auth_json = json_array ();
+  json_array_append (auth_json, verify_relative_ref_json);
+  json_object_set (didd, "authentication", auth_json);
+
+  // Add assertion method to issue a Verifiable Credential
+  assert_json = json_array ();
+  json_array_append (assert_json, verify_relative_ref_json);
+  json_object_set (didd, "assertionMethod", assert_json);
+
+  // Encode DID Document as JSON string
+  didd_str = json_dumps (didd, JSON_INDENT (2));
+  if (didd_str == NULL)
+  {
+    printf ("DID Document could not be encoded");
+    GNUNET_SCHEDULER_add_now (&cleanup, NULL);
+    ret = 1;
+    return NULL;
+  }
+
+  // TODO: MORE FREEEEEEEE
+  /* FIXME-MSC: json_t's are free'd using "json_decref". Also json_t usually
+   * keeps a reference counter. Check jansson docs for how to use it.
+   * Also: Use valgrind to find leaks.
+   */
+  free (pkey_multibase_str);
+  free (b64);
+
+  free (didd);
+  free (did_json);
+  free (pkey_multibase_json);
+  free (context_json);
+  free (context_1_json);
+  free (context_2_json);
+  free (verify_json);
+  free (verify_1_json);
+  free (verify_1_type_json);
+  free (verify_1_id_json);
+  free (auth_json);
+  free (assert_json);
+  free (verify_relative_ref_json);
+
+  return didd_str;
+}
+
+/**
+ * @brief Create a DID. Store DID in Namestore cb
+ *
+ */
+static void
+create_did_store_cb (void *cls, int32_t success, const char *emsg)
+{
+  GNUNET_SCHEDULER_add_now (&cleanup, NULL);
+  ret = 0;
+  return;
+}
+
+/**
+ * @brief Create a did. Store DID in Namestore
+ *
+ * @param didd_str String endoced DID Docuement
+ * @param ego Identity whos DID Document is stored
+ */
+static void
+create_did_store (char *didd_str, struct GNUNET_IDENTITY_Ego *ego)
+{
+
+  struct GNUNET_TIME_Relative expire_time;
+  struct GNUNET_GNSRECORD_Data record_data;
+  const struct GNUNET_IDENTITY_PrivateKey *skey;
+
+  if (GNUNET_STRINGS_fancy_time_to_relative ((NULL != expire) ?
+                                             expire :
+                                             
GNUNET_DID_DEFAULT_DID_DOCUMENT_EXPIRATION_TIME,
+                                             &expire_time) == GNUNET_OK)
+  {
+    record_data.data = didd_str;
+    record_data.expiration_time = expire_time.rel_value_us;
+    record_data.data_size = strlen (didd_str) + 1;
+    record_data.record_type = GNUNET_GNSRECORD_typename_to_number ("TXT"),
+    record_data.flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
+
+    skey = GNUNET_IDENTITY_ego_get_private_key (ego);
+
+    GNUNET_NAMESTORE_records_store (namestore_handle,
+                                    skey,
+                                    GNUNET_GNS_EMPTY_LABEL_AT,
+                                    1, //FIXME what if 
GNUNET_GNS_EMPTY_LABEL_AT has records
+                                    &record_data,
+                                    &create_did_store_cb,
+                                    NULL);
+  }
+  else {
+    printf ("Failed to read given expiration time\n");
+    GNUNET_SCHEDULER_add_now (&cleanup, NULL);
+    ret = 1;
+    return;
+  }
+}
+
+/**
+ * @brief Create a did ego lockup cb
+ *
+ * @param cls
+ * @param ego
+ */
+static void
+create_did_ego_lockup_cb (void *cls, struct GNUNET_IDENTITY_Ego *ego)
+{
+  struct GNUNET_IDENTITY_PublicKey pkey;
+  char *didd_str;
+
+  if (ego == NULL)
+  {
+    printf ("EGO not found\n");
+    GNUNET_SCHEDULER_add_now (&cleanup, NULL);
+    ret = 1;
+    return;
+  }
+
+  GNUNET_IDENTITY_ego_get_public_key (ego, &pkey);
+
+  if (ntohl (pkey.type) != GNUNET_GNSRECORD_TYPE_EDKEY)
+  {
+    printf ("The EGO has to have an EDDSA key pair\n");
+    GNUNET_SCHEDULER_add_now (&cleanup, NULL);
+    ret = 1;
+    return;
+  }
+
+  if (didd != NULL)
+  {
+    printf (
+      "DID Docuement is read from \"did-document\" argument (EXPERIMENTAL)\n");
+    didd_str = strdup (didd);
+  }
+  else {
+    // Generate DID Docuement from public key
+    didd_str = create_did_generate (pkey);
+  }
+
+  // Print DID Document to stdout
+  printf ("%s\n", didd_str);
+
+  // Store the DID Document
+  create_did_store (didd_str, ego);
+
+  // Save DID Document String to GNS
+  free (didd_str);
+}
+
+/**
+ * @brief Create a did document - Create a new identity first
+ */
+static void
+create_did_document_ego_create_cb (void *cls,
+                                   const struct GNUNET_IDENTITY_PrivateKey *pk,
+                                   const char *emsg)
+{
+
+  if (emsg != NULL)
+  {
+    printf ("%s\n", emsg);
+    GNUNET_SCHEDULER_add_now (&cleanup, NULL);
+    ret = 1;
+    return;
+  }
+
+  GNUNET_IDENTITY_ego_lookup (my_cfg,
+                              egoname,
+                              &create_did_ego_lockup_cb,
+                              NULL);
+}
+
+/**
+ * @brief Create a did document
+ *
+ */
+static void
+create_did_document ()
+{
+  if ((egoname != NULL) && (expire != NULL))
+  {
+    GNUNET_IDENTITY_create (identity_handle,
+                            egoname,
+                            NULL,
+                            GNUNET_IDENTITY_TYPE_EDDSA,
+                            &create_did_document_ego_create_cb,
+                            egoname);
+  }
+  else {
+    printf (
+      "Set the EGO and the Expiration-time argument to create a new 
DID(-Document)\n");
+    GNUNET_SCHEDULER_add_now (&cleanup, NULL);
+    ret = 1;
+    return;
+  }
+}
+
+
+/**
+ * @brief Replace a DID Docuemnt. Callback function after ego lockup
+ *
+ * @param cls
+ * @param ego
+ */
+static void
+replace_did_document_ego_lookup_cb (void *cls, struct GNUNET_IDENTITY_Ego *ego)
+{
+  create_did_store (didd, ego);
+}
+
+/**
+ * @brief Replace a DID Document. Callback functiona after remove
+ *
+ * @param cls
+ */
+static void
+replace_did_document_remove_cb (void *cls)
+{
+  GNUNET_IDENTITY_ego_lookup (my_cfg,
+                              egoname,
+                              &replace_did_document_ego_lookup_cb,
+                              NULL);
+}
+
+/**
+ * @brief Replace a DID Docuemnt
+ *
+ */
+static void
+replace_did_document ()
+{
+  if ((didd != NULL) && (expire != NULL))
+  {
+    remove_did_document (&replace_did_document_remove_cb, NULL);
+  }
+  else {
+    printf (
+      "Set the DID Document and expiration time argument to replace the DID 
Document\n");
+    GNUNET_SCHEDULER_add_now (&cleanup, NULL);
+    ret = 1;
+    return;
+  }
+}
+
+static void
+post_ego_iteration (void *cls)
+{
+  if (1 == replace)
+  {
+    replace_did_document ();
+  }
+  else if (1 == get)
+  {
+    resolve_did_document ();
+  }
+  else if (1 == remove_did)
+  {
+    remove_did_document (NULL, NULL);
+  }
+  else if (1 == create)
+  {
+    create_did_document ();
+  }
+  else {
+    // No Argument found
+    GNUNET_SCHEDULER_add_now (&cleanup, NULL);
+    return;
+  }
+}
+
+static void
+process_dids (void *cls, struct GNUNET_IDENTITY_Ego *ego,
+              void **ctx, const char*name)
+{
+  char *did_str;
+
+  if (ego == NULL)
+  {
+    if (1 == ego_exists)
+    {
+      GNUNET_SCHEDULER_add_now (&cleanup, NULL);
+      return;
+    }
+    GNUNET_SCHEDULER_add_now (&post_ego_iteration, NULL);
+    return;
+  }
+  if (NULL == name)
+    return;
+  if ((1 == create) &&
+      (0 == strncmp (name, egoname, strlen (egoname))) &&
+      (1 != ego_exists))
+  {
+    fprintf(stderr, "%s already exists!\n", egoname);
+    ego_exists = 1;
+    return;
+  }
+  if (1 == show_all)
+  {
+    did_str = ego_to_did (ego);
+    printf ("%s\n", did_str);
+    GNUNET_free (did_str);
+    return;
+  }
+  if (1 == show)
+  {
+    if (0 == strncmp (name, egoname, strlen (egoname)))
+    {
+      did_str = ego_to_did (ego);
+      printf ("%s\n", did_str);
+      GNUNET_free (did_str);
+      return;
+    }
+  }
+}
+
+
+
+static void
+run (void *cls,
+     char *const *args,
+     const char *cfgfile,
+     const struct GNUNET_CONFIGURATION_Handle *c)
+{
+  gns_handle = GNUNET_GNS_connect (c);
+  namestore_handle = GNUNET_NAMESTORE_connect (c);
+  my_cfg = c;
+
+  // check if GNS_handle could connect
+  if (gns_handle == NULL)
+  {
+    ret = 1;
+    return;
+  }
+
+  // check if NAMESTORE_handle could connect
+  if (namestore_handle == NULL)
+  {
+    GNUNET_SCHEDULER_add_now (&cleanup, NULL);
+    ret = 1;
+    return;
+  }
+
+  identity_handle = GNUNET_IDENTITY_connect (c, &process_dids, NULL);
+  if (identity_handle == NULL)
+  {
+    GNUNET_SCHEDULER_add_now (&cleanup, NULL);
+    ret = 1;
+    return;
+  }
+}
+
+int
+main (int argc, char *const argv[])
+{
+  struct GNUNET_GETOPT_CommandLineOption options[] = {
+    GNUNET_GETOPT_option_flag ('C',
+                               "create",
+                               gettext_noop (
+                                 "Create a DID Document and display its DID"),
+                               &create),
+    GNUNET_GETOPT_option_flag ('g',
+                               "get",
+                               gettext_noop (
+                                 "Get the DID Document associated with the 
given DID"),
+                               &get),
+    GNUNET_GETOPT_option_flag ('s',
+                               "show",
+                               gettext_noop ("Show the DID for a given ego"),
+                               &show),
+    GNUNET_GETOPT_option_flag ('r',
+                               "remove",
+                               gettext_noop (
+                                 "Remove the DID"),
+                               &remove_did),
+    GNUNET_GETOPT_option_flag ('R',
+                               "replace",
+                               gettext_noop ("Replace the DID Document."),
+                               &replace),
+    GNUNET_GETOPT_option_flag ('A',
+                               "--show-all",
+                               gettext_noop ("Replace the DID Document."),
+                               &show_all),
+    GNUNET_GETOPT_option_string ('d',
+                                 "did",
+                                 "DID",
+                                 gettext_noop (
+                                   "The Decentralized Identity (DID)"),
+                                 &did),
+    GNUNET_GETOPT_option_string ('D',
+                                 "--did-document",
+                                 "JSON",
+                                 gettext_noop (
+                                   "The DID Document to store in GNUNET"),
+                                 &didd),
+    GNUNET_GETOPT_option_string ('e',
+                                 "ego",
+                                 "EGO",
+                                 gettext_noop ("The name of the EGO"),
+                                 &egoname),
+    GNUNET_GETOPT_option_string ('t',
+                                 "expiration-time",
+                                 "TIME",
+                                 gettext_noop (
+                                   "The time until the DID Document is going 
to expire (e.g. 5d)"),
+                                 &expire),
+    GNUNET_GETOPT_OPTION_END
+  };
+
+  if (GNUNET_OK != GNUNET_PROGRAM_run (argc,
+                                       argv,
+                                       "gnunet-did",
+                                       _ (
+                                         "Manage Decentralized Identities 
(DIDs)"),
+                                       options,
+                                       &run,
+                                       NULL))
+    return 1;
+  else
+    return ret;
+}
diff --git a/src/reclaim/test_w3c_ed25519_2020.c 
b/src/reclaim/test_w3c_ed25519_2020.c
new file mode 100644
index 000000000..e2534e6ab
--- /dev/null
+++ b/src/reclaim/test_w3c_ed25519_2020.c
@@ -0,0 +1,69 @@
+/*
+   This file is part of GNUnet.
+   Copyright (C) 2012-2021 GNUnet e.V.
+
+   GNUnet is free software: you can redistribute it and/or modify it
+   under the terms of the GNU Affero General Public License as published
+   by the Free Software Foundation, either version 3 of the License,
+   or (at your option) any later version.
+
+   GNUnet is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Affero General Public License for more details.
+
+   You should have received a copy of the GNU Affero General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+     SPDX-License-Identifier: AGPL3.0-or-later
+ */
+
+
+/**
+ * @file src/did/test_w3c_ed25519_2020.c
+ * @brief Testcases for the w3c Ed25519 formats for SSIs 
https://w3c-ccg.github.io/lds-ed25519-2020
+ * @author Martin Schanzenbach
+ */
+
+#include "platform.h"
+#include "gnunet_crypto_lib.h"
+#include "gnunet_strings_lib.h"
+
+static char test_privkey[32] = {
+  0x9b, 0x93, 0x7b, 0x81, 0x32, 0x2d, 0x81, 0x6c,
+  0xfa, 0xb9, 0xd5, 0xa3, 0xba, 0xac, 0xc9, 0xb2,
+  0xa5, 0xfe, 0xbe, 0x4b, 0x14, 0x9f, 0x12, 0x6b,
+  0x36, 0x30, 0xf9, 0x3a, 0x29, 0x52, 0x70, 0x17
+};
+
+static char *targetPublicKeyMultibase = 
"u7QEJX5oaWV3edV2CeGhkrQPfpaT71ogyVmNk4rZeE8yeRA";
+
+int
+main ()
+{
+  struct GNUNET_CRYPTO_EddsaPrivateKey privkey;
+  struct GNUNET_CRYPTO_EddsaPublicKey pubkey;
+
+  memcpy (&privkey, test_privkey, sizeof (privkey));
+  GNUNET_CRYPTO_eddsa_key_get_public (&privkey, &pubkey);
+
+  //This is how to convert out pubkeys to W3c Ed25519-2020 multibase 
(base64url no padding)
+  char *b64;
+  char pkx[34];
+  pkx[0] = 0xed;
+  pkx[1] = 0x01;
+  memcpy (pkx+2, &pubkey, sizeof (pubkey));
+  GNUNET_STRINGS_base64url_encode (pkx,
+                                   sizeof (pkx),
+                                   &b64);
+  printf ("u%s\n%s\n", b64, targetPublicKeyMultibase);
+  // FIXME convert pubkey to target
+  char *res;
+  GNUNET_asprintf (&res, "u%s", b64);
+  GNUNET_assert (0 == strcmp (res,
+                              targetPublicKeyMultibase));
+
+  GNUNET_free (b64);
+  GNUNET_free (res);
+  return 0;
+}

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]