gnunet-svn
[Top][All Lists]
Advanced

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

[gnunet] 21/25: Basic Functionality Implemented


From: gnunet
Subject: [gnunet] 21/25: Basic Functionality Implemented
Date: Mon, 13 Jan 2020 13:47:06 +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 cb08bbcbefc98afe6b8c7600bb0dfb1241343cff
Author: Markus Voggenreiter <address@hidden>
AuthorDate: Wed Nov 27 12:30:49 2019 +0100

    Basic Functionality Implemented
---
 src/include/gnunet_gnsrecord_lib.h           |   9 -
 src/include/gnunet_reclaim_attribute_lib.h   |  22 +++
 src/reclaim-attribute/reclaim_attribute.c    | 214 +++++++++++++++++++---
 src/reclaim/gnunet-service-reclaim.c         |  71 ++++++--
 src/reclaim/gnunet-service-reclaim_tickets.c | 260 ++++++++++++++++++++++-----
 src/reclaim/json_reclaim.c                   |   7 +-
 src/reclaim/oidc_helper.c                    | 126 ++++++++++++-
 src/reclaim/oidc_helper.h                    |   2 +-
 src/reclaim/plugin_gnsrecord_reclaim.c       |   2 -
 src/reclaim/plugin_rest_openid_connect.c     | 167 ++++++++++++-----
 src/reclaim/plugin_rest_reclaim.c            |   5 +
 src/reclaim/reclaim_api.c                    |  18 +-
 12 files changed, 750 insertions(+), 153 deletions(-)

diff --git a/src/include/gnunet_gnsrecord_lib.h 
b/src/include/gnunet_gnsrecord_lib.h
index b49e39b76..797c71380 100644
--- a/src/include/gnunet_gnsrecord_lib.h
+++ b/src/include/gnunet_gnsrecord_lib.h
@@ -150,15 +150,6 @@ extern "C" {
  */
 #define GNUNET_GNSRECORD_TYPE_RECLAIM_REFERENCE 65555
 
-/**
- * Record type for reclaim attestation records
- */
-#define GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_REF 65556
-
-/**
- * Record type for reclaim reference records
- */
-#define GNUNET_GNSRECORD_TYPE_RECLAIM_REFERENCE_REF 65557
 
 /**
  * Flags that can be set for a record.
diff --git a/src/include/gnunet_reclaim_attribute_lib.h 
b/src/include/gnunet_reclaim_attribute_lib.h
index c761d20ed..004f2bd10 100644
--- a/src/include/gnunet_reclaim_attribute_lib.h
+++ b/src/include/gnunet_reclaim_attribute_lib.h
@@ -198,6 +198,20 @@ struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry
    * The attribute claim
    */
   struct GNUNET_RECLAIM_ATTRIBUTE_Claim *claim;
+  /**
+   * The attestation claim
+   */
+  struct GNUNET_RECLAIM_ATTESTATION_Claim *attest;
+
+  /**
+  * The reference
+  */
+  struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *reference;
+};
+
+struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType
+{
+  uint32_t type;
 };
 
 
