#include "gnunet_signatures.h"
/**
- * Init flag
+ * List attribute flag
*/
-static int init;
+static int list;
/**
- * List attribute flag
+ * Relying party
*/
-static int list;
+static char* rp;
/**
* The attribute
*/
static char* attr_value;
+/**
+ * Attributes to issue
+ */
+static char* issue_attrs;
+
/**
* Ego name
*/
static struct GNUNET_IDENTITY_PROVIDER_Operation *idp_op;
/**
- * Namestore handle
+ * Attribute iterator
*/
-static struct GNUNET_NAMESTORE_Handle *namestore_handle;
+static struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *attr_iterator;
/**
- * Attribute iterator
+ * Master ABE key
*/
-static struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *attr_iterator;
+static struct GNUNET_CRYPTO_AbeMasterKey *abe_key;
/**
- * Namestore queue
+ * ego private key
*/
-static struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
+static const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey;
/**
- * Master ABE key
+ * rp public key
*/
-static struct GNUNET_CRYPTO_AbeMasterKey *abe_key;
+static struct GNUNET_CRYPTO_EcdsaPublicKey rp_key;
+
+
+/**
+ * Attribute list
+ */
+static struct GNUNET_IDENTITY_PROVIDER_AttributeList *attr_list;
static void
do_cleanup(void *cls)
{
- if (NULL != ns_qe)
- GNUNET_NAMESTORE_cancel (ns_qe);
if (NULL != attr_iterator)
GNUNET_IDENTITY_PROVIDER_get_attributes_stop (attr_iterator);
if (NULL != idp_handle)
GNUNET_IDENTITY_PROVIDER_disconnect (idp_handle);
- if (NULL != namestore_handle)
- GNUNET_NAMESTORE_disconnect (namestore_handle);
if (NULL != identity_handle)
GNUNET_IDENTITY_disconnect (identity_handle);
if (NULL != abe_key)
GNUNET_free (abe_key);
+ if (NULL != attr_list)
+ GNUNET_free (attr_list);
}
static void
-ns_error_cb (void *cls)
-{
- ns_qe = NULL;
- GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
- "Failed.");
- do_cleanup(NULL);
- return;
-}
-
-static void
-store_attr_cont (void *cls,
- int32_t success,
- const char*emsg)
+ticket_issue_cb (void* cls,
+ const struct GNUNET_IDENTITY_PROVIDER_Ticket2 *ticket)
{
- ns_qe = NULL;
- if (GNUNET_SYSERR == success) {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "%s\n", emsg);
- } else {
+ char* ticket_str;
+ if (NULL != ticket) {
+ ticket_str = GNUNET_STRINGS_data_to_string_alloc (&ticket->rnd,
+ sizeof (uint64_t));
GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
- "Sucessfully added identity attribute %s=%s\n",
- attr_name, attr_value);
+ "Got ticket, %s\n",
+ ticket_str);
+ GNUNET_free (ticket_str);
}
GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
}
static void
-store_abe_cont (void *cls,
+store_attr_cont (void *cls,
int32_t success,
const char*emsg)
{
- ns_qe = NULL;
+ GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
+ "Store continuation\n");
+
if (GNUNET_SYSERR == success) {
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"%s\n", emsg);
} else {
GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
- "Bootstrapped ABE master key. Please run command again.\n");
+ "Sucessfully added identity attribute %s=%s\n",
+ attr_name, attr_value);
}
GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
}
static void
iter_finished (void *cls)
{
- attr_iterator = NULL;
- GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
-}
+ struct GNUNET_IDENTITY_PROVIDER_Attribute *attr;
-static void
-iter_cb (void *cls,
- const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
- const struct GNUNET_IDENTITY_PROVIDER_Attribute *attr)
-{
-
GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
- "%s: %s\n", attr->name, (char*)attr->data);
- GNUNET_IDENTITY_PROVIDER_get_attributes_next (attr_iterator);
-}
-
-static void
-abe_lookup_cb (void *cls,
- const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
- const char *label,
- unsigned int rd_count,
- const struct GNUNET_GNSRECORD_Data *rd)
-{
- struct GNUNET_GNSRECORD_Data new_record;
- struct GNUNET_CRYPTO_AbeMasterKey *new_key;
- int i;
- ssize_t size;
- ns_qe = NULL;
- for (i=0;i<rd_count;i++) {
- if (GNUNET_GNSRECORD_TYPE_ABE_MASTER != rd[i].record_type)
- continue;
- abe_key = GNUNET_CRYPTO_cpabe_deserialize_master_key (rd[i].data,
- rd[i].data_size);
- }
- if (NULL == abe_key) {
- new_key = GNUNET_CRYPTO_cpabe_create_master_key ();
- size = GNUNET_CRYPTO_cpabe_serialize_master_key (new_key,
- (void**)&new_record.data);
- new_record.data_size = size;
- new_record.record_type = GNUNET_GNSRECORD_TYPE_ABE_MASTER;
- new_record.expiration_time = GNUNET_TIME_UNIT_DAYS.rel_value_us;
- new_record.flags = GNUNET_GNSRECORD_RF_PRIVATE | GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
- ns_qe = GNUNET_NAMESTORE_records_store (namestore_handle,
- zone,
- "+",
- 1,
- &new_record,
- &store_abe_cont,
- NULL);
- return;
- }
- if (init) {
+ "Attribute collection finished!\n");
+ attr_iterator = NULL;
+ if (list) {
GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
return;
}
- if (list) {
- attr_iterator = GNUNET_IDENTITY_PROVIDER_get_attributes_start (idp_handle,
- zone,
- &iter_error,
- NULL,
- &iter_cb,
- NULL,
- &iter_finished,
- NULL);
+ if (issue_attrs) {
+ idp_op = GNUNET_IDENTITY_PROVIDER_idp_ticket_issue (idp_handle,
+ pkey,
+ &rp_key,
+ attr_list,
+ &ticket_issue_cb,
+ NULL);
return;
}
+ attr = GNUNET_IDENTITY_PROVIDER_attribute_new (attr_name,
+ GNUNET_IDENTITY_PROVIDER_AT_STRING,
+ attr_value,
+ strlen (attr_value));
+ GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
+ "Adding attribute\n");
- struct GNUNET_IDENTITY_PROVIDER_Attribute *attr = GNUNET_IDENTITY_PROVIDER_attribute_new (attr_name,
- GNUNET_IDENTITY_PROVIDER_AT_STRING,
- attr_value,
- strlen (attr_value));
idp_op = GNUNET_IDENTITY_PROVIDER_attribute_store (idp_handle,
- zone,
- attr,
- &store_attr_cont,
- NULL);
-
- /*size = GNUNET_CRYPTO_cpabe_encrypt (attr_value,
- strlen (attr_value) + 1,
- attr_name,
- abe_key,
- (void**)&new_record.data);
- new_record.data_size = size;
- new_record.record_type = GNUNET_GNSRECORD_TYPE_ID_ATTR;
- new_record.expiration_time = GNUNET_TIME_UNIT_HOURS.rel_value_us;
- new_record.flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
-
- ns_qe = GNUNET_NAMESTORE_records_store (namestore_handle,
- zone,
- attr_name,
- 1,
- &new_record,
- &store_attr_cont,
- NULL);*/
+ pkey,
+ attr,
+ &store_attr_cont,
+ NULL);
+
+
+}
+
+static void
+iter_cb (void *cls,
+ const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
+ const struct GNUNET_IDENTITY_PROVIDER_Attribute *attr)
+{
+ struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry *le;
+ char *attrs_tmp;
+ char *attr_str;
+
+ if (issue_attrs)
+ {
+ attrs_tmp = GNUNET_strdup (issue_attrs);
+ attr_str = strtok (attrs_tmp, ",");
+ while (NULL != attr_str) {
+ if (0 != strcmp (attr_str, attr->name)) {
+ attr_str = strtok (NULL, ",");
+ continue;
+ }
+ le = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry);
+ le->attribute = GNUNET_IDENTITY_PROVIDER_attribute_new (attr->name,
+ attr->attribute_type,
+ attr->data,
+ attr->data_size);
+ GNUNET_CONTAINER_DLL_insert (attr_list->list_head,
+ attr_list->list_tail,
+ le);
+ break;
+ }
+ GNUNET_free (attrs_tmp);
+ } else {
+ GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
+ "%s: %s\n", attr->name, (char*)attr->data);
+ }
+ GNUNET_IDENTITY_PROVIDER_get_attributes_next (attr_iterator);
}
static void
void **ctx,
const char *name)
{
- const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey;
if (NULL == name)
return;
if (0 != strcmp (name, ego_name))
return;
pkey = GNUNET_IDENTITY_ego_get_private_key (ego);
- ns_qe = GNUNET_NAMESTORE_records_lookup (namestore_handle,
- pkey,
- "+",
- &ns_error_cb,
- NULL,
- &abe_lookup_cb,
- NULL);
+
+ if (NULL != rp)
+ GNUNET_CRYPTO_ecdsa_public_key_from_string (rp,
+ strlen (rp),
+ &rp_key);
+
+ attr_list = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_AttributeList);
+
+ attr_iterator = GNUNET_IDENTITY_PROVIDER_get_attributes_start (idp_handle,
+ pkey,
+ &iter_error,
+ NULL,
+ &iter_cb,
+ NULL,
+ &iter_finished,
+ NULL);
+
+
}
static void
return;
}
- if ((NULL == attr_name) && !list && !init)
- {
- return;
- }
- if ((NULL == attr_value) && !list && !init)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
- _("Value is required\n"));
- return;
- }
-
- namestore_handle = GNUNET_NAMESTORE_connect (c);
idp_handle = GNUNET_IDENTITY_PROVIDER_connect (c);
//Get Ego
identity_handle = GNUNET_IDENTITY_connect (c,
NULL,
gettext_noop ("Ego"),
&ego_name),
+ GNUNET_GETOPT_option_string ('r',
+ "rp",
+ NULL,
+ gettext_noop ("Audience (relying party)"),
+ &rp),
GNUNET_GETOPT_option_flag ('D',
"dump",
gettext_noop ("List attributes for Ego"),
&list),
- GNUNET_GETOPT_option_flag ('i',
- "init",
- gettext_noop ("Initialize attribute store"),
- &init),
+ GNUNET_GETOPT_option_string ('i',
+ "issue",
+ NULL,
+ gettext_noop ("Issue a ticket"),
+ &issue_attrs),
GNUNET_GETOPT_OPTION_END
};
return GNUNET_PROGRAM_run (argc, argv, "ct",
char *label;
};
+
+struct TicketIssueHandle
+{
+
+ /**
+ * Client connection
+ */
+ struct IdpClient *client;
+
+ /**
+ * Attributes to issue
+ */
+ struct GNUNET_IDENTITY_PROVIDER_AttributeList *attrs;
+
+ /**
+ * Issuer Key
+ */
+ struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
+
+ /**
+ * Ticket to issue
+ */
+ struct GNUNET_IDENTITY_PROVIDER_Ticket2 ticket;
+
+ /**
+ * QueueEntry
+ */
+ struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
+
+ /**
+ * request id
+ */
+ uint32_t r_id;
+};
+
+
+/**
+ * DEPRECATED
+ */
struct IssueHandle
{
cleanup();
}
+/**
+ * Finished storing newly bootstrapped ABE key
+ */
+static void
+bootstrap_store_cont (void *cls,
+ int32_t success,
+ const char *emsg)
+{
+ struct AbeBootstrapHandle *abh = cls;
+ if (GNUNET_SYSERR == success)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Failed to bootstrap ABE master %s\n",
+ emsg);
+ abh->proc (abh->proc_cls, NULL);
+ GNUNET_free (abh->abe_key);
+ GNUNET_free (abh);
+ return;
+ }
+ abh->proc (abh->proc_cls, abh->abe_key);
+ GNUNET_free (abh);
+}
+
+/**
+ * Generates and stores a new ABE key
+ */
+static void
+bootstrap_store_task (void *cls)
+{
+ struct AbeBootstrapHandle *abh = cls;
+ struct GNUNET_GNSRECORD_Data rd[1];
+
+ rd[0].data_size = GNUNET_CRYPTO_cpabe_serialize_master_key (abh->abe_key,
+ (void**)&rd[0].data);
+ rd[0].record_type = GNUNET_GNSRECORD_TYPE_ABE_MASTER;
+ rd[0].flags = GNUNET_GNSRECORD_RF_NONE | GNUNET_GNSRECORD_RF_PRIVATE;
+ rd[0].expiration_time = GNUNET_TIME_UNIT_HOURS.rel_value_us; //TODO sane?
+ abh->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
+ &abh->identity,
+ "+",
+ 1,
+ rd,
+ &bootstrap_store_cont,
+ abh);
+}
+
+/**
+ * Error checking for ABE master
+ */
+static void
+bootstrap_abe_error (void *cls)
+{
+ struct AbeBootstrapHandle *abh = cls;
+ GNUNET_free (abh);
+ abh->proc (abh->proc_cls, NULL);
+ GNUNET_free (abh);
+}
+
+
+/**
+ * Handle ABE lookup in namestore
+ */
+static void
+bootstrap_abe_result (void *cls,
+ const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
+ const char *label,
+ unsigned int rd_count,
+ const struct GNUNET_GNSRECORD_Data *rd)
+{
+ struct AbeBootstrapHandle *abh = cls;
+ struct GNUNET_CRYPTO_AbeMasterKey *abe_key;
+ int i;
+
+ for (i=0;i<rd_count;i++) {
+ if (GNUNET_GNSRECORD_TYPE_ABE_MASTER != rd[i].record_type)
+ continue;
+ abe_key = GNUNET_CRYPTO_cpabe_deserialize_master_key ((void**)rd[i].data,
+ rd[i].data_size);
+ abh->proc (abh->proc_cls, abe_key);
+ GNUNET_free (abh);
+ return;
+ }
+
+ //No ABE master found, bootstrapping...
+ abh->abe_key = GNUNET_CRYPTO_cpabe_create_master_key ();
+ GNUNET_SCHEDULER_add_now (&bootstrap_store_task, abh);
+}
+
+/**
+ * Bootstrap ABE master if it does not yet exists.
+ * Will call the AbeBootstrapResult processor when done.
+ */
+static void
+bootstrap_abe (const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
+ AbeBootstrapResult proc,
+ void* cls)
+{
+ struct AbeBootstrapHandle *abh;
+
+ abh = GNUNET_new (struct AbeBootstrapHandle);
+ abh->proc = proc;
+ abh->proc_cls = cls;
+ abh->identity = *identity;
+ abh->ns_qe = GNUNET_NAMESTORE_records_lookup (ns_handle,
+ identity,
+ "+",
+ &bootstrap_abe_error,
+ abh,
+ &bootstrap_abe_result,
+ abh);
+
+}
+
+
static struct GNUNET_MQ_Envelope*
create_exchange_result_message (const char* token,
&handle_vattr_collection,
handle);
}
+
/**
* Collect attributes for token
*/
}
-/**
- * Checks an issue message
- *
- * @param cls client sending the message
- * @param im message of type `struct IssueMessage`
- * @return #GNUNET_OK if @a im is well-formed
- */
-static int
-check_issue_message(void *cls,
- const struct IssueMessage *im)
-{
- uint16_t size;
-
- size = ntohs (im->header.size);
- if (size <= sizeof (struct IssueMessage))
- {
- GNUNET_break (0);
- return GNUNET_SYSERR;
- }
- scopes = (char *) &im[1];
- if ('\0' != scopes[size - sizeof (struct IssueMessage) - 1])
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Malformed scopes received!\n");
- GNUNET_break (0);
- return GNUNET_SYSERR;
- }
- return GNUNET_OK;
-}
-
void
attr_collect_task (void *cls)
{
issue_handle);
}
-
-
void
abe_key_lookup_error (void *cls)
{
}
+
+/**
+ * Checks an issue message
+ *
+ * @param cls client sending the message
+ * @param im message of type `struct IssueMessage`
+ * @return #GNUNET_OK if @a im is well-formed
+ */
+static int
+check_issue_message(void *cls,
+ const struct IssueMessage *im)
+{
+ uint16_t size;
+
+ size = ntohs (im->header.size);
+ if (size <= sizeof (struct IssueMessage))
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ scopes = (char *) &im[1];
+ if ('\0' != scopes[size - sizeof (struct IssueMessage) - 1])
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Malformed scopes received!\n");
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ return GNUNET_OK;
+}
+
+
/**
*
* Handler for issue message
issue_handle);
}
+static void
+cleanup_ticket_issue_handle (struct TicketIssueHandle *handle)
+{
+ struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry *le;
+ struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry *tmp_le;
+
+ for (le = handle->attrs->list_head; NULL != le;)
+ {
+ GNUNET_free (le->attribute);
+ tmp_le = le;
+ le = le->next;
+ GNUNET_free (tmp_le);
+ }
+ GNUNET_free (handle->attrs);
+ if (NULL != handle->ns_qe)
+ GNUNET_NAMESTORE_cancel (handle->ns_qe);
+ GNUNET_free (handle);
+}
+
+static void
+store_ticket_issue_cont (void *cls,
+ int32_t success,
+ const char *emsg)
+{
+ struct GNUNET_IDENTITY_PROVIDER_Ticket2 *ticket;
+ struct TicketIssueHandle *handle = cls;
+ struct TicketResultMessage *irm;
+ struct GNUNET_MQ_Envelope *env;
+
+ handle->ns_qe = NULL;
+ if (GNUNET_SYSERR == success)
+ {
+ cleanup_ticket_issue_handle (handle);
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n",
+ "Unknown Error\n");
+ GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
+ return;
+ }
+ env = GNUNET_MQ_msg_extra (irm,
+ sizeof (struct GNUNET_IDENTITY_PROVIDER_Ticket2),
+ GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_RESULT);
+ ticket = (struct GNUNET_IDENTITY_PROVIDER_Ticket2 *)&irm[1];
+ *ticket = handle->ticket;
+ irm->id = handle->r_id;
+
+ GNUNET_MQ_send (handle->client->mq,
+ env);
+ cleanup_ticket_issue_handle (handle);
+}
+
+
+
+/**
+ * Checks a ticket issue message
+ *
+ * @param cls client sending the message
+ * @param im message of type `struct TicketIssueMessage`
+ * @return #GNUNET_OK if @a im is well-formed
+ */
+static int
+check_ticket_issue_message(void *cls,
+ const struct TicketIssueMessage *im)
+{
+ uint16_t size;
+
+ size = ntohs (im->header.size);
+ if (size <= sizeof (struct IssueMessage))
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ return GNUNET_OK;
+}
+
+int
+serialize_abe_keyinfo2 (const struct TicketIssueHandle *handle,
+ const struct GNUNET_CRYPTO_AbeKey *rp_key,
+ struct GNUNET_CRYPTO_EcdhePrivateKey **ecdh_privkey,
+ char **result)
+{
+ struct GNUNET_CRYPTO_EcdhePublicKey ecdh_pubkey;
+ struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry *le;
+ char *enc_keyinfo;
+ char *serialized_key;
+ char *buf;
+ char *write_ptr;
+ char attrs_str_len;
+ ssize_t size;
+
+ struct GNUNET_CRYPTO_SymmetricSessionKey skey;
+ struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
+ struct GNUNET_HashCode new_key_hash;
+ ssize_t enc_size;
+
+ size = GNUNET_CRYPTO_cpabe_serialize_key (rp_key,
+ (void**)&serialized_key);
+ attrs_str_len = 0;
+ for (le = handle->attrs->list_head; NULL != le; le = le->next) {
+ attrs_str_len += strlen (le->attribute->name) + 1;
+ }
+ buf = GNUNET_malloc (attrs_str_len + size);
+ write_ptr = buf;
+ for (le = handle->attrs->list_head; NULL != le; le = le->next) {
+ GNUNET_memcpy (write_ptr,
+ le->attribute->name,
+ strlen (le->attribute->name));
+ write_ptr[strlen (le->attribute->name)] = ',';
+ write_ptr += strlen (le->attribute->name) + 1;
+ }
+ write_ptr--;
+ write_ptr[0] = '\0'; //replace last , with a 0-terminator
+ write_ptr++;
+ GNUNET_memcpy (write_ptr,
+ serialized_key,
+ size);
+ // ECDH keypair E = eG
+ *ecdh_privkey = GNUNET_CRYPTO_ecdhe_key_create();
+ GNUNET_CRYPTO_ecdhe_key_get_public (*ecdh_privkey,
+ &ecdh_pubkey);
+ enc_keyinfo = GNUNET_malloc (size + attrs_str_len);
+ // Derived key K = H(eB)
+ GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecdh_ecdsa (*ecdh_privkey,
+ &handle->ticket.audience,
+ &new_key_hash));
+ create_sym_key_from_ecdh(&new_key_hash, &skey, &iv);
+ enc_size = GNUNET_CRYPTO_symmetric_encrypt (buf,
+ size + attrs_str_len,
+ &skey, &iv,
+ enc_keyinfo);
+ *result = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)+
+ enc_size);
+ GNUNET_memcpy (*result,
+ &ecdh_pubkey,
+ sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
+ GNUNET_memcpy (*result + sizeof (struct GNUNET_CRYPTO_EcdhePublicKey),
+ enc_keyinfo,
+ enc_size);
+ GNUNET_free (enc_keyinfo);
+ return sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)+enc_size;
+}
+
+
+
+static void
+issue_ticket_after_abe_bootstrap (void *cls,
+ struct GNUNET_CRYPTO_AbeMasterKey *abe_key)
+{
+ struct TicketIssueHandle *ih = cls;
+ struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry *le;
+ struct GNUNET_CRYPTO_EcdhePrivateKey *ecdhe_privkey;
+ struct GNUNET_GNSRECORD_Data code_record[1];
+ struct GNUNET_CRYPTO_AbeKey *rp_key;
+ char *code_record_data;
+ char **attrs;
+ char *label;
+ int attrs_len;
+ int i;
+ size_t code_record_len;
+
+ //Create new ABE key for RP
+ attrs_len = 0;
+ for (le = ih->attrs->list_head; NULL != le; le = le->next)
+ attrs_len++;
+ attrs = GNUNET_malloc (attrs_len);
+ i = 0;
+ for (le = ih->attrs->list_head; NULL != le; le = le->next) {
+ attrs[i] = (char*) le->attribute->name;
+ i++;
+ }
+ rp_key = GNUNET_CRYPTO_cpabe_create_key (abe_key,
+ attrs);
+
+ //TODO review this wireformat
+ code_record_len = serialize_abe_keyinfo2 (ih,
+ rp_key,
+ &ecdhe_privkey,
+ &code_record_data);
+ code_record[0].data = code_record_data;
+ code_record[0].data_size = code_record_len;
+ code_record[0].expiration_time = GNUNET_TIME_UNIT_DAYS.rel_value_us;
+ code_record[0].record_type = GNUNET_GNSRECORD_TYPE_ABE_KEY;
+ code_record[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
+
+ label = GNUNET_STRINGS_data_to_string_alloc (&ih->ticket.rnd,
+ sizeof (uint64_t));
+ //Publish record
+ ih->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
+ &ih->identity,
+ label,
+ 1,
+ code_record,
+ &store_ticket_issue_cont,
+ ih);
+ GNUNET_free (ecdhe_privkey);
+ GNUNET_free (label);
+ GNUNET_free (code_record_data);
+}
+
+
+/**
+ *
+ * Handler for ticket issue message
+ *
+ * @param cls unused
+ * @param client who sent the message
+ * @param message the message
+ */
+static void
+handle_ticket_issue_message (void *cls,
+ const struct TicketIssueMessage *im)
+{
+ struct TicketIssueHandle *ih;
+ struct IdpClient *idp = cls;
+ size_t attrs_len;
+
+ ih = GNUNET_new (struct TicketIssueHandle);
+ attrs_len = ntohs (im->attr_len);
+ ih->attrs = attribute_list_deserialize ((char*)&im[1], attrs_len);
+ ih->r_id = im->id;
+ ih->client = idp;
+ ih->identity = im->identity;
+ GNUNET_CRYPTO_ecdsa_key_get_public (&ih->identity,
+ &ih->ticket.identity);
+ ih->ticket.audience = im->rp;
+ ih->ticket.rnd =
+ GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG,
+ UINT64_MAX);
+ bootstrap_abe (&ih->identity, &issue_ticket_after_abe_bootstrap, ih);
+ GNUNET_SERVICE_client_continue (idp->client);
+
+}
+
+
+
static void
cleanup_as_handle (struct AttributeStoreHandle *handle)
{
return;
}
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Sending ATTRIBUTE_STORE_RESPONSE message\n");
+ GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
+ "Sending ATTRIBUTE_STORE_RESPONSE message\n");
env = GNUNET_MQ_msg (acr_msg,
- GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_STORE_RESPONSE);
+ GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_STORE_RESPONSE);
acr_msg->id = htonl (as_handle->r_id);
acr_msg->op_result = htonl (GNUNET_OK);
GNUNET_MQ_send (as_handle->client->mq,
char* buf;
size_t buf_size;
+ GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
+ "Storing attribute\n");
buf_size = attribute_serialize_get_size (as_handle->attribute);
buf = GNUNET_malloc (buf_size);
}
-static void
-bootstrap_store_cont (void *cls,
- int32_t success,
- const char *emsg)
-{
- struct AbeBootstrapHandle *abh = cls;
- if (GNUNET_SYSERR == success)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Failed to bootstrap ABE master %s\n",
- emsg);
- abh->proc (abh->proc_cls, NULL);
- GNUNET_free (abh->abe_key);
- GNUNET_free (abh);
- return;
- }
- abh->proc (abh->proc_cls, abh->abe_key);
- GNUNET_free (abh);
-}
-
-static void
-bootstrap_store_task (void *cls)
-{
- struct AbeBootstrapHandle *abh = cls;
- struct GNUNET_GNSRECORD_Data rd[1];
-
- rd[0].data_size = GNUNET_CRYPTO_cpabe_serialize_master_key (abh->abe_key,
- (void**)&rd[0].data);
- rd[0].record_type = GNUNET_GNSRECORD_TYPE_ABE_MASTER;
- rd[0].flags = GNUNET_GNSRECORD_RF_NONE | GNUNET_GNSRECORD_RF_PRIVATE;
- rd[0].expiration_time = GNUNET_TIME_UNIT_HOURS.rel_value_us; //TODO sane?
- abh->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
- &abh->identity,
- "+",
- 1,
- rd,
- &bootstrap_store_cont,
- abh);
-}
-
-static void
-bootstrap_abe_error (void *cls)
-{
- struct AbeBootstrapHandle *abh = cls;
- GNUNET_free (abh);
- abh->proc (abh->proc_cls, NULL);
- GNUNET_free (abh);
-}
-
-
-
-static void
-bootstrap_abe_result (void *cls,
- const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
- const char *label,
- unsigned int rd_count,
- const struct GNUNET_GNSRECORD_Data *rd)
-{
- struct AbeBootstrapHandle *abh = cls;
- struct GNUNET_CRYPTO_AbeMasterKey *abe_key;
- int i;
-
- for (i=0;i<rd_count;i++) {
- if (GNUNET_GNSRECORD_TYPE_ABE_MASTER != rd[i].record_type)
- continue;
- abe_key = GNUNET_CRYPTO_cpabe_deserialize_master_key ((void**)rd[i].data,
- rd[i].data_size);
- abh->proc (abh->proc_cls, abe_key);
- GNUNET_free (abh);
- return;
- }
-
- //No ABE master found, bootstrapping...
- abh->abe_key = GNUNET_CRYPTO_cpabe_create_master_key ();
- GNUNET_SCHEDULER_add_now (&bootstrap_store_task, abh);
-}
-
-static void
-bootstrap_abe (const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
- AbeBootstrapResult proc,
- void* cls)
-{
- struct AbeBootstrapHandle *abh;
-
- abh = GNUNET_new (struct AbeBootstrapHandle);
- abh->proc = proc;
- abh->proc_cls = cls;
- abh->identity = *identity;
- abh->ns_qe = GNUNET_NAMESTORE_records_lookup (ns_handle,
- identity,
- "+",
- &bootstrap_abe_error,
- abh,
- &bootstrap_abe_result,
- abh);
-
-}
static void
store_after_abe_bootstrap (void *cls,
struct GNUNET_CRYPTO_AbeMasterKey *abe_key)
{
+ GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
+ "Finished ABE bootstrap\n");
struct AttributeStoreHandle *ash = cls;
ash->abe_key = abe_key;
GNUNET_SCHEDULER_add_now (&attr_store_task, ash);
struct AttributeStoreHandle *as_handle;
struct IdpClient *idp = cls;
size_t data_len;
+ GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
+ "Received ATTRIBUTE_STORE message\n");
data_len = ntohs (sam->attr_len);
as_handle->attribute = attribute_deserialize ((char*)&sam[1],
data_len);
- as_handle->r_id = sam->id;
+ as_handle->r_id = ntohl (sam->id);
as_handle->identity = sam->identity;
GNUNET_CRYPTO_ecdsa_key_get_public (&sam->identity,
&as_handle->identity_pkey);
GNUNET_SERVICE_client_continue (idp->client);
as_handle->client = idp;
-
bootstrap_abe (&as_handle->identity, &store_after_abe_bootstrap, as_handle);
}
{
if (NULL != ai->abe_key)
GNUNET_free (ai->abe_key);
+ GNUNET_CONTAINER_DLL_remove (ai->client->op_head,
+ ai->client->op_tail,
+ ai);
GNUNET_free (ai);
}
GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_STOP,
struct AttributeIterationStopMessage,
NULL),
+ GNUNET_MQ_hd_var_size (ticket_issue_message,
+ GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ISSUE,
+ struct TicketIssueMessage,
+ NULL),
GNUNET_MQ_handler_end());
/* end of gnunet-service-identity-provider.c */
return attr;
}
+size_t
+attribute_list_serialize_get_size (const struct GNUNET_IDENTITY_PROVIDER_AttributeList *attrs)
+{
+ struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry *le;
+ size_t len = 0;
+ for (le = attrs->list_head; NULL != le; le = le->next)
+ len += attribute_serialize_get_size (le->attribute);
+ return len;
+}
+
+size_t
+attribute_list_serialize (const struct GNUNET_IDENTITY_PROVIDER_AttributeList *attrs,
+ char *result)
+{
+ struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry *le;
+ 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 = attribute_serialize (le->attribute,
+ write_ptr);
+ total_len += len;
+ write_ptr += len;
+ }
+ return total_len;
+}
+
+struct GNUNET_IDENTITY_PROVIDER_AttributeList *
+attribute_list_deserialize (const char* data,
+ size_t data_size)
+{
+ struct GNUNET_IDENTITY_PROVIDER_AttributeList *attrs;
+ struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry *le;
+ size_t attr_len;
+ const char* read_ptr;
+
+ if (data_size < sizeof (struct Attribute))
+ return NULL;
+
+ attrs = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_AttributeList);
+ read_ptr = data;
+ while (((data + data_size) - read_ptr) >= sizeof (struct Attribute))
+ {
+ le = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry);
+ le->attribute = attribute_deserialize (read_ptr,
+ data_size - (read_ptr - data));
+ attr_len = attribute_serialize_get_size (le->attribute);
+ read_ptr += attr_len;
+ }
+ return attrs;
+}
+
size_t
attribute_serialize_get_size (const struct GNUNET_IDENTITY_PROVIDER_Attribute *attr)
{
return sizeof (struct Attribute)
- + strlen (attr->name) + 1
+ + strlen (attr->name)
+ attr->data_size; //TODO get data_size from plugin
}
-int
+size_t
attribute_serialize (const struct GNUNET_IDENTITY_PROVIDER_Attribute *attr,
char *result)
{
GNUNET_memcpy (write_ptr, attr->data, attr->data_size);
attr_ser->data_size = htons (data_len_ser);
- return GNUNET_OK;
+ return sizeof (struct Attribute) + strlen (attr->name) + attr->data_size;
}
struct GNUNET_IDENTITY_PROVIDER_Attribute *
size_t data_len;
size_t name_len;
char* write_ptr;
-
+
if (data_size < sizeof (struct Attribute))
return NULL;
data_len = ntohs (attr_ser->data_size);
name_len = ntohs (attr_ser->name_len);
attr = GNUNET_malloc (sizeof (struct GNUNET_IDENTITY_PROVIDER_Attribute)
- + data_len + name_len + 1);
+ + data_len + name_len + 1);
attr->attribute_type = ntohs (attr_ser->attribute_type);
attr->data_size = ntohs (attr_ser->data_size);
-
+
write_ptr = (char*)&attr[1];
GNUNET_memcpy (write_ptr,
&attr_ser[1],
//followed by data_size Attribute value data
};
+/**
+ * Get required size for serialization buffer
+ *
+ * @param attrs the attribute list to serialize
+ *
+ * @return the required buffer size
+ */
+size_t
+attribute_list_serialize_get_size (const struct GNUNET_IDENTITY_PROVIDER_AttributeList *attrs);
+
+
+
+/**
+ * Serialize an attribute list
+ *
+ * @param attrs the attribute list to serialize
+ * @param result the serialized attribute
+ *
+ * @return length of serialized data
+ */
+size_t
+attribute_list_serialize (const struct GNUNET_IDENTITY_PROVIDER_AttributeList *attrs,
+ char *result);
+
+/**
+ * Deserialize an attribute list
+ *
+ * @param data the serialized attribute list
+ * @param data_size the length of the serialized data
+ *
+ * @return a GNUNET_IDENTITY_PROVIDER_AttributeList, must be free'd by caller
+ */
+struct GNUNET_IDENTITY_PROVIDER_AttributeList *
+attribute_list_deserialize (const char* data,
+ size_t data_size);
+
+
/**
* Get required size for serialization buffer
*
* @param attr the attribute to serialize
* @param result the serialized attribute
*
- * @return GNUNET_OK on success
+ * @return length of serialized data
*/
-int
+size_t
attribute_serialize (const struct GNUNET_IDENTITY_PROVIDER_Attribute *attr,
char *result);
};
/**
- * The ticket
+ * The ticket DEPRECATED
*/
struct GNUNET_IDENTITY_PROVIDER_Ticket
{
};
+/**
+ * Ticket issue message
+ */
+struct TicketIssueMessage
+{
+ /**
+ * Type will be #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ISSUE
+ */
+ struct GNUNET_MessageHeader header;
+
+ /**
+ * Unique identifier for this request (for key collisions).
+ */
+ uint32_t id GNUNET_PACKED;
+
+ /**
+ * Identity.
+ */
+ struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
+
+ /**
+ * Requesting party.
+ */
+ struct GNUNET_CRYPTO_EcdsaPublicKey rp;
+ /**
+ * length of serialized attribute list
+ */
+ uint32_t attr_len GNUNET_PACKED;
+
+ //Followed by a serialized attribute list
+};
+
+/**
+ * Ticket result message
+ */
+struct TicketResultMessage
+{
+ /**
+ * Type will be #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_RESULT
+ */
+ struct GNUNET_MessageHeader header;
+
+ /**
+ * Unique identifier for this request (for key collisions).
+ */
+ uint32_t id GNUNET_PACKED;
+
+};
GNUNET_NETWORK_STRUCT_END
#endif
*/
GNUNET_IDENTITY_PROVIDER_ContinuationWithStatus as_cb;
+ /**
+ * Ticket result callback
+ */
+ GNUNET_IDENTITY_PROVIDER_TicketCallback tr_cb;
+
/**
* Envelope with the message for this queue entry.
*/
GNUNET_assert (0);
}
+/**
+ * Handle an incoming message of type
+ * #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_RESULT
+ *
+ * @param cls
+ * @param msg the message we received
+ * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
+ */
+static int
+check_ticket_result (void *cls,
+ const struct TicketResultMessage *msg)
+{
+ size_t msg_len;
+
+ msg_len = ntohs (msg->header.size);
+ if (msg_len < sizeof (struct TicketResultMessage))
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ return GNUNET_OK;
+}
+
+
+
+/**
+ * Handle an incoming message of type
+ * #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_RESULT
+ *
+ * @param cls
+ * @param msg the message we received
+ */
+static void
+handle_ticket_result (void *cls,
+ const struct TicketResultMessage *msg)
+{
+ struct GNUNET_IDENTITY_PROVIDER_Handle *handle = cls;
+ struct GNUNET_IDENTITY_PROVIDER_Operation *op;
+ const struct GNUNET_IDENTITY_PROVIDER_Ticket2 *ticket;
+ uint32_t r_id = ntohl (msg->id);
+
+ for (op = handle->op_head; NULL != op; op = op->next)
+ if (op->r_id == r_id)
+ break;
+ if (NULL == op)
+ return;
+ GNUNET_CONTAINER_DLL_remove (handle->op_head,
+ handle->op_tail,
+ op);
+ ticket = (struct GNUNET_IDENTITY_PROVIDER_Ticket2 *)&msg[1];
+ if (NULL != op->tr_cb)
+ op->tr_cb (op->cls, ticket);
+ GNUNET_free (op);
+
+}
+
/**
GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_RESULT,
struct AttributeResultMessage,
h),
+ GNUNET_MQ_hd_var_size (ticket_result,
+ GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_RESULT,
+ struct TicketResultMessage,
+ h),
GNUNET_MQ_handler_end ()
};
struct GNUNET_IDENTITY_PROVIDER_Operation *op;
}
+/** TODO
+ * Issues a ticket to another identity. The identity may use
+ * @GNUNET_IDENTITY_PROVIDER_authorization_ticket_consume to consume the ticket
+ * and retrieve the attributes specified in the AttributeList.
+ *
+ * @param h the identity provider to use
+ * @param iss the issuing identity
+ * @param rp the subject of the ticket (the relying party)
+ * @param attr the attributes that the relying party is given access to
+ * @param cb the callback
+ * @param cb_cls the callback closure
+ * @return handle to abort the operation
+ */
+struct GNUNET_IDENTITY_PROVIDER_Operation *
+GNUNET_IDENTITY_PROVIDER_idp_ticket_issue (struct GNUNET_IDENTITY_PROVIDER_Handle *h,
+ const struct GNUNET_CRYPTO_EcdsaPrivateKey *iss,
+ const struct GNUNET_CRYPTO_EcdsaPublicKey *rp,
+ const struct GNUNET_IDENTITY_PROVIDER_AttributeList *attrs,
+ GNUNET_IDENTITY_PROVIDER_TicketCallback cb,
+ void *cb_cls)
+{
+ struct GNUNET_IDENTITY_PROVIDER_Operation *op;
+ struct TicketIssueMessage *tim;
+ size_t attr_len;
+
+ op = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_Operation);
+ op->h = h;
+ op->tr_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);
+ attr_len = attribute_list_serialize_get_size (attrs);
+ op->env = GNUNET_MQ_msg_extra (tim,
+ attr_len,
+ GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ISSUE);
+ tim->identity = *iss;
+ tim->rp = *rp;
+ tim->id = htonl (op->r_id);
+
+ attribute_list_serialize (attrs,
+ (char*)&tim[1]);
+
+ tim->attr_len = htons (attr_len);
+ if (NULL != h->mq)
+ GNUNET_MQ_send_copy (h->mq,
+ op->env);
+ return op;
+}
+
- /* end of identity_provider_api.c */
+/* end of identity_provider_api.c */
#!/bin/bash
-trap "gnunet-arm -e -c test_idp_lookup.conf" SIGINT
+#trap "gnunet-arm -e -c test_idp_lookup.conf" SIGINT
LOCATION=$(which gnunet-config)
if [ -z $LOCATION ]
TEST_ATTR="test"
gnunet-arm -s -c test_idp.conf
gnunet-identity -C testego -c test_idp.conf
-gnunet-idp -e testego --init -c test_idp.conf
-gnunet-idp -e testego -a email -V john@doe.gnu -c test_idp.conf
+valgrind gnunet-idp -e testego -a email -V john@doe.gnu -c test_idp.conf
gnunet-idp -e testego -a name -V John -c test_idp.conf
gnunet-idp -e testego -D -c test_idp.conf
gnunet-arm -e -c test_idp.conf
--- /dev/null
+#!/bin/bash
+trap "gnunet-arm -e -c test_idp_lookup.conf" SIGINT
+
+LOCATION=$(which gnunet-config)
+if [ -z $LOCATION ]
+then
+ LOCATION="gnunet-config"
+fi
+$LOCATION --version 1> /dev/null
+if test $? != 0
+then
+ echo "GNUnet command line tools cannot be found, check environmental variables PATH and GNUNET_PREFIX"
+ exit 77
+fi
+
+rm -rf `gnunet-config -c test_idp.conf -s PATHS -o GNUNET_HOME -f`
+
+# (1) PKEY1.user -> PKEY2.resu.user
+# (2) PKEY2.resu -> PKEY3
+# (3) PKEY3.user -> PKEY4
+
+
+which timeout &> /dev/null && DO_TIMEOUT="timeout 30"
+
+TEST_ATTR="test"
+gnunet-arm -s -c test_idp.conf
+gnunet-identity -C testego -c test_idp.conf
+gnunet-identity -C rpego -c test_idp.conf
+SUBJECT_KEY=$(gnunet-identity -d -c test_idp.conf | grep rpego | awk '{print $3}')
+gnunet-idp -e testego -a email -V john@doe.gnu -c test_idp.conf
+gnunet-idp -e testego -a name -V John -c test_idp.conf
+gnunet-idp -e testego -D -c test_idp.conf
+gnunet-idp -e testego -i "email,name" -r $SUBJECT_KEY -c test_idp.conf
+gnunet-namestore -z testego -D -c test_idp.conf
+gnunet-arm -e -c test_idp.conf
struct GNUNET_IDENTITY_PROVIDER_Token;
/**
- * Handle for a ticket
+ * Handle for a ticket DEPRECATED
*/
struct GNUNET_IDENTITY_PROVIDER_Ticket;
+/**
+ * The ticket
+ */
+struct GNUNET_IDENTITY_PROVIDER_Ticket2
+{
+ /**
+ * The ticket issuer
+ */
+ struct GNUNET_CRYPTO_EcdsaPublicKey identity;
+
+ /**
+ * The ticket audience
+ */
+ struct GNUNET_CRYPTO_EcdsaPublicKey audience;
+
+ /**
+ * The ticket random (NBO)
+ */
+ uint64_t rnd;
+};
+
/**
* Handle for an operation with the identity provider service.
*/
};
+struct GNUNET_IDENTITY_PROVIDER_AttributeList
+{
+ /**
+ * List head
+ */
+ struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry *list_head;
+ /**
+ * List tail
+ */
+ struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry *list_tail;
+};
+
+struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry
+{
+ /**
+ * DLL
+ */
+ struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry *prev;
+
+ /**
+ * DLL
+ */
+ struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry *next;
+
+ /**
+ * The attribute
+ */
+ struct GNUNET_IDENTITY_PROVIDER_Attribute *attribute;
+};
/**
* Method called when a token has been exchanged for a ticket.
GNUNET_IDENTITY_PROVIDER_get_attributes_stop (struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *it);
+/**
+ * Method called when a token has been issued.
+ * On success returns a ticket that can be given to the audience to retrive the
+ * token
+ *
+ * @param cls closure
+ * @param grant the label in GNS pointing to the token
+ * @param ticket the ticket
+ * @param token the issued token
+ * @param name name assigned by the user for this ego,
+ * NULL if the user just deleted the ego and it
+ * must thus no longer be used
+ */
+typedef void
+(*GNUNET_IDENTITY_PROVIDER_TicketCallback)(void *cls,
+ const struct GNUNET_IDENTITY_PROVIDER_Ticket2 *ticket);
+
+
+/** TODO
+ * Issues a ticket to another identity. The identity may use
+ * @GNUNET_IDENTITY_PROVIDER_authorization_ticket_consume to consume the ticket
+ * and retrieve the attributes specified in the AttributeList.
+ *
+ * @param id the identity provider to use
+ * @param iss the issuing identity
+ * @param rp the subject of the ticket (the relying party)
+ * @param attr the attributes that the relying party is given access to
+ * @param cb the callback
+ * @param cb_cls the callback closure
+ * @return handle to abort the operation
+ */
+struct GNUNET_IDENTITY_PROVIDER_Operation *
+GNUNET_IDENTITY_PROVIDER_idp_ticket_issue (struct GNUNET_IDENTITY_PROVIDER_Handle *id,
+ const struct GNUNET_CRYPTO_EcdsaPrivateKey *iss,
+ const struct GNUNET_CRYPTO_EcdsaPublicKey *rp,
+ const struct GNUNET_IDENTITY_PROVIDER_AttributeList *attrs,
+ GNUNET_IDENTITY_PROVIDER_TicketCallback cb,
+ void *cb_cls);
+
+/** TODO
+ * Revoked an issued ticket. The relying party will be unable to retrieve
+ * updated attributes.
+ *
+ * @param id the identity provider to use
+ * @param identity the issuing identity
+ * @param ticket the ticket to revoke
+ * @param cb the callback
+ * @param cb_cls the callback closure
+ * @return handle to abort the operation
+ */
+struct GNUNET_IDENTITY_PROVIDER_Operation *
+GNUNET_IDENTITY_PROVIDER_idp_ticket_revoke (struct GNUNET_IDENTITY_PROVIDER_Handle *id,
+ const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
+ const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket,
+ GNUNET_IDENTITY_PROVIDER_ContinuationWithStatus cb,
+ void *cb_cls);
+
+
+
+/** TODO
+ * Consumes an issued ticket. The ticket is persisted
+ * and used to retrieve identity information from the issuer
+ *
+ * @param id the identity provider to use
+ * @param identity the identity that is the subject of the issued ticket (the relying party)
+ * @param ticket the issued ticket to consume
+ * @param cb the callback to call
+ * @param cb_cls the callback closure
+ * @return handle to abort the operation
+ */
+struct GNUNET_IDENTITY_PROVIDER_Operation *
+GNUNET_IDENTITY_PROVIDER_rp_ticket_consume (struct GNUNET_IDENTITY_PROVIDER_Handle *id,
+ const struct GNUNET_CRYPTO_EcdsaPrivateKey * identity,
+ const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket,
+ GNUNET_IDENTITY_PROVIDER_AttributeResult cb,
+ void *cb_cls);
+
+/** TODO
+ * Lists all tickets that have been issued to remote
+ * identites (relying parties)
+ *
+ * @param id the identity provider to use
+ * @param identity the issuing identity
+ * @param cb the callback to use
+ * @param cb_cls the callback closure
+ * @return handle to abort the operation
+ */
+struct GNUNET_IDENTITY_PROVIDER_Operation *
+GNUNET_IDENTITY_PROVIDER_idp_tickets_list (struct GNUNET_IDENTITY_PROVIDER_Handle *id,
+ const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
+ GNUNET_IDENTITY_PROVIDER_TicketCallback *cb,
+ void *cb_cls);
+
+/** TODO
+ * Lists all attributes that are shared with this identity
+ * by remote parties
+ *
+ * @param id identity provider service to use
+ * @param identity the identity (relying party)
+ * @param cb the result callback
+ * @param cb_cls the result callback closure
+ * @return handle to abort the operation
+ */
+struct GNUNET_IDENTITY_PROVIDER_Operation *
+GNUNET_IDENTITY_PROVIDER_rp_attributes_list (struct GNUNET_IDENTITY_PROVIDER_Handle *id,
+ const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
+ GNUNET_IDENTITY_PROVIDER_AttributeResult *cb,
+ void *cb_cls);
/**
* Issue a token for a specific audience.
#define GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_RESULT 970
+#define GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ISSUE 971
+
+#define GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_RESULT 972
+
/**************************************************
*
* CREDENTIAL MESSAGE TYPES
*/
-#define GNUNET_MESSAGE_TYPE_CREDENTIAL_VERIFY 971
+#define GNUNET_MESSAGE_TYPE_CREDENTIAL_VERIFY 981
-#define GNUNET_MESSAGE_TYPE_CREDENTIAL_VERIFY_RESULT 972
+#define GNUNET_MESSAGE_TYPE_CREDENTIAL_VERIFY_RESULT 982
-#define GNUNET_MESSAGE_TYPE_CREDENTIAL_COLLECT 973
+#define GNUNET_MESSAGE_TYPE_CREDENTIAL_COLLECT 983
-#define GNUNET_MESSAGE_TYPE_CREDENTIAL_COLLECT_RESULT 974
+#define GNUNET_MESSAGE_TYPE_CREDENTIAL_COLLECT_RESULT 984
/******************************************************************************/