gnunet-svn
[Top][All Lists]
Advanced

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

[gnunet] branch master updated (c0a6838a1 -> e52520756)


From: gnunet
Subject: [gnunet] branch master updated (c0a6838a1 -> e52520756)
Date: Mon, 13 Jan 2020 13:46:45 +0100

This is an automated email from the git hooks/post-receive script.

martin-schanzenbach pushed a change to branch master
in repository gnunet.

    from c0a6838a1 allow GNS clients to control recursion depth limit
     new 60d2660de Adapted Namestore and reclaim REST
     new e6eb523e1 Adapted JSON Conversion and Serialization
     new f3c860651 Initial Fixes of plugin
     new edd153311 Fixed direct Namestore Access
     new d5178cdc0 Direct Namestore Deletion Implemented
     new 2c65283b0 Add Attestations via Reclaim Service
     new 0def2d57e Delete Attestation via Service
     new 483bc7e30 Prepare Listing Attestations
     new 4eda8d336 Listing Attestations through service
     new c136a1660 some comments
     new bb286cb25 Preparation for Reference Type
     new df903a80b Adding Reference Type Implemented
     new b62682f35 Deletion of Reference Type
     new 6157f0cb7 Fixed Reference Deletion
     new 17af2a636 Prepared Listing of References
     new 6fad96b49 Listing of References with Attributes
     new 0688b167e Pure Listing of References
     new 554abc7d4 Prepared JWT Plugin
     new 854dfdf70 Fixed Open Issues with Listing
     new c0fce9ca7 JWT Plugin, Prepared Ticketing
     new cb08bbcbe Basic Functionality Implemented
     new 1267dec77 JWT Parser Implemented
     new 76df96b59 Fixed Adding Attestations
     new ed9b8362e Fixed Ticket Management
     new e52520756 JWT Parsing API

The 25 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 src/include/gnunet_gnsrecord_lib.h                 |   11 +
 src/include/gnunet_protocols.h                     |   11 +
 src/include/gnunet_reclaim_attribute_lib.h         |  245 +++++
 src/include/gnunet_reclaim_attribute_plugin.h      |   27 +
 src/include/gnunet_reclaim_service.h               |   82 +-
 .../plugin_reclaim_attribute_gnuid.c               |  109 +++
 src/reclaim-attribute/reclaim_attribute.c          |  587 ++++++++++-
 src/reclaim-attribute/reclaim_attribute.h          |   62 ++
 src/reclaim/gnunet-reclaim.c                       |   14 +-
 src/reclaim/gnunet-service-reclaim.c               |  903 ++++++++++++++++-
 src/reclaim/gnunet-service-reclaim_tickets.c       |  260 ++++-
 src/reclaim/json_reclaim.c                         |  221 ++++-
 src/reclaim/json_reclaim.h                         |   19 +
 src/reclaim/oidc_helper.c                          |  126 ++-
 src/reclaim/oidc_helper.h                          |    2 +-
 src/reclaim/plugin_gnsrecord_reclaim.c             |    6 +
 src/reclaim/plugin_rest_openid_connect.c           |  236 ++++-
 src/reclaim/plugin_rest_reclaim.c                  | 1029 +++++++++++++++++---
 src/reclaim/reclaim.h                              |   39 +
 src/reclaim/reclaim_api.c                          |  418 +++++++-
 20 files changed, 4115 insertions(+), 292 deletions(-)