@@ -278,6 +292,14 @@ GNUNET_RECLAIM_ATTRIBUTE_list_serialize (
 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *
 GNUNET_RECLAIM_ATTRIBUTE_list_deserialize (const char *data, size_t data_size);
 
+/**
+ * Count attestations in claim list
+ *
+ * @param attrs list
+ */
+int
+GNUNET_RECLAIM_ATTRIBUTE_list_count_attest (
+  const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs);
 
 /**
  * Get required size for serialization buffer
diff --git a/src/reclaim-attribute/reclaim_attribute.c 
b/src/reclaim-attribute/reclaim_attribute.c
index 207bfb617..43199c108 100644
--- a/src/reclaim-attribute/reclaim_attribute.c
+++ b/src/reclaim-attribute/reclaim_attribute.c
@@ -476,7 +476,30 @@ GNUNET_RECLAIM_ATTRIBUTE_list_serialize_get_size (
   size_t len = 0;
 
   for (le = attrs->list_head; NULL != le; le = le->next)
-    len += GNUNET_RECLAIM_ATTRIBUTE_serialize_get_size (le->claim);
+  {
+    if (NULL != le->claim)
+    {
+      len += sizeof(struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType);
+      len += GNUNET_RECLAIM_ATTRIBUTE_serialize_get_size (le->claim);
+    }
+    else if (NULL != le->attest )
+    {
+      len += sizeof(struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType);
+      len += GNUNET_RECLAIM_ATTESTATION_serialize_get_size (le->attest);
+    }
+    else if (NULL != le->reference)
+    {
+      len += sizeof(struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType);
+      len += GNUNET_RECLAIM_ATTESTATION_REF_serialize_get_size (le->reference);
+    }
+    else
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                  "Unserialized Claim List Entry Type for size not known.\n");
+      break;
+    }
+    len += sizeof(struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry);
+  }
   return len;
 }
 
@@ -497,14 +520,50 @@ GNUNET_RECLAIM_ATTRIBUTE_list_serialize (
   size_t len;
   size_t total_len;
   char *write_ptr;
-
   write_ptr = result;
   total_len = 0;
   for (le = attrs->list_head; NULL != le; le = le->next)
   {
-    len = GNUNET_RECLAIM_ATTRIBUTE_serialize (le->claim, write_ptr);
-    total_len += len;
-    write_ptr += len;
+    struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType *list_type;
+    if (NULL != le->claim)
+    {
+      list_type = (struct
+                   GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType *) write_ptr;
+      list_type->type = htons (1);
+      total_len += sizeof(struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType);
+      write_ptr += sizeof(struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType);
+      len = GNUNET_RECLAIM_ATTRIBUTE_serialize (le->claim, write_ptr);
+      total_len += len;
+      write_ptr += len;
+    }
+    else if (NULL != le->attest )
+    {
+      list_type = (struct
+                   GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType *) write_ptr;
+      list_type->type = htons (2);
+      total_len += sizeof(struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType);
+      write_ptr += sizeof(struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType);
+      len = GNUNET_RECLAIM_ATTESTATION_serialize (le->attest, write_ptr);
+      total_len += len;
+      write_ptr += len;
+    }
+    else if (NULL != le->reference)
+    {
+      list_type = (struct
+                   GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType *) write_ptr;
+      list_type->type = htons (3);
+      total_len += sizeof(struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType);
+      write_ptr += sizeof(struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType);
+      len = GNUNET_RECLAIM_ATTESTATION_REF_serialize (le->reference, 
write_ptr);
+      total_len += len;
+      write_ptr += len;
+    }
+    else
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                  "Unserialized Claim List Entry Type not known.\n");
+      continue;
+    }
   }
   return total_len;
 }
@@ -525,23 +584,75 @@ GNUNET_RECLAIM_ATTRIBUTE_list_deserialize (const char 
*data, size_t data_size)
   size_t attr_len;
   const char *read_ptr;
 
-  if (data_size < sizeof(struct Attribute))
+  if ((data_size < sizeof(struct Attribute) + sizeof(struct
+                                                     
GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry))
+      && (data_size < sizeof(struct
+                             Attestation)
+          + sizeof(struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry)) &&
+      (data_size < sizeof(struct Attestation_Reference) + sizeof(struct
+                                                                 
GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry)) )
     return NULL;
 
   attrs = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList);
   read_ptr = data;
   while (((data + data_size) - read_ptr) >= sizeof(struct Attribute))
   {
-    le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry);
-    le->claim =
-      GNUNET_RECLAIM_ATTRIBUTE_deserialize (read_ptr,
-                                            data_size - (read_ptr - data));
-    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                "Deserialized attribute %s\n",
-                le->claim->name);
-    GNUNET_CONTAINER_DLL_insert (attrs->list_head, attrs->list_tail, le);
-    attr_len = GNUNET_RECLAIM_ATTRIBUTE_serialize_get_size (le->claim);
-    read_ptr += attr_len;
+    struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType *list_type;
+    list_type = (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType *) 
read_ptr;
+    if (1 == ntohs (list_type->type))
+    {
+      le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry);
+      read_ptr += sizeof(struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType);
+      if (((data + data_size) - read_ptr) < sizeof(struct Attribute))
+        break;
+      le->attest = NULL;
+      le->reference = NULL;
+      le->claim =
+        GNUNET_RECLAIM_ATTRIBUTE_deserialize (read_ptr,
+                                              data_size - (read_ptr - data));
+      GNUNET_CONTAINER_DLL_insert (attrs->list_head, attrs->list_tail, le);
+      attr_len = GNUNET_RECLAIM_ATTRIBUTE_serialize_get_size (le->claim);
+      read_ptr += attr_len;
+    }
+    else if (2 == ntohs (list_type->type))
+    {
+      le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry);
+      read_ptr += sizeof(struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType);
+      if (((data + data_size) - read_ptr) < sizeof(struct Attestation))
+        break;
+      le->claim = NULL;
+      le->reference = NULL;
+      le->attest =
+        GNUNET_RECLAIM_ATTESTATION_deserialize (read_ptr,
+                                                data_size - (read_ptr - data));
+      GNUNET_CONTAINER_DLL_insert (attrs->list_head, attrs->list_tail, le);
+      attr_len = GNUNET_RECLAIM_ATTESTATION_serialize_get_size (le->attest);
+      read_ptr += attr_len;
+    }
+    else if (3 == ntohs (list_type->type))
+    {
+      le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry);
+      read_ptr += sizeof(struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType);
+      if (((data + data_size) - read_ptr) < sizeof(struct
+                                                   Attestation_Reference))
+        break;
+      le->claim = NULL;
+      le->attest = NULL;
+      le->reference =
+        GNUNET_RECLAIM_ATTESTATION_REF_deserialize (read_ptr,
+                                                    data_size - (read_ptr
+                                                                 - data));
+      GNUNET_CONTAINER_DLL_insert (attrs->list_head, attrs->list_tail, le);
+      attr_len = GNUNET_RECLAIM_ATTESTATION_REF_serialize_get_size (
+        le->reference);
+      read_ptr += attr_len;
+    }
+    else
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                  "Serialized Claim List Entry Type not known.\n");
+      break;
+    }
   }
   return attrs;
 }
@@ -561,16 +672,45 @@ GNUNET_RECLAIM_ATTRIBUTE_list_dup (
   struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *result;
 
   result = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList);
+  if (NULL == attrs->list_head)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Duplicating empty List\n");
+  }
   for (le = attrs->list_head; NULL != le; le = le->next)
   {
     result_le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry);
-    result_le->claim =
-      GNUNET_RECLAIM_ATTRIBUTE_claim_new (le->claim->name,
-                                          le->claim->type,
-                                          le->claim->data,
-                                          le->claim->data_size);
-    result_le->claim->id = le->claim->id;
-    result_le->claim->flag = le->claim->flag;
+    result_le->claim = NULL;
+    result_le->attest = NULL;
+    result_le->reference = NULL;
+    if (NULL != le->claim)
+    {
+      result_le->claim =
+        GNUNET_RECLAIM_ATTRIBUTE_claim_new (le->claim->name,
+                                            le->claim->type,
+                                            le->claim->data,
+                                            le->claim->data_size);
+
+      result_le->claim->id = le->claim->id;
+      result_le->claim->flag = le->claim->flag;
+    }
+    if ( NULL != le->attest)
+    {
+      result_le->attest = GNUNET_RECLAIM_ATTESTATION_claim_new (
+        le->attest->name,
+        le->attest->type,
+        le->attest->data,
+        le->attest->
+        data_size);
+      result_le->attest->id = le->attest->id;
+    }
+    if (NULL !=le->reference)
+    {
+      result_le->reference = GNUNET_RECLAIM_ATTESTATION_reference_new (
+        le->reference->name,
+        le->reference->reference_value);
+      result_le->reference->id = le->reference->id;
+      result_le->reference->id_attest = le->reference->id_attest;
+    }
     GNUNET_CONTAINER_DLL_insert (result->list_head,
                                  result->list_tail,
                                  result_le);
@@ -591,9 +731,14 @@ GNUNET_RECLAIM_ATTRIBUTE_list_destroy (
   struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le;
   struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *tmp_le;
 
-  for (le = attrs->list_head; NULL != le;)
+  for (le = attrs->list_head; NULL != le; le = le->next)
   {
-    GNUNET_free (le->claim);
+    if (NULL != le->claim)
+      GNUNET_free (le->claim);
+    if (NULL != le->attest)
+      GNUNET_free (le->attest);
+    if (NULL != le->reference)
+      GNUNET_free (le->reference);
     tmp_le = le;
     le = le->next;
     GNUNET_free (tmp_le);
@@ -601,7 +746,24 @@ GNUNET_RECLAIM_ATTRIBUTE_list_destroy (
   GNUNET_free (attrs);
 }
 
-
+/**
+ * Count attestations in claim list
+ *
+ * @param attrs list
+ */
+int
+GNUNET_RECLAIM_ATTRIBUTE_list_count_attest (
+  const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs)
+{
+  struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le;
+  int i = 0;
+  for (le = attrs->list_head; NULL != le; le = le->next)
+  {
+    if (NULL != le->attest)
+      i++;
+  }
+  return i;
+}
 /**
  * Get required size for serialization buffer
  *
diff --git a/src/reclaim/gnunet-service-reclaim.c 
b/src/reclaim/gnunet-service-reclaim.c
index fcbd9413f..8b7557090 100644
--- a/src/reclaim/gnunet-service-reclaim.c
+++ b/src/reclaim/gnunet-service-reclaim.c
@@ -1250,6 +1250,31 @@ reference_store_cont (void *cls, int32_t success, const 
char *emsg)
   cleanup_as_handle (ash);
 }
 
+/**
+     * Send a reference error response
+     *
+     * @param ash our attribute store handle
+     * @param success the success status
+     */
+static void
+send_ref_error (struct AttributeStoreHandle  *ash)
+{
+  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);
+
+  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_SYSERR);
+  GNUNET_MQ_send (ash->client->mq, env);
+  cleanup_as_handle (ash);
+}
+
 /**
 * Check for existing record before storing reference
 *
@@ -1272,33 +1297,46 @@ ref_add_cb (void *cls,
   buf_size = GNUNET_RECLAIM_ATTESTATION_REF_serialize_get_size 
(ash->reference);
   buf = GNUNET_malloc (buf_size);
   GNUNET_RECLAIM_ATTESTATION_REF_serialize (ash->reference, buf);
+  struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *ref;
+  char *data_tmp;
   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);
+    send_ref_error (ash);
     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);
+    send_ref_error (ash);
     return;
   }
   struct GNUNET_GNSRECORD_Data rd_new[rd_count + 1];
   int i;
   for (i = 0; i<rd_count; i++)
   {
+    data_tmp = GNUNET_malloc (rd[i].data_size);
+    GNUNET_memcpy (data_tmp, rd[i].data, rd[i].data_size);
+    ref = GNUNET_RECLAIM_ATTESTATION_REF_deserialize (data_tmp, htons (
+                                                        rd[i].data_size));
     rd_new[i] = rd[i];
+    if ((strcmp (ash->reference->name,ref->name) == 0)&&
+        (strcmp (ash->reference->reference_value,ref->reference_value)==0) )
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                  "Reference already stored\n");
+      reference_store_cont (ash,GNUNET_OK, NULL);
+      return;
+    }
   }
   rd_new[rd_count].data_size = buf_size;
   rd_new[rd_count].data = buf;
   rd_new[rd_count].record_type = GNUNET_GNSRECORD_TYPE_RECLAIM_REFERENCE;
   rd_new[rd_count].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
   rd_new[rd_count].expiration_time = ash->exp.rel_value_us;
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Encrypting with label %s\n", label);
   ash->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
                                                &ash->identity,
                                                label,
@@ -1339,7 +1377,8 @@ reference_store_task (void *cls)
 
   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);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Looking up existing data under label %s\n", label);
 // Test for the content of the existing ID
 
   ash->ns_qe = GNUNET_NAMESTORE_records_lookup (nsh,
@@ -1452,9 +1491,7 @@ ticket_iter (void *cls,
   int has_changed = GNUNET_NO;
   for (int i = 0; i < rd_count; i++)
   {
-    if ((GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF != rd[i].record_type) &&
-        (GNUNET_GNSRECORD_TYPE_RECLAIM_REFERENCE_REF != rd[i].record_type) &&
-        (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_REF != rd[i].record_type))
+    if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF != rd[i].record_type)
       continue;
     if (&adh->claim != NULL)
       if (0 != memcmp (rd[i].data, &adh->claim->id, sizeof(uint64_t)))
@@ -1559,10 +1596,10 @@ update_tickets (void *cls)
     if ((GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF == rd[i].record_type)
         && (0 == memcmp (rd[i].data, &adh->claim->id, sizeof(uint64_t))))
       continue;
-    if ((GNUNET_GNSRECORD_TYPE_RECLAIM_REFERENCE_REF == rd[i].record_type)
+    if ((GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF == rd[i].record_type)
         && (0 == memcmp (rd[i].data, &adh->attest->id, sizeof(uint64_t))))
       continue;
-    if ((GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_REF == rd[i].record_type)
+    if ((GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF == rd[i].record_type)
         && (0 == memcmp (rd[i].data, &adh->reference->id, sizeof(uint64_t))))
       continue;
     rd_new[j] = rd[i];
@@ -1879,7 +1916,7 @@ ref_del_cb (void *cls,
   {
     data_tmp = GNUNET_malloc (rd[i].data_size);
     GNUNET_memcpy (data_tmp, rd[i].data, rd[i].data_size);
-    attr_len = htons (rd->data_size);
+    attr_len = htons (rd[i].data_size);
     ref = GNUNET_RECLAIM_ATTESTATION_REF_deserialize (data_tmp, attr_len);
     if (NULL == ref )
     {
@@ -2045,10 +2082,18 @@ attr_iter_cb (void *cls,
   }
   if (rd_count > 1)
   {
-    if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR != rd[0].record_type)
+    if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF == rd[0].record_type)
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                  "Found Ticket. Ignoring.\n");
+      GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it, 1);
+      return;
+    }
+    else if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR != rd[0].record_type)
     {
       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  "Non-Attestation record with multiple entries found\n");
+                  "Non-Attestation record with multiple entries found: %u\n",
+                  rd[0].record_type);
       GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it, 1);
       return;
     }
diff --git a/src/reclaim/gnunet-service-reclaim_tickets.c 
b/src/reclaim/gnunet-service-reclaim_tickets.c
index 4d1a26333..b022225b8 100644
--- a/src/reclaim/gnunet-service-reclaim_tickets.c
+++ b/src/reclaim/gnunet-service-reclaim_tickets.c
@@ -667,8 +667,7 @@ rvk_move_attr_cb (void *cls,
                   const struct GNUNET_GNSRECORD_Data *rd)
 {
   struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
-  struct GNUNET_RECLAIM_ATTRIBUTE_Claim *claim;
-  struct GNUNET_GNSRECORD_Data new_rd;
+  struct GNUNET_GNSRECORD_Data new_rd[rd_count];
   struct RevokedAttributeEntry *le;
   char *new_label;
   char *attr_data;
@@ -677,7 +676,7 @@ rvk_move_attr_cb (void *cls,
   if (0 == rd_count)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                "The attribute %s no longer exists!\n",
+                "The claim %s no longer exists!\n",
                 label);
     le = rvk->move_attr;
     rvk->move_attr = le->next;
@@ -686,32 +685,82 @@ rvk_move_attr_cb (void *cls,
     GNUNET_SCHEDULER_add_now (&move_attrs_cont, rvk);
     return;
   }
-  /** find a new place for this attribute **/
-  rvk->move_attr->new_id =
-    GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG, UINT64_MAX);
-  new_rd = *rd;
-  claim = GNUNET_RECLAIM_ATTRIBUTE_deserialize (rd->data, rd->data_size);
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Attribute to update: Name=%s, ID=%" PRIu64 "\n",
-              claim->name,
-              claim->id);
-  claim->id = rvk->move_attr->new_id;
-  new_rd.data_size = GNUNET_RECLAIM_ATTRIBUTE_serialize_get_size (claim);
-  attr_data = GNUNET_malloc (rd->data_size);
-  new_rd.data_size = GNUNET_RECLAIM_ATTRIBUTE_serialize (claim, attr_data);
-  new_rd.data = attr_data;
-  new_label = GNUNET_STRINGS_data_to_string_alloc (&rvk->move_attr->new_id,
-                                                   sizeof(uint64_t));
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding attribute %s\n", new_label);
+  rvk->move_attr->new_id =GNUNET_CRYPTO_random_u64 
(GNUNET_CRYPTO_QUALITY_STRONG, UINT64_MAX);
+  new_label=NULL;
+  attr_data=NULL;
+  //new_rd = *rd;
+  for (int i = 0; i < rd_count; i++)
+  {
+    if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR == rd[i].record_type)
+    {
+      /** find a new place for this attribute **/
+      struct GNUNET_RECLAIM_ATTRIBUTE_Claim *claim;
+      claim = GNUNET_RECLAIM_ATTRIBUTE_deserialize (rd[i].data, 
rd[i].data_size);
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                  "Attribute to update: Name=%s, ID=%" PRIu64 "\n",
+                  claim->name,
+                  claim->id);
+      claim->id = rvk->move_attr->new_id;
+      new_rd[i].data_size = GNUNET_RECLAIM_ATTRIBUTE_serialize_get_size 
(claim);
+      attr_data = GNUNET_malloc (rd[i].data_size);
+      new_rd[i].data_size = GNUNET_RECLAIM_ATTRIBUTE_serialize (claim, 
attr_data);
+      new_rd[i].data = attr_data;
+      new_rd[i].record_type = rd[i].record_type;
+      new_rd[i].flags = rd[i].flags;
+      new_rd[i].expiration_time = rd[i].expiration_time;
+      new_label = GNUNET_STRINGS_data_to_string_alloc (&rvk->move_attr->new_id,
+                                                       sizeof(uint64_t));
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding attribute %s\n", new_label);
+      GNUNET_free (claim);
+    } else if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR == rd[i].record_type) 
+    {
+      struct GNUNET_RECLAIM_ATTESTATION_Claim *attest;
+      attest=GNUNET_RECLAIM_ATTESTATION_deserialize(rd[i].data, 
rd[i].data_size);
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                  "Attestation to update: Name=%s, ID=%" PRIu64 "\n",
+                  attest->name,
+                  attest->id);
+      attest->id = rvk->move_attr->new_id;
+      new_rd[i].data_size = GNUNET_RECLAIM_ATTESTATION_serialize_get_size 
(attest);
+      attr_data = GNUNET_malloc (rd[i].data_size);
+      new_rd[i].data_size = GNUNET_RECLAIM_ATTESTATION_serialize (attest, 
attr_data);
+      new_rd[i].data = attr_data;
+      new_rd[i].record_type = rd[i].record_type;
+      new_rd[i].flags = rd[i].flags;
+      new_rd[i].expiration_time = rd[i].expiration_time;
+      new_label = GNUNET_STRINGS_data_to_string_alloc 
(&rvk->move_attr->new_id, sizeof(uint64_t));
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding attestation %s\n", 
new_label);
+      GNUNET_free (attest);
+    } else if (GNUNET_GNSRECORD_TYPE_RECLAIM_REFERENCE == rd[i].record_type)
+    {
+      struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *reference;
+      reference=GNUNET_RECLAIM_ATTESTATION_REF_deserialize(rd[i].data, 
rd[i].data_size);
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                  "Reference to update: Name=%s, ID=%" PRIu64 "\n",
+                  reference->name,
+                  reference->id);
+      reference->id = rvk->move_attr->new_id;
+      reference->id_attest = rvk->move_attr->new_id;
+      new_rd[i].data_size = GNUNET_RECLAIM_ATTESTATION_REF_serialize_get_size 
(reference);
+      attr_data = GNUNET_malloc (rd[i].data_size);
+      new_rd[i].data_size = GNUNET_RECLAIM_ATTESTATION_REF_serialize 
(reference, attr_data);
+      new_rd[i].data = attr_data;
+      new_label = GNUNET_STRINGS_data_to_string_alloc 
(&rvk->move_attr->new_id, sizeof(uint64_t));
+      new_rd[i].record_type = rd[i].record_type;
+      new_rd[i].flags = rd[i].flags;
+      new_rd[i].expiration_time = rd[i].expiration_time;
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding reference %s\n", new_label);
+      GNUNET_free (reference);
+    }
+  }
   rvk->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
