[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.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [gnunet] branch master updated: RECLAIM: Add DIDs - trizuz,
gnunet <=