diff --git a/src/include/gnunet_gnsrecord_lib.h 
b/src/include/gnunet_gnsrecord_lib.h
index 3a49d98b9..797c71380 100644
--- a/src/include/gnunet_gnsrecord_lib.h
+++ b/src/include/gnunet_gnsrecord_lib.h
@@ -140,6 +140,17 @@ extern "C" {
  */
 #define GNUNET_GNSRECORD_TYPE_RECLAIM_OIDC_REDIRECT 65553
 
+/**
+ * Record type for reclaim identity attestation
+ */
+#define GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR 65554
+
+/**
+ * Record type for reclaim identity references
+ */
+#define GNUNET_GNSRECORD_TYPE_RECLAIM_REFERENCE 65555
+
+
 /**
  * Flags that can be set for a record.
  */
diff --git a/src/include/gnunet_protocols.h b/src/include/gnunet_protocols.h
index cd7cb50de..8091fb367 100644
--- a/src/include/gnunet_protocols.h
+++ b/src/include/gnunet_protocols.h
@@ -2714,6 +2714,14 @@ extern "C" {
 
 #define GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_DELETE 976
 
+#define GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_STORE 977
+
+#define GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_DELETE 978
+
+#define GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_RESULT 979
+
+#define GNUNET_MESSAGE_TYPE_RECLAIM_REFERENCE_STORE 980
+
 /**************************************************
  *
  * ABD MESSAGE TYPES
@@ -3301,6 +3309,9 @@ extern "C" {
 /**
  * Next available: 1500
  */
+#define GNUNET_MESSAGE_TYPE_RECLAIM_REFERENCE_DELETE 1500
+
+#define GNUNET_MESSAGE_TYPE_RECLAIM_REFERENCE_RESULT 1501
 
 
 /**
diff --git a/src/include/gnunet_reclaim_attribute_lib.h 
b/src/include/gnunet_reclaim_attribute_lib.h
index 4563a5f67..004f2bd10 100644
--- a/src/include/gnunet_reclaim_attribute_lib.h
+++ b/src/include/gnunet_reclaim_attribute_lib.h
@@ -50,6 +50,15 @@ extern "C" {
  */
 #define GNUNET_RECLAIM_ATTRIBUTE_TYPE_STRING 1
 
+/**
+* No value attestation.
+*/
+#define GNUNET_RECLAIM_ATTESTATION_TYPE_NONE 10
+
+/**
+* A JSON Web Token attestation.
+*/
+#define GNUNET_RECLAIM_ATTESTATION_TYPE_JWT 11
 
 /**
  * An attribute.
@@ -66,10 +75,49 @@ struct GNUNET_RECLAIM_ATTRIBUTE_Claim
    */
   uint32_t type;
 
+  /**
+   * Flags
+   */
+  uint32_t flag;
+  /**
+   * The name of the attribute. Note "name" must never be individually
+   * free'd
+   */
+  const char *name;
+
+  /**
+   * Number of bytes in @e data.
+   */
+  size_t data_size;
+
+  /**
+   * Binary value stored as attribute value.  Note: "data" must never
+   * be individually 'malloc'ed, but instead always points into some
+   * existing data area.
+   */
+  const void *data;
+};
+
+/**
+ * An attestation.
+ */
+struct GNUNET_RECLAIM_ATTESTATION_Claim
+{
+  /**
+   * ID
+   */
+  uint64_t id;
+
+  /**
+   * Type/Format of Claim
+   */
+  uint32_t type;
+
   /**
    * Version
    */
   uint32_t version;
+
   /**
    * The name of the attribute. Note "name" must never be individually
    * free'd
@@ -89,6 +137,33 @@ struct GNUNET_RECLAIM_ATTRIBUTE_Claim
   const void *data;
 };
 
+/**
+ * A reference to an Attestatiom.
+ */
+struct GNUNET_RECLAIM_ATTESTATION_REFERENCE
+{
+  /**
+   * ID
+   */
+  uint64_t id;
+
+  /**
+   * Referenced ID of Attestation
+   */
+  uint64_t id_attest;
+
+  /**
+   * The name of the attribute/attestation reference value. Note "name" must 
never be individually
+   * free'd
+   */
+  const char *name;
+
+  /**
+   * The name of the attribute/attestation reference value. Note "name" must 
never be individually
+   * free'd
+   */
+  const char *reference_value;
+};
 
 /**
  * A list of GNUNET_RECLAIM_ATTRIBUTE_Claim structures.
@@ -123,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;
 };
 
 
@@ -203,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
@@ -299,6 +396,154 @@ GNUNET_RECLAIM_ATTRIBUTE_value_to_string (uint32_t type,
 const char *
 GNUNET_RECLAIM_ATTRIBUTE_number_to_typename (uint32_t type);
 
+/**
+   * Get required size for serialization buffer
+   * FIXME:
+   * 1. The naming convention is violated here.
+   * It should GNUNET_RECLAIM_ATTRIBUTE_<lowercase from here>.
+   * It might make sense to refactor attestations into a separate folder.
+   * 2. The struct should be called GNUNET_RECLAIM_ATTESTATION_Data or
+   * GNUNET_RECLAIM_ATTRIBUTE_Attestation depending on location in source.
+   *
+   * @param attr the attestation to serialize
+   * @return the required buffer size
+   */
+size_t
+GNUNET_RECLAIM_ATTESTATION_serialize_get_size (
+  const struct GNUNET_RECLAIM_ATTESTATION_Claim *attr);
+
+
+/**
+ * Serialize an attestation
+ *
+ * @param attr the attestation to serialize
+ * @param result the serialized attestation
+ * @return length of serialized data
+ */
+size_t
+GNUNET_RECLAIM_ATTESTATION_serialize (
+  const struct GNUNET_RECLAIM_ATTESTATION_Claim *attr,
+  char *result);
+
+
+/**
+ * Deserialize an attestation
+ *
+ * @param data the serialized attestation
+ * @param data_size the length of the serialized data
+ *
+ * @return a GNUNET_IDENTITY_PROVIDER_Attribute, must be free'd by caller
+ */
+struct GNUNET_RECLAIM_ATTESTATION_Claim *
+GNUNET_RECLAIM_ATTESTATION_deserialize (const char *data, size_t data_size);
+
+
+/**
+   * Create a new attestation.
+   *
+   * @param attr_name the attestation name
+   * @param type the attestation type
+   * @param data the attestation value
+   * @param data_size the attestation value size
+   * @return the new attestation
+   */
+struct GNUNET_RECLAIM_ATTESTATION_Claim *
+GNUNET_RECLAIM_ATTESTATION_claim_new (const char *attr_name,
+                                      uint32_t type,
+                                      const void *data,
+                                      size_t data_size);
+
+/**
+ * Convert the 'claim' of an attestation to a string
+ *
+ * @param type the type of attestation
+ * @param data claim in binary encoding
+ * @param data_size number of bytes in @a data
+ * @return NULL on error, otherwise human-readable representation of the claim
+ */
+char *
+GNUNET_RECLAIM_ATTESTATION_value_to_string (uint32_t type,
+                                            const void *data,
+                                            size_t data_size);
+
+/**
+ * Convert human-readable version of a 'claim' of an attestation to the binary
+ * representation
+ *
+ * @param type type of the claim
+ * @param s human-readable string
+ * @param data set to value in binary encoding (will be allocated)
+ * @param data_size set to number of bytes in @a data
+ * @return #GNUNET_OK on success
+ */
+int
+GNUNET_RECLAIM_ATTESTATION_string_to_value (uint32_t type,
+                                            const char *s,
+                                            void **data,
+                                            size_t *data_size);
+
+/**
+ * Convert an attestation type number to the corresponding attestation type 
string
+ *
+ * @param type number of a type
+ * @return corresponding typestring, NULL on error
+ */
+const char *
+GNUNET_RECLAIM_ATTESTATION_number_to_typename (uint32_t type);
+
+/**
+ * Convert an attestation type name to the corresponding number
+ *
+ * @param typename name to convert
+ * @return corresponding number, UINT32_MAX on error
+ */
+uint32_t
+GNUNET_RECLAIM_ATTESTATION_typename_to_number (const char *typename);
+
+/**
+ * Create a new attestation reference.
+ *
+ * @param attr_name the referenced claim name
+ * @param ref_value the claim name in the attestation
+ * @return the new reference
+ */
+struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *
+GNUNET_RECLAIM_ATTESTATION_reference_new (const char *attr_name,
+                                          const char *ref_value);
+
+
+/**
+ * Get required size for serialization buffer
+ *
+ * @param attr the reference to serialize
+ * @return the required buffer size
+ */
+size_t
+GNUNET_RECLAIM_ATTESTATION_REF_serialize_get_size (
+  const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *attr);
+
+/**
+ * Serialize a reference
+ *
+ * @param attr the reference to serialize
+ * @param result the serialized reference
+ * @return length of serialized data
+ */
+size_t
+GNUNET_RECLAIM_ATTESTATION_REF_serialize (
+  const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *attr,
+  char *result);
+
+/**
+ * Deserialize a reference
+ *
+ * @param data the serialized reference
+ * @param data_size the length of the serialized data
+ *
+ * @return a GNUNET_IDENTITY_PROVIDER_Attribute, must be free'd by caller
+ */
+struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *
+GNUNET_RECLAIM_ATTESTATION_REF_deserialize (const char *data, size_t 
data_size);
 
 #if 0 /* keep Emacsens' auto-indent happy */
 {
diff --git a/src/include/gnunet_reclaim_attribute_plugin.h 
b/src/include/gnunet_reclaim_attribute_plugin.h
index 26a4bb4f2..e61cca5b2 100644
--- a/src/include/gnunet_reclaim_attribute_plugin.h
+++ b/src/include/gnunet_reclaim_attribute_plugin.h
@@ -134,6 +134,33 @@ struct GNUNET_RECLAIM_ATTRIBUTE_PluginFunctions
    * Number to typename.
    */
   GNUNET_RECLAIM_ATTRIBUTE_NumberToTypenameFunction number_to_typename;
+
+  /**
+   * FIXME: It is odd that attestation functions are withing the attribute
+   * plugin. An attribute type may be backed by an attestation, but not
+   * necessarily.
+   * Maybe it would make more sense to refactor this into an attestation
+   * plugin?
+   *
+   * Attestation Conversion to string.
+   */
+  GNUNET_RECLAIM_ATTRIBUTE_ValueToStringFunction value_to_string_attest;
+
+  /**
+  * Attestation Conversion to binary.
+  */
+  GNUNET_RECLAIM_ATTRIBUTE_StringToValueFunction string_to_value_attest;
+
+  /**
+  * Attestation Typename to number.
+  */
+  GNUNET_RECLAIM_ATTRIBUTE_TypenameToNumberFunction typename_to_number_attest;
+
+  /**
+  * Attestation Number to typename.
+  */
+  GNUNET_RECLAIM_ATTRIBUTE_NumberToTypenameFunction number_to_typename_attest;
+
 };
 
 
diff --git a/src/include/gnunet_reclaim_service.h 
b/src/include/gnunet_reclaim_service.h
index 237d791d9..214cdba69 100644
--- a/src/include/gnunet_reclaim_service.h
+++ b/src/include/gnunet_reclaim_service.h
@@ -117,7 +117,9 @@ typedef void (*GNUNET_RECLAIM_ContinuationWithStatus) (void 
*cls,
  */
 typedef void (*GNUNET_RECLAIM_AttributeResult) (
   void *cls, const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
-  const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr);
+  const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr,
+  const struct GNUNET_RECLAIM_ATTESTATION_Claim *attest,
+  const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *reference);
 
 
 /**
@@ -151,6 +153,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.
@@ -169,7 +193,43 @@ GNUNET_RECLAIM_attribute_delete (
   const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr,
   GNUNET_RECLAIM_ContinuationWithStatus cont, void *cont_cls);
 
+/**
+ * Delete an attestation. Tickets used to share this attestation are updated
+ * accordingly.
+ *
+ * @param h handle to the re:claimID service
+ * @param pkey Private key of the identity to add an attribute to
+ * @param attr The attestation
+ * @param cont Continuation to call when done
+ * @param cont_cls Closure for @a cont
+ * @return handle Used to to abort the request
+ */
+struct GNUNET_RECLAIM_Operation *
+GNUNET_RECLAIM_attestation_delete (
+  struct GNUNET_RECLAIM_Handle *h,
+  const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey,
+  const struct GNUNET_RECLAIM_ATTESTATION_Claim *attr,
+  GNUNET_RECLAIM_ContinuationWithStatus cont,
+  void *cont_cls);
 
+/**
+ * Delete an attestation reference. Tickets used to share this reference are 
updated
+ * accordingly.
+ *
+ * @param h handle to the re:claimID service
+ * @param pkey Private key of the identity to delete the reference from
+ * @param attr The reference
+ * @param cont Continuation to call when done
+ * @param cont_cls Closure for @a cont
+ * @return handle Used to to abort the request
+ */
+struct GNUNET_RECLAIM_Operation *
+GNUNET_RECLAIM_attestation_reference_delete (
+  struct GNUNET_RECLAIM_Handle *h,
+  const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey,
+  const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *attr,
+  GNUNET_RECLAIM_ContinuationWithStatus cont,
+  void *cont_cls);
 /**
  * List all attributes for a local identity.
  * This MUST lock the `struct GNUNET_RECLAIM_Handle`
@@ -202,6 +262,26 @@ GNUNET_RECLAIM_get_attributes_start (
   GNUNET_RECLAIM_AttributeResult proc, void *proc_cls,
   GNUNET_SCHEDULER_TaskCallback finish_cb, void *finish_cb_cls);
 
+/**
+   * Store an attestation reference.  If the reference is already present,
+   * it is replaced with the new reference.
+   *
+   * @param h handle to the re:claimID service
+   * @param pkey private key of the identity
+   * @param attr the reference value
+   * @param exp_interval the relative expiration interval for the reference
+   * @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_reference_store (
+  struct GNUNET_RECLAIM_Handle *h,
+  const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey,
+  const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *attr,
+  const struct GNUNET_TIME_Relative *exp_interval,
+  GNUNET_RECLAIM_ContinuationWithStatus cont,
+  void *cont_cls);
 
 /**
  * Calls the record processor specified in #GNUNET_RECLAIM_get_attributes_start
diff --git a/src/reclaim-attribute/plugin_reclaim_attribute_gnuid.c 
b/src/reclaim-attribute/plugin_reclaim_attribute_gnuid.c
index bb60909d9..ade2a27bb 100644
--- a/src/reclaim-attribute/plugin_reclaim_attribute_gnuid.c
+++ b/src/reclaim-attribute/plugin_reclaim_attribute_gnuid.c
@@ -90,6 +90,63 @@ gnuid_string_to_value (void *cls,
   }
 }
 
+/**
+   * Convert the 'value' of an attestation to a string.
+   *
+   * @param cls closure, unused
+   * @param type type of the attestation
+   * @param data value in binary encoding
+   * @param data_size number of bytes in @a data
+   * @return NULL on error, otherwise human-readable representation of the 
value
+   */
+static char *
+gnuid_value_to_string_attest (void *cls,
+                              uint32_t type,
+                              const void *data,
+                              size_t data_size)
+{
+  switch (type)
+  {
+  case GNUNET_RECLAIM_ATTESTATION_TYPE_JWT:
+    return GNUNET_strndup (data, data_size);
+
+  default:
+    return NULL;
+  }
+}
+
+
+/**
+ * Convert human-readable version of a 'value' of an attestation to the binary
+ * representation.
+ *
+ * @param cls closure, unused
+ * @param type type of the attestation
+ * @param s human-readable string
+ * @param data set to value in binary encoding (will be allocated)
+ * @param data_size set to number of bytes in @a data
+ * @return #GNUNET_OK on success
+ */
+static int
+gnuid_string_to_value_attest (void *cls,
+                              uint32_t type,
+                              const char *s,
+                              void **data,
+                              size_t *data_size)
+{
+  if (NULL == s)
+    return GNUNET_SYSERR;
+  switch (type)
+  {
+  case GNUNET_RECLAIM_ATTESTATION_TYPE_JWT:
+    *data = GNUNET_strdup (s);
+    *data_size = strlen (s);
+    return GNUNET_OK;
+
+  default:
+    return GNUNET_SYSERR;
+  }
+}
 
 /**
  * Mapping of attribute type numbers to human-readable
@@ -102,6 +159,16 @@ static struct
 } gnuid_name_map[] = { { "STRING", GNUNET_RECLAIM_ATTRIBUTE_TYPE_STRING },
                        { NULL, UINT32_MAX } };
 
+/**
+ * Mapping of attestation type numbers to human-readable
+ * attestation type names.
+ */
+static struct
+{
+  const char *name;
+  uint32_t number;
+} gnuid_attest_name_map[] = { { "JWT", GNUNET_RECLAIM_ATTESTATION_TYPE_JWT },
+                              { NULL, UINT32_MAX } };
 
 /**
  * Convert a type name to the corresponding number.
@@ -141,6 +208,44 @@ gnuid_number_to_typename (void *cls, uint32_t type)
   return gnuid_name_map[i].name;
 }
 
+/**
+   * Convert a type name to the corresponding number.
+   *
+   * @param cls closure, unused
+   * @param gnuid_typename name to convert
+   * @return corresponding number, UINT32_MAX on error
+   */
+static uint32_t
+gnuid_typename_to_number_attest (void *cls, const char *gnuid_typename)
+{
+  unsigned int i;
+
+  i = 0;
+  while ((NULL != gnuid_attest_name_map[i].name) &&
+         (0 != strcasecmp (gnuid_typename, gnuid_attest_name_map[i].name)))
+    i++;
+  return gnuid_attest_name_map[i].number;
+}
+
+/**
+ * Convert a type number (i.e. 1) to the corresponding type string
+ *
+ * @param cls closure, unused
+ * @param type number of a type to convert
+ * @return corresponding typestring, NULL on error
+ */
+static const char *
+gnuid_number_to_typename_attest (void *cls, uint32_t type)
+{
+  unsigned int i;
+
+  i = 0;
+  while ((NULL != gnuid_attest_name_map[i].name) && (type !=
+                                                     gnuid_attest_name_map[i].
+                                                     number))
+    i++;
+  return gnuid_attest_name_map[i].name;
+}
 
 /**
  * Entry point for the plugin.
@@ -158,6 +263,10 @@ libgnunet_plugin_reclaim_attribute_gnuid_init (void *cls)
   api->string_to_value = &gnuid_string_to_value;
   api->typename_to_number = &gnuid_typename_to_number;
   api->number_to_typename = &gnuid_number_to_typename;
+  api->value_to_string_attest = &gnuid_value_to_string_attest;
+  api->string_to_value_attest = &gnuid_string_to_value_attest;
+  api->typename_to_number_attest = &gnuid_typename_to_number_attest;
+  api->number_to_typename_attest = &gnuid_number_to_typename_attest;
   return api;
 }
 
diff --git a/src/reclaim-attribute/reclaim_attribute.c 
b/src/reclaim-attribute/reclaim_attribute.c
index b81394ad2..43199c108 100644
--- a/src/reclaim-attribute/reclaim_attribute.c
+++ b/src/reclaim-attribute/reclaim_attribute.c
@@ -217,6 +217,116 @@ GNUNET_RECLAIM_ATTRIBUTE_value_to_string (uint32_t type,
   return NULL;
 }
 
+/**
+   * Convert an attestation type name to the corresponding number
+   *
+   * @param typename name to convert
+   * @return corresponding number, UINT32_MAX on error
+   */
+uint32_t
+GNUNET_RECLAIM_ATTESTATION_typename_to_number (const char *typename)
+{
+  unsigned int i;
+  struct Plugin *plugin;
+  uint32_t ret;
+  init ();
+  for (i = 0; i < num_plugins; i++)
+  {
+    plugin = attr_plugins[i];
+    if (UINT32_MAX !=
+        (ret = plugin->api->typename_to_number_attest (plugin->api->cls,
+                                                       typename)))
+      return ret;
+  }
+  return UINT32_MAX;
+}
+
+/**
+ * Convert an attestation type number to the corresponding attestation type 
string
+ *
+ * @param type number of a type
+ * @return corresponding typestring, NULL on error
+ */
+const char *
+GNUNET_RECLAIM_ATTESTATION_number_to_typename (uint32_t type)
+{
+  unsigned int i;
+  struct Plugin *plugin;
+  const char *ret;
+
+  init ();
+  for (i = 0; i < num_plugins; i++)
+  {
+    plugin = attr_plugins[i];
+    if (NULL !=
+        (ret = plugin->api->number_to_typename_attest (plugin->api->cls, 
type)))
+      return ret;
+  }
+  return NULL;
+}
+/**
+ * Convert human-readable version of a 'claim' of an attestation to the binary
+ * representation
+ *
+ * @param type type of the claim
+ * @param s human-readable string
+ * @param data set to value in binary encoding (will be allocated)
+ * @param data_size set to number of bytes in @a data
+ * @return #GNUNET_OK on success
+ */
+int
+GNUNET_RECLAIM_ATTESTATION_string_to_value (uint32_t type,
+                                            const char *s,
+                                            void **data,
+                                            size_t *data_size)
+{
+  unsigned int i;
+  struct Plugin *plugin;
+
+  init ();
+  for (i = 0; i < num_plugins; i++)
+  {
+    plugin = attr_plugins[i];
+    if (GNUNET_OK == plugin->api->string_to_value_attest (plugin->api->cls,
+                                                          type,
+                                                          s,
+                                                          data,
+                                                          data_size))
+      return GNUNET_OK;
+  }
+  return GNUNET_SYSERR;
+}
+
+
+/**
+ * Convert the 'claim' of an attestation to a string
+ *
+ * @param type the type of attestation
+ * @param data claim in binary encoding
+ * @param data_size number of bytes in @a data
+ * @return NULL on error, otherwise human-readable representation of the claim
+ */
+char *
+GNUNET_RECLAIM_ATTESTATION_value_to_string (uint32_t type,
+                                            const void *data,
+                                            size_t data_size)
+{
+  unsigned int i;
+  struct Plugin *plugin;
+  char *ret;
+
+  init ();
+  for (i = 0; i < num_plugins; i++)
+  {
+    plugin = attr_plugins[i];
+    if (NULL != (ret = plugin->api->value_to_string_attest (plugin->api->cls,
+                                                            type,
+                                                            data,
+                                                            data_size)))
+      return ret;
+  }
+  return NULL;
+}
 
 /**
  * Create a new attribute.
@@ -243,6 +353,42 @@ GNUNET_RECLAIM_ATTRIBUTE_claim_new (const char *attr_name,
                         + strlen (attr_name_tmp) + 1 + data_size);
   attr->type = type;
   attr->data_size = data_size;
+  attr->flag = 0;
+  write_ptr = (char *) &attr[1];
+  GNUNET_memcpy (write_ptr, attr_name_tmp, strlen (attr_name_tmp) + 1);
+  attr->name = write_ptr;
+  write_ptr += strlen (attr->name) + 1;
+  GNUNET_memcpy (write_ptr, data, data_size);
+  attr->data = write_ptr;
+  GNUNET_free (attr_name_tmp);
+  return attr;
+}
+
+/**
+   * Create a new attestation.
+   *
+   * @param attr_name the attestation name
+   * @param type the attestation type
+   * @param data the attestation value
+   * @param data_size the attestation value size
+   * @return the new attestation
+   */
+struct GNUNET_RECLAIM_ATTESTATION_Claim *
+GNUNET_RECLAIM_ATTESTATION_claim_new (const char *attr_name,
+                                      uint32_t type,
+                                      const void *data,
+                                      size_t data_size)
+{
+  struct GNUNET_RECLAIM_ATTESTATION_Claim *attr;
+  char *write_ptr;
+  char *attr_name_tmp = GNUNET_strdup (attr_name);
+
+  GNUNET_STRINGS_utf8_tolower (attr_name, attr_name_tmp);
+
+  attr = GNUNET_malloc (sizeof(struct GNUNET_RECLAIM_ATTESTATION_Claim)
+                        + strlen (attr_name_tmp) + 1 + data_size);
+  attr->type = type;
+  attr->data_size = data_size;
   attr->version = 0;
   write_ptr = (char *) &attr[1];
   GNUNET_memcpy (write_ptr, attr_name_tmp, strlen (attr_name_tmp) + 1);
@@ -254,6 +400,40 @@ GNUNET_RECLAIM_ATTRIBUTE_claim_new (const char *attr_name,
   return attr;
 }
 
+/**
+ * Create a new attestation reference.
+ *
+ * @param attr_name the referenced claim name
+ * @param ref_value the claim name in the attestation
+ * @return the new reference
+ */
+struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *
+GNUNET_RECLAIM_ATTESTATION_reference_new (const char *attr_name,
+                                          const char *ref_value)
+{
+  struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *attr;
+  char *write_ptr;
+  char *attr_name_tmp = GNUNET_strdup (attr_name);
+  char *ref_value_tmp = GNUNET_strdup (ref_value);
+
+  GNUNET_STRINGS_utf8_tolower (attr_name, attr_name_tmp);
+  GNUNET_STRINGS_utf8_tolower (ref_value, ref_value_tmp);
+
+  attr = GNUNET_malloc (sizeof(struct GNUNET_RECLAIM_ATTESTATION_REFERENCE)
+                        + strlen (attr_name_tmp) + strlen (ref_value_tmp) + 2);
+
+  write_ptr = (char *) &attr[1];
+  GNUNET_memcpy (write_ptr, attr_name_tmp, strlen (attr_name_tmp) + 1);
+  attr->name = write_ptr;
+
+  write_ptr += strlen (attr_name) + 1;
+  GNUNET_memcpy (write_ptr, ref_value_tmp, strlen (ref_value_tmp) + 1);
+  attr->reference_value = write_ptr;
+
+  GNUNET_free (attr_name_tmp);
+  GNUNET_free (ref_value_tmp);
+  return attr;
+}
 
 /**
  * Add a new attribute to a claim list
@@ -296,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;
 }
 
@@ -317,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;
 }
@@ -345,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;
 }
@@ -381,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->version = le->claim->version;
-    result_le->claim->id = le->claim->id;
+    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);
@@ -411,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);
@@ -421,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
  *
@@ -455,7 +797,7 @@ GNUNET_RECLAIM_ATTRIBUTE_serialize (
 
   attr_ser = (struct Attribute *) result;
   attr_ser->attribute_type = htons (attr->type);
-  attr_ser->attribute_version = htonl (attr->version);
+  attr_ser->attribute_version = htonl (attr->flag);
   attr_ser->attribute_id = GNUNET_htonll (attr->id);
   name_len = strlen (attr->name);
   attr_ser->name_len = htons (name_len);
@@ -505,7 +847,7 @@ GNUNET_RECLAIM_ATTRIBUTE_deserialize (const char *data, 
size_t data_size)
   attr = GNUNET_malloc (sizeof(struct GNUNET_RECLAIM_ATTRIBUTE_Claim)
                         + data_len + name_len + 1);
   attr->type = ntohs (attr_ser->attribute_type);
-  attr->version = ntohl (attr_ser->attribute_version);
+  attr->flag = ntohl (attr_ser->attribute_version);
   attr->id = GNUNET_ntohll (attr_ser->attribute_id);
   attr->data_size = data_len;
 
@@ -521,4 +863,193 @@ GNUNET_RECLAIM_ATTRIBUTE_deserialize (const char *data, 
size_t data_size)
 }
 
 
+/**
+ * Get required size for serialization buffer
+ *
+ * @param attr the attestation to serialize
+ * @return the required buffer size
+ */
+size_t
+GNUNET_RECLAIM_ATTESTATION_serialize_get_size (
+  const struct GNUNET_RECLAIM_ATTESTATION_Claim *attr)
+{
+  return sizeof(struct Attestation) + strlen (attr->name) + attr->data_size;
+}
+
+/**
+ * Serialize an attestation
+ *
+ * @param attr the attestation to serialize
+ * @param result the serialized attestation
+ * @return length of serialized data
+ */
+size_t
+GNUNET_RECLAIM_ATTESTATION_serialize (
+  const struct GNUNET_RECLAIM_ATTESTATION_Claim *attr,
+  char *result)
+{
+  size_t data_len_ser;
+  size_t name_len;
+  struct Attestation *attr_ser;
+  char *write_ptr;
+
+  attr_ser = (struct Attestation *) result;
+  attr_ser->attestation_type = htons (attr->type);
+  attr_ser->attestation_version = htonl (attr->version);
+  attr_ser->attestation_id = GNUNET_htonll (attr->id);
+  name_len = strlen (attr->name);
+  attr_ser->name_len = htons (name_len);
+  write_ptr = (char *) &attr_ser[1];
+  GNUNET_memcpy (write_ptr, attr->name, name_len);
+  write_ptr += name_len;
+  // TODO plugin-ize
+  // data_len_ser = plugin->serialize_attribute_value (attr,
+  //                                                  &attr_ser[1]);
+  data_len_ser = attr->data_size;
+  GNUNET_memcpy (write_ptr, attr->data, attr->data_size);
+  attr_ser->data_size = htons (data_len_ser);
+
+  return sizeof(struct Attestation) + strlen (attr->name) + attr->data_size;
+}
+
+/**
+ * Deserialize an attestation
+ *
+ * @param data the serialized attestation
+ * @param data_size the length of the serialized data
+ *
+ * @return a GNUNET_IDENTITY_PROVIDER_Attribute, must be free'd by caller
+ */
+struct GNUNET_RECLAIM_ATTESTATION_Claim *
+GNUNET_RECLAIM_ATTESTATION_deserialize (const char *data, size_t data_size)
+{
+  struct GNUNET_RECLAIM_ATTESTATION_Claim *attr;
+  struct Attestation *attr_ser;
+  size_t data_len;
+  size_t name_len;
+  char *write_ptr;
+
+  if (data_size < sizeof(struct Attestation))
+    return NULL;
+
+  attr_ser = (struct Attestation *) data;
+  data_len = ntohs (attr_ser->data_size);
+  name_len = ntohs (attr_ser->name_len);
+  if (data_size < sizeof(struct Attestation) + data_len + name_len)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Buffer too small to deserialize\n");
+    return NULL;
+  }
+  attr = GNUNET_malloc (sizeof(struct GNUNET_RECLAIM_ATTESTATION_Claim)
+                        + data_len + name_len + 1);
+  attr->type = ntohs (attr_ser->attestation_type);
+  attr->version = ntohl (attr_ser->attestation_version);
+  attr->id = GNUNET_ntohll (attr_ser->attestation_id);
+  attr->data_size = data_len;
+
+  write_ptr = (char *) &attr[1];
+  GNUNET_memcpy (write_ptr, &attr_ser[1], name_len);
+  write_ptr[name_len] = '\0';
+  attr->name = write_ptr;
+
+  write_ptr += name_len + 1;
+  GNUNET_memcpy (write_ptr, (char *) &attr_ser[1] + name_len, attr->data_size);
+  attr->data = write_ptr;
+  return attr;
+}
+
+/**
+ * Get required size for serialization buffer
+ *
+ * @param attr the reference to serialize
+ * @return the required buffer size
+ */
+size_t
+GNUNET_RECLAIM_ATTESTATION_REF_serialize_get_size (
+  const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *attr)
+{
+  return sizeof(struct Attestation_Reference) + strlen (attr->name) + strlen (
+    attr->reference_value);
+}
+
+
+/**
+ * Serialize a reference
+ *
+ * @param attr the reference to serialize
+ * @param result the serialized reference
+ * @return length of serialized data
+ */
+size_t
+GNUNET_RECLAIM_ATTESTATION_REF_serialize (
+  const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *attr,
+  char *result)
+{
+  size_t name_len;
+  size_t refval_len;
+  struct Attestation_Reference *attr_ser;
+  char *write_ptr;
+  attr_ser = (struct Attestation_Reference *) result;
+  attr_ser->reference_id = GNUNET_htonll (attr->id);
+  attr_ser->attestation_id = GNUNET_htonll (attr->id_attest);
+  name_len = strlen (attr->name);
+  refval_len = strlen (attr->reference_value);
+  attr_ser->name_len = htons (name_len);
+  attr_ser->ref_value_len = htons (refval_len);
+  write_ptr = (char *) &attr_ser[1];
+  GNUNET_memcpy (write_ptr, attr->name, name_len);
+  write_ptr += name_len;
+  GNUNET_memcpy (write_ptr, attr->reference_value, refval_len);
+
+  return sizeof(struct Attestation_Reference) + strlen (attr->name) + strlen (
+    attr->reference_value);
+}
+
+
+/**
+ * Deserialize a reference
+ *
+ * @param data the serialized reference
+ * @param data_size the length of the serialized data
+ *
+ * @return a GNUNET_IDENTITY_PROVIDER_Attribute, must be free'd by caller
+ */
+struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *
+GNUNET_RECLAIM_ATTESTATION_REF_deserialize (const char *data, size_t data_size)
+{
+  struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *attr;
+  struct Attestation_Reference *attr_ser;
+  size_t name_len;
+  size_t refval_len;
+  char *write_ptr;
+
+  if (data_size < sizeof(struct Attestation_Reference))
+    return NULL;
+  attr_ser = (struct Attestation_Reference *) data;
+  name_len = ntohs (attr_ser->name_len);
+  refval_len = ntohs (attr_ser->ref_value_len);
+  if (data_size < sizeof(struct Attestation_Reference) + refval_len + name_len)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Buffer too small to deserialize\n");
+    return NULL;
+  }
+  attr = GNUNET_malloc (sizeof(struct GNUNET_RECLAIM_ATTESTATION_REFERENCE)
+                        + refval_len + name_len + 2);
+
+  attr->id = GNUNET_ntohll (attr_ser->reference_id);
+  attr->id_attest = GNUNET_ntohll (attr_ser->attestation_id);
+
+  write_ptr = (char *) &attr[1];
+  GNUNET_memcpy (write_ptr, &attr_ser[1], name_len);
+  write_ptr[name_len] = '\0';
+  attr->name = write_ptr;
+
+  write_ptr += name_len + 1;
+  GNUNET_memcpy (write_ptr, (char *) &attr_ser[1] + name_len, refval_len);
+  write_ptr[refval_len] = '\0';
+  attr->reference_value = write_ptr;
+  return attr;
+}
 /* end of reclaim_attribute.c */
diff --git a/src/reclaim-attribute/reclaim_attribute.h 
b/src/reclaim-attribute/reclaim_attribute.h
index d7358847e..80f1e5aac 100644
--- a/src/reclaim-attribute/reclaim_attribute.h
+++ b/src/reclaim-attribute/reclaim_attribute.h
@@ -61,4 +61,66 @@ struct Attribute
   // followed by data_size Attribute value data
 };
 
