Add Attestations via Reclaim Service
authorMarkus Voggenreiter <Markus.Voggenreiter@tum.de>
Sun, 13 Oct 2019 14:31:17 +0000 (16:31 +0200)
committerSchanzenbach, Martin <mschanzenbach@posteo.de>
Mon, 13 Jan 2020 12:31:02 +0000 (13:31 +0100)
src/include/gnunet_protocols.h
src/include/gnunet_reclaim_service.h
src/reclaim/gnunet-service-reclaim.c
src/reclaim/plugin_rest_reclaim.c
src/reclaim/reclaim_api.c

index cd7cb50dea5d5ca9e2fd108b5235fb2e8f7c124c..8de779ad333eaf03846d607671197b0e12ca911d 100644 (file)
@@ -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
index 237d791d9aed02c4e28a346ee89781f21a91767f..a9061d6e8763bfd8e7c8f5eb27fceb10b75ed7c4 100644 (file)
@@ -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.
index a83ea05a645f94d3a5fffc38fbda1652c190d553..d6c93812f4ef12f6f72c3400ff77ccf6810a671c 100644 (file)
@@ -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,
index bb08e6385ffe49303e5e9b43453b0addc8c3dc83..9290925b8d0b3afc401d262a241dfbbf7921fca5 100644 (file)
@@ -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;
 }
 
 /**
index 7d4d7588a73e9ea822e0595d7a5948acf05b1876..98865045083fde345028d6bbc3fa58f7718a8810 100644 (file)
@@ -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.