#define GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_RESULT 979
-#define GNUNET_MESSAGE_TYPE_RECLAIM_REFERENCE_STORE 980
+#define GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_ITERATION_START 963
+
+#define GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_ITERATION_STOP 964
+
+#define GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_ITERATION_NEXT 965
+
/**************************************************
*
* ABD MESSAGE TYPES
*/
-#define GNUNET_MESSAGE_TYPE_ABD_VERIFY 981
+#define GNUNET_MESSAGE_TYPE_ABD_VERIFY 991
-#define GNUNET_MESSAGE_TYPE_ABD_VERIFY_RESULT 982
+#define GNUNET_MESSAGE_TYPE_ABD_VERIFY_RESULT 992
-#define GNUNET_MESSAGE_TYPE_ABD_COLLECT 983
+#define GNUNET_MESSAGE_TYPE_ABD_COLLECT 993
-#define GNUNET_MESSAGE_TYPE_ABD_COLLECT_RESULT 984
+#define GNUNET_MESSAGE_TYPE_ABD_COLLECT_RESULT 994
-#define GNUNET_MESSAGE_TYPE_ABD_INTERMEDIATE_RESULT 985
+#define GNUNET_MESSAGE_TYPE_ABD_INTERMEDIATE_RESULT 995
/******************************************************************************/
int32_t success,
const char *emsg);
-
/**
* Callback used to notify the client of attribute results.
*
* @param attestation The attestation for the attribute (may be NULL)
*/
typedef void (*GNUNET_RECLAIM_AttributeResult) (
+ void *cls, const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
+ const struct GNUNET_RECLAIM_Attribute *attr);
+
+/**
+ * Callback used to notify the client of attribute results.
+ *
+ * @param cls The callback closure
+ * @param identity The identity authoritative over the attributes
+ * @param attr The attribute
+ * @param attestation The attestation for the attribute (may be NULL)
+ */
+typedef void (*GNUNET_RECLAIM_AttributeTicketResult) (
void *cls, const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
const struct GNUNET_RECLAIM_Attribute *attr,
const struct GNUNET_RECLAIM_Attestation *attestation);
struct GNUNET_RECLAIM_AttributeIterator *it);
+/**
+ * List all attestations for a local identity.
+ * This MUST lock the `struct GNUNET_RECLAIM_Handle`
+ * for any other calls than #GNUNET_RECLAIM_get_attestations_next() and
+ * #GNUNET_RECLAIM_get_attestations_stop. @a proc will be called once
+ * immediately, and then again after
+ * #GNUNET_RECLAIM_get_attestations_next() is invoked.
+ *
+ * On error (disconnect), @a error_cb will be invoked.
+ * On normal completion, @a finish_cb proc will be
+ * invoked.
+ *
+ * @param h Handle to the re:claimID service
+ * @param identity Identity to iterate over
+ * @param error_cb Function to call on error (i.e. disconnect),
+ * the handle is afterwards invalid
+ * @param error_cb_cls Closure for @a error_cb
+ * @param proc Function to call on each attestation
+ * @param proc_cls Closure for @a proc
+ * @param finish_cb Function to call on completion
+ * the handle is afterwards invalid
+ * @param finish_cb_cls Closure for @a finish_cb
+ * @return an iterator Handle to use for iteration
+ */
+struct GNUNET_RECLAIM_AttestationIterator *
+GNUNET_RECLAIM_get_attestations_start (
+ struct GNUNET_RECLAIM_Handle *h,
+ const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
+ GNUNET_SCHEDULER_TaskCallback error_cb,
+ void *error_cb_cls,
+ GNUNET_RECLAIM_AttestationResult proc,
+ void *proc_cls,
+ GNUNET_SCHEDULER_TaskCallback finish_cb,
+ void *finish_cb_cls);
+
+
+/**
+ * Calls the record processor specified in #GNUNET_RECLAIM_get_attestation_start
+ * for the next record.
+ *
+ * @param it the iterator
+ */
+void
+GNUNET_RECLAIM_get_attestations_next (struct GNUNET_RECLAIM_AttestationIterator *ait);
+
+
+/**
+ * Stops iteration and releases the handle for further calls. Must
+ * be called on any iteration that has not yet completed prior to calling
+ * #GNUNET_RECLAIM_disconnect.
+ *
+ * @param it the iterator
+ */
+void
+GNUNET_RECLAIM_get_attestations_stop (struct GNUNET_RECLAIM_AttestationIterator *ait);
+
+
/**
* Issues a ticket to a relying party. The identity may use
* GNUNET_RECLAIM_ticket_consume to consume the ticket
struct GNUNET_RECLAIM_Handle *h,
const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
const struct GNUNET_RECLAIM_Ticket *ticket,
- GNUNET_RECLAIM_AttributeResult cb, void *cb_cls);
+ GNUNET_RECLAIM_AttributeTicketResult cb, void *cb_cls);
/**
static void
iter_cb (void *cls,
const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
- const struct GNUNET_RECLAIM_Attribute *attr,
- const struct GNUNET_RECLAIM_Attestation *attest)
+ const struct GNUNET_RECLAIM_Attribute *attr)
{
struct GNUNET_RECLAIM_AttributeListEntry *le;
char *attrs_tmp;
/**
* An attribute iteration operation.
*/
-struct AttributeIterator
+struct Iterator
{
/**
* Next element in the DLL
*/
- struct AttributeIterator *next;
+ struct Iterator *next;
/**
* Previous element in the DLL
*/
- struct AttributeIterator *prev;
+ struct Iterator *prev;
/**
* IDP client which intiated this zone iteration
* The operation id fot the zone iteration in the response for the client
*/
uint32_t request_id;
+
+ /**
+ * Context
+ */
+ void *ctx;
};
* Attribute iteration operations in
* progress initiated by this client
*/
- struct AttributeIterator *attr_iter_head;
+ struct Iterator *attr_iter_head;
+
+ /**
+ * Tail of the DLL of
+ * Attribute iteration operations
+ * in progress initiated by this client
+ */
+ struct Iterator *attr_iter_tail;
+
+ /**
+ * Head of the DLL of
+ * Attribute iteration operations in
+ * progress initiated by this client
+ */
+ struct Iterator *attest_iter_head;
/**
* Tail of the DLL of
* Attribute iteration operations
* in progress initiated by this client
*/
- struct AttributeIterator *attr_iter_tail;
+ struct Iterator *attest_iter_tail;
/**
* Head of DLL of ticket iteration ops
static void
cleanup_client (struct IdpClient *idp)
{
- struct AttributeIterator *ai;
+ struct Iterator *ai;
struct TicketIteration *ti;
struct TicketRevocationOperation *rop;
struct TicketIssueOperation *iss;
GNUNET_CONTAINER_DLL_remove (idp->attr_iter_head, idp->attr_iter_tail, ai);
GNUNET_free (ai);
}
+ while (NULL != (ai = idp->attest_iter_head))
+ {
+ GNUNET_CONTAINER_DLL_remove (idp->attest_iter_head, idp->attest_iter_tail,
+ ai);
+ GNUNET_free (ai);
+ }
+
while (NULL != (rop = idp->revoke_op_head))
{
GNUNET_CONTAINER_DLL_remove (idp->revoke_op_head, idp->revoke_op_tail, rop);
static void
attr_iter_finished (void *cls)
{
- struct AttributeIterator *ai = cls;
+ struct Iterator *ai = cls;
struct GNUNET_MQ_Envelope *env;
struct AttributeResultMessage *arm;
static void
attr_iter_error (void *cls)
{
- struct AttributeIterator *ai = cls;
+ struct Iterator *ai = cls;
GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to iterate over attributes\n");
attr_iter_finished (ai);
unsigned int rd_count,
const struct GNUNET_GNSRECORD_Data *rd)
{
- struct AttributeIterator *ai = cls;
+ struct Iterator *ai = cls;
struct GNUNET_MQ_Envelope *env;
char *data_tmp;
GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it, 1);
return;
}
- if (rd_count > 1)
- {
- if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTRIBUTE_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_ATTESTATION != 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;
- }
- }
for (int i = 0; i<rd_count; i++)
{
- if ((GNUNET_GNSRECORD_TYPE_RECLAIM_ATTRIBUTE != rd[i].record_type) &&
- (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTESTATION != rd[i].record_type))
- {
- GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it, 1);
- return;
- }
- // FIXME Send attribute TOGETHER with respective attestation if applicable
- if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTRIBUTE == 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_ATTESTATION == 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);
- }
- }
+ if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTRIBUTE != rd[i].record_type)
+ continue;
+ 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);
}
}
const struct AttributeIterationStartMessage *ais_msg)
{
struct IdpClient *idp = cls;
- struct AttributeIterator *ai;
+ struct Iterator *ai;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Received ATTRIBUTE_ITERATION_START message\n");
- ai = GNUNET_new (struct AttributeIterator);
+ ai = GNUNET_new (struct Iterator);
ai->request_id = ntohl (ais_msg->id);
ai->client = idp;
ai->identity = ais_msg->identity;
const struct AttributeIterationStopMessage *ais_msg)
{
struct IdpClient *idp = cls;
- struct AttributeIterator *ai;
+ struct Iterator *ai;
uint32_t rid;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
const struct AttributeIterationNextMessage *ais_msg)
{
struct IdpClient *idp = cls;
- struct AttributeIterator *ai;
+ struct Iterator *ai;
uint32_t rid;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
}
+/*************************************************
+* Attestation iteration
+*************************************************/
+
+
+/**
+ * Done iterating over attestations
+ *
+ * @param cls our iterator handle
+ */
+static void
+attest_iter_finished (void *cls)
+{
+ struct Iterator *ai = cls;
+ struct GNUNET_MQ_Envelope *env;
+ struct AttestationResultMessage *arm;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending ATTESTATION_RESULT message\n");
+ env = GNUNET_MQ_msg (arm, GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_RESULT);
+ arm->id = htonl (ai->request_id);
+ arm->attestation_len = htons (0);
+ GNUNET_MQ_send (ai->client->mq, env);
+ GNUNET_CONTAINER_DLL_remove (ai->client->attest_iter_head,
+ ai->client->attest_iter_tail,
+ ai);
+ GNUNET_free (ai);
+}
+
+
+/**
+ * Error iterating over attestations. Abort.
+ *
+ * @param cls our attribute iteration handle
+ */
+static void
+attest_iter_error (void *cls)
+{
+ struct Iterator *ai = cls;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to iterate over attestations\n");
+ attest_iter_finished (ai);
+}
+
+
+/**
+ * Got record. Return attestation.
+ *
+ * @param cls our attribute iterator
+ * @param zone zone we are iterating
+ * @param label label of the records
+ * @param rd_count record count
+ * @param rd records
+ */
+static void
+attest_iter_cb (void *cls,
+ const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
+ const char *label,
+ unsigned int rd_count,
+ const struct GNUNET_GNSRECORD_Data *rd)
+{
+ struct Iterator *ai = cls;
+ struct GNUNET_MQ_Envelope *env;
+ char *data_tmp;
+
+ if (rd_count == 0)
+ {
+ GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it, 1);
+ return;
+ }
+
+ for (int i = 0; i<rd_count; i++)
+ {
+ if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTESTATION != rd[i].record_type)
+ continue;
+ struct AttestationResultMessage *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->attestation_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);
+ }
+}
+
+
+/**
+ * Iterate over zone to get attributes
+ *
+ * @param cls our client
+ * @param ais_msg the iteration message to start
+ */
+static void
+handle_attestation_iteration_start (void *cls,
+ const struct
+ AttestationIterationStartMessage *ais_msg)
+{
+ struct IdpClient *idp = cls;
+ struct Iterator *ai;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Received ATTESTATION_ITERATION_START message\n");
+ ai = GNUNET_new (struct Iterator);
+ ai->request_id = ntohl (ais_msg->id);
+ ai->client = idp;
+ ai->identity = ais_msg->identity;
+
+ GNUNET_CONTAINER_DLL_insert (idp->attest_iter_head, idp->attest_iter_tail,
+ ai);
+ ai->ns_it = GNUNET_NAMESTORE_zone_iteration_start (nsh,
+ &ai->identity,
+ &attest_iter_error,
+ ai,
+ &attest_iter_cb,
+ ai,
+ &attest_iter_finished,
+ ai);
+ GNUNET_SERVICE_client_continue (idp->client);
+}
+
+
+/**
+ * Handle iteration stop message from client
+ *
+ * @param cls the client
+ * @param ais_msg the stop message
+ */
+static void
+handle_attestation_iteration_stop (void *cls,
+ const struct
+ AttestationIterationStopMessage *ais_msg)
+{
+ struct IdpClient *idp = cls;
+ struct Iterator *ai;
+ uint32_t rid;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Received `%s' message\n",
+ "ATTESTATION_ITERATION_STOP");
+ rid = ntohl (ais_msg->id);
+ for (ai = idp->attest_iter_head; NULL != ai; ai = ai->next)
+ if (ai->request_id == rid)
+ break;
+ if (NULL == ai)
+ {
+ GNUNET_break (0);
+ GNUNET_SERVICE_client_drop (idp->client);
+ return;
+ }
+ GNUNET_CONTAINER_DLL_remove (idp->attest_iter_head, idp->attest_iter_tail,
+ ai);
+ GNUNET_free (ai);
+ GNUNET_SERVICE_client_continue (idp->client);
+}
+
+
+/**
+ * Client requests next attestation from iterator
+ *
+ * @param cls the client
+ * @param ais_msg the message
+ */
+static void
+handle_attestation_iteration_next (void *cls,
+ const struct
+ AttestationIterationNextMessage *ais_msg)
+{
+ struct IdpClient *idp = cls;
+ struct Iterator *ai;
+ uint32_t rid;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Received ATTESTATION_ITERATION_NEXT message\n");
+ rid = ntohl (ais_msg->id);
+ for (ai = idp->attest_iter_head; NULL != ai; ai = ai->next)
+ if (ai->request_id == rid)
+ break;
+ if (NULL == ai)
+ {
+ GNUNET_break (0);
+ GNUNET_SERVICE_client_drop (idp->client);
+ return;
+ }
+ GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it, 1);
+ GNUNET_SERVICE_client_continue (idp->client);
+}
+
+
/******************************************************
* Ticket iteration
******************************************************/
GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_STOP,
struct AttributeIterationStopMessage,
NULL),
+ GNUNET_MQ_hd_fixed_size (attestation_iteration_start,
+ GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_ITERATION_START,
+ struct AttestationIterationStartMessage,
+ NULL),
+ GNUNET_MQ_hd_fixed_size (attestation_iteration_next,
+ GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_ITERATION_NEXT,
+ struct AttestationIterationNextMessage,
+ NULL),
+ GNUNET_MQ_hd_fixed_size (attestation_iteration_stop,
+ GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_ITERATION_STOP,
+ struct AttestationIterationStopMessage,
+ NULL),
+
GNUNET_MQ_hd_var_size (issue_ticket_message,
GNUNET_MESSAGE_TYPE_RECLAIM_ISSUE_TICKET,
struct IssueTicketMessage,
*/
struct GNUNET_RECLAIM_AttributeIterator *attr_it;
+ /**
+ * Attestation iterator
+ */
+ struct GNUNET_RECLAIM_AttestationIterator *attest_it;
+
+
/**
* Ticket iterator
*/
static void
cleanup_handle (struct RequestHandle *handle)
{
- struct GNUNET_RECLAIM_AttributeListEntry *claim_entry;
struct EgoEntry *ego_entry;
struct EgoEntry *ego_tmp;
GNUNET_IDENTITY_disconnect (handle->identity_handle);
if (NULL != handle->attr_it)
GNUNET_RECLAIM_get_attributes_stop (handle->attr_it);
+ if (NULL != handle->attest_it)
+ GNUNET_RECLAIM_get_attestations_stop (handle->attest_it);
if (NULL != handle->ticket_it)
GNUNET_RECLAIM_ticket_iteration_stop (handle->ticket_it);
if (NULL != handle->idp)
static void
-oidc_collect_finished_cb (void *cls)
+oidc_attest_collect_finished_cb (void *cls)
+{
+ struct RequestHandle *handle = cls;
+
+ handle->attest_it = NULL;
+ handle->idp_op = GNUNET_RECLAIM_ticket_issue (handle->idp,
+ &handle->priv_key,
+ &handle->oidc->client_pkey,
+ handle->attr_list,
+ &oidc_ticket_issue_cb,
+ handle);
+}
+
+
+/**
+ * Collects all attributes for an ego if in scope parameter
+ */
+static void
+oidc_attest_collect (void *cls,
+ const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
+ const struct GNUNET_RECLAIM_Attestation *attest)
+{
+ struct RequestHandle *handle = cls;
+ struct GNUNET_RECLAIM_AttributeListEntry *le;
+
+ for (le = handle->attr_list->list_head; NULL != le; le = le->next)
+ {
+ if (GNUNET_NO == GNUNET_RECLAIM_id_is_equal (&le->attribute->attestation,
+ &attest->id))
+ {
+ struct GNUNET_RECLAIM_AttestationListEntry *ale;
+ ale = GNUNET_new (struct GNUNET_RECLAIM_AttestationListEntry);
+ ale->attestation = GNUNET_RECLAIM_attestation_new (attest->name,
+ attest->type,
+ attest->data,
+ attest->data_size);
+ GNUNET_CONTAINER_DLL_insert (handle->attests_list->list_head,
+ handle->attests_list->list_tail,
+ ale);
+ }
+ }
+ GNUNET_RECLAIM_get_attestations_next (handle->attest_it);
+}
+
+
+static void
+oidc_attr_collect_finished_cb (void *cls)
{
struct RequestHandle *handle = cls;
GNUNET_SCHEDULER_add_now (&do_redirect_error, handle);
return;
}
+ handle->attests_list = GNUNET_new (struct GNUNET_RECLAIM_AttestationList);
+ handle->attest_it =
+ GNUNET_RECLAIM_get_attestations_start (handle->idp,
+ &handle->priv_key,
+ &oidc_iteration_error,
+ handle,
+ &oidc_attest_collect,
+ handle,
+ &oidc_attest_collect_finished_cb,
+ handle);
+
handle->idp_op = GNUNET_RECLAIM_ticket_issue (handle->idp,
&handle->priv_key,
&handle->oidc->client_pkey,
static void
oidc_attr_collect (void *cls,
const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
- const struct GNUNET_RECLAIM_Attribute *attr,
- const struct GNUNET_RECLAIM_Attestation *attest)
+ const struct GNUNET_RECLAIM_Attribute *attr)
{
struct RequestHandle *handle = cls;
struct GNUNET_RECLAIM_AttributeListEntry *le;
GNUNET_CONTAINER_DLL_insert (handle->attr_list->list_head,
handle->attr_list->list_tail,
le);
- if (GNUNET_NO == GNUNET_RECLAIM_id_is_zero (&attr->attestation))
- {
- struct GNUNET_RECLAIM_AttestationListEntry *ale;
- ale = GNUNET_new (struct GNUNET_RECLAIM_AttestationListEntry);
- ale->attestation = GNUNET_RECLAIM_attestation_new (attest->name,
- attest->type,
- attest->data,
- attest->data_size);
- GNUNET_CONTAINER_DLL_insert (handle->attests_list->list_head,
- handle->attests_list->list_tail,
- ale);
- }
GNUNET_RECLAIM_get_attributes_next (handle->attr_it);
}
handle,
&oidc_attr_collect,
handle,
- &oidc_collect_finished_cb,
+ &oidc_attr_collect_finished_cb,
handle);
return;
}
priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
handle->idp = GNUNET_RECLAIM_connect (cfg);
handle->attest_it = GNUNET_RECLAIM_get_attestations_start (handle->idp,
- priv_key,
- &collect_error_cb,
- handle,
- &attest_collect,
- handle,
- &collect_finished_cb,
- handle);
+ priv_key,
+ &collect_error_cb,
+ handle,
+ &attest_collect,
+ handle,
+ &
+ collect_finished_cb,
+ handle);
}
static void
attr_collect (void *cls,
const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
- const struct GNUNET_RECLAIM_Attribute *attr,
- const struct GNUNET_RECLAIM_Attestation *attest)
+ const struct GNUNET_RECLAIM_Attribute *attr)
{
struct RequestHandle *handle = cls;
json_t *attr_obj;
const char *type;
char *id_str;
- if (GNUNET_NO == GNUNET_RECLAIM_id_is_zero (&attr->attestation))
- {
- struct GNUNET_RECLAIM_Attribute *attr2;
- attr2 = parse_jwt (attest, attr->data);
- if (NULL == attr2)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Attribute Collection with unparsed Attestation\n");
- return;
- }
- attr2->name = attr->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(attr2->id));
- 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
- {
- 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(attr->id));
- 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);
- }
+ char *tmp_value;
+ 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));
+
+ json_object_set_new (attr_obj, "flag", json_string ("1"));
+ 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(attr->id));
+ json_object_set_new (attr_obj, "id", json_string (id_str));
+ id_str = GNUNET_STRINGS_data_to_string_alloc (&attr->attestation,
+ sizeof(attr->attestation));
+ json_object_set_new (attr_obj, "attestation", json_string (id_str));
+ json_array_append (handle->resp_object, attr_obj);
+ json_decref (attr_obj);
+ GNUNET_free (tmp_value);
}
/**
- * Reference plus Attestation is returned from the idp.
+ * Start a attribute iteration for the given identity
*/
-struct ReferenceResultMessage
+struct AttributeIterationStartMessage
{
/**
- * Message header
+ * Message
*/
struct GNUNET_MessageHeader header;
uint32_t id GNUNET_PACKED;
/**
- * Length of serialized attestation data
+ * Identity.
*/
- uint16_t attest_len GNUNET_PACKED;
+ struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
+};
- /**
- * Length of serialized reference data
- */
- uint16_t ref_len GNUNET_PACKED;
+/**
+ * Ask for next result of attribute iteration for the given operation
+ */
+struct AttributeIterationNextMessage
+{
/**
- * always zero (for alignment)
+ * Type will be #GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_NEXT
*/
- uint16_t reserved GNUNET_PACKED;
+ struct GNUNET_MessageHeader header;
/**
- * The public key of the identity.
- */
- struct GNUNET_CRYPTO_EcdsaPublicKey identity;
-
- /* followed by:
- * serialized reference data + attestation data
+ * Unique identifier for this request (for key collisions).
*/
+ uint32_t id GNUNET_PACKED;
};
+
/**
- * Start a attribute iteration for the given identity
+ * Start a attestation iteration for the given identity
*/
-struct AttributeIterationStartMessage
+struct AttestationIterationStartMessage
{
/**
* Message
/**
- * Ask for next result of attribute iteration for the given operation
+ * Ask for next result of attestation iteration for the given operation
*/
-struct AttributeIterationNextMessage
+struct AttestationIterationNextMessage
{
/**
* Type will be #GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_NEXT
};
+/**
+ * Stop attestation iteration for the given operation
+ */
+struct AttestationIterationStopMessage
+{
+ /**
+ * Type will be #GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_STOP
+ */
+ struct GNUNET_MessageHeader header;
+
+ /**
+ * Unique identifier for this request (for key collisions).
+ */
+ uint32_t id GNUNET_PACKED;
+};
+
+
/**
* Stop attribute iteration for the given operation
*/
*/
GNUNET_RECLAIM_AttributeResult ar_cb;
+ /**
+ * Attribute result callback
+ */
+ GNUNET_RECLAIM_AttributeTicketResult atr_cb;
+
/**
* Attestation result callback
*/
read_ptr = ((char *) &msg[1]) + attrs_len;
attests =
GNUNET_RECLAIM_attestation_list_deserialize (read_ptr, attests_len);
- if (NULL != op->ar_cb)
+ if (NULL != op->atr_cb)
{
if (NULL == attrs)
{
- op->ar_cb (op->cls, &msg->identity, NULL, NULL);
+ op->atr_cb (op->cls, &msg->identity, NULL, NULL);
}
else
{
GNUNET_RECLAIM_id_is_equal (&le->attribute->id,
&ale->attestation->id))
{
- op->ar_cb (op->cls, &msg->identity,
+ op->atr_cb (op->cls, &msg->identity,
le->attribute, ale->attestation);
break;
}
}
else // No attestations
{
- op->ar_cb (op->cls, &msg->identity,
+ op->atr_cb (op->cls, &msg->identity,
le->attribute, NULL);
}
}
attrs = NULL;
attests = NULL;
}
- op->ar_cb (op->cls, NULL, NULL, NULL);
+ op->atr_cb (op->cls, NULL, NULL, NULL);
}
GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, op);
free_op (op);
if (NULL != op)
{
if (NULL != op->ar_cb)
- op->ar_cb (op->cls, NULL, NULL, NULL);
+ op->ar_cb (op->cls, NULL, NULL);
GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, op);
free_op (op);
}
{
struct GNUNET_RECLAIM_Attribute *attr;
- struct GNUNET_RECLAIM_Attestation *attest;
- char *read_ptr;
attr = GNUNET_RECLAIM_attribute_deserialize ((char *) &msg[1], attr_len);
- read_ptr = ((char *) &msg[1]) + attr_len;
- attest = GNUNET_RECLAIM_attestation_deserialize (read_ptr, attest_len);
if (NULL != it)
{
if (NULL != it->proc)
- it->proc (it->proc_cls, &msg->identity, attr, attest);
+ it->proc (it->proc_cls, &msg->identity, attr);
}
else if (NULL != op)
{
if (NULL != op->ar_cb)
- op->ar_cb (op->cls, &msg->identity, attr, attest);
+ op->ar_cb (op->cls, &msg->identity, attr);
}
GNUNET_free (attr);
return;
}
+/**
+ * List all attestations for a local identity.
+ * This MUST lock the `struct GNUNET_RECLAIM_Handle`
+ * for any other calls than #GNUNET_RECLAIM_get_attestations_next() and
+ * #GNUNET_RECLAIM_get_attestations_stop. @a proc will be called once
+ * immediately, and then again after
+ * #GNUNET_RECLAIM_get_attestations_next() is invoked.
+ *
+ * On error (disconnect), @a error_cb will be invoked.
+ * On normal completion, @a finish_cb proc will be
+ * invoked.
+ *
+ * @param h Handle to the re:claimID service
+ * @param identity Identity to iterate over
+ * @param error_cb Function to call on error (i.e. disconnect),
+ * the handle is afterwards invalid
+ * @param error_cb_cls Closure for @a error_cb
+ * @param proc Function to call on each attestation
+ * @param proc_cls Closure for @a proc
+ * @param finish_cb Function to call on completion
+ * the handle is afterwards invalid
+ * @param finish_cb_cls Closure for @a finish_cb
+ * @return an iterator Handle to use for iteration
+ */
+struct GNUNET_RECLAIM_AttestationIterator *
+GNUNET_RECLAIM_get_attestations_start (
+ struct GNUNET_RECLAIM_Handle *h,
+ const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
+ GNUNET_SCHEDULER_TaskCallback error_cb,
+ void *error_cb_cls,
+ GNUNET_RECLAIM_AttestationResult proc,
+ void *proc_cls,
+ GNUNET_SCHEDULER_TaskCallback finish_cb,
+ void *finish_cb_cls)
+{
+ struct GNUNET_RECLAIM_AttestationIterator *ait;
+ struct GNUNET_MQ_Envelope *env;
+ struct AttestationIterationStartMessage *msg;
+ uint32_t rid;
+
+ rid = h->r_id_gen++;
+ ait = GNUNET_new (struct GNUNET_RECLAIM_AttestationIterator);
+ ait->h = h;
+ ait->error_cb = error_cb;
+ ait->error_cb_cls = error_cb_cls;
+ ait->finish_cb = finish_cb;
+ ait->finish_cb_cls = finish_cb_cls;
+ ait->proc = proc;
+ ait->proc_cls = proc_cls;
+ ait->r_id = rid;
+ ait->identity = *identity;
+ GNUNET_CONTAINER_DLL_insert_tail (h->ait_head, h->ait_tail, ait);
+ env =
+ GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_START);
+ msg->id = htonl (rid);
+ msg->identity = *identity;
+ if (NULL == h->mq)
+ ait->env = env;
+ else
+ GNUNET_MQ_send (h->mq, env);
+ return ait;
+}
+
+
+/**
+ * Calls the record processor specified in #GNUNET_RECLAIM_get_attestation_start
+ * for the next record.
+ *
+ * @param it the iterator
+ */
+void
+GNUNET_RECLAIM_get_attestations_next (struct GNUNET_RECLAIM_AttestationIterator *ait)
+{
+ struct GNUNET_RECLAIM_Handle *h = ait->h;
+ struct AttestationIterationNextMessage *msg;
+ struct GNUNET_MQ_Envelope *env;
+
+ env =
+ GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_ITERATION_NEXT);
+ msg->id = htonl (ait->r_id);
+ GNUNET_MQ_send (h->mq, env);
+}
+
+
+/**
+ * Stops iteration and releases the handle for further calls. Must
+ * be called on any iteration that has not yet completed prior to calling
+ * #GNUNET_RECLAIM_disconnect.
+ *
+ * @param it the iterator
+ */
+void
+GNUNET_RECLAIM_get_attestations_stop (struct GNUNET_RECLAIM_AttestationIterator *ait)
+{
+ struct GNUNET_RECLAIM_Handle *h = ait->h;
+ struct GNUNET_MQ_Envelope *env;
+ struct AttestationIterationStopMessage *msg;
+
+ if (NULL != h->mq)
+ {
+ env =
+ GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_ITERATION_STOP);
+ msg->id = htonl (ait->r_id);
+ GNUNET_MQ_send (h->mq, env);
+ }
+ free_ait (ait);
+}
+
+
+
/**
* Issues a ticket to another relying party. The identity may use
* @GNUNET_RECLAIM_ticket_consume to consume the ticket
struct GNUNET_RECLAIM_Handle *h,
const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
const struct GNUNET_RECLAIM_Ticket *ticket,
- GNUNET_RECLAIM_AttributeResult cb,
+ GNUNET_RECLAIM_AttributeTicketResult cb,
void *cb_cls)
{
struct GNUNET_RECLAIM_Operation *op;
op = GNUNET_new (struct GNUNET_RECLAIM_Operation);
op->h = h;
- op->ar_cb = cb;
+ op->atr_cb = cb;
op->cls = cb_cls;
op->r_id = h->r_id_gen++;
GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, op);