json_t *resp_object;
};
+/**
+ * Handle for attribute store request
+ */
+struct AttributeStoreHandle
+{
+ /**
+ * DLL
+ */
+ struct AttributeStoreHandle *next;
+
+ /**
+ * DLL
+ */
+ struct AttributeStoreHandle *prev;
+
+ /**
+ * Client connection
+ */
+ struct IdpClient *client;
+
+ /**
+ * Identity
+ */
+ struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
+
+ /**
+ * Identity pubkey
+ */
+ struct GNUNET_CRYPTO_EcdsaPublicKey identity_pkey;
+
+ /**
+ * QueueEntry
+ */
+ struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
+
+ /**
+ * The attribute to store
+ */
+ struct GNUNET_RECLAIM_ATTRIBUTE_Claim *claim;
+
+ /**
+ * The attestation to store
+ */
+ struct GNUNET_RECLAIM_ATTESTATION_Claim *attest;
+
+ /**
+ * The attribute expiration interval
+ */
+ struct GNUNET_TIME_Relative exp;
+
+ /**
+ * request id
+ */
+ uint32_t r_id;
+};
+
+/**
+ * Handle to the service.
+ */
+struct GNUNET_RECLAIM_Handle
+{
+ /**
+ * Configuration to use.
+ */
+ const struct GNUNET_CONFIGURATION_Handle *cfg;
+
+ /**
+ * Socket (if available).
+ */
+ struct GNUNET_CLIENT_Connection *client;
+
+ /**
+ * Closure for 'cb'.
+ */
+ void *cb_cls;
+
+ /**
+ * Head of active operations.
+ */
+ struct GNUNET_RECLAIM_Operation *op_head;
+
+ /**
+ * Tail of active operations.
+ */
+ struct GNUNET_RECLAIM_Operation *op_tail;
+
+ /**
+ * Head of active iterations
+ */
+ struct GNUNET_RECLAIM_AttributeIterator *it_head;
+
+ /**
+ * Tail of active iterations
+ */
+ struct GNUNET_RECLAIM_AttributeIterator *it_tail;
+
+ /**
+ * Head of active iterations
+ */
+ struct GNUNET_RECLAIM_TicketIterator *ticket_it_head;
+
+ /**
+ * Tail of active iterations
+ */
+ struct GNUNET_RECLAIM_TicketIterator *ticket_it_tail;
+
+ /**
+ * Currently pending transmission request, or NULL for none.
+ */
+ struct GNUNET_CLIENT_TransmitHandle *th;
+
+ /**
+ * Task doing exponential back-off trying to reconnect.
+ */
+ struct GNUNET_SCHEDULER_Task *reconnect_task;
+
+ /**
+ * Time for next connect retry.
+ */
+ struct GNUNET_TIME_Relative reconnect_backoff;
+
+ /**
+ * Connection to service (if available).
+ */
+ struct GNUNET_MQ_Handle *mq;
+
+ /**
+ * Request Id generator. Incremented by one for each request.
+ */
+ uint32_t r_id_gen;
+
+ /**
+ * Are we polling for incoming messages right now?
+ */
+ int in_receive;
+};
+
/**
* Cleanup lookup handle
* @param handle Handle to clean up
const char *url,
void *cls)
{
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Adding Attestations not supported\n");
- GNUNET_SCHEDULER_add_now (&do_error, cls);
- return;
+ const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity_priv;
+ const char *identity;
+ struct RequestHandle *handle = cls;
+ struct EgoEntry *ego_entry;
+ 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_attest (&attribute),
+ GNUNET_JSON_spec_end () };
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Adding an attestation 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 = 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;
+
+ 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 attestation 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;
+ /*New */
+ struct GNUNET_RECLAIM_Handle *h = handle->idp;
+ struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey = identity_priv;
+ /*struct GNUNET_RECLAIM_ATTESTATION_Claim *attr = attribute;*/
+ struct GNUNET_TIME_Relative *exp_interval = &exp;
+ /*GNUNET_RECLAIM_ContinuationWithStatus cont = &finished_cont;*/
+ void *cont_cls = handle;
+
+ struct AttributeStoreHandle *ash;
+ struct GNUNET_GNSRECORD_Data rd[1];
+ char *buf;
+ char *label;
+ size_t buf_size;
+ struct IdpClient *idp = cont_cls;
+ struct GNUNET_NAMESTORE_Handle *nsh;
+ nsh = GNUNET_NAMESTORE_connect (cfg);
+ if (NULL == nsh)
+ {
+ GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
+ "error connecting to namestore");
+ }
+ ash = GNUNET_new (struct AttributeStoreHandle);
+ ash->identity = *pkey;
+ ash->r_id = h->r_id_gen++;
+ ash->exp.rel_value_us = exp_interval->rel_value_us;
+ ash->attest = attribute;
+ ash->client = idp;
+ /*GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Type:%u\n", type);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ID:%s\n", id_str);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Size:%u\n", data_size);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Data:%s\n", data);*/
+ buf_size = GNUNET_RECLAIM_ATTESTATION_serialize_get_size (ash->attest);
+ buf = GNUNET_malloc (buf_size);
+ // Give the ash a new id if unset
+ if (0 == ash->attest->id)
+ ash->attest->id
+ = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG, UINT64_MAX);
+ GNUNET_RECLAIM_ATTESTATION_serialize (ash->attest, buf);
+ label = GNUNET_STRINGS_data_to_string_alloc (&ash->attest->id,
+ sizeof(uint64_t));
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Encrypting with label %s\n", label);
+
+ rd[0].data_size = buf_size;
+ rd[0].data = buf;
+ rd[0].record_type = GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR;
+ rd[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
+ rd[0].expiration_time = ash->exp.rel_value_us;
+ ash->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
+ &ash->identity,
+ label,
+ 1,
+ rd,
+ &finished_cont,
+ ash);
+ GNUNET_free (buf);
+ GNUNET_free (label);
+ GNUNET_JSON_parse_free (attrspec);
}
/*Placeholder*/
static void