+/**
+ * Serialized attestation claim
+ */
+struct Attestation
+{
+  /**
+   * Attestation type
+   */
+  uint32_t attestation_type;
+
+  /**
+   * Attestation version
+   */
+  uint32_t attestation_version;
+
+  /**
+   * Attestation ID
+   */
+  uint64_t attestation_id;
+
+  /**
+   * Name length
+   */
+  uint32_t name_len;
+
+  /**
+   * Data size
+   */
+  uint32_t data_size;
+
+  // followed by data_size Attestation value data
+};
+
+/**
+ * Serialized attestation reference
+ */
+struct Attestation_Reference
+{
+  /**
+   * Reference ID
+   */
+  uint64_t reference_id;
+
+  /**
+   * The ID of the referenced attestation
+   */
+  uint64_t attestation_id;
+
+  /**
+   * Claim Name length
+   */
+  uint32_t name_len;
+
+    /**
+   * Length of the referenced value
+   */
+  uint32_t ref_value_len;
+
+
+  // followed by the name and referenced value
+};
+
 #endif
diff --git a/src/reclaim/gnunet-reclaim.c b/src/reclaim/gnunet-reclaim.c
index 58f8cd6e2..5f9170f05 100644
--- a/src/reclaim/gnunet-reclaim.c
+++ b/src/reclaim/gnunet-reclaim.c
@@ -226,7 +226,9 @@ store_attr_cont (void *cls, int32_t success, const char 
*emsg)
 static void
 process_attrs (void *cls,
                const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
-               const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr)
+               const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr,
+               const struct GNUNET_RECLAIM_ATTESTATION_Claim *attest, 
+               const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *reference)
 {
   char *value_str;
   char *id;
@@ -253,7 +255,7 @@ process_attrs (void *cls,
            attr->name,
            value_str,
            attr_type,
-           attr->version,
+           attr->flag,
            id);
   GNUNET_free (id);
 }
@@ -445,7 +447,9 @@ iter_finished (void *cls)
 static void
 iter_cb (void *cls,
          const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
-         const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr)
+         const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr,
+         const struct GNUNET_RECLAIM_ATTESTATION_Claim *attest,
+         const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *reference)
 {
   struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le;
   char *attrs_tmp;
@@ -480,7 +484,7 @@ iter_cb (void *cls,
                                                       attr->type,
                                                       attr->data,
                                                       attr->data_size);
-      le->claim->version = attr->version;
+      le->claim->flag = attr->flag;
       le->claim->id = attr->id;
       GNUNET_CONTAINER_DLL_insert (attr_list->list_head,
                                    attr_list->list_tail,
@@ -514,7 +518,7 @@ iter_cb (void *cls,
              attr->name,
              attr_str,
              attr_type,
-             attr->version,
+             attr->flag,
              id);
     GNUNET_free (id);
   }
diff --git a/src/reclaim/gnunet-service-reclaim.c 
b/src/reclaim/gnunet-service-reclaim.c
index a83ea05a6..556006af0 100644
--- a/src/reclaim/gnunet-service-reclaim.c
+++ b/src/reclaim/gnunet-service-reclaim.c
@@ -265,6 +265,15 @@ struct AttributeDeleteHandle
    */
   struct GNUNET_RECLAIM_ATTRIBUTE_Claim *claim;
 
+  /**
+   * The attestation to delete
+   */
+  struct GNUNET_RECLAIM_ATTESTATION_Claim *attest;
+
+  /**
+  * The reference to delete
+  */
+  struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *reference;
   /**
    * Tickets to update
    */
@@ -327,6 +336,16 @@ struct AttributeStoreHandle
    */
   struct GNUNET_RECLAIM_ATTRIBUTE_Claim *claim;
 
+  /**
+  * The attestation to store
+  */
+  struct GNUNET_RECLAIM_ATTESTATION_Claim *attest;
+
+  /**
+  * The reference to store
+  */
+  struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *reference;
+
   /**
    * The attribute expiration interval
    */
@@ -459,6 +478,10 @@ cleanup_adh (struct AttributeDeleteHandle *adh)
     GNUNET_free (adh->label);
   if (NULL != adh->claim)
     GNUNET_free (adh->claim);
+  if (NULL != adh->attest)
+    GNUNET_free (adh->attest);
+  if (NULL != adh->reference)
+    GNUNET_free (adh->reference);
   while (NULL != (le = adh->tickets_to_update_head))
   {
     GNUNET_CONTAINER_DLL_remove (adh->tickets_to_update_head,
@@ -486,6 +509,10 @@ 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);
+  if (NULL != ash->reference)
+    GNUNET_free (ash->reference);
   GNUNET_free (ash);
 }
 
@@ -1022,6 +1049,478 @@ 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);
+}
+
+/**
+     * 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);
+}
+
+/**
+ * Error looking up potential attestation. Abort.
+ *
+ * @param cls our attribute store handle
+ */
+static void
+attest_error (void *cls)
+{
+  struct AttributeStoreHandle *ash = cls;
+  GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+              "Failed to check for existing Attestation\n");
+  cleanup_as_handle (ash);
+  GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
+  return;
+}
+
+/**
+* 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
+attest_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_serialize_get_size (ash->attest);
+  buf = GNUNET_malloc (buf_size);
+  GNUNET_RECLAIM_ATTESTATION_serialize (ash->attest, buf);
+  if (0 == rd_count )
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "Storing new Attestation\n");
+    struct GNUNET_GNSRECORD_Data rd_new[1];
+    rd_new[0].data_size = buf_size;
+    rd_new[0].data = buf;
+    rd_new[0].record_type = GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR;
+    rd_new[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
+    rd_new[0].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,
+                                                 1,
+                                                 rd_new,
+                                                 &attest_store_cont,
+                                                 ash);
+    GNUNET_free (buf);
+    return;
+  }
+  if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR != rd[0].record_type)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Existing Attestation location is not an Attestation\n");
+    send_ref_error (ash);
+    return;
+  }
+  struct GNUNET_GNSRECORD_Data rd_new[rd_count];
+  for (int i = 0; i<rd_count; i++)
+  {
+    rd_new[i] = rd[i];
+  }
+  rd_new[0].data_size = buf_size;
+  rd_new[0].data = buf;
+  rd_new[0].record_type = GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR;
+  rd_new[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
+  rd_new[0].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,
+                                               rd_count,
+                                               rd_new,
+                                               &attest_store_cont,
+                                               ash);
+  GNUNET_free (buf);
+}
+
+/**
+ * Add a new attestation
+ *
+ * @param cls the AttributeStoreHandle
+ */
+static void
+attest_store_task (void *cls)
+{
+  struct AttributeStoreHandle *ash = cls;
+  char *label;
+
+  // 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);
+  label = GNUNET_STRINGS_data_to_string_alloc (&ash->attest->id,
+                                               sizeof(uint64_t));
+  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,
+                                                &ash->identity,
+                                                label,
+                                                &attest_error,
+                                                ash,
+                                                &attest_add_cb,
+                                                ash);
+  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);
+}
+
+/**
+ * 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;
+}
+
+/**
+ * Error looking up potential reference value. Abort.
+ *
+ * @param cls our attribute delete handle
+ */
+static void
+ref_del_error (void *cls)
+{
+  struct AttributeDeleteHandle *adh = cls;
+  GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+              "Failed to find Attestation entry for Attestation reference\n");
+  cleanup_adh (adh);
+  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);
+  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");
+    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");
+    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,
+                                               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,
+              "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,
+                                                &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
  *
