Adding Reference Type Implemented
authorMarkus Voggenreiter <Markus.Voggenreiter@tum.de>
Fri, 25 Oct 2019 10:13:25 +0000 (12:13 +0200)
committerSchanzenbach, Martin <mschanzenbach@posteo.de>
Mon, 13 Jan 2020 12:31:03 +0000 (13:31 +0100)
src/reclaim/gnunet-service-reclaim.c

index 45b2a57c5e65a487eff3bec6ae2db9688ea599da..aea96e61e37068d1e334f88cb2f8b0729d6756a9 100644 (file)
@@ -337,6 +337,11 @@ struct AttributeStoreHandle
   */
   struct GNUNET_RECLAIM_ATTESTATION_Claim *attest;
 
+  /**
+  * The reference to store
+  */
+  struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *reference;
+
   /**
    * The attribute expiration interval
    */
@@ -500,6 +505,8 @@ cleanup_as_handle (struct AttributeStoreHandle *ash)
     GNUNET_free (ash->claim);
   if (NULL != ash->attest)
     GNUNET_free (ash->attest);
+  if (NULL != ash->reference)
+    GNUNET_free (ash->reference);
   GNUNET_free (ash);
 }
 
@@ -1169,6 +1176,214 @@ handle_attestation_store_message (void *cls,
   GNUNET_SCHEDULER_add_now (&attest_store_task, ash);
 }
 
+/**
+ * Error looking up potential reference value. Abort.
+ *
+ * @param cls our attribute store handle
+ */
+static void
+ref_error (void *cls)
+{
+  struct AttributeStoreHandle *ash = cls;
+  GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+              "Failed to find Attestation entry for Attestation reference\n");
+  cleanup_as_handle (ash);
+  GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
+  return;
+}
+
+/**
+* Reference 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
+reference_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 reference %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);
+}
+
+/**
+* Check for existing record before storing reference
+*
+* @param cls our attribute store handle
+* @param zone zone we are iterating
+* @param label label of the records
+* @param rd_count record count
+* @param rd records
+*/
+static void
+ref_add_cb (void *cls,
+            const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
+            const char *label,
+            unsigned int rd_count,
+            const struct GNUNET_GNSRECORD_Data *rd)
+{
+  struct AttributeStoreHandle *ash = cls;
+  char *buf;
+  size_t buf_size;
+  buf_size = GNUNET_RECLAIM_ATTESTATION_REF_serialize_get_size (ash->reference);
+  buf = GNUNET_malloc (buf_size);
+  GNUNET_RECLAIM_ATTESTATION_REF_serialize (ash->reference, buf);
+  if (0 == rd_count )
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Failed to find Attestation entry for Attestation reference\n");
+    cleanup_as_handle (ash);
+    GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
+    return;
+  }
+  if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR != rd[0].record_type)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Intended Reference storage location is not an attestation\n");
+    cleanup_as_handle (ash);
+    GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
+    return;
+  }
+  struct GNUNET_GNSRECORD_Data rd_new[rd_count + 1];
+  int i;
+  for (i = 0; i<rd_count; i++)
+  {
+    rd_new[i] = rd[i];
+  }
+  rd_new[rd_count].data_size = buf_size;
+  rd_new[rd_count].data = buf;
+  rd_new[rd_count].record_type = GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_REF;
+  rd_new[rd_count].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
+  rd_new[rd_count].expiration_time = ash->exp.rel_value_us;
+  ash->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
+                                               &ash->identity,
+                                               label,
+                                               rd_count + 1,
+                                               rd_new,
+                                               &reference_store_cont,
+                                               ash);
+  GNUNET_free (buf);
+}
+
+/**
+ * Add a new reference
+ *
+ * @param cls the AttributeStoreHandle
+ */
+static void
+reference_store_task (void *cls)
+{
+  struct AttributeStoreHandle *ash = cls;
+  char *label;
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Storing reference\n");
+
+  // Give the ash a new id if unset
+  if (0 == ash->reference->id)
+  {
+    if (0 == ash->reference->id_attest)
+    {
+      ash->reference->id = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG,
+                                                  UINT64_MAX);
+    }
+    else
+    {
+      ash->reference->id = ash->reference->id_attest;
+    }
+  }
+
+  label = GNUNET_STRINGS_data_to_string_alloc (&ash->reference->id,
+                                               sizeof(uint64_t));
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Encrypting with label %s\n", label);
+// Test for the content of the existing ID
+
+  ash->ns_qe = GNUNET_NAMESTORE_records_lookup (nsh,
+                                                &ash->identity,
+                                                label,
+                                                &ref_error,
+                                                ash,
+                                                &ref_add_cb,
+                                                ash);
+               GNUNET_free (label);
+}
+
+/**
+     * Check an attestation reference store message
+     *
+     * @param cls unused
+     * @param sam the message to check
+     */
+static int
+check_reference_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 reference store message
+    *
+    * @param cls our client
+    * @param sam the message to handle
+    */
+static void
+handle_reference_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 REFERENCE_STORE message\n");
+
+  data_len = ntohs (sam->attr_len);
+  ash = GNUNET_new (struct AttributeStoreHandle);
+  ash->reference = GNUNET_RECLAIM_ATTESTATION_REF_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 (&reference_store_task, ash);
+}
 /**
  * Send a deletion success response
  *
@@ -2019,6 +2234,10 @@ GNUNET_SERVICE_MAIN (
                          GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_DELETE,
                          struct AttributeDeleteMessage,
                          NULL),
+  GNUNET_MQ_hd_var_size (reference_store_message,
+                         GNUNET_MESSAGE_TYPE_RECLAIM_REFERENCE_STORE,
+                         struct AttributeStoreMessage,
+                         NULL),
   GNUNET_MQ_hd_fixed_size (
     iteration_start,
     GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_START,