-                                               &rvk->identity,
-                                               new_label,
-                                               1,
-                                               &new_rd,
-                                               &move_attr_finished,
-                                               rvk);
+                                           &rvk->identity,
+                                           new_label,
+                                           rd_count,
+                                           new_rd,
+                                           &move_attr_finished,
+                                           rvk);
   GNUNET_free (new_label);
-  GNUNET_free (claim);
   GNUNET_free (attr_data);
 }
 
@@ -745,7 +794,7 @@ move_attrs (struct RECLAIM_TICKETS_RevokeHandle *rvk)
   }
   label = GNUNET_STRINGS_data_to_string_alloc (&rvk->move_attr->old_id,
                                                sizeof(uint64_t));
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Moving attribute %s\n", label);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Moving claim %s\n", label);
 
   rvk->ns_qe = GNUNET_NAMESTORE_records_lookup (nsh,
                                                 &rvk->identity,
@@ -982,21 +1031,70 @@ process_parallel_lookup_result (void *cls,
 
 
   GNUNET_free (parallel_lookup);
-  if (1 != rd_count)
-    GNUNET_break (0); // FIXME: We should never find this.
-  if (rd->record_type == GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR)
+  if (0 == rd_count)
+    GNUNET_break (0);
+  // REMARK: It is possible now to find rd_count > 1
+  for (int i = 0; i < rd_count; i++)
   {
-    attr_le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry);
-    attr_le->claim =
-      GNUNET_RECLAIM_ATTRIBUTE_deserialize (rd->data, rd->data_size);
-    GNUNET_CONTAINER_DLL_insert (cth->attrs->list_head,
-                                 cth->attrs->list_tail,
-                                 attr_le);
-  }
+    if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR == rd[i].record_type)
+    {
+      attr_le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry);
+      attr_le->claim =
+        GNUNET_RECLAIM_ATTRIBUTE_deserialize (rd[i].data, rd[i].data_size);
+      GNUNET_CONTAINER_DLL_insert (cth->attrs->list_head,
+                                   cth->attrs->list_tail,
+                                   attr_le);
+      attr_le->reference = NULL;
+      attr_le->attest = NULL;
+    }
+    else if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR == rd[i].record_type)
+    {
+      /**Ignore all plain attestations
+      *attr_le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry);
+      *attr_le->attest =
+      *  GNUNET_RECLAIM_ATTESTATION_deserialize (rd[i].data, rd[i].data_size);
+      *GNUNET_CONTAINER_DLL_insert (cth->attrs->list_head,
+      *                             cth->attrs->list_tail,
+      *                             attr_le);
+      */
+      continue;
+    }
+    else if (GNUNET_GNSRECORD_TYPE_RECLAIM_REFERENCE == rd[i].record_type)
+    {
+      struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *attr_le2;
+      attr_le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry);
+      attr_le2 = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry);
+      if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR == rd[0].record_type)
+      {
+        attr_le->attest = GNUNET_RECLAIM_ATTESTATION_deserialize (rd[0].data,
+                                                                  rd[0].
+                                                                  data_size);
+        attr_le2->reference =
+          GNUNET_RECLAIM_ATTESTATION_REF_deserialize (rd[i].data,
+                                                      rd[i].data_size);
+        attr_le->claim = NULL;
+        attr_le->reference = NULL;
+        attr_le2->claim = NULL;
+        attr_le2->attest = NULL;
+        GNUNET_CONTAINER_DLL_insert (cth->attrs->list_head,
+                                     cth->attrs->list_tail,
+                                     attr_le);
+        GNUNET_CONTAINER_DLL_insert (cth->attrs->list_head,
+                                     cth->attrs->list_tail,
+                                     attr_le2);
+      }
+      else
+      {
+        GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                    "Parallel Lookup of Reference without Attestation");
+        continue;
+      }
 