@@ -1066,15 +1565,21 @@ ticket_iter (void *cls,
   struct AttributeDeleteHandle *adh = cls;
   struct TicketRecordsEntry *le;
   int has_changed = GNUNET_NO;
-
   for (int i = 0; i < rd_count; i++)
   {
     if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF != rd[i].record_type)
       continue;
-    if (0 != memcmp (rd[i].data, &adh->claim->id, sizeof(uint64_t)))
-      continue;
+    if (adh->claim != NULL)
+      if (0 != memcmp (rd[i].data, &adh->claim->id, sizeof(uint64_t)))
+        continue;
+    if (adh->attest != NULL)
+      if (0 != memcmp (rd[i].data, &adh->attest->id, sizeof(uint64_t)))
+        continue;
+    if (adh->reference != NULL)
+      if (0 != memcmp (rd[i].data, &adh->reference->id, sizeof(uint64_t)))
+        continue;
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Attribute to delete found (%s)\n",
+                "Attribute or Attestation/Reference to delete found (%s)\n",
                 adh->label);
     has_changed = GNUNET_YES;
     break;
@@ -1136,7 +1641,7 @@ update_tickets (void *cls)
   if (NULL == adh->tickets_to_update_head)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Finished updatding tickets, success\n");
+                "Finished updating tickets, success\n");
     send_delete_response (adh, GNUNET_OK);
     cleanup_adh (adh);
     return;
@@ -1164,9 +1669,18 @@ update_tickets (void *cls)
   int j = 0;
   for (int i = 0; i < le->rd_count; i++)
   {
-    if ((GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF == rd[i].record_type)
-        && (0 == memcmp (rd[i].data, &adh->claim->id, sizeof(uint64_t))))
-      continue;
+    if (adh->claim != NULL)
+      if ((GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF == rd[i].record_type)
+          && (0 == memcmp (rd[i].data, &adh->claim->id, sizeof(uint64_t))))
+        continue;
+    if (adh->attest != NULL)
+      if ((GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF == rd[i].record_type)
+          && (0 == memcmp (rd[i].data, &adh->attest->id, sizeof(uint64_t))))
+        continue;
+    if (adh->reference != NULL)
+      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];
     j++;
   }
@@ -1192,7 +1706,6 @@ static void
 ticket_iter_fin (void *cls)
 {
   struct AttributeDeleteHandle *adh = cls;
-
   adh->ns_it = NULL;
   GNUNET_SCHEDULER_add_now (&update_tickets, adh);
 }
@@ -1309,6 +1822,8 @@ handle_attribute_delete_message (void *cls,
   adh = GNUNET_new (struct AttributeDeleteHandle);
   adh->claim = GNUNET_RECLAIM_ATTRIBUTE_deserialize ((char *) &dam[1],
                                                      data_len);
+  adh->reference = NULL;
+  adh->attest = NULL;
 
   adh->r_id = ntohl (dam->id);
   adh->identity = dam->identity;
@@ -1326,6 +1841,256 @@ handle_attribute_delete_message (void *cls,
                                                adh);
 }
 
+/**
+   * Attestation deleted callback
+   *
+   * @param cls our handle
+   * @param success success status
+   * @param emsg error message (NULL if success=GNUNET_OK)
+   */
+static void
+attest_delete_cont (void *cls, int32_t success, const char *emsg)
+{
+  struct AttributeDeleteHandle *adh = cls;
+
+  adh->ns_qe = NULL;
+  if (GNUNET_SYSERR == success)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Error deleting attestation %s\n",
+                adh->label);
+    send_delete_response (adh, GNUNET_SYSERR);
+    cleanup_adh (adh);
+    return;
+  }
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating tickets...\n");
+  GNUNET_SCHEDULER_add_now (&start_ticket_update, adh);
+}
+
+/**
+ * Check attestation delete message format
+ *
+ * @cls unused
+ * @dam message to check
+ */
+static int
+check_attestation_delete_message (void *cls,
+                                  const struct AttributeDeleteMessage *dam)
+{
+  uint16_t size;
+
+  size = ntohs (dam->header.size);
+  if (size <= sizeof(struct AttributeDeleteMessage))
+  {
+    GNUNET_break (0);
+    return GNUNET_SYSERR;
+  }
+  return GNUNET_OK;
+}
+
+
+/**
+ * Handle attestation deletion
+ *
+ * @param cls our client
+ * @param dam deletion message
+ */
+static void
+handle_attestation_delete_message (void *cls,
+                                   const struct AttributeDeleteMessage *dam)
+{
+  struct AttributeDeleteHandle *adh;
+  struct IdpClient *idp = cls;
+  size_t data_len;
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received ATTESTATION_DELETE 
message\n");
+
+  data_len = ntohs (dam->attr_len);
+
+  adh = GNUNET_new (struct AttributeDeleteHandle);
+  adh->attest = GNUNET_RECLAIM_ATTESTATION_deserialize ((char *) &dam[1],
+                                                        data_len);
+  adh->reference = NULL;
+  adh->claim = NULL;
+
+  adh->r_id = ntohl (dam->id);
+  adh->identity = dam->identity;
+  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,
+                                               &attest_delete_cont,
+                                               adh);
+}
+
+
+
+/**
+* Reference deleted callback
+*
+* @param cls our handle
+* @param success success status
+* @param emsg error message (NULL if success=GNUNET_OK)
+*/
+static void
+reference_delete_cont (void *cls, int32_t success, const char *emsg)
+{
+  struct AttributeDeleteHandle *adh = cls;
+
+  adh->ns_qe = NULL;
+  if (GNUNET_SYSERR == success)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Error deleting reference %s\n",
+                adh->label);
+    send_delete_response (adh, GNUNET_SYSERR);
+    cleanup_adh (adh);
+    return;
+  }
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating tickets...\n");
+  //GNUNET_SCHEDULER_add_now (&start_ticket_update, adh);
+  send_delete_response (adh, GNUNET_OK);
+  cleanup_adh (adh);
+  return;
+}
+
+static void
+ref_del_cb (void *cls,
+            const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
+            const char *label,
+            unsigned int rd_count,
+            const struct GNUNET_GNSRECORD_Data *rd)
+{
+
+  struct AttributeDeleteHandle *adh = cls;
+  char *data_tmp;
+  struct GNUNET_GNSRECORD_Data rd_new[rd_count - 1];
+  struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *ref;
+  size_t attr_len;
+
+  if (0 == rd_count )
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Failed to find Attestation entry for Attestation 
reference\n");
+    cleanup_adh (adh);
+    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 location is not an attestation\n");
+    cleanup_adh (adh);
+    GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
+    return;
+  }
+  rd_new[0] = rd[0];
+  int i;
+  int j = 1;
+  for (i = 1; i<rd_count; i++)
+  {
+    data_tmp = GNUNET_malloc (rd[i].data_size);
+    GNUNET_memcpy (data_tmp, rd[i].data, rd[i].data_size);
+    attr_len = htons (rd[i].data_size);
+    ref = GNUNET_RECLAIM_ATTESTATION_REF_deserialize (data_tmp, attr_len);
+    if (NULL == ref )
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                  "Unable to parse attestation reference from %s\n",
+                  data_tmp);
+      rd_new[j] = rd[i];
+      j += 1;
+      continue;
+    }
+    if ((strcmp (adh->reference->name,ref->name) == 0)&&
+        (strcmp (adh->reference->reference_value,ref->reference_value)==0) )
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                  "Found reference to delete.\n");
+    }
+    else
+    {
+      rd_new[j] = rd[i];
+      j += 1;
+    }
+    GNUNET_free (data_tmp);
+  }
+  adh->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
+                                               &adh->identity,
+                                               label,
+                                               j,
+                                               rd_new,
+                                               &reference_delete_cont,
+                                               adh);
+}
+
+/**
+ * Check an attestation reference delete message
+ *
+ * @param cls unused
+ * @param sam the message to check
+ */
+static int
+check_reference_delete_message (void *cls,
+                                const struct AttributeDeleteMessage *dam)
+{
+  uint16_t size;
+
+  size = ntohs (dam->header.size);
+  if (size <= sizeof(struct AttributeDeleteMessage))
+  {
+    GNUNET_break (0);
+    return GNUNET_SYSERR;
+  }
+  return GNUNET_OK;
+}
+
+/**
+ * Handle reference deletion
+ *
+ * @param cls our client
+ * @param dam deletion message
+ */
+static void
+handle_reference_delete_message (void *cls,
+                                 const struct AttributeDeleteMessage *dam)
+{
+  struct AttributeDeleteHandle *adh;
+  struct IdpClient *idp = cls;
+  size_t data_len;
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received REFERENCE_DELETE message\n");
+  data_len = ntohs (dam->attr_len);
+  adh = GNUNET_new (struct AttributeDeleteHandle);
+  adh->reference = GNUNET_RECLAIM_ATTESTATION_REF_deserialize ((char *) 
&dam[1],
+                                                               data_len);
+  adh->attest = NULL;
+  adh->claim = NULL;
+
+  adh->r_id = ntohl (dam->id);
+  adh->identity = dam->identity;
+  adh->label
+    = GNUNET_STRINGS_data_to_string_alloc (&adh->reference->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_lookup (nsh,
+                                                &adh->identity,
+                                                adh->label,
+                                                &ref_del_error,
+                                                adh,
+                                                &ref_del_cb,
+                                                adh);
+}
+
+
 
 /*************************************************
 * Attrubute iteration
@@ -1372,7 +2137,7 @@ attr_iter_error (void *cls)
 
 
 /**
- * Got record. Return if it is an attribute.
+ * Got record. Return if it is an attribute or attestation/reference.
  *
  * @param cls our attribute iterator
  * @param zone zone we are iterating
@@ -1388,35 +2153,103 @@ attr_iter_cb (void *cls,
               const struct GNUNET_GNSRECORD_Data *rd)
 {
   struct AttributeIterator *ai = cls;
-  struct AttributeResultMessage *arm;
   struct GNUNET_MQ_Envelope *env;
   char *data_tmp;
 
-  if (rd_count != 1)
+  if (rd_count == 0)
   {
     GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it, 1);
     return;
   }
+  if (rd_count > 1)
+  {
+    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: %u\n",
+                  rd[0].record_type);
+      GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it, 1);
+      return;
+    }
+  }
 
-  if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR != rd->record_type)
+  for (int i = 0; i<rd_count; i++)
   {
-    GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it, 1);
-    return;
+    if ((GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR != rd[i].record_type) &&
+        (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR != rd[i].record_type) &&
+        (GNUNET_GNSRECORD_TYPE_RECLAIM_REFERENCE != rd[i].record_type))
+    {
+      GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it, 1);
+      return;
+    }
+
+    if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR == rd[i].record_type )
+    {
+      struct AttributeResultMessage *arm;
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found attribute under: %s\n",
+                  label);
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                  "Sending ATTRIBUTE_RESULT message\n");
+      env = GNUNET_MQ_msg_extra (arm,
+                                 rd[i].data_size,
+                                 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT);
+      arm->id = htonl (ai->request_id);
+      arm->attr_len = htons (rd[i].data_size);
+      GNUNET_CRYPTO_ecdsa_key_get_public (zone, &arm->identity);
+      data_tmp = (char *) &arm[1];
+      GNUNET_memcpy (data_tmp, rd[i].data, rd[i].data_size);
+      GNUNET_MQ_send (ai->client->mq, env);
+    }
+    else
+    {
+      if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR == rd[i].record_type )
+      {
+        struct AttributeResultMessage *arm;
+        GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found attestation under: %s\n",
+                    label);
+        GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                    "Sending ATTESTATION_RESULT message\n");
+        env = GNUNET_MQ_msg_extra (arm,
+                                   rd[i].data_size,
+                                   
GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_RESULT);
+        arm->id = htonl (ai->request_id);
+        arm->attr_len = htons (rd[i].data_size);
+        GNUNET_CRYPTO_ecdsa_key_get_public (zone, &arm->identity);
+        data_tmp = (char *) &arm[1];
+        GNUNET_memcpy (data_tmp, rd[i].data, rd[i].data_size);
+        GNUNET_MQ_send (ai->client->mq, env);
+      }
+      else
+      {
+        struct ReferenceResultMessage *rrm;
+        GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found reference under: %s\n",
+                    label);
+        GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                    "Sending REFERENCE_RESULT message\n");
+        env = GNUNET_MQ_msg_extra (rrm,
+                                   rd[i].data_size + rd[0].data_size,
+                                   
GNUNET_MESSAGE_TYPE_RECLAIM_REFERENCE_RESULT);
+        rrm->id = htonl (ai->request_id);
+        rrm->attest_len = htons (rd[0].data_size);
+        rrm->ref_len = htons (rd[i].data_size);
+        GNUNET_CRYPTO_ecdsa_key_get_public (zone, &rrm->identity);
+        data_tmp = (char *) &rrm[1];
+        GNUNET_memcpy (data_tmp, rd[0].data, rd[0].data_size);
+        data_tmp += rd[0].data_size;
+        GNUNET_memcpy (data_tmp, rd[i].data, rd[i].data_size);
+        GNUNET_MQ_send (ai->client->mq, env);
+      }
+    }
   }
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found attribute under: %s\n", label);
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending ATTRIBUTE_RESULT message\n");
-  env = GNUNET_MQ_msg_extra (arm,
-                             rd->data_size,
-                             GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT);
-  arm->id = htonl (ai->request_id);
-  arm->attr_len = htons (rd->data_size);
-  GNUNET_CRYPTO_ecdsa_key_get_public (zone, &arm->identity);
-  data_tmp = (char *) &arm[1];
-  GNUNET_memcpy (data_tmp, rd->data, rd->data_size);
-  GNUNET_MQ_send (ai->client->mq, env);
 }
 
-
 /**
  * Iterate over zone to get attributes
  *
@@ -1742,10 +2575,26 @@ 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,
                          NULL),
+  GNUNET_MQ_hd_var_size (attestation_delete_message,
+                         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_var_size (reference_delete_message,
+                         GNUNET_MESSAGE_TYPE_RECLAIM_REFERENCE_DELETE,
+                         struct AttributeDeleteMessage,
+                         NULL),
   GNUNET_MQ_hd_fixed_size (
     iteration_start,
     GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_START,
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 e029fdfb6..a464a9088 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))
   {
@@ -264,3 +267,217 @@ GNUNET_RECLAIM_JSON_spec_ticket (struct 
GNUNET_RECLAIM_Ticket **ticket)
   *ticket = NULL;
   return ret;
 }
+
+/**
+   * Parse given JSON object to an attestation claim
+   *
+   * @param cls closure, NULL
+   * @param root the json object representing data
+   * @param spec where to write the data
+   * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
+   */
+static int
+parse_attest (void *cls, json_t *root, struct GNUNET_JSON_Specification *spec)
+{
+  struct GNUNET_RECLAIM_ATTESTATION_Claim *attr;
+  const char *name_str = NULL;
+  const char *val_str = NULL;
+  const char *type_str = NULL;
+  const char *id_str = NULL;
+  char *data;
+  int unpack_state;
+  uint32_t type;
+  size_t data_size;
+
+  GNUNET_assert (NULL != root);
+
+  if (! json_is_object (root))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Error json is not array nor object!\n");
+    return GNUNET_SYSERR;
+  }
+  // interpret single attribute
+  unpack_state = json_unpack (root,
+                              "{s:s, s?s, s:s, s:s!}",
+                              "name",
+                              &name_str,
+                              "id",
+                              &id_str,
+                              "type",
+                              &type_str,
+                              "value",
+                              &val_str);
+  if ((0 != unpack_state) || (NULL == name_str) || (NULL == val_str) ||
+      (NULL == type_str))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Error json object has a wrong format!\n");
+    return GNUNET_SYSERR;
+  }
+  type = GNUNET_RECLAIM_ATTESTATION_typename_to_number (type_str);
+  if (GNUNET_SYSERR ==
+      (GNUNET_RECLAIM_ATTESTATION_string_to_value (type,
+                                                   val_str,
+                                                   (void **) &data,
+                                                   &data_size)))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Attestation value invalid!\n");
+    return GNUNET_SYSERR;
+  }
+  attr = GNUNET_RECLAIM_ATTESTATION_claim_new (name_str, type, data, 
data_size);
+  if ((NULL == id_str) || (0 == strlen (id_str)))
+    attr->id = 0;
+  else
+    GNUNET_STRINGS_string_to_data (id_str,
+                                   strlen (id_str),
+                                   &attr->id,
+                                   sizeof(uint64_t));
+
+  *(struct GNUNET_RECLAIM_ATTESTATION_Claim **) spec->ptr = attr;
+  return GNUNET_OK;
+}
+
+/**
+ * Cleanup data left from parsing RSA public key.
+ *
+ * @param cls closure, NULL
+ * @param[out] spec where to free the data
+ */
+static void
+clean_attest (void *cls, struct GNUNET_JSON_Specification *spec)
+{
+  struct GNUNET_RECLAIM_ATTESTATION_Claim **attr;
+
+  attr = (struct GNUNET_RECLAIM_ATTESTATION_Claim **) spec->ptr;
+  if (NULL != *attr)
+  {
+    GNUNET_free (*attr);
+    *attr = NULL;
+  }
+}
+/**
+ * JSON Specification for Reclaim attestation claims.
+ *
+ * @param ticket struct of GNUNET_RECLAIM_ATTESTATION_Claim to fill
+ * @return JSON Specification
+ */
+struct GNUNET_JSON_Specification
+GNUNET_RECLAIM_JSON_spec_claim_attest (struct
+                                       GNUNET_RECLAIM_ATTESTATION_Claim **attr)
+{
+  struct GNUNET_JSON_Specification ret = { .parser = &parse_attest,
+                                           .cleaner = &clean_attest,
+                                           .cls = NULL,
+                                           .field = NULL,
+                                           .ptr = attr,
+                                           .ptr_size = 0,
+                                           .size_ptr = NULL };
+
+  *attr = NULL;
+  return ret;
+}
+
+/**
+   * Parse given JSON object to an attestation claim
+   *
+   * @param cls closure, NULL
+   * @param root the json object representing data
+   * @param spec where to write the data
+   * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
+   */
+static int
+parse_attest_ref (void *cls, json_t *root, struct
+                  GNUNET_JSON_Specification *spec)
+{
+  struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *attr;
+  const char *name_str = NULL;
+  const char *ref_val_str = NULL;
+  const char *ref_id_str = NULL;
+  const char *id_str = NULL;
+  int unpack_state;
+
+  GNUNET_assert (NULL != root);
+
+  if (! json_is_object (root))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Error json is not array nor object!\n");
+    return GNUNET_SYSERR;
+  }
+  // interpret single reference
+  unpack_state = json_unpack (root,
+                              "{s:s, s?s, s:s, s:s!}",
+                              "name",
+                              &name_str,
+                              "id",
+                              &id_str,
+                              "ref_id",
+                              &ref_id_str,
+                              "ref_value",
+                              &ref_val_str);
+  if ((0 != unpack_state) || (NULL == name_str) || (NULL == ref_val_str) ||
+      (NULL == ref_id_str))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Error json object has a wrong format!\n");
+    return GNUNET_SYSERR;
+  }
+
+  attr = GNUNET_RECLAIM_ATTESTATION_reference_new (name_str, ref_val_str);
+
+  attr->id = 0;
+
+  if ((NULL == ref_id_str) || (0 == strlen (ref_id_str)))
+    attr->id_attest = 0;
+  else
+    GNUNET_STRINGS_string_to_data (ref_id_str,
+                                   strlen (ref_id_str),
+                                   &attr->id_attest,
+                                   sizeof(uint64_t));
+
+  *(struct GNUNET_RECLAIM_ATTESTATION_REFERENCE **) spec->ptr = attr;
+  return GNUNET_OK;
+}
+
+/**
+ * Cleanup data left from parsing RSA public key.
+ *
+ * @param cls closure, NULL
+ * @param[out] spec where to free the data
+ */
+static void
+clean_attest_ref (void *cls, struct GNUNET_JSON_Specification *spec)
+{
+  struct GNUNET_RECLAIM_ATTESTATION_REFERENCE **attr;
+
+  attr = (struct GNUNET_RECLAIM_ATTESTATION_REFERENCE **) spec->ptr;
+  if (NULL != *attr)
+  {
+    GNUNET_free (*attr);
+    *attr = NULL;
+  }
+}
+
+/**
+ * JSON Specification for Reclaim attestation references.
+ *
+ * @param ticket struct of GNUNET_RECLAIM_ATTESTATION_REFERENCE to fill
+ * @return JSON Specification
+ */
+struct GNUNET_JSON_Specification
+GNUNET_RECLAIM_JSON_spec_claim_attest_ref (struct
+                                           GNUNET_RECLAIM_ATTESTATION_REFERENCE
+                                           **attr)
+{
+  struct GNUNET_JSON_Specification ret = { .parser = &parse_attest_ref,
+                                           .cleaner = &clean_attest_ref,
+                                           .cls = NULL,
+                                           .field = NULL,
+                                           .ptr = attr,
+                                           .ptr_size = 0,
+                                           .size_ptr = NULL };
+
+  *attr = NULL;
+  return ret;
+}
\ No newline at end of file
diff --git a/src/reclaim/json_reclaim.h b/src/reclaim/json_reclaim.h
index 3fd26167f..9e6479e5e 100644
--- a/src/reclaim/json_reclaim.h
+++ b/src/reclaim/json_reclaim.h
@@ -46,3 +46,22 @@ GNUNET_RECLAIM_JSON_spec_claim (struct 
GNUNET_RECLAIM_ATTRIBUTE_Claim **attr);
  */
 struct GNUNET_JSON_Specification
 GNUNET_RECLAIM_JSON_spec_ticket (struct GNUNET_RECLAIM_Ticket **ticket);
