[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[gnunet] 06/25: Add Attestations via Reclaim Service
From: |
gnunet |
Subject: |
[gnunet] 06/25: Add Attestations via Reclaim Service |
Date: |
Mon, 13 Jan 2020 13:46:51 +0100 |
This is an automated email from the git hooks/post-receive script.
martin-schanzenbach pushed a commit to branch master
in repository gnunet.
commit 2c65283b0bd97a8719f4c71aee8cc091a491129a
Author: Markus Voggenreiter <address@hidden>
AuthorDate: Sun Oct 13 16:31:17 2019 +0200
Add Attestations via Reclaim Service
---
src/include/gnunet_protocols.h | 2 +
src/include/gnunet_reclaim_service.h | 22 +++
src/reclaim/gnunet-service-reclaim.c | 144 +++++++++++++++
src/reclaim/plugin_rest_reclaim.c | 342 ++---------------------------------
src/reclaim/reclaim_api.c | 46 +++++
5 files changed, 225 insertions(+), 331 deletions(-)
diff --git a/src/include/gnunet_protocols.h b/src/include/gnunet_protocols.h
index cd7cb50de..8de779ad3 100644
--- a/src/include/gnunet_protocols.h
+++ b/src/include/gnunet_protocols.h
@@ -2714,6 +2714,8 @@ extern "C" {
#define GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_DELETE 976
+#define GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_STORE 977
+
/**************************************************
*
* ABD MESSAGE TYPES
diff --git a/src/include/gnunet_reclaim_service.h
b/src/include/gnunet_reclaim_service.h
index 237d791d9..a9061d6e8 100644
--- a/src/include/gnunet_reclaim_service.h
+++ b/src/include/gnunet_reclaim_service.h
@@ -151,6 +151,28 @@ GNUNET_RECLAIM_attribute_store (
GNUNET_RECLAIM_ContinuationWithStatus cont, void *cont_cls);
+/**
+ * Store an attestation. If the attestation is already present,
+ * it is replaced with the new attestation.
+ *
+ * @param h handle to the re:claimID service
+ * @param pkey private key of the identity
+ * @param attr the attestation value
+ * @param exp_interval the relative expiration interval for the attestation
+ * @param cont continuation to call when done
+ * @param cont_cls closure for @a cont
+ * @return handle to abort the request
+ */
+struct GNUNET_RECLAIM_Operation *
+GNUNET_RECLAIM_attestation_store (
+ struct GNUNET_RECLAIM_Handle *h,
+ const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey,
+ const struct GNUNET_RECLAIM_ATTESTATION_Claim *attr,
+ const struct GNUNET_TIME_Relative *exp_interval,
+ GNUNET_RECLAIM_ContinuationWithStatus cont,
+ void *cont_cls);
+
+
/**
* Delete an attribute. Tickets used to share this attribute are updated
* accordingly.
diff --git a/src/reclaim/gnunet-service-reclaim.c
b/src/reclaim/gnunet-service-reclaim.c
index a83ea05a6..d6c93812f 100644
--- a/src/reclaim/gnunet-service-reclaim.c
+++ b/src/reclaim/gnunet-service-reclaim.c
@@ -327,6 +327,11 @@ struct AttributeStoreHandle
*/
struct GNUNET_RECLAIM_ATTRIBUTE_Claim *claim;
+ /**
+ * The attestation to store
+ */
+ struct GNUNET_RECLAIM_ATTESTATION_Claim *attest;
+
/**
* The attribute expiration interval
*/
@@ -486,6 +491,8 @@ cleanup_as_handle (struct AttributeStoreHandle *ash)
GNUNET_NAMESTORE_cancel (ash->ns_qe);
if (NULL != ash->claim)
GNUNET_free (ash->claim);
+ if (NULL != ash->attest)
+ GNUNET_free (ash->attest);
GNUNET_free (ash);
}
@@ -1022,6 +1029,139 @@ handle_attribute_store_message (void *cls,
}
+/**
+ * Attestation store result handler
+ *
+ * @param cls our attribute store handle
+ * @param success GNUNET_OK if successful
+ * @param emsg error message (NULL if success=GNUNET_OK)
+ */
+static void
+attest_store_cont (void *cls, int32_t success, const char *emsg)
+{
+ struct AttributeStoreHandle *ash = cls;
+ struct GNUNET_MQ_Envelope *env;
+ struct SuccessResultMessage *acr_msg;
+
+ ash->ns_qe = NULL;
+ GNUNET_CONTAINER_DLL_remove (ash->client->store_op_head,
+ ash->client->store_op_tail,
+ ash);
+
+ if (GNUNET_SYSERR == success)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Failed to store attestation %s\n",
+ emsg);
+ cleanup_as_handle (ash);
+ GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
+ return;
+ }
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending SUCCESS_RESPONSE message\n");
+ env = GNUNET_MQ_msg (acr_msg, GNUNET_MESSAGE_TYPE_RECLAIM_SUCCESS_RESPONSE);
+ acr_msg->id = htonl (ash->r_id);
+ acr_msg->op_result = htonl (GNUNET_OK);
+ GNUNET_MQ_send (ash->client->mq, env);
+ cleanup_as_handle (ash);
+}
+
+/**
+ * Add a new attestation
+ *
+ * @param cls the AttributeStoreHandle
+ */
+static void
+attest_store_task (void *cls)
+{
+ struct AttributeStoreHandle *ash = cls;
+ struct GNUNET_GNSRECORD_Data rd[1];
+ char *buf;
+ char *label;
+ size_t buf_size;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Storing attestation\n");
+ buf_size = GNUNET_RECLAIM_ATTESTATION_serialize_get_size (ash->attest);
+ buf = GNUNET_malloc (buf_size);
+ // Give the ash a new id if unset
+ if (0 == ash->attest->id)
+ ash->attest->id
+ = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG, UINT64_MAX);
+ GNUNET_RECLAIM_ATTESTATION_serialize (ash->attest, buf);
+ label = GNUNET_STRINGS_data_to_string_alloc (&ash->attest->id,
+ sizeof(uint64_t));
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Encrypting with label %s\n", label);
+
+ rd[0].data_size = buf_size;
+ rd[0].data = buf;
+ rd[0].record_type = GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR;
+ rd[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
+ rd[0].expiration_time = ash->exp.rel_value_us;
+ ash->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
+ &ash->identity,
+ label,
+ 1,
+ rd,
+ &attest_store_cont,
+ ash);
+ GNUNET_free (buf);
+ GNUNET_free (label);
+}
+
+/**
+ * Check an attestation store message
+ *
+ * @param cls unused
+ * @param sam the message to check
+ */
+static int
+check_attestation_store_message (void *cls,
+ const struct AttributeStoreMessage *sam)
+{
+ uint16_t size;
+
+ size = ntohs (sam->header.size);
+ if (size <= sizeof(struct AttributeStoreMessage))
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ return GNUNET_OK;
+}
+
+/**
+* Handle an attestation store message
+*
+* @param cls our client
+* @param sam the message to handle
+*/
+static void
+handle_attestation_store_message (void *cls,
+ const struct AttributeStoreMessage *sam)
+{
+ struct AttributeStoreHandle *ash;
+ struct IdpClient *idp = cls;
+ size_t data_len;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received ATTESTATION_STORE message\n");
+
+ data_len = ntohs (sam->attr_len);
+
+ ash = GNUNET_new (struct AttributeStoreHandle);
+ ash->attest = GNUNET_RECLAIM_ATTESTATION_deserialize ((char *) &sam[1],
+ data_len);
+
+ ash->r_id = ntohl (sam->id);
+ ash->identity = sam->identity;
+ ash->exp.rel_value_us = GNUNET_ntohll (sam->exp);
+ GNUNET_CRYPTO_ecdsa_key_get_public (&sam->identity, &ash->identity_pkey);
+
+ GNUNET_SERVICE_client_continue (idp->client);
+ ash->client = idp;
+ GNUNET_CONTAINER_DLL_insert (idp->store_op_head, idp->store_op_tail, ash);
+ GNUNET_SCHEDULER_add_now (&attest_store_task, ash);
+}
+
/**
* Send a deletion success response
*
@@ -1742,6 +1882,10 @@ GNUNET_SERVICE_MAIN (
GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_STORE,
struct AttributeStoreMessage,
NULL),
+ GNUNET_MQ_hd_var_size (attestation_store_message,
+ GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_STORE,
+ struct AttributeStoreMessage,
+ NULL),
GNUNET_MQ_hd_var_size (attribute_delete_message,
GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_DELETE,
struct AttributeDeleteMessage,
diff --git a/src/reclaim/plugin_rest_reclaim.c
b/src/reclaim/plugin_rest_reclaim.c
index bb08e6385..9290925b8 100644
--- a/src/reclaim/plugin_rest_reclaim.c
+++ b/src/reclaim/plugin_rest_reclaim.c
@@ -241,210 +241,6 @@ struct RequestHandle
json_t *resp_object;
};
-/**
- * Handle for attribute store request
- */
-struct AttributeStoreHandle
-{
- /**
- * DLL
- */
- struct AttributeStoreHandle *next;
-
- /**
- * DLL
- */
- struct AttributeStoreHandle *prev;
-
- /**
- * Client connection
- */
- struct IdpClient *client;
-
- /**
- * Identity
- */
- struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
-
- /**
- * Identity pubkey
- */
- struct GNUNET_CRYPTO_EcdsaPublicKey identity_pkey;
-
- /**
- * QueueEntry
- */
- struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
-
- /**
- * The attribute to store
- */
- struct GNUNET_RECLAIM_ATTRIBUTE_Claim *claim;
-
- /**
- * The attestation to store
- */
- struct GNUNET_RECLAIM_ATTESTATION_Claim *attest;
-
- /**
- * The attribute expiration interval
- */
- struct GNUNET_TIME_Relative exp;
-
- /**
- * request id
- */
- uint32_t r_id;
-};
-
-/**
- * Handle for attribute deletion request
- */
-struct AttributeDeleteHandle
-{
- /**
- * DLL
- */
- struct AttributeDeleteHandle *next;
-
- /**
- * DLL
- */
- struct AttributeDeleteHandle *prev;
-
- /**
- * Client connection
- */
- struct IdpClient *client;
-
- /**
- * Identity
- */
- struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
-
-
- /**
- * QueueEntry
- */
- struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
-
- /**
- * Iterator
- */
- struct GNUNET_NAMESTORE_ZoneIterator *ns_it;
-
- /**
- * The attribute to delete
- */
- struct GNUNET_RECLAIM_ATTRIBUTE_Claim *claim;
-
- /**
- * The attestation to store
- */
- struct GNUNET_RECLAIM_ATTESTATION_Claim *attest;
-
- /**
- * Tickets to update
- */
- struct TicketRecordsEntry *tickets_to_update_head;
-
- /**
- * Tickets to update
- */
- struct TicketRecordsEntry *tickets_to_update_tail;
-
- /**
- * Attribute label
- */
- char *label;
-
- /**
- * request id
- */
- uint32_t r_id;
-};
-
-/**
- * Handle to the service.
- */
-struct GNUNET_RECLAIM_Handle
-{
- /**
- * Configuration to use.
- */
- const struct GNUNET_CONFIGURATION_Handle *cfg;
-
- /**
- * Socket (if available).
- */
- struct GNUNET_CLIENT_Connection *client;
-
- /**
- * Closure for 'cb'.
- */
- void *cb_cls;
-
- /**
- * Head of active operations.
- */
- struct GNUNET_RECLAIM_Operation *op_head;
-
- /**
- * Tail of active operations.
- */
- struct GNUNET_RECLAIM_Operation *op_tail;
-
- /**
- * Head of active iterations
- */
- struct GNUNET_RECLAIM_AttributeIterator *it_head;
-
- /**
- * Tail of active iterations
- */
- struct GNUNET_RECLAIM_AttributeIterator *it_tail;
-
- /**
- * Head of active iterations
- */
- struct GNUNET_RECLAIM_TicketIterator *ticket_it_head;
-
- /**
- * Tail of active iterations
- */
- struct GNUNET_RECLAIM_TicketIterator *ticket_it_tail;
-
- /**
- * Currently pending transmission request, or NULL for none.
- */
- struct GNUNET_CLIENT_TransmitHandle *th;
-
- /**
- * Task doing exponential back-off trying to reconnect.
- */
- struct GNUNET_SCHEDULER_Task *reconnect_task;
-
- /**
- * Time for next connect retry.
- */
- struct GNUNET_TIME_Relative reconnect_backoff;
-
- /**
- * Connection to service (if available).
- */
- struct GNUNET_MQ_Handle *mq;
-
- /**
- * Request Id generator. Incremented by one for each request.
- */
- uint32_t r_id_gen;
-
- /**
- * Are we polling for incoming messages right now?
- */
- int in_receive;
-};
-
/**
* Cleanup lookup handle
* @param handle Handle to clean up
@@ -656,6 +452,8 @@ ticket_collect (void *cls, const struct
GNUNET_RECLAIM_Ticket *ticket)
GNUNET_free (tmp);
GNUNET_RECLAIM_ticket_iteration_next (handle->ticket_it);
}
+
+
static void
add_attestation_cont (struct GNUNET_REST_RequestHandle *con_handle,
const char *url,
@@ -729,58 +527,12 @@ add_attestation_cont (struct GNUNET_REST_RequestHandle
*con_handle,
GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG, UINT64_MAX);
handle->idp = GNUNET_RECLAIM_connect (cfg);
exp = GNUNET_TIME_UNIT_HOURS;
- /*New */
- struct GNUNET_RECLAIM_Handle *h = handle->idp;
- struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey = identity_priv;
- /*struct GNUNET_RECLAIM_ATTESTATION_Claim *attr = attribute;*/
- struct GNUNET_TIME_Relative *exp_interval = &exp;
- /*GNUNET_RECLAIM_ContinuationWithStatus cont = &finished_cont;*/
- void *cont_cls = handle;
-
- struct AttributeStoreHandle *ash;
- struct GNUNET_GNSRECORD_Data rd[1];
- char *buf;
- char *label;
- size_t buf_size;
- struct IdpClient *idp = cont_cls;
- struct GNUNET_NAMESTORE_Handle *nsh;
- nsh = GNUNET_NAMESTORE_connect (cfg);
- if (NULL == nsh)
- {
- GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
- "error connecting to namestore");
- }
- ash = GNUNET_new (struct AttributeStoreHandle);
- ash->identity = *pkey;
- ash->r_id = h->r_id_gen++;
- ash->exp.rel_value_us = exp_interval->rel_value_us;
- ash->attest = attribute;
- ash->client = idp;
- buf_size = GNUNET_RECLAIM_ATTESTATION_serialize_get_size (ash->attest);
- buf = GNUNET_malloc (buf_size);
- // Give the ash a new id if unset
- if (0 == ash->attest->id)
- ash->attest->id
- = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG, UINT64_MAX);
- GNUNET_RECLAIM_ATTESTATION_serialize (ash->attest, buf);
- label = GNUNET_STRINGS_data_to_string_alloc (&ash->attest->id,
- sizeof(uint64_t));
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Encrypting with label %s\n", label);
-
- rd[0].data_size = buf_size;
- rd[0].data = buf;
- rd[0].record_type = GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR;
- rd[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
- rd[0].expiration_time = ash->exp.rel_value_us;
- ash->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
- &ash->identity,
- label,
- 1,
- rd,
- &finished_cont,
- ash);
- GNUNET_free (buf);
- GNUNET_free (label);
+ handle->idp_op = GNUNET_RECLAIM_attestation_store (handle->idp,
+ identity_priv,
+ attribute,
+ &exp,
+ &finished_cont,
+ handle);
GNUNET_JSON_parse_free (attrspec);
}
/*Placeholder*/
@@ -800,81 +552,9 @@ delete_attestation_cont (struct GNUNET_REST_RequestHandle
*con_handle,
const char *url,
void *cls)
{
- const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key;
- struct RequestHandle *handle = cls;
- struct GNUNET_RECLAIM_ATTESTATION_Claim attr;
- struct EgoEntry *ego_entry;
- char *identity_id_str;
- char *identity;
- char *id;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deleting attestation.\n");
- if (strlen (GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) >= strlen (
- handle->url))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No identity given.\n");
- GNUNET_SCHEDULER_add_now (&do_error, handle);
- return;
- }
- identity_id_str =
- strdup (handle->url + strlen (
- GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) + 1);
- identity = strtok (identity_id_str, "/");
- id = strtok (NULL, "/");
- if ((NULL == identity) || (NULL == id))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Malformed request.\n");
- GNUNET_free (identity_id_str);
- GNUNET_SCHEDULER_add_now (&do_error, handle);
- return;
- }
-
- for (ego_entry = handle->ego_head; NULL != ego_entry;
- ego_entry = ego_entry->next)
- if (0 == strcmp (identity, ego_entry->identifier))
- break;
- handle->resp_object = json_array ();
- if (NULL == ego_entry)
- {
- // Done
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Ego %s not found.\n", identity);
- GNUNET_free (identity_id_str);
- GNUNET_SCHEDULER_add_now (&return_response, handle);
- return;
- }
- priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
- handle->idp = GNUNET_RECLAIM_connect (cfg);
- memset (&attr, 0, sizeof(struct GNUNET_RECLAIM_ATTESTATION_Claim));
- GNUNET_STRINGS_string_to_data (id, strlen (id), &attr.id, sizeof(uint64_t));
- attr.name = "";
-
- struct GNUNET_RECLAIM_Handle *h = handle->idp;
- struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey = priv_key;
-
- struct AttributeDeleteHandle *adh;
- struct IdpClient *idp = handle;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received ATTRIBUTE_DELETE message\n");
- struct GNUNET_NAMESTORE_Handle *nsh;
- nsh = GNUNET_NAMESTORE_connect (cfg);
- adh = GNUNET_new (struct AttributeDeleteHandle);
- adh->attest = &attr;
- adh->r_id = h->r_id_gen++;
- adh->identity = *pkey;
- adh->label = GNUNET_STRINGS_data_to_string_alloc (&adh->attest->id,
- sizeof(uint64_t));
- /*GNUNET_SERVICE_client_continue (idp->client);*/
- adh->client = idp;
- /*GNUNET_CONTAINER_DLL_insert (idp->delete_op_head, idp->delete_op_tail,
adh);*/
- adh->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
- &adh->identity,
- adh->label,
- 0,
- NULL,
- &delete_finished_cb,
- adh);
-
-
- GNUNET_free (identity_id_str);
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Deleting Attestations not
supported\n");
+ GNUNET_SCHEDULER_add_now (&do_error, cls);
+ return;
}
/**
diff --git a/src/reclaim/reclaim_api.c b/src/reclaim/reclaim_api.c
index 7d4d7588a..988650450 100644
--- a/src/reclaim/reclaim_api.c
+++ b/src/reclaim/reclaim_api.c
@@ -925,6 +925,52 @@ GNUNET_RECLAIM_attribute_delete (
return op;
}
+/**
+ * Store an attestation. If the attestation is already present,
+ * it is replaced with the new attestation.
+ *
+ * @param h handle to the re:claimID service
+ * @param pkey private key of the identity
+ * @param attr the attestation value
+ * @param exp_interval the relative expiration interval for the attestation
+ * @param cont continuation to call when done
+ * @param cont_cls closure for @a cont
+ * @return handle to abort the request
+ */
+struct GNUNET_RECLAIM_Operation *
+GNUNET_RECLAIM_attestation_store (
+ struct GNUNET_RECLAIM_Handle *h,
+ const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey,
+ const struct GNUNET_RECLAIM_ATTESTATION_Claim *attr,
+ const struct GNUNET_TIME_Relative *exp_interval,
+ GNUNET_RECLAIM_ContinuationWithStatus cont,
+ void *cont_cls)
+{
+ struct GNUNET_RECLAIM_Operation *op;
+ struct AttributeStoreMessage *sam;
+ size_t attr_len;
+
+ op = GNUNET_new (struct GNUNET_RECLAIM_Operation);
+ op->h = h;
+ op->as_cb = cont;
+ op->cls = cont_cls;
+ op->r_id = h->r_id_gen++;
+ GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, op);
+ attr_len = GNUNET_RECLAIM_ATTESTATION_serialize_get_size (attr);
+ op->env = GNUNET_MQ_msg_extra (sam,
+ attr_len,
+
GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_STORE);
+ sam->identity = *pkey;
+ sam->id = htonl (op->r_id);
+ sam->exp = GNUNET_htonll (exp_interval->rel_value_us);
+
+ GNUNET_RECLAIM_ATTESTATION_serialize (attr, (char *) &sam[1]);
+
+ sam->attr_len = htons (attr_len);
+ if (NULL != h->mq)
+ GNUNET_MQ_send_copy (h->mq, op->env);
+ return op;
+}
/**
* List all attributes for a local identity.
--
To stop receiving notification emails like this one, please contact
address@hidden.
- [gnunet] branch master updated (c0a6838a1 -> e52520756), gnunet, 2020/01/13
- [gnunet] 03/25: Initial Fixes of plugin, gnunet, 2020/01/13
- [gnunet] 01/25: Adapted Namestore and reclaim REST, gnunet, 2020/01/13
- [gnunet] 02/25: Adapted JSON Conversion and Serialization, gnunet, 2020/01/13
- [gnunet] 04/25: Fixed direct Namestore Access, gnunet, 2020/01/13
- [gnunet] 05/25: Direct Namestore Deletion Implemented, gnunet, 2020/01/13
- [gnunet] 06/25: Add Attestations via Reclaim Service,
gnunet <=
- [gnunet] 07/25: Delete Attestation via Service, gnunet, 2020/01/13
- [gnunet] 08/25: Prepare Listing Attestations, gnunet, 2020/01/13
- [gnunet] 10/25: some comments, gnunet, 2020/01/13
- [gnunet] 09/25: Listing Attestations through service, gnunet, 2020/01/13
- [gnunet] 11/25: Preparation for Reference Type, gnunet, 2020/01/13
- [gnunet] 12/25: Adding Reference Type Implemented, gnunet, 2020/01/13
- [gnunet] 13/25: Deletion of Reference Type, gnunet, 2020/01/13
- [gnunet] 14/25: Fixed Reference Deletion, gnunet, 2020/01/13
- [gnunet] 16/25: Listing of References with Attributes, gnunet, 2020/01/13
- [gnunet] 17/25: Pure Listing of References, gnunet, 2020/01/13