+
+    }
+  }
   if (NULL != cth->parallel_lookups_head)
     return; // Wait for more
-
   /* Else we are done */
   cth->cb (cth->cb_cls, &cth->ticket.identity, cth->attrs, GNUNET_OK, NULL);
   cleanup_cth (cth);
@@ -1076,7 +1174,7 @@ lookup_authz_cb (void *cls,
       GNUNET_GNS_lookup (gns,
                          lbl,
                          &cth->ticket.identity,
-                         GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR,
+                         GNUNET_GNSRECORD_TYPE_ANY,
                          GNUNET_GNS_LO_DEFAULT,
                          &process_parallel_lookup_result,
                          parallel_lookup);
@@ -1223,6 +1321,7 @@ issue_ticket (struct TicketIssueHandle *ih)
   char *label;
   size_t list_len = 1;
   int i;
+  char *attest_string;
 
   for (le = ih->attrs->list_head; NULL != le; le = le->next)
     list_len++;
@@ -1232,8 +1331,51 @@ issue_ticket (struct TicketIssueHandle *ih)
   i = 0;
   for (le = ih->attrs->list_head; NULL != le; le = le->next)
   {
-    attrs_record[i].data = &le->claim->id;
-    attrs_record[i].data_size = sizeof(le->claim->id);
+    if (NULL != le->claim)
+    {
+      attrs_record[i].data = &le->claim->id;
+      attrs_record[i].data_size = sizeof(le->claim->id);
+    }
+    else if (NULL != le->attest)
+    {
+      // REMARK: Since we only store IDs, the references are irrelevant
+      int j = 0;
+      GNUNET_asprintf (&attest_string,"%d",le->attest->id);
+      while (j<i)
+      {
+        if (0 == strcmp (attest_string,GNUNET_STRINGS_data_to_string_alloc (
+                           attrs_record[j].data, attrs_record[j].data_size)))
+          break;
+        j++;
+      }
+      if (j < i)
+      {
+        list_len--;
+        continue;
+      }
+      attrs_record[i].data = &le->attest->id;
+      attrs_record[i].data_size = sizeof(le->attest->id);
+    }
+    else if (NULL != le->reference)
+    {
+      list_len--;
+      continue;
+      /*
+      int j = 0;
+      GNUNET_asprintf (&attest_string,"%d",le->attest->id);
+      while (j<i)
+      {
+        if (strcmp(attest_string, GNUNET_STRINGS_data_to_string_alloc (
+              attrs_record[j].data, attrs_record[j].data_size)))
+          break;
+        j++;
+      }
+      if (j < i)
+        continue;
+      attrs_record[i].data = &le->reference->id;
+      attrs_record[i].data_size = sizeof(le->reference->id);
+      */
+    }
     /**
      * FIXME: Should this be the attribute expiration time or ticket
      * refresh interval? Probably min(attrs.expiration)
@@ -1344,14 +1486,34 @@ filter_tickets_cb (void *cls,
     for (le = tih->attrs->list_head; NULL != le; le = le->next)
     {
       // cmp attr_ref id with requested attr id
-      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                  " %" PRIu64 "\n  %" PRIu64 "\n",
-                  *((uint64_t *) rd[i].data),
-                  le->claim->id);
-
+      if (NULL !=le->claim)
+      {
+        GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                    " %" PRIu64 "\n  %" PRIu64 "\n",
+                    *((uint64_t *) rd[i].data),
+                    le->claim->id);
+        if (0 == memcmp (rd[i].data, &le->claim->id, sizeof(uint64_t)))
+          found_attrs_cnt++;
+      }
+      else if (NULL !=le->attest)
+      {
+        GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                    " %" PRIu64 "\n  %" PRIu64 "\n",
+                    *((uint64_t *) rd[i].data),
+                    le->attest->id);
+        if (0 == memcmp (rd[i].data, &le->attest->id, sizeof(uint64_t)))
+          found_attrs_cnt++;
+      }
+      else if (NULL != le->reference)
+      {
+        GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                    " %" PRIu64 "\n  %" PRIu64 "\n",
+                    *((uint64_t *) rd[i].data),
+                    le->reference->id);
+        if (0 == memcmp (rd[i].data, &le->reference->id, sizeof(uint64_t)))
+          found_attrs_cnt++;
+      }
 
-      if (0 == memcmp (rd[i].data, &le->claim->id, sizeof(uint64_t)))
-        found_attrs_cnt++;
     }
   }
 
diff --git a/src/reclaim/json_reclaim.c b/src/reclaim/json_reclaim.c
index 552ca0e69..775ab58d6 100644
--- a/src/reclaim/json_reclaim.c
+++ b/src/reclaim/json_reclaim.c
@@ -48,6 +48,7 @@ parse_attr (void *cls, json_t *root, struct 
GNUNET_JSON_Specification *spec)
   const char *val_str = NULL;
   const char *type_str = NULL;
   const char *id_str = NULL;
+  const char *flag_str = NULL;
   char *data;
   int unpack_state;
   uint32_t type;
@@ -63,7 +64,7 @@ parse_attr (void *cls, json_t *root, struct 
GNUNET_JSON_Specification *spec)
   }
   // interpret single attribute
   unpack_state = json_unpack (root,
-                              "{s:s, s?s, s:s, s:s!}",
+                              "{s:s, s?s, s:s, s:s, s?s!}",
                               "name",
                               &name_str,
                               "id",
@@ -71,7 +72,9 @@ parse_attr (void *cls, json_t *root, struct 
GNUNET_JSON_Specification *spec)
                               "type",
                               &type_str,
                               "value",
-                              &val_str);
+                              &val_str,
+                              "flag",
+                              &flag_str);
   if ((0 != unpack_state) || (NULL == name_str) || (NULL == val_str) ||
       (NULL == type_str))
   {
diff --git a/src/reclaim/oidc_helper.c b/src/reclaim/oidc_helper.c
index 1c3d65f35..2ce462854 100644
--- a/src/reclaim/oidc_helper.c
+++ b/src/reclaim/oidc_helper.c
@@ -118,7 +118,7 @@ fix_base64 (char *str)
 char *
 OIDC_id_token_new (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key,
                    const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key,
-                   const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs,
+                   struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs,
                    const struct GNUNET_TIME_Relative *expiration_time,
                    const char *nonce,
                    const char *secret_key)
@@ -131,13 +131,22 @@ OIDC_id_token_new (const struct 
GNUNET_CRYPTO_EcdsaPublicKey *aud_key,
   char *subject;
   char *header;
   char *body_str;
+  char *aggr_names_str;
+  char *aggr_sources_str;
+  char *aggr_sources_jwt_str;
+  char *source_name;
   char *result;
   char *header_base64;
   char *body_base64;
   char *signature_target;
   char *signature_base64;
   char *attr_val_str;
+  char *attest_val_str;
   json_t *body;
+  json_t *aggr_names;
+  json_t *aggr_sources;
+  json_t *aggr_sources_jwt;
+  uint64_t attest_arr[GNUNET_RECLAIM_ATTRIBUTE_list_count_attest (attrs)];
 
   // iat REQUIRED time now
   time_now = GNUNET_TIME_absolute_get ();
@@ -156,6 +165,8 @@ OIDC_id_token_new (const struct 
GNUNET_CRYPTO_EcdsaPublicKey *aud_key,
                                                 GNUNET_CRYPTO_EcdsaPublicKey));
   header = create_jwt_header ();
   body = json_object ();
+  aggr_names = json_object ();
+  aggr_sources = json_object ();
 
   // iss REQUIRED case sensitive server uri with https
   // The issuer is the local reclaim instance (e.g.
@@ -180,18 +191,111 @@ OIDC_id_token_new (const struct 
GNUNET_CRYPTO_EcdsaPublicKey *aud_key,
   // nonce
   if (NULL != nonce)
     json_object_set_new (body, "nonce", json_string (nonce));
-
+  int i = 0;
+  attest_val_str = NULL;
+  aggr_names_str = NULL;
+  aggr_sources_str = NULL;
+  aggr_sources_jwt_str = NULL;
+  source_name = NULL;
   for (le = attrs->list_head; NULL != le; le = le->next)
   {
-    attr_val_str =
-      GNUNET_RECLAIM_ATTRIBUTE_value_to_string (le->claim->type,
-                                                le->claim->data,
-                                                le->claim->data_size);
-    json_object_set_new (body, le->claim->name, json_string (attr_val_str));
-    GNUNET_free (attr_val_str);
+
+    if (le->claim != NULL)
+    {
+
+      attr_val_str =
+        GNUNET_RECLAIM_ATTRIBUTE_value_to_string (le->claim->type,
+                                                  le->claim->data,
+                                                  le->claim->data_size);
+      json_object_set_new (body, le->claim->name, json_string (attr_val_str));
+      GNUNET_free (attr_val_str);
+    }
+    else if (NULL != le->reference)
+    {
+      // Check if attest is there
+      int j = 0;
+      while (j<i)
+      {
+        if (attest_arr[j] == le->reference->id_attest)
+          break;
+        j++;
+      }
+      if (j==i)
+      {
+        // Attest not yet existent. Append to the end of the list
+        GNUNET_CONTAINER_DLL_remove (attrs->list_head, attrs->list_tail, le);
+        GNUNET_CONTAINER_DLL_insert_tail (attrs->list_head, attrs->list_tail,
+                                          le);
+        continue;
+      }
+      else
+      {
+        // Attestation is existing, hence take the respective source str
+        GNUNET_asprintf (&source_name,
+                         "src%d",
+                         j);
+        json_object_set_new (aggr_names, le->reference->name, json_string (
+                               source_name));
+      }
+
+    }
+    else if (NULL != le->attest)
+    {
+      // We assume that at max 99 different attestations
+      int j = 0;
+      while (j<i)
+      {
+        if (attest_arr[j] == le->attest->id)
+          break;
+        j++;
+      }
+      if (j==i)
+      {
+        // New Attestation
+        attest_arr[i] = le->attest->id;
+        GNUNET_asprintf (&source_name,
+                         "src%d",
+                         i);
+        aggr_sources_jwt = json_object ();
+        attest_val_str = GNUNET_RECLAIM_ATTESTATION_value_to_string (
+          le->attest->type, le->attest->data, le->attest->data_size);
+        json_object_set_new (aggr_sources_jwt, "JWT",json_string (
+                               attest_val_str) );
+        aggr_sources_jwt_str = json_dumps (aggr_sources_jwt, JSON_INDENT (0)
+                                           | JSON_COMPACT);
+        json_object_set_new (aggr_sources, source_name,json_string (
+                               aggr_sources_jwt_str));
+        i++;
+      }
+      else
+      {
+        // Attestation already existent. Ignore
+        continue;
+      }
+
+    }
+  }
+  if (NULL != attest_val_str)
+    GNUNET_free (attest_val_str);
+  if (NULL != source_name)
+    GNUNET_free (source_name);
+  if (0!=i)
+  {
+    aggr_names_str = json_dumps (aggr_names, JSON_INDENT (0) | JSON_COMPACT);
+    aggr_sources_str = json_dumps (aggr_sources, JSON_INDENT (0)
+                                   | JSON_COMPACT);
+    json_object_set_new (body, "_claim_names", json_string (aggr_names_str));
+    json_object_set_new (body, "_claim_sources", json_string (
+                           aggr_sources_str));
   }
+
+  json_decref (aggr_names);
+  json_decref (aggr_sources);
+  json_decref (aggr_sources_jwt);
+
   body_str = json_dumps (body, JSON_INDENT (0) | JSON_COMPACT);
   json_decref (body);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"ID-Token: %s\n", body_str);
 
   GNUNET_STRINGS_base64_encode (header, strlen (header), &header_base64);
   fix_base64 (header_base64);
@@ -226,6 +330,12 @@ OIDC_id_token_new (const struct 
GNUNET_CRYPTO_EcdsaPublicKey *aud_key,
   GNUNET_free (signature_target);
   GNUNET_free (header);
   GNUNET_free (body_str);
+  if (NULL != aggr_sources_str)
+    GNUNET_free (aggr_sources_str);
+  if (NULL != aggr_names_str)
+    GNUNET_free (aggr_names_str);
+  if (NULL != aggr_sources_jwt_str)
+    GNUNET_free (aggr_sources_jwt_str);
   GNUNET_free (signature_base64);
   GNUNET_free (body_base64);
   GNUNET_free (header_base64);
diff --git a/src/reclaim/oidc_helper.h b/src/reclaim/oidc_helper.h
index 1774618e8..a7072755b 100644
--- a/src/reclaim/oidc_helper.h
+++ b/src/reclaim/oidc_helper.h
@@ -51,7 +51,7 @@
 char*
 OIDC_id_token_new (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key,
                    const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key,
-                   const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs,
+                   struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs,
                    const struct GNUNET_TIME_Relative *expiration_time,
                    const char *nonce,
                    const char *secret_key);
diff --git a/src/reclaim/plugin_gnsrecord_reclaim.c 
b/src/reclaim/plugin_gnsrecord_reclaim.c
index 0f59082dc..f7145a272 100644
--- a/src/reclaim/plugin_gnsrecord_reclaim.c
+++ b/src/reclaim/plugin_gnsrecord_reclaim.c
@@ -122,8 +122,6 @@ static struct
   { "RECLAIM_OIDC_REDIRECT", GNUNET_GNSRECORD_TYPE_RECLAIM_OIDC_REDIRECT },
   { "RECLAIM_TICKET", GNUNET_GNSRECORD_TYPE_RECLAIM_TICKET },
   { "RECLAIM_REFERENCE", GNUNET_GNSRECORD_TYPE_RECLAIM_REFERENCE },
-  { "RECLAIM_REFERENCE_REF", GNUNET_GNSRECORD_TYPE_RECLAIM_REFERENCE_REF },
-  { "RECLAIM_ATTEST_REF", GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_REF },
   { NULL, UINT32_MAX }
 };
 
diff --git a/src/reclaim/plugin_rest_openid_connect.c 
b/src/reclaim/plugin_rest_openid_connect.c
index 2c4b75c3f..741094f21 100644
--- a/src/reclaim/plugin_rest_openid_connect.c
+++ b/src/reclaim/plugin_rest_openid_connect.c
@@ -119,6 +119,11 @@
  */
 #define OIDC_NONCE_KEY "nonce"
 
+/**
+ * OIDC claims key
+ */
+#define OIDC_CLAIMS_KEY "claims"
+
 /**
  * OIDC PKCE code challenge
  */
@@ -290,6 +295,11 @@ struct OIDC_Variables
    */
   char *nonce;
 
+  /**
+   * The OIDC claims
+   */
+  char *claims;
+
   /**
    * The OIDC response type
    */
@@ -560,7 +570,12 @@ cleanup_handle (struct RequestHandle *handle)
     {
       claim_tmp = claim_entry;
       claim_entry = claim_entry->next;
-      GNUNET_free (claim_tmp->claim);
+      if (NULL != claim_tmp->claim)
+        GNUNET_free (claim_tmp->claim);
+      if (NULL != claim_tmp->attest)
+        GNUNET_free (claim_tmp->attest);
+      if (NULL != claim_tmp->reference)
+        GNUNET_free (claim_tmp->reference);
       GNUNET_free (claim_tmp);
     }
     GNUNET_free (handle->attr_list);
@@ -697,7 +712,7 @@ return_userinfo_response (void *cls)
   struct MHD_Response *resp;
 
   result_str = json_dumps (handle->oidc->response, 0);
-
+  GNUNET_log (GNUNET_ERROR_TYPE_ERROR,"ID-Token: %s\n",result_str);
   resp = GNUNET_REST_create_response (result_str);
   handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
   GNUNET_free (result_str);
@@ -838,7 +853,7 @@ login_redirect (void *cls)
                                                           &login_base_url))
   {
     GNUNET_asprintf (&new_redirect,
-                     "%s?%s=%s&%s=%s&%s=%s&%s=%s&%s=%s&%s=%s&%s=%s",
+                     "%s?%s=%s&%s=%s&%s=%s&%s=%s&%s=%s&%s=%s&%s=%s&%s=%s",
                      login_base_url,
                      OIDC_RESPONSE_TYPE_KEY,
                      handle->oidc->response_type,
@@ -854,7 +869,10 @@ login_redirect (void *cls)
                      (NULL != handle->oidc->code_challenge) ?
                      handle->oidc->code_challenge : "",
                      OIDC_NONCE_KEY,
-                     (NULL != handle->oidc->nonce) ? handle->oidc->nonce : "");
+                     (NULL != handle->oidc->nonce) ? handle->oidc->nonce : "",
+                     OIDC_CLAIMS_KEY,
+                     (NULL != handle->oidc->claims) ? handle->oidc->claims :
+                     "");
     resp = GNUNET_REST_create_response ("");
     MHD_add_response_header (resp, "Location", new_redirect);
     GNUNET_free (login_base_url);