+
+/**
+    * JSON Specification for Reclaim attestation claims.
+    *
+    * @param ticket struct of GNUNET_RECLAIM_ATTESTATION_Claim to fill
+    * @return JSON Specification
+    */
+struct GNUNET_JSON_Specification
+GNUNET_RECLAIM_JSON_spec_claim_attest (struct
+                                       GNUNET_RECLAIM_ATTESTATION_Claim 
**attr);
+
+  /**
+   * JSON Specification for Reclaim attestation references.
+   *
+   * @param ticket struct of GNUNET_RECLAIM_ATTESTATION_REFERENCE to fill
+   * @return JSON Specification
+   */
+  struct GNUNET_JSON_Specification
+  GNUNET_RECLAIM_JSON_spec_claim_attest_ref(struct 
GNUNET_RECLAIM_ATTESTATION_REFERENCE **attr);
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 d530ef01d..f7145a272 100644
--- a/src/reclaim/plugin_gnsrecord_reclaim.c
+++ b/src/reclaim/plugin_gnsrecord_reclaim.c
@@ -54,6 +54,8 @@ value_to_string (void *cls, uint32_t type, const void *data, 
size_t data_size)
   case GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF:
   case GNUNET_GNSRECORD_TYPE_RECLAIM_TICKET:
   case GNUNET_GNSRECORD_TYPE_RECLAIM_MASTER:
+  case GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR:
+  case GNUNET_GNSRECORD_TYPE_RECLAIM_REFERENCE:
     return GNUNET_STRINGS_data_to_string_alloc (data, data_size);
 
   default:
@@ -93,6 +95,8 @@ string_to_value (void *cls, uint32_t type, const char *s, 
void **data,
   case GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF:
   case GNUNET_GNSRECORD_TYPE_RECLAIM_MASTER:
   case GNUNET_GNSRECORD_TYPE_RECLAIM_TICKET:
+  case GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR:
+  case GNUNET_GNSRECORD_TYPE_RECLAIM_REFERENCE:
     return GNUNET_STRINGS_string_to_data (s, strlen (s), *data, *data_size);
 
   default:
@@ -112,10 +116,12 @@ static struct
 } name_map[] = {
   { "RECLAIM_ATTR", GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR },
   { "RECLAIM_ATTR_REF", GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF },
+  { "RECLAIM_ATTEST", GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR },
   { "RECLAIM_MASTER", GNUNET_GNSRECORD_TYPE_RECLAIM_MASTER },
   { "RECLAIM_OIDC_CLIENT", GNUNET_GNSRECORD_TYPE_RECLAIM_OIDC_CLIENT },
   { "RECLAIM_OIDC_REDIRECT", GNUNET_GNSRECORD_TYPE_RECLAIM_OIDC_REDIRECT },
   { "RECLAIM_TICKET", GNUNET_GNSRECORD_TYPE_RECLAIM_TICKET },
+  { "RECLAIM_REFERENCE", GNUNET_GNSRECORD_TYPE_RECLAIM_REFERENCE },
   { NULL, UINT32_MAX }
 };
 
diff --git a/src/reclaim/plugin_rest_openid_connect.c 
b/src/reclaim/plugin_rest_openid_connect.c
index 92a1de621..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);
@@ -973,12 +991,14 @@ oidc_collect_finished_cb (void *cls)
 
 
 /**
- * Collects all attributes for an ego if in scope parameter
+ * Collects all attributes/references for an ego if in scope parameter
  */
 static void
 oidc_attr_collect (void *cls,
                    const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
-                   const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr)
+                   const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr,
+                   const struct GNUNET_RECLAIM_ATTESTATION_Claim *attest,
+                   const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE 
*reference)
 {
   struct RequestHandle *handle = cls;
   struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le;
@@ -986,39 +1006,92 @@ oidc_attr_collect (void *cls,
   char *scope_variable;
   char delimiter[] = " ";
 
-  if ((NULL == attr->name) || (NULL == attr->data))
+  if ((NULL == attr) && (NULL == reference))
   {
     GNUNET_RECLAIM_get_attributes_next (handle->attr_it);
     return;
   }
-
-  scope_variables = GNUNET_strdup (handle->oidc->scope);
-  scope_variable = strtok (scope_variables, delimiter);
-  while (NULL != scope_variable)
-  {
-    if (0 == strcmp (attr->name, scope_variable))
-      break;
-    scope_variable = strtok (NULL, delimiter);
-  }
-  if (NULL == scope_variable)
+  if (NULL != reference)
   {
-    GNUNET_RECLAIM_get_attributes_next (handle->attr_it);
+    if ((NULL == reference->name) || (NULL == reference->reference_value))
+    {
+      return;
+    }
+    scope_variables = GNUNET_strdup (handle->oidc->scope);
+    scope_variable = strtok (scope_variables, delimiter);
+    while (NULL != scope_variable)
+    {
+      if (0 == strcmp (reference->name, scope_variable))
+        break;
+      scope_variable = strtok (NULL, delimiter);
+    }
+    if (NULL == scope_variable)
+    {
+      GNUNET_free (scope_variables);
+      return;
+    }
     GNUNET_free (scope_variables);
-    return;
+    struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le2;
+    le2 = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry);
+    le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry);
+    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 if (NULL != attr)
+  {
+    if ((NULL == attr->name) || (NULL == attr->data))
+    {
+      GNUNET_RECLAIM_get_attributes_next (handle->attr_it);
+      return;
+    }
+    scope_variables = GNUNET_strdup (handle->oidc->scope);
+    scope_variable = strtok (scope_variables, delimiter);
+    while (NULL != scope_variable)
+    {
+      if (0 == strcmp (attr->name, scope_variable))
+        break;
+      scope_variable = strtok (NULL, delimiter);
+    }
+    if (NULL == scope_variable)
+    {
+      GNUNET_RECLAIM_get_attributes_next (handle->attr_it);
+      GNUNET_free (scope_variables);
+      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,
+                                                    attr->data_size);
+    le->claim->id = attr->id;
+    le->claim->flag = attr->flag;
+
+    GNUNET_CONTAINER_DLL_insert (handle->attr_list->list_head,
+                                 handle->attr_list->list_tail,
+                                 le);
+    GNUNET_RECLAIM_get_attributes_next (handle->attr_it);
   }
-  GNUNET_free (scope_variables);
-
-  le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry);
-  le->claim = GNUNET_RECLAIM_ATTRIBUTE_claim_new (attr->name,
-                                                  attr->type,
-                                                  attr->data,
-                                                  attr->data_size);
-  le->claim->id = attr->id;
-  le->claim->version = attr->version;
-  GNUNET_CONTAINER_DLL_insert (handle->attr_list->list_head,
-                               handle->attr_list->list_tail,
-                               le);
-  GNUNET_RECLAIM_get_attributes_next (handle->attr_it);
 }
 
 
@@ -1304,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 *);
@@ -1454,6 +1530,9 @@ authorize_endpoint (struct GNUNET_REST_RequestHandle 
*con_handle,
       handle->ego_entry = handle->ego_tail;
     }
   }
+  handle->oidc->scope = get_url_parameter_copy (handle, OIDC_SCOPE_KEY);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Scope: %s\n",GNUNET_strdup (
+                handle->oidc->scope));
   if (NULL == handle->tld)
     GNUNET_CONFIGURATION_iterate_section_values (cfg, "gns", tld_iter, handle);
   if (NULL == handle->tld)
@@ -1857,28 +1936,97 @@ 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,
-                const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr)
+                const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr,
+                const struct GNUNET_RECLAIM_ATTESTATION_Claim *attest,
+                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 9a75b2d16..dcda75b65 100644
--- a/src/reclaim/plugin_rest_reclaim.c
+++ b/src/reclaim/plugin_rest_reclaim.c
@@ -37,7 +37,6 @@
 #include "gnunet_rest_plugin.h"
 #include "gnunet_signatures.h"
 #include "json_reclaim.h"
-
 /**
  * REST root namespace
  */
@@ -48,6 +47,11 @@
  */
 #define GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES "/reclaim/attributes"
 
+/**
+   * Attestation namespace
+   */
+#define GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE "/reclaim/attestation"
+
 /**
  * Ticket namespace
  */
@@ -272,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);
@@ -360,6 +366,21 @@ finished_cont (void *cls, int32_t success, const char 
*emsg)
   GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle);
 }
 
+static void
+delete_finished_cb (void *cls, int32_t success, const char *emsg)
+{
+  struct RequestHandle *handle = cls;
+  struct MHD_Response *resp;
+
+  resp = GNUNET_REST_create_response (emsg);
+  if (GNUNET_OK != success)
+  {
+    GNUNET_SCHEDULER_add_now (&do_error, handle);
+    return;
+  }
+  handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
+  GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle);
+}
 
 /**
  * Return attributes for identity
@@ -434,88 +455,205 @@ ticket_collect (void *cls, const struct 
GNUNET_RECLAIM_Ticket *ticket)
 }
 
 
-/**
- * List tickets for identity request
- *
- * @param con_handle the connection handle
- * @param url the url
- * @param cls the RequestHandle
- */
 static void