@@ -993,7 +1011,7 @@ oidc_attr_collect (void *cls,
     GNUNET_RECLAIM_get_attributes_next (handle->attr_it);
     return;
   }
-  if (NULL == attr)
+  if (NULL != reference)
   {
     if ((NULL == reference->name) || (NULL == reference->reference_value))
     {
@@ -1013,35 +1031,31 @@ oidc_attr_collect (void *cls,
       return;
     }
     GNUNET_free (scope_variables);
-    // Store references as attributes as they only use the ID later
-    const char *type_str = NULL;
-    char *data;
-    size_t data_size;
-    uint32_t type;
+    struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le2;
+    le2 = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry);
     le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry);
-    type_str = "String";
-    type = GNUNET_RECLAIM_ATTRIBUTE_typename_to_number (type_str);
-    if (GNUNET_SYSERR ==(GNUNET_RECLAIM_ATTRIBUTE_string_to_value (type,
-                                                                   reference->
-                                                                   
reference_value,
-                                                                   (void **) &
-                                                                   data,
-                                                                   
&data_size)))
-    {
-      return;
-    }
-    le->claim = GNUNET_RECLAIM_ATTRIBUTE_claim_new (reference->name,
-                                                    type,
-                                                    data,
-                                                    data_size);
-    le->claim->id = reference->id;
-    le->claim->flag = 1;
-
+    le->claim = NULL;
+    le->reference = NULL;
+    le->attest = GNUNET_RECLAIM_ATTESTATION_claim_new (attest->name,
+                                                       attest->type,
+                                                       attest->data,
+                                                       attest->data_size);
+    le->attest->id = attest->id;
+    le2->attest = NULL;
+    le2->claim = NULL;
+    le2->reference = GNUNET_RECLAIM_ATTESTATION_reference_new (reference->name,
+                                                               reference->
+                                                               
reference_value);
+    le2->reference->id = reference->id;
+    le2->reference->id_attest = reference->id_attest;
     GNUNET_CONTAINER_DLL_insert (handle->attr_list->list_head,
                                  handle->attr_list->list_tail,
                                  le);