-list_tickets_cont (struct GNUNET_REST_RequestHandle *con_handle,
-                   const char *url,
-                   void *cls)
+add_attestation_ref_cont (struct GNUNET_REST_RequestHandle *con_handle,
+                          const char *url,
+                          void *cls)
 {
-  const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key;
   struct RequestHandle *handle = cls;
+  const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity_priv;
+  const char *identity;
   struct EgoEntry *ego_entry;
-  char *identity;
-
+  struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *attribute;
+  struct GNUNET_TIME_Relative exp;
+  char term_data[handle->rest_handle->data_size + 1];
+  json_t *data_json;
+  json_error_t err;
+  struct GNUNET_JSON_Specification attrspec[] =
+  { GNUNET_RECLAIM_JSON_spec_claim_attest_ref (&attribute),
+    GNUNET_JSON_spec_end () };
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Getting tickets for %s.\n",
+              "Adding an attestation reference for %s.\n",
               handle->url);
-  if (strlen (GNUNET_REST_API_NS_IDENTITY_TICKETS) >= strlen (handle->url))
+  if (strlen (GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) + strlen (
+        "reference/") + 1 >= strlen (
+        handle->url))
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No identity given.\n");
     GNUNET_SCHEDULER_add_now (&do_error, handle);
     return;
   }
-  identity = handle->url + strlen (GNUNET_REST_API_NS_IDENTITY_TICKETS) + 1;
-
+  identity = handle->url + strlen (
+    GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) + strlen ("reference/")
+             + 1;
   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_SCHEDULER_add_now (&return_response, handle);
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Identity unknown (%s)\n", identity);
     return;
   }
-  priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
+  identity_priv = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
+  if (0 >= handle->rest_handle->data_size)
+  {
+    GNUNET_SCHEDULER_add_now (&do_error, handle);
+    return;
+  }
+
+  term_data[handle->rest_handle->data_size] = '\0';
+  GNUNET_memcpy (term_data,
+                 handle->rest_handle->data,
+                 handle->rest_handle->data_size);
+  data_json = json_loads (term_data, JSON_DECODE_ANY, &err);
+  GNUNET_assert (GNUNET_OK ==
+                 GNUNET_JSON_parse (data_json, attrspec, NULL, NULL));
+  json_decref (data_json);
+  if (NULL == attribute)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Unable to parse attestation reference from %s\n",
+                term_data);
+    GNUNET_SCHEDULER_add_now (&do_error, handle);
+    return;
+  }
+  /**
+   * New ID for attribute
+   */
+  if (0 == attribute->id)
+    attribute->id = attribute->id_attest;
   handle->idp = GNUNET_RECLAIM_connect (cfg);
-  handle->ticket_it =
-    GNUNET_RECLAIM_ticket_iteration_start (handle->idp,
-                                           priv_key,
-                                           &collect_error_cb,
-                                           handle,
-                                           &ticket_collect,
-                                           handle,
-                                           &collect_finished_cb,
-                                           handle);
+  exp = GNUNET_TIME_UNIT_HOURS;
+  handle->idp_op = GNUNET_RECLAIM_attestation_reference_store (handle->idp,
+                                                               identity_priv,
+                                                               attribute,
+                                                               &exp,
+                                                               &finished_cont,
+                                                               handle);
+  GNUNET_JSON_parse_free (attrspec);
 }
 
+static void
+parse_attestation_cont (struct GNUNET_REST_RequestHandle *con_handle,
+                        const char *url,
+                        void *cls)
+{
+  struct RequestHandle *handle = cls;
+
+  char term_data[handle->rest_handle->data_size + 1];
+  json_t *data_json;
+  json_error_t err;
+  int unpack_state;
+  struct MHD_Response *resp;
+  char *val_str = NULL;
+  const char *type_str = NULL;
+  term_data[handle->rest_handle->data_size] = '\0';
+  GNUNET_memcpy (term_data,
+                 handle->rest_handle->data,
+                 handle->rest_handle->data_size);
+  data_json = json_loads (term_data, JSON_DECODE_ANY, &err);
+  GNUNET_assert (NULL != data_json);
+  if (! json_is_object (data_json))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Error json is not array nor object!\n");
+    GNUNET_SCHEDULER_add_now (&do_error, handle);
+    return;
+  }
+  unpack_state = json_unpack (data_json,
+                              "{s:s, s:s!}",
+                              "value",
+                              &val_str,
+                              "type",
+                              &type_str);
+  if ((0 != unpack_state) || (NULL == val_str) || (NULL == type_str))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Error json object has a wrong format!\n");
+    GNUNET_SCHEDULER_add_now (&do_error, handle);
+    return;
+  }
+  if (0 == strcmp (type_str, "JWT"))
+  {
+  // The value is a JWT
+  char *decoded_jwt;
+  char delim[] = ".";
+  char *jwt_body = strtok (val_str, delim);
+  jwt_body = strtok (NULL, delim);
+  GNUNET_STRINGS_base64_decode (jwt_body, strlen (jwt_body),
+                                (void **) &decoded_jwt);
+  resp = GNUNET_REST_create_response (decoded_jwt);
+  handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
+  GNUNET_free (decoded_jwt);
+  }
+  else
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Error requested parsing type not supported!\n");
+    GNUNET_SCHEDULER_add_now (&do_error, handle);
+    return;
+  }
+  cleanup_handle (handle);
+  json_decref (data_json);
+}
 
 static void
-add_attribute_cont (struct GNUNET_REST_RequestHandle *con_handle,
-                    const char *url,
-                    void *cls)
+add_attestation_cont (struct GNUNET_REST_RequestHandle *con_handle,
+                      const char *url,
+                      void *cls)
 {
+  struct RequestHandle *handle = cls;
+  /* Check for substring "reference" */
+  if (strlen (GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) < strlen (
+        handle->url))
+  {
+    if ( strncmp ("reference/", (handle->url + strlen (
+                                   
GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE)
+                                 + 1), strlen (
+                    "reference/")) == 0)
+    {
+      add_attestation_ref_cont (con_handle,url,cls);
+      return;
+    }
+  }
+  /* Check for substring "parse" */
+  if (strlen (GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) < strlen (
+      handle->url))
+      {
+        if ( strncmp ("parse", (handle->url + strlen (
+                          GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE)
+                        + 1), strlen (
+            "parse")) == 0)
+        {
+          parse_attestation_cont (con_handle,url,cls);
+          return;
+        }
+      }
   const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity_priv;
   const char *identity;
-  struct RequestHandle *handle = cls;
   struct EgoEntry *ego_entry;
-  struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attribute;
+  struct GNUNET_RECLAIM_ATTESTATION_Claim *attribute;
   struct GNUNET_TIME_Relative exp;
   char term_data[handle->rest_handle->data_size + 1];
   json_t *data_json;
   json_error_t err;
   struct GNUNET_JSON_Specification attrspec[] =
-  { GNUNET_RECLAIM_JSON_spec_claim (&attribute), GNUNET_JSON_spec_end () };
+  { GNUNET_RECLAIM_JSON_spec_claim_attest (&attribute),
+    GNUNET_JSON_spec_end () };
 
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Adding an attribute for %s.\n",
+              "Adding an attestation for %s.\n",
               handle->url);
-  if (strlen (GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES) >= strlen (handle->url))
+  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 = handle->url + strlen (GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES) + 1;
+  identity = handle->url + strlen (
+    GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) + 1;
 
   for (ego_entry = handle->ego_head; NULL != ego_entry;
        ego_entry = ego_entry->next)
@@ -546,7 +684,7 @@ add_attribute_cont (struct GNUNET_REST_RequestHandle 
*con_handle,
   if (NULL == attribute)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Unable to parse attribute from %s\n",
+                "Unable to parse attestation from %s\n",
                 term_data);
     GNUNET_SCHEDULER_add_now (&do_error, handle);
     return;
@@ -559,66 +697,67 @@ add_attribute_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;
-  handle->idp_op = GNUNET_RECLAIM_attribute_store (handle->idp,
-                                                   identity_priv,
-                                                   attribute,
-                                                   &exp,
-                                                   &finished_cont,
-                                                   handle);
+  handle->idp_op = GNUNET_RECLAIM_attestation_store (handle->idp,
+                                                     identity_priv,
+                                                     attribute,
+                                                     &exp,
+                                                     &finished_cont,
+                                                     handle);
   GNUNET_JSON_parse_free (attrspec);
 }
 
-
 /**
- * Collect all attributes for an ego
+ * Collect all references for an ego
  *
  */
 static void
-attr_collect (void *cls,
-              const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
-              const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr)
+ref_collect (void *cls,
+             const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
+             const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr,
+             const struct GNUNET_RECLAIM_ATTESTATION_Claim *attest,
+             const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *reference)
 {
   struct RequestHandle *handle = cls;
   json_t *attr_obj;
-  const char *type;
-  char *tmp_value;
   char *id_str;
+  char *id_attest_str;
 
-  if ((NULL == attr->name) || (NULL == attr->data))
+  if (NULL == reference)
   {
     GNUNET_RECLAIM_get_attributes_next (handle->attr_it);
     return;
   }
 
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding attribute: %s\n", attr->name);
-
-  tmp_value = GNUNET_RECLAIM_ATTRIBUTE_value_to_string (attr->type,
-                                                        attr->data,
-                                                        attr->data_size);
+  if ((NULL == reference->name) || (NULL == reference->reference_value))
+  {
+    return;
+  }
 
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding reference: %s\n",
+              reference->name);
   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));
-  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));
+  json_object_set_new (attr_obj, "name", json_string (reference->name));
+  json_object_set_new (attr_obj, "ref_value", json_string (
+                         reference->reference_value));
+  id_str = GNUNET_STRINGS_data_to_string_alloc (&reference->id,
+                                                sizeof(uint64_t));
+  id_attest_str = GNUNET_STRINGS_data_to_string_alloc (&reference->id_attest,
+                                                       sizeof(uint64_t));
   json_object_set_new (attr_obj, "id", json_string (id_str));
+  json_object_set_new (attr_obj, "ref_id", json_string (id_attest_str));
   json_array_append (handle->resp_object, attr_obj);
   json_decref (attr_obj);
-  GNUNET_free (tmp_value);
-  GNUNET_RECLAIM_get_attributes_next (handle->attr_it);
 }
 
-
 /**
- * List attributes for identity request
+ * Lists references for identity request
  *
  * @param con_handle the connection handle
  * @param url the url
  * @param cls the RequestHandle
  */
 static void
-list_attribute_cont (struct GNUNET_REST_RequestHandle *con_handle,
+list_reference_cont (struct GNUNET_REST_RequestHandle *con_handle,
                      const char *url,
                      void *cls)
 {
@@ -628,23 +767,25 @@ list_attribute_cont (struct GNUNET_REST_RequestHandle 
*con_handle,
   char *identity;
 
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Getting attributes for %s.\n",
+              "Getting references for %s.\n",
               handle->url);
-  if (strlen (GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES) >= strlen (handle->url))
+  if (strlen (GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) + strlen (
+        "reference/") + 1 >= strlen (
+        handle->url))
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No identity given.\n");
     GNUNET_SCHEDULER_add_now (&do_error, handle);
     return;
   }
-  identity = handle->url + strlen (GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES) + 1;
-
+  identity = handle->url + strlen (
+    GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) + strlen ("reference/")
+             + 1;
   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
@@ -658,100 +799,737 @@ list_attribute_cont (struct GNUNET_REST_RequestHandle 
*con_handle,
                                                          priv_key,
                                                          &collect_error_cb,
                                                          handle,
-                                                         &attr_collect,
+                                                         &ref_collect,
                                                          handle,
                                                          &collect_finished_cb,
                                                          handle);
 }
 
-
+/**
+ * Collect all attestations for an ego
+ *
+ */
 static void
-delete_finished_cb (void *cls, int32_t success, const char *emsg)
+attest_collect (void *cls,
+                const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
+                const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr,
+                const struct GNUNET_RECLAIM_ATTESTATION_Claim *attest,
+                const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *reference)
 {
   struct RequestHandle *handle = cls;
-  struct MHD_Response *resp;
+  json_t *attr_obj;
+  const char *type;
+  char *tmp_value;
+  char *id_str;
 
-  resp = GNUNET_REST_create_response (emsg);
-  if (GNUNET_OK != success)
+
+  if (NULL != reference)
   {
-    GNUNET_SCHEDULER_add_now (&do_error, handle);
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "Attestation Collection with Reference\n");
     return;
   }
-  handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
-  GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle);
+  if (NULL == attest)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "Attestation Collection with empty Attestation\n");
+    GNUNET_RECLAIM_get_attributes_next (handle->attr_it);
+    return;
+  }
+
+  if ((NULL == attest->name) || (NULL == attest->data))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "Attestation Collection with empty Name/Value\n");
+    GNUNET_RECLAIM_get_attributes_next (handle->attr_it);
+    return;
+  }
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding attestation: %s\n",
+              attest->name);
+
+  tmp_value = GNUNET_RECLAIM_ATTESTATION_value_to_string (attest->type,
+                                                          attest->data,
+                                                          attest->data_size);
+  attr_obj = json_object ();
+  json_object_set_new (attr_obj, "value", json_string (tmp_value));
+  json_object_set_new (attr_obj, "name", json_string (attest->name));
+  type = GNUNET_RECLAIM_ATTESTATION_number_to_typename (attest->type);
+  json_object_set_new (attr_obj, "type", json_string (type));
+  id_str = GNUNET_STRINGS_data_to_string_alloc (&attest->id, sizeof(uint64_t));
+  json_object_set_new (attr_obj, "id", json_string (id_str));
+  json_array_append (handle->resp_object, attr_obj);
+  json_decref (attr_obj);
+  GNUNET_free (tmp_value);
+  GNUNET_RECLAIM_get_attributes_next (handle->attr_it);
 }
 
 
 /**
- * List attributes for identity request
+ * Lists attestation for identity request
  *
  * @param con_handle the connection handle
  * @param url the url
  * @param cls the RequestHandle
  */
 static void
-delete_attribute_cont (struct GNUNET_REST_RequestHandle *con_handle,
+list_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_ATTRIBUTE_Claim attr;
+  /* Check for substring "reference" */
+  if (strlen (GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) < strlen (
+        handle->url))
+  {
+    if ( strncmp ("reference/", (handle->url + strlen (
+                                   
GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE)
+                                 + 1), strlen (
+                    "reference/")) == 0)
+    {
+      list_reference_cont (con_handle,url,cls);
+      return;
+    }
+  }
+  const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key;
   struct EgoEntry *ego_entry;
-  char *identity_id_str;
   char *identity;
-  char *id;
 
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deleting attributes.\n");
-  if (strlen (GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES) >= strlen (handle->url))
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Getting attestations for %s.\n",
+              handle->url);
+  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_ATTRIBUTES) + 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;
-  }
+  identity = handle->url + strlen (
+    GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) + 1;
 
   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_ATTRIBUTE_Claim));
-  GNUNET_STRINGS_string_to_data (id, strlen (id), &attr.id, sizeof(uint64_t));
-  attr.name = "";
-  handle->idp_op = GNUNET_RECLAIM_attribute_delete (handle->idp,
-                                                    priv_key,
-                                                    &attr,
-                                                    &delete_finished_cb,
-                                                    handle);
-  GNUNET_free (identity_id_str);
+  handle->attr_it = GNUNET_RECLAIM_get_attributes_start (handle->idp,
+                                                         priv_key,
+                                                         &collect_error_cb,
+                                                         handle,
+                                                         &attest_collect,
+                                                         handle,
+                                                         &collect_finished_cb,
+                                                         handle);
 }
 
-
+/**
+ * Deletes reference from an identity
+ *
+ * @param con_handle the connection handle
+ * @param url the url
+ * @param cls the RequestHandle
+ */
 static void
-revoke_ticket_cont (struct GNUNET_REST_RequestHandle *con_handle,
-                    const char *url,
-                    void *cls)
+delete_attestation_ref_cont (struct GNUNET_REST_RequestHandle *con_handle,
+                             const char *url,
+                             void *cls)
+{
+  struct RequestHandle *handle = cls;
+  const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key;
+  struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *attr;
+  struct EgoEntry *ego_entry;
+  char *identity;
+  char *identity_id_str;
+  char *id;
+  char term_data[handle->rest_handle->data_size + 1];
+  json_t *data_json;
+  json_error_t err;
+
+  struct GNUNET_JSON_Specification attrspec[] =
+  { GNUNET_RECLAIM_JSON_spec_claim_attest_ref (&attr),
+    GNUNET_JSON_spec_end () };
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Deleting attestation reference.\n");
+  if (strlen (GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) + strlen (
+        "reference/") + 1 >= 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)
+                            + strlen ("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_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)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Ego %s not found.\n", identity);
+    GNUNET_SCHEDULER_add_now (&return_response, handle);
+    return;
+  }
+  priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
+  if (0 >= handle->rest_handle->data_size)
+  {
+    GNUNET_SCHEDULER_add_now (&do_error, handle);
+    return;
+  }
+
+  term_data[handle->rest_handle->data_size] = '\0';
+  GNUNET_memcpy (term_data,
+                 handle->rest_handle->data,
+                 handle->rest_handle->data_size);
+  data_json = json_loads (term_data, JSON_DECODE_ANY, &err);
+  GNUNET_assert (GNUNET_OK ==
+                 GNUNET_JSON_parse (data_json, attrspec, NULL, NULL));
+  json_decref (data_json);
+  if (NULL == attr)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Unable to parse attestation reference from %s\n",
+                term_data);
+    GNUNET_SCHEDULER_add_now (&do_error, handle);
+    return;
+  }
+  GNUNET_STRINGS_string_to_data (id, strlen (id), &attr->id, sizeof(uint64_t));
+
+  handle->idp = GNUNET_RECLAIM_connect (cfg);
+  handle->idp_op = GNUNET_RECLAIM_attestation_reference_delete (handle->idp,
+                                                                priv_key,
+                                                                attr,
+                                                                &
+                                                                
delete_finished_cb,
+                                                                handle);
+  GNUNET_JSON_parse_free (attrspec);
+}
+
+
+/**
+ * Deletes attestation from an identity
+ *
+ * @param con_handle the connection handle
+ * @param url the url
+ * @param cls the RequestHandle
+ */
+static void
+delete_attestation_cont (struct GNUNET_REST_RequestHandle *con_handle,
+                         const char *url,
+                         void *cls)
+{
+  struct RequestHandle *handle = cls;
+  /* Check for substring "reference" */
+  if (strlen (GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) < strlen (
+        handle->url))
+  {
+    if ( strncmp ("reference", (handle->url + strlen (
+                                  
GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE)
+                                + 1), strlen (
+                    "reference")) == 0)
+    {
+      delete_attestation_ref_cont (con_handle,url,cls);
+      return;
+    }
+  }
+  const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key;
+  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 = "";
+  handle->idp_op = GNUNET_RECLAIM_attestation_delete (handle->idp,
+                                                      priv_key,
+                                                      &attr,
+                                                      &delete_finished_cb,
+                                                      handle);
+  GNUNET_free (identity_id_str);
+}
+
+/**
+ * List tickets for identity request
+ *
+ * @param con_handle the connection handle
+ * @param url the url
+ * @param cls the RequestHandle
+ */
+static void
+list_tickets_cont (struct GNUNET_REST_RequestHandle *con_handle,
+                   const char *url,
+                   void *cls)
+{
+  const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key;
+  struct RequestHandle *handle = cls;
+  struct EgoEntry *ego_entry;
+  char *identity;
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Getting tickets for %s.\n",
+              handle->url);
+  if (strlen (GNUNET_REST_API_NS_IDENTITY_TICKETS) >= strlen (handle->url))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No identity given.\n");
+    GNUNET_SCHEDULER_add_now (&do_error, handle);
+    return;
+  }
+  identity = handle->url + strlen (GNUNET_REST_API_NS_IDENTITY_TICKETS) + 1;
+
+  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_SCHEDULER_add_now (&return_response, handle);
+    return;
+  }
+  priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
+  handle->idp = GNUNET_RECLAIM_connect (cfg);
+  handle->ticket_it =
+    GNUNET_RECLAIM_ticket_iteration_start (handle->idp,
+                                           priv_key,
+                                           &collect_error_cb,
+                                           handle,
+                                           &ticket_collect,
+                                           handle,
+                                           &collect_finished_cb,
+                                           handle);
+}
+
+
+static void
+add_attribute_cont (struct GNUNET_REST_RequestHandle *con_handle,
+                    const char *url,
+                    void *cls)
+{
+  const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity_priv;
+  const char *identity;
+  struct RequestHandle *handle = cls;
+  struct EgoEntry *ego_entry;
+  struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attribute;
+  struct GNUNET_TIME_Relative exp;
+  char term_data[handle->rest_handle->data_size + 1];
+  json_t *data_json;
+  json_error_t err;
+  struct GNUNET_JSON_Specification attrspec[] =
+  { GNUNET_RECLAIM_JSON_spec_claim (&attribute), GNUNET_JSON_spec_end () };
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Adding an attribute for %s.\n",
+              handle->url);
+  if (strlen (GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES) >= strlen (handle->url))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No identity given.\n");
+    GNUNET_SCHEDULER_add_now (&do_error, handle);
+    return;
+  }
+  identity = handle->url + strlen (GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES) + 1;
+
+  for (ego_entry = handle->ego_head; NULL != ego_entry;
+       ego_entry = ego_entry->next)
+    if (0 == strcmp (identity, ego_entry->identifier))
+      break;
+
+  if (NULL == ego_entry)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Identity unknown (%s)\n", identity);
+    return;
+  }
+  identity_priv = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
+
+  if (0 >= handle->rest_handle->data_size)
+  {
+    GNUNET_SCHEDULER_add_now (&do_error, handle);
+    return;
+  }
+
+  term_data[handle->rest_handle->data_size] = '\0';
+  GNUNET_memcpy (term_data,
+                 handle->rest_handle->data,
+                 handle->rest_handle->data_size);
+  data_json = json_loads (term_data, JSON_DECODE_ANY, &err);
+  GNUNET_assert (GNUNET_OK ==
+                 GNUNET_JSON_parse (data_json, attrspec, NULL, NULL));
+  json_decref (data_json);
+  if (NULL == attribute)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Unable to parse attribute from %s\n",
+                term_data);
+    GNUNET_SCHEDULER_add_now (&do_error, handle);
+    return;
+  }
+  /**
+   * New ID for attribute
+   */
+  if (0 == attribute->id)
+    attribute->id =
+      GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG, UINT64_MAX);
+  handle->idp = GNUNET_RECLAIM_connect (cfg);
+  exp = GNUNET_TIME_UNIT_HOURS;
+  handle->idp_op = GNUNET_RECLAIM_attribute_store (handle->idp,
+                                                   identity_priv,
+                                                   attribute,
+                                                   &exp,
+                                                   &finished_cont,
+                                                   handle);
+  GNUNET_JSON_parse_free (attrspec);
+}
+
+/**
+ * Parse a JWT and return the respective claim value as Attribute
+ *
+ * @param attest the jwt attestation
+ * @param claim the name of the claim in the JWT
+ *
+ * @return a GNUNET_RECLAIM_ATTRIBUTE_Claim, containing the new value
+ */
+struct GNUNET_RECLAIM_ATTRIBUTE_Claim *
+parse_jwt (const struct GNUNET_RECLAIM_ATTESTATION_Claim *attest,
+           const char *claim)
+{
+  char *jwt_string;
+  struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr;
+  char delim[] = ".";
+  const char *type_str = NULL;
+  const char *val_str = NULL;
+  char *data;
+  size_t data_size;
+  uint32_t type;
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Parsing JWT attributes.\n");
+  char *decoded_jwt;
+  json_t *json_val;
+  json_error_t *json_err = NULL;
+
+  jwt_string = GNUNET_RECLAIM_ATTESTATION_value_to_string (attest->type,
+                                                           attest->data,
+                                                           attest->data_size);
+  char *jwt_body = strtok (jwt_string, delim);
+  jwt_body = strtok (NULL, delim);
+  GNUNET_STRINGS_base64_decode (jwt_body, strlen (jwt_body),
+                                (void **) &decoded_jwt);
+  json_val = json_loads (decoded_jwt, JSON_DECODE_ANY, json_err);
+  const char *key;
+  json_t *value;
+  json_object_foreach (json_val, key, value) {
+    if (0 == strcasecmp (key,claim))
+    {
+      val_str = json_dumps (value, JSON_ENCODE_ANY);
+    }
+  }
+  type_str = "String";
+  type = GNUNET_RECLAIM_ATTRIBUTE_typename_to_number (type_str);
+  if (GNUNET_SYSERR ==(GNUNET_RECLAIM_ATTRIBUTE_string_to_value (type,val_str,
+                                                                 (void **) 
&data,
+                                                                 &data_size)))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "Attribute value from JWT Parser invalid!\n");
+    GNUNET_RECLAIM_ATTRIBUTE_string_to_value (type,
+                                              "Error: Referenced Claim Name 
not Found",
+                                              (void **) &data,
+                                              &data_size);
+    attr = GNUNET_RECLAIM_ATTRIBUTE_claim_new (claim, type, data, data_size);
+    attr->id = attest->id;
+    attr->flag = 1;
+  }
+  else
+  {
+    attr = GNUNET_RECLAIM_ATTRIBUTE_claim_new (claim, type, data, data_size);
+    attr->id = attest->id;
+    attr->flag = 1;
+  }
+  return attr;
+}
+
+
+/**
+ * Collect all attributes for an ego
+ *
+ */
+static void
+attr_collect (void *cls,
+              const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
+              const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr,
+              const struct GNUNET_RECLAIM_ATTESTATION_Claim *attest,
+              const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *reference)
+{
+  struct RequestHandle *handle = cls;
+  json_t *attr_obj;
+  const char *type;
+  char *id_str;
+
+  if ((NULL == attr) && (NULL == reference))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "Attribute Collection with empty Attribute/Reference\n");
+    GNUNET_RECLAIM_get_attributes_next (handle->attr_it);
+    return;
+  }
+
+  if (NULL == attr)
+  {
+
+    if ((NULL == reference->name) || (NULL == reference->reference_value))
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                  "Attribute Collection with empty Reference Name/Value\n");
+      return;
+    }
+    struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr2;
+    attr2 = parse_jwt (attest, reference->reference_value);
+    if (NULL == attr2)
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                  "Attribute Collection with unparsed Attestation\n");
+      return;
+    }
+    attr2->name = reference->name;
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding reference as attribute: %s\n",
+                reference->name);
+    char *tmp_value;
+    tmp_value = GNUNET_RECLAIM_ATTRIBUTE_value_to_string (attr2->type,
+                                                          attr2->data,
+                                                          attr2->data_size);
+    attr_obj = json_object ();
+
+    json_object_set_new (attr_obj, "value", json_string (tmp_value));
+    json_object_set_new (attr_obj, "name", json_string (attr2->name));
+    json_object_set_new (attr_obj, "flag", json_string ("1"));
+    type = GNUNET_RECLAIM_ATTRIBUTE_number_to_typename (attr2->type);
+    json_object_set_new (attr_obj, "type", json_string (type));
+    id_str = GNUNET_STRINGS_data_to_string_alloc (&attr2->id, 
sizeof(uint64_t));
+    json_object_set_new (attr_obj, "id", json_string (id_str));
+    json_array_append (handle->resp_object, attr_obj);
+    json_decref (attr_obj);
+    GNUNET_free (tmp_value);
+  }
+  else
+  {
+    if ((NULL == attr->name) || (NULL == attr->data))
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                  "Attribute Collection with empty Attribute Name/Value\n");
+      GNUNET_RECLAIM_get_attributes_next (handle->attr_it);
+      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,
+                                                          attr->data,
+                                                          attr->data_size);
+
+    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));
+    json_object_set_new (attr_obj, "id", json_string (id_str));
+    json_array_append (handle->resp_object, attr_obj);
+    json_decref (attr_obj);
+    GNUNET_free (tmp_value);
+    GNUNET_RECLAIM_get_attributes_next (handle->attr_it);
+  }
+}
+
+/**
+ * List attributes for identity request
+ *
+ * @param con_handle the connection handle
+ * @param url the url
+ * @param cls the RequestHandle
+ */
+static void
+list_attribute_cont (struct GNUNET_REST_RequestHandle *con_handle,
+                     const char *url,
+                     void *cls)
+{
+  const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key;
+  struct RequestHandle *handle = cls;
+  struct EgoEntry *ego_entry;
+  char *identity;
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Getting attributes for %s.\n",
+              handle->url);
+  if (strlen (GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES) >= strlen (handle->url))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No identity given.\n");
+    GNUNET_SCHEDULER_add_now (&do_error, handle);
+    return;
+  }
+  identity = handle->url + strlen (GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES) + 1;
+
+  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_SCHEDULER_add_now (&return_response, handle);
+    return;
+  }
+  priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
+  handle->idp = GNUNET_RECLAIM_connect (cfg);
+  handle->attr_it = GNUNET_RECLAIM_get_attributes_start (handle->idp,
+                                                         priv_key,
+                                                         &collect_error_cb,
+                                                         handle,
+                                                         &attr_collect,
+                                                         handle,
+                                                         &collect_finished_cb,
+                                                         handle);
+}
+
+
+/**
+ * List attributes for identity request
+ *
+ * @param con_handle the connection handle
+ * @param url the url
+ * @param cls the RequestHandle
+ */
+static void
+delete_attribute_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_ATTRIBUTE_Claim attr;
+  struct EgoEntry *ego_entry;
+  char *identity_id_str;
+  char *identity;
+  char *id;
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deleting attributes.\n");
+  if (strlen (GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES) >= 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_ATTRIBUTES) + 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_ATTRIBUTE_Claim));
+  GNUNET_STRINGS_string_to_data (id, strlen (id), &attr.id, sizeof(uint64_t));
+  attr.name = "";
+  handle->idp_op = GNUNET_RECLAIM_attribute_delete (handle->idp,
+                                                    priv_key,
+                                                    &attr,
+                                                    &delete_finished_cb,
+                                                    handle);
+  GNUNET_free (identity_id_str);
+}
+
+
+static void
+revoke_ticket_cont (struct GNUNET_REST_RequestHandle *con_handle,
+                    const char *url,
+                    void *cls)
 {
   const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity_priv;
   struct RequestHandle *handle = cls;
@@ -825,7 +1603,9 @@ revoke_ticket_cont (struct GNUNET_REST_RequestHandle 
*con_handle,
 static void
 consume_cont (void *cls,
               const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
-              const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr)
+              const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr,
+              const struct GNUNET_RECLAIM_ATTESTATION_Claim *attest,
+              const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *reference)
 {
   struct RequestHandle *handle = cls;
   char *val_str;
@@ -968,6 +1748,15 @@ init_cont (struct RequestHandle *handle)
     { MHD_HTTP_METHOD_DELETE,
       GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES,
       &delete_attribute_cont },
+    { MHD_HTTP_METHOD_GET,
+      GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE,
+      &list_attestation_cont },
+    { MHD_HTTP_METHOD_POST,
+      GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE,
+      &add_attestation_cont },
+    { MHD_HTTP_METHOD_DELETE,
+      GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE,
+      &delete_attestation_cont },
     { MHD_HTTP_METHOD_GET,
       GNUNET_REST_API_NS_IDENTITY_TICKETS,
       &list_tickets_cont },
diff --git a/src/reclaim/reclaim.h b/src/reclaim/reclaim.h
index 8e731812e..ff953a096 100644
--- a/src/reclaim/reclaim.h
+++ b/src/reclaim/reclaim.h
@@ -153,6 +153,45 @@ struct AttributeResultMessage
    */
 };
 
+/**
+ * Reference plus Attestation is returned from the idp.
+ */
+struct ReferenceResultMessage
+{
+  /**
+   * Message header
+   */
+  struct GNUNET_MessageHeader header;
+
+  /**
+   * Unique identifier for this request (for key collisions).
+   */
+  uint32_t id GNUNET_PACKED;
+
+  /**
+   * Length of serialized attestation data
+   */
+  uint16_t attest_len GNUNET_PACKED;
+
+  /**
+   * Length of serialized reference data
+   */
+  uint16_t ref_len GNUNET_PACKED;
+
+  /**
+   * always zero (for alignment)
+   */
+  uint16_t reserved GNUNET_PACKED;
+
+  /**
+   * The public key of the identity.
+   */
+  struct GNUNET_CRYPTO_EcdsaPublicKey identity;
+
+  /* followed by:
+   * serialized reference data + attestation data
+   */
+};
 
 /**
  * Start a attribute iteration for the given identity
diff --git a/src/reclaim/reclaim_api.c b/src/reclaim/reclaim_api.c
index 7d4d7588a..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,22 +498,36 @@ 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)
     {
       if (NULL == attrs)
       {
-        op->ar_cb (op->cls, &msg->identity, NULL);
+        op->ar_cb (op->cls, &msg->identity, NULL, NULL, NULL);
       }
       else
       {
         for (le = attrs->list_head; NULL != le; le = le->next)
-          op->ar_cb (op->cls, &msg->identity, le->claim);
+        {
+          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;
       }
-      op->ar_cb (op->cls, NULL, NULL);
+      op->ar_cb (op->cls, NULL, NULL, NULL, NULL);
     }
     GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, op);
     free_op (op);
@@ -597,7 +611,7 @@ handle_attribute_result (void *cls, const struct 
AttributeResultMessage *msg)
     if (NULL != op)
     {
       if (NULL != op->ar_cb)
-        op->ar_cb (op->cls, NULL, NULL);
+        op->ar_cb (op->cls, NULL, NULL, NULL, NULL);
       GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, op);
       free_op (op);
     }
@@ -610,12 +624,111 @@ handle_attribute_result (void *cls, const struct 
AttributeResultMessage *msg)
     if (NULL != it)
     {
       if (NULL != it->proc)
-        it->proc (it->proc_cls, &msg->identity, attr);
+        it->proc (it->proc_cls, &msg->identity, attr, NULL, NULL);
+    }
+    else if (NULL != op)
+    {
+      if (NULL != op->ar_cb)
+        op->ar_cb (op->cls, &msg->identity, attr, NULL, NULL);
+    }
+    GNUNET_free (attr);
+    return;
+  }
+  GNUNET_assert (0);
+}
+
+/**
+   * Handle an incoming message of type
+   * #GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_RESULT
+   *
+   * @param cls
+   * @param msg the message we received
+   * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
+   */
+static int
+check_attestation_result (void *cls, const struct AttributeResultMessage *msg)
+{
+  size_t msg_len;
+  size_t attr_len;
+
+  msg_len = ntohs (msg->header.size);
+  attr_len = ntohs (msg->attr_len);
+  if (msg_len != sizeof(struct AttributeResultMessage) + attr_len)
+  {
+    GNUNET_break (0);
+    return GNUNET_SYSERR;
+  }
+  return GNUNET_OK;
+}
+
+
+/**
+ * Handle an incoming message of type
+ * #GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_RESULT
+ *
+ * @param cls
+ * @param msg the message we received
+ */
+static void
+handle_attestation_result (void *cls, const struct AttributeResultMessage *msg)
+{
+  static struct GNUNET_CRYPTO_EcdsaPrivateKey identity_dummy;
+  struct GNUNET_RECLAIM_Handle *h = cls;
+  struct GNUNET_RECLAIM_AttributeIterator *it;
+  struct GNUNET_RECLAIM_Operation *op;
+  size_t attr_len;
+  uint32_t r_id = ntohl (msg->id);
+
+  attr_len = ntohs (msg->attr_len);
+  LOG (GNUNET_ERROR_TYPE_DEBUG, "Processing attestation result.\n");
+
+
+  for (it = h->it_head; NULL != it; it = it->next)
+    if (it->r_id == r_id)
+      break;
+  for (op = h->op_head; NULL != op; op = op->next)
+    if (op->r_id == r_id)
+      break;
+  if ((NULL == it) && (NULL == op))
+    return;
+
+  if ((0 ==
+       (memcmp (&msg->identity, &identity_dummy, sizeof(identity_dummy)))))
+  {
+    if ((NULL == it) && (NULL == op))
+    {
+      GNUNET_break (0);
+      force_reconnect (h);
+      return;
+    }
+    if (NULL != it)
+    {
+      if (NULL != it->finish_cb)
+        it->finish_cb (it->finish_cb_cls);
+      free_it (it);
+    }
+    if (NULL != op)
+    {
+      if (NULL != op->ar_cb)
+        op->ar_cb (op->cls, NULL, NULL, NULL, NULL);
+      GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, op);
+      free_op (op);
+    }
+    return;
+  }
+
+  {
+    struct GNUNET_RECLAIM_ATTESTATION_Claim *attr;
+    attr = GNUNET_RECLAIM_ATTESTATION_deserialize ((char *) &msg[1], attr_len);
+    if (NULL != it)
+    {
+      if (NULL != it->proc)
+        it->proc (it->proc_cls, &msg->identity, NULL, attr, NULL);
     }
     else if (NULL != op)
     {
       if (NULL != op->ar_cb)
-        op->ar_cb (op->cls, &msg->identity, attr);
+        op->ar_cb (op->cls, &msg->identity, NULL, attr, NULL);
     }
     GNUNET_free (attr);
     return;
@@ -623,6 +736,110 @@ handle_attribute_result (void *cls, const struct 
AttributeResultMessage *msg)
   GNUNET_assert (0);
 }
 
+/**
+   * Handle an incoming message of type
+   * #GNUNET_MESSAGE_TYPE_RECLAIM_REFERENCE_RESULT
+   *
+   * @param cls
+   * @param msg the message we received
+   * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
+   */
+static int
+check_reference_result (void *cls, const struct ReferenceResultMessage *msg)
+{
+  size_t msg_len;
+  size_t attr_len;
+  size_t ref_len;
+
+  msg_len = ntohs (msg->header.size);
+  attr_len = ntohs (msg->attest_len);
+  ref_len = ntohs (msg->ref_len);
+  if (msg_len != sizeof(struct ReferenceResultMessage) + attr_len + ref_len)
+  {
+    GNUNET_break (0);
+    return GNUNET_SYSERR;
+  }
+  return GNUNET_OK;
+}
+
+/**
+* Handle an incoming message of type
+* #GNUNET_MESSAGE_TYPE_RECLAIM_REFERENCE_RESULT
+*
+* @param cls
+* @param msg the message we received
+*/
+static void
+handle_reference_result (void *cls, const struct ReferenceResultMessage *msg)
+{
+  static struct GNUNET_CRYPTO_EcdsaPrivateKey identity_dummy;
+  struct GNUNET_RECLAIM_Handle *h = cls;
+  struct GNUNET_RECLAIM_AttributeIterator *it;
+  struct GNUNET_RECLAIM_Operation *op;
+  size_t attest_len;
+  size_t ref_len;
+  uint32_t r_id = ntohl (msg->id);
+  attest_len = ntohs (msg->attest_len);
+  ref_len = ntohs (msg->ref_len);
+  LOG (GNUNET_ERROR_TYPE_DEBUG, "Processing reference result.\n");
+  for (it = h->it_head; NULL != it; it = it->next)
+    if (it->r_id == r_id)
+      break;
+  for (op = h->op_head; NULL != op; op = op->next)
+    if (op->r_id == r_id)
+      break;
+  if ((NULL == it) && (NULL == op))
+    return;
+
+  if ((0 ==
+       (memcmp (&msg->identity, &identity_dummy, sizeof(identity_dummy)))))
+  {
+    if ((NULL == it) && (NULL == op))
+    {
+      GNUNET_break (0);
+      force_reconnect (h);
+      return;
+    }
+    if (NULL != it)
+    {
+      if (NULL != it->finish_cb)
+        it->finish_cb (it->finish_cb_cls);
+      free_it (it);
+    }
+    if (NULL != op)
+    {
+      if (NULL != op->ar_cb)
+        op->ar_cb (op->cls, NULL, NULL, NULL, NULL);
+      GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, op);
+      free_op (op);
+    }
+    return;
+  }
+
+  {
+    struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *ref;
+    struct GNUNET_RECLAIM_ATTESTATION_Claim *attest;
+    attest = GNUNET_RECLAIM_ATTESTATION_deserialize ((char *) &msg[1],
+                                                     attest_len);
+    ref = GNUNET_RECLAIM_ATTESTATION_REF_deserialize ((char *) &msg[1]
+                                                      + attest_len,
+                                                      ref_len);
+    if (NULL != it)
+    {
+      if (NULL != it->proc)
+        it->proc (it->proc_cls, &msg->identity, NULL, attest, ref);
+    }
+    else if (NULL != op)
+    {
+      if (NULL != op->ar_cb)
+        op->ar_cb (op->cls, &msg->identity, NULL, attest, ref);
+    }
+    GNUNET_free (ref);
+    GNUNET_free (attest);
+    return;
+  }
+  GNUNET_assert (0);
+}
 
 /**
  * Handle an incoming message of type
@@ -742,6 +959,14 @@ reconnect (struct GNUNET_RECLAIM_Handle *h)
                            GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT,
                            struct AttributeResultMessage,
                            h),
+    GNUNET_MQ_hd_var_size (attestation_result,
+                           GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_RESULT,
+                           struct AttributeResultMessage,
+                           h),
+    GNUNET_MQ_hd_var_size (reference_result,
+                           GNUNET_MESSAGE_TYPE_RECLAIM_REFERENCE_RESULT,
+                           struct ReferenceResultMessage,
+                           h),
     GNUNET_MQ_hd_fixed_size (ticket_result,
                              GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT,
                              struct TicketResultMessage,
@@ -925,6 +1150,185 @@ 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;
+}
+
+/**
+   * Delete an attestation. Tickets used to share this attestation are updated
+   * accordingly.
+   *
+   * @param h handle to the re:claimID service
+   * @param pkey Private key of the identity to add an attribute to
+   * @param attr The attestation
+   * @param cont Continuation to call when done
+   * @param cont_cls Closure for @a cont
+   * @return handle Used to to abort the request
+   */
+struct GNUNET_RECLAIM_Operation *
+GNUNET_RECLAIM_attestation_delete (
+  struct GNUNET_RECLAIM_Handle *h,
+  const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey,
+  const struct GNUNET_RECLAIM_ATTESTATION_Claim *attr,
+  GNUNET_RECLAIM_ContinuationWithStatus cont,
+  void *cont_cls)
+{
+  struct GNUNET_RECLAIM_Operation *op;
+  struct AttributeDeleteMessage *dam;
+  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 (dam,
+                                 attr_len,
+                                 
GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_DELETE);
+  dam->identity = *pkey;
+  dam->id = htonl (op->r_id);
+  GNUNET_RECLAIM_ATTESTATION_serialize (attr, (char *) &dam[1]);
+
+  dam->attr_len = htons (attr_len);
+  if (NULL != h->mq)
+    GNUNET_MQ_send_copy (h->mq, op->env);
+  return op;
+}
+
+/**
+   * Store an attestation reference.  If the reference is already present,
+   * it is replaced with the new reference.
+   *
+   * @param h handle to the re:claimID service
+   * @param pkey private key of the identity
+   * @param attr the reference value
+   * @param exp_interval the relative expiration interval for the reference
+   * @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_reference_store (
+  struct GNUNET_RECLAIM_Handle *h,
+  const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey,
+  const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *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_REF_serialize_get_size (attr);
+  op->env = GNUNET_MQ_msg_extra (sam,
+                                 attr_len,
+                                 GNUNET_MESSAGE_TYPE_RECLAIM_REFERENCE_STORE);
+  sam->identity = *pkey;
+  sam->id = htonl (op->r_id);
+  sam->exp = GNUNET_htonll (exp_interval->rel_value_us);
+
+  GNUNET_RECLAIM_ATTESTATION_REF_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;
+}
+
+/**
+ * Delete an attestation reference. Tickets used to share this reference are 
updated
+ * accordingly.
+ *
+ * @param h handle to the re:claimID service
+ * @param pkey Private key of the identity to delete the reference from
+ * @param attr The reference
+ * @param cont Continuation to call when done
+ * @param cont_cls Closure for @a cont
+ * @return handle Used to to abort the request
+ */
+struct GNUNET_RECLAIM_Operation *
+GNUNET_RECLAIM_attestation_reference_delete (
+  struct GNUNET_RECLAIM_Handle *h,
+  const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey,
+  const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *attr,
+  GNUNET_RECLAIM_ContinuationWithStatus cont,
+  void *cont_cls)
+{
+
+  struct GNUNET_RECLAIM_Operation *op;
+  struct AttributeDeleteMessage *dam;
+  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_REF_serialize_get_size (attr);
+  op->env = GNUNET_MQ_msg_extra (dam,
+                                 attr_len,
+                                 GNUNET_MESSAGE_TYPE_RECLAIM_REFERENCE_DELETE);
+  dam->identity = *pkey;
+  dam->id = htonl (op->r_id);
+  GNUNET_RECLAIM_ATTESTATION_REF_serialize (attr, (char *) &dam[1]);
+
+  dam->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.



reply via email to

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