+    GNUNET_CONTAINER_DLL_insert (handle->attr_list->list_head,
+                                 handle->attr_list->list_tail,
+                                 le2);
   }
-  else
+  else if (NULL != attr)
   {
     if ((NULL == attr->name) || (NULL == attr->data))
     {
@@ -1063,8 +1077,9 @@ oidc_attr_collect (void *cls,
       return;
     }
     GNUNET_free (scope_variables);
-
     le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry);
+    le->reference = NULL;
+    le->attest = NULL;
     le->claim = GNUNET_RECLAIM_ATTRIBUTE_claim_new (attr->name,
                                                     attr->type,
                                                     attr->data,
@@ -1362,6 +1377,9 @@ build_authz_response (void *cls)
   // OPTIONAL value: nonce
   handle->oidc->nonce = get_url_parameter_copy (handle, OIDC_NONCE_KEY);
 
+  // OPTIONAL value: claims
+  handle->oidc->claims = get_url_parameter_copy (handle, OIDC_CLAIMS_KEY);
+
   // TODO check other values if needed
   number_of_ignored_parameter =
     sizeof(OIDC_ignored_parameter_array) / sizeof(char *);
@@ -1918,8 +1936,8 @@ token_endpoint (struct GNUNET_REST_RequestHandle 
*con_handle,
 
 
 /**
- * Collects claims and stores them in handle
- */
+     * Collects claims and stores them in handle
+     */
 static void
 consume_ticket (void *cls,
                 const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
@@ -1928,20 +1946,87 @@ consume_ticket (void *cls,
                 const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *reference)
 {
   struct RequestHandle *handle = cls;
-  char *tmp_value;
-  json_t *value;
-
   if (NULL == identity)
   {
     GNUNET_SCHEDULER_add_now (&return_userinfo_response, handle);
     return;
   }
-  tmp_value = GNUNET_RECLAIM_ATTRIBUTE_value_to_string (attr->type,
-                                                        attr->data,
-                                                        attr->data_size);
-  value = json_string (tmp_value);
-  json_object_set_new (handle->oidc->response, attr->name, value);
-  GNUNET_free (tmp_value);
+  if (NULL != attr)
+  {
+    char *tmp_value;
+    json_t *value;
+    tmp_value = GNUNET_RECLAIM_ATTRIBUTE_value_to_string (attr->type,
+                                                          attr->data,
+                                                          attr->data_size);
+    value = json_string (tmp_value);
+    json_object_set_new (handle->oidc->response, attr->name, value);
+    GNUNET_free (tmp_value);
+  }
+  else if ((NULL != attest) && (NULL != reference))
+  {
+    json_t *claim_sources;
+    json_t *claim_sources_jwt;
+    json_t *claim_names;
+    char *attest_val_str;
+    claim_sources=json_object_get(handle->oidc->response,"_claim_sources");
+    claim_names=json_object_get(handle->oidc->response,"_claim_names");
+    attest_val_str = GNUNET_RECLAIM_ATTESTATION_value_to_string (attest->type,
+                                                                 attest->data,
+                                                                 attest->
+                                                                 data_size);
+    if ((NULL == claim_sources) && (NULL == claim_names) )
+    {
+      claim_sources = json_object ();
+      claim_names = json_object ();
+    }
+    char *source_name;
+    int i = 0;
+    GNUNET_asprintf (&source_name,"src%d",i);
+    while (NULL != (claim_sources_jwt = json_object_get (claim_sources,
+                                                         source_name)))
+    {
+      if (0 == strcmp (json_string_value (json_object_get (claim_sources_jwt,
+                                                           "JWT")),
+                       attest_val_str))
+      {
+        // Adapt only the claim names
+        json_object_set_new (claim_names, reference->name, json_string (
+                               source_name));
+        json_object_set (handle->oidc->response, "_claim_names",claim_names);
+        handle->oidc->response = json_deep_copy(handle->oidc->response);
+        break;
+      }
+      i++;
+      GNUNET_asprintf (&source_name,"src%d",i);
+    }
+
+    // Create new one
+    if (NULL == claim_sources_jwt)
+    {
+      claim_sources_jwt = json_object ();
+      // Set the JWT for names
+      json_object_set_new (claim_names, reference->name, json_string (
+                             source_name));
+      // Set the JWT for the inner source
+      json_object_set_new (claim_sources_jwt, "JWT", json_string (
+                             attest_val_str));
+      // Set the JWT for the source
+      json_object_set_new (claim_sources, source_name,claim_sources_jwt);
+      // Set as claims
+      json_object_set (handle->oidc->response, "_claim_names", claim_names);
+      json_object_set (handle->oidc->response, "_claim_sources",claim_sources);
+      handle->oidc->response = json_deep_copy(handle->oidc->response);
+    }
+
+    json_decref (claim_sources);
+    json_decref (claim_names);
+    json_decref (claim_sources_jwt);
+    GNUNET_free (attest_val_str);
+  }
+  else
+  {
+    // REMARK: We should not find any claim, one of attest/ref is NULL
+  }
 }
 
 
diff --git a/src/reclaim/plugin_rest_reclaim.c 
b/src/reclaim/plugin_rest_reclaim.c
index 16286444a..70defae3d 100644
--- a/src/reclaim/plugin_rest_reclaim.c
+++ b/src/reclaim/plugin_rest_reclaim.c
@@ -276,6 +276,8 @@ cleanup_handle (struct RequestHandle *handle)
       claim_tmp = claim_entry;
       claim_entry = claim_entry->next;
       GNUNET_free (claim_tmp->claim);
+      GNUNET_free (claim_tmp->attest);
+      GNUNET_free (claim_tmp->reference);
       GNUNET_free (claim_tmp);
     }
     GNUNET_free (handle->attr_list);
@@ -1286,6 +1288,7 @@ attr_collect (void *cls,
       return;
     }
     char *tmp_value;
+    char *flag_str;
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding attribute: %s\n", attr->name);
 
     tmp_value = GNUNET_RECLAIM_ATTRIBUTE_value_to_string (attr->type,
@@ -1295,6 +1298,8 @@ attr_collect (void *cls,
     attr_obj = json_object ();
     json_object_set_new (attr_obj, "value", json_string (tmp_value));
     json_object_set_new (attr_obj, "name", json_string (attr->name));
+    GNUNET_asprintf (&flag_str,"%d",attr->flag);
+    json_object_set_new (attr_obj, "flag", json_string (flag_str));
     type = GNUNET_RECLAIM_ATTRIBUTE_number_to_typename (attr->type);
     json_object_set_new (attr_obj, "type", json_string (type));
     id_str = GNUNET_STRINGS_data_to_string_alloc (&attr->id, sizeof(uint64_t));
diff --git a/src/reclaim/reclaim_api.c b/src/reclaim/reclaim_api.c
index 75ef22c8c..847abb58a 100644
--- a/src/reclaim/reclaim_api.c
+++ b/src/reclaim/reclaim_api.c
@@ -486,7 +486,7 @@ handle_consume_ticket_result (void *cls,
   uint32_t r_id = ntohl (msg->id);
 
   attrs_len = ntohs (msg->attrs_len);
-  LOG (GNUNET_ERROR_TYPE_DEBUG, "Processing attribute result.\n");
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Processing ticket result.\n");
 
 
   for (op = h->op_head; NULL != op; op = op->next)
@@ -498,6 +498,7 @@ handle_consume_ticket_result (void *cls,
   {
     struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs;
     struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le;
+    struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le2;
     attrs =
       GNUNET_RECLAIM_ATTRIBUTE_list_deserialize ((char *) &msg[1], attrs_len);
     if (NULL != op->ar_cb)
@@ -509,7 +510,20 @@ handle_consume_ticket_result (void *cls,
       else
       {
         for (le = attrs->list_head; NULL != le; le = le->next)
-          op->ar_cb (op->cls, &msg->identity, le->claim, NULL, NULL);
+        {
+          if (le->reference != NULL && le->attest == NULL)
+          {
+            for (le2 = attrs->list_head; NULL != le2; le2 = le2->next)
+            {
+              if (le2->attest != NULL && le2->attest->id == 
le->reference->id_attest)
+              {
+                op->ar_cb (op->cls, &msg->identity, le->claim, le2->attest, 
le->reference);
+                break;
+              }
+
+            }
+          }
+        }
         GNUNET_RECLAIM_ATTRIBUTE_list_destroy (attrs);
         attrs = NULL;
       }

-- 
To stop receiving notification emails like this one, please contact
address@hidden.



reply via email to

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