#include "gnunet_identity_service.h"
#include "gnunet_gnsrecord_lib.h"
#include "gnunet_namestore_service.h"
+#include "gnunet_abe_lib.h"
+#include "gnunet_credential_service.h"
#include "gnunet_statistics_service.h"
#include "gnunet_gns_service.h"
+#include "gnunet_identity_provider_plugin.h"
+#include "gnunet_identity_attribute_lib.h"
#include "gnunet_signatures.h"
#include "identity_provider.h"
-#include "identity_token.h"
/**
* First pass state
#define DEFAULT_TOKEN_EXPIRATION_INTERVAL GNUNET_TIME_UNIT_HOURS
/**
- * Service state (to detect initial update pass)
- */
-static int state;
-
-/**
- * Head of ego entry DLL
+ * Identity handle
*/
-static struct EgoEntry *ego_head;
+static struct GNUNET_IDENTITY_Handle *identity_handle;
/**
- * Tail of ego entry DLL
+ * Database handle
*/
-static struct EgoEntry *ego_tail;
+static struct GNUNET_IDENTITY_PROVIDER_PluginFunctions *TKT_database;
/**
- * Identity handle
+ * Name of DB plugin
*/
-static struct GNUNET_IDENTITY_Handle *identity_handle;
+static char *db_lib_name;
/**
* Token expiration interval
*/
static struct GNUNET_GNS_Handle *gns_handle;
+/**
+ * Credential handle
+ */
+static struct GNUNET_CREDENTIAL_Handle *credential_handle;
+
/**
* Namestore qe
*/
/**
* Timeout task
*/
-static struct GNUNET_SCHEDULER_Task * timeout_task;
-
+static struct GNUNET_SCHEDULER_Task *timeout_task;
/**
* Update task
*/
-static struct GNUNET_SCHEDULER_Task * update_task;
-
-/**
- * Timeout for next update pass
- */
-static struct GNUNET_TIME_Relative min_rel_exp;
+static struct GNUNET_SCHEDULER_Task *update_task;
/**
static char* scopes;
/**
- * Expiration for processed token
+ * Handle to the statistics service.
*/
-static uint64_t rd_exp;
+static struct GNUNET_STATISTICS_Handle *stats;
/**
- * ECDHE Privkey for processed token metadata
+ * Our configuration.
*/
-static struct GNUNET_CRYPTO_EcdhePrivateKey ecdhe_privkey;
+static const struct GNUNET_CONFIGURATION_Handle *cfg;
/**
- * Handle to the statistics service.
+ * An idp client
*/
-static struct GNUNET_STATISTICS_Handle *stats;
+struct IdpClient;
/**
- * Notification context, simplifies client broadcasts.
+ * A ticket iteration operation.
*/
-static struct GNUNET_SERVER_NotificationContext *nc;
+struct TicketIteration
+{
+ /**
+ * DLL
+ */
+ struct TicketIteration *next;
+
+ /**
+ * DLL
+ */
+ struct TicketIteration *prev;
+
+ /**
+ * Client which intiated this zone iteration
+ */
+ struct IdpClient *client;
+
+ /**
+ * Key of the identity we are iterating over.
+ */
+ struct GNUNET_CRYPTO_EcdsaPublicKey identity;
+
+ /**
+ * Identity is audience
+ */
+ uint32_t is_audience;
+
+ /**
+ * The operation id fot the iteration in the response for the client
+ */
+ uint32_t r_id;
+
+ /**
+ * Offset of the iteration used to address next result of the
+ * iteration in the store
+ *
+ * Initialy set to 0 in handle_iteration_start
+ * Incremented with by every call to handle_iteration_next
+ */
+ uint32_t offset;
+
+};
+
+
/**
- * Our configuration.
+ * Callback after an ABE bootstrap
+ *
+ * @param cls closure
+ * @param abe_key the ABE key that exists or was created
*/
-static const struct GNUNET_CONFIGURATION_Handle *cfg;
+typedef void
+(*AbeBootstrapResult) (void *cls,
+ struct GNUNET_ABE_AbeMasterKey *abe_key);
+
+
+struct AbeBootstrapHandle
+{
+ /**
+ * Function to call when finished
+ */
+ AbeBootstrapResult proc;
+
+ /**
+ * Callback closure
+ */
+ char *proc_cls;
+
+ /**
+ * Key of the zone we are iterating over.
+ */
+ struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
+
+ /**
+ * Namestore Queue Entry
+ */
+ struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
+
+ /**
+ * The issuer egos ABE master key
+ */
+ struct GNUNET_ABE_AbeMasterKey *abe_key;
+};
+
+/**
+ * An attribute iteration operation.
+ */
+struct AttributeIterator
+{
+ /**
+ * Next element in the DLL
+ */
+ struct AttributeIterator *next;
+
+ /**
+ * Previous element in the DLL
+ */
+ struct AttributeIterator *prev;
+
+ /**
+ * IDP client which intiated this zone iteration
+ */
+ struct IdpClient *client;
+
+ /**
+ * Key of the zone we are iterating over.
+ */
+ struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
+
+ /**
+ * The issuer egos ABE master key
+ */
+ struct GNUNET_ABE_AbeMasterKey *abe_key;
+
+ /**
+ * Namestore iterator
+ */
+ struct GNUNET_NAMESTORE_ZoneIterator *ns_it;
+
+ /**
+ * The operation id fot the zone iteration in the response for the client
+ */
+ uint32_t request_id;
+
+};
+
+
+
+/**
+ * An idp client
+ */
+struct IdpClient
+{
+
+ /**
+ * The client
+ */
+ struct GNUNET_SERVICE_Client *client;
+
+ /**
+ * Message queue for transmission to @e client
+ */
+ struct GNUNET_MQ_Handle *mq;
+
+ /**
+ * Head of the DLL of
+ * Attribute iteration operations in
+ * progress initiated by this client
+ */
+ struct AttributeIterator *op_head;
+
+ /**
+ * Tail of the DLL of
+ * Attribute iteration operations
+ * in progress initiated by this client
+ */
+ struct AttributeIterator *op_tail;
+
+ /**
+ * Head of DLL of ticket iteration ops
+ */
+ struct TicketIteration *ticket_iter_head;
+
+ /**
+ * Tail of DLL of ticket iteration ops
+ */
+ struct TicketIteration *ticket_iter_tail;
+
+
+ /**
+ * Head of DLL of ticket revocation ops
+ */
+ struct TicketRevocationHandle *revocation_list_head;
+
+ /**
+ * Tail of DLL of ticket revocation ops
+ */
+ struct TicketRevocationHandle *revocation_list_tail;
+};
+
-struct ExchangeHandle
+struct AttributeStoreHandle
{
/**
* Client connection
*/
- struct GNUNET_SERVER_Client *client;
+ struct IdpClient *client;
/**
- * Ticket
+ * Identity
+ */
+ struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
+
+ /**
+ * Identity pubkey
+ */
+ struct GNUNET_CRYPTO_EcdsaPublicKey identity_pkey;
+
+ /**
+ * The issuer egos ABE master key
+ */
+ struct GNUNET_ABE_AbeMasterKey *abe_key;
+
+ /**
+ * QueueEntry
+ */
+ struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
+
+ /**
+ * The attribute to store
+ */
+ struct GNUNET_IDENTITY_ATTRIBUTE_Claim *claim;
+
+ /**
+ * request id
+ */
+ uint32_t r_id;
+};
+
+
+/* Prototype */
+struct ParallelLookup;
+
+struct ConsumeTicketHandle
+{
+
+ /**
+ * Client connection
*/
- struct TokenTicket *ticket;
+ struct IdpClient *client;
/**
- * Token returned
+ * Ticket
*/
- struct IdentityToken *token;
+ struct GNUNET_IDENTITY_PROVIDER_Ticket ticket;
/**
* LookupRequest
*/
struct GNUNET_GNS_LookupRequest *lookup_request;
-
+
/**
* Audience Key
*/
- struct GNUNET_CRYPTO_EcdsaPrivateKey aud_privkey;
+ struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
+
+ /**
+ * Audience Key
+ */
+ struct GNUNET_CRYPTO_EcdsaPublicKey identity_pub;
+
+ /**
+ * Lookup DLL
+ */
+ struct ParallelLookup *parallel_lookups_head;
+
+ /**
+ * Lookup DLL
+ */
+ struct ParallelLookup *parallel_lookups_tail;
+
+ /**
+ * Kill task
+ */
+ struct GNUNET_SCHEDULER_Task *kill_task;
+
+ /**
+ * The ABE key
+ */
+ struct GNUNET_ABE_AbeKey *key;
+
+ /**
+ * Attributes
+ */
+ struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs;
+
+ /**
+ * Lookup time
+ */
+ struct GNUNET_TIME_Absolute lookup_start_time;
+
+ /**
+ * request id
+ */
+ uint32_t r_id;
+};
+
+/**
+ * Handle for a parallel GNS lookup job
+ */
+struct ParallelLookup
+{
+ /* DLL */
+ struct ParallelLookup *next;
+
+ /* DLL */
+ struct ParallelLookup *prev;
+
+ /* The GNS request */
+ struct GNUNET_GNS_LookupRequest *lookup_request;
+
+ /* The handle the return to */
+ struct ConsumeTicketHandle *handle;
/**
- * Label to return
+ * Lookup time
*/
+ struct GNUNET_TIME_Absolute lookup_start_time;
+
+ /* The label to look up */
char *label;
};
-struct IssueHandle
+/**
+ * Ticket revocation request handle
+ */
+struct TicketRevocationHandle
{
+ /**
+ * DLL
+ */
+ struct TicketRevocationHandle *next;
+
+ /**
+ * DLL
+ */
+ struct TicketRevocationHandle *prev;
/**
* Client connection
*/
- struct GNUNET_SERVER_Client *client;
+ struct IdpClient *client;
+
+ /**
+ * Attributes to reissue
+ */
+ struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs;
+
+ /**
+ * Attributes to revoke
+ */
+ struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *rvk_attrs;
/**
* Issuer Key
*/
- struct GNUNET_CRYPTO_EcdsaPrivateKey iss_key;
+ struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
/**
- * Issue pubkey
+ * Ticket to issue
*/
- struct GNUNET_CRYPTO_EcdsaPublicKey iss_pkey;
+ struct GNUNET_IDENTITY_PROVIDER_Ticket ticket;
/**
- * Audience Key
+ * QueueEntry
*/
- struct GNUNET_CRYPTO_EcdsaPublicKey aud_key;
+ struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
/**
- * Expiration
+ * Namestore iterator
*/
- struct GNUNET_TIME_Absolute expiration;
+ struct GNUNET_NAMESTORE_ZoneIterator *ns_it;
/**
- * Scopes
+ * The ABE master key
*/
- char *scopes;
+ struct GNUNET_ABE_AbeMasterKey *abe_key;
/**
- * nonce
+ * Offset
*/
- uint64_t nonce;
+ uint32_t offset;
/**
- * NS iterator
+ * request id
*/
- struct GNUNET_NAMESTORE_ZoneIterator *ns_it;
+ uint32_t r_id;
+};
+
+
+
+/**
+ * Ticket issue request handle
+ */
+struct TicketIssueHandle
+{
/**
- * Attribute map
+ * Client connection
*/
- struct GNUNET_CONTAINER_MultiHashMap *attr_map;
+ struct IdpClient *client;
/**
- * Token
+ * Attributes to issue
*/
- struct IdentityToken *token;
+ struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs;
/**
- * Ticket
+ * Issuer Key
+ */
+ struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
+
+ /**
+ * Ticket to issue
*/
- struct TokenTicket *ticket;
+ struct GNUNET_IDENTITY_PROVIDER_Ticket ticket;
/**
* QueueEntry
struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
/**
- * The label the token is stored under
+ * request id
*/
- char *label;
+ uint32_t r_id;
};
+
/**
* DLL for ego handles to egos containing the ID_ATTRS in a map in json_t format
*
*/
struct GNUNET_CONTAINER_MultiHashMap *attr_map;
- /**
- * Attributes are old and should be updated if GNUNET_YES
- */
- int attributes_dirty;
};
/**
- * Continuation for token store call
- *
- * @param cls NULL
- * @param success error code
- * @param emsg error message
+ * Cleanup task
*/
static void
-store_token_cont (void *cls,
- int32_t success,
- const char *emsg)
+cleanup()
{
- ns_qe = NULL;
- if (GNUNET_SYSERR == success)
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Cleaning up\n");
+ if (NULL != stats)
{
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Failed to update token: %s\n",
- emsg);
- return;
+ GNUNET_STATISTICS_destroy (stats, GNUNET_NO);
+ stats = NULL;
}
- GNUNET_NAMESTORE_zone_iterator_next (ns_it);
-}
-
-
-/**
- * This function updates the old token with new attributes,
- * removes deleted attributes and expiration times.
- *
- * @param cls the ego entry
- * @param tc task context
- */
-static void
-handle_token_update (void *cls,
- const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
- char *token_metadata;
- char *write_ptr;
- char *enc_token_str;
- const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key;
- struct GNUNET_CRYPTO_EcdsaPublicKey pub_key;
- struct GNUNET_CRYPTO_EcdhePrivateKey *new_ecdhe_privkey;
- struct EgoEntry *ego_entry = cls;
- struct GNUNET_GNSRECORD_Data token_record[2];
- struct GNUNET_HashCode key_hash;
- struct GNUNET_TIME_Relative token_rel_exp;
- struct GNUNET_TIME_Relative token_ttl;
- struct GNUNET_TIME_Absolute token_exp;
- struct GNUNET_TIME_Absolute token_nbf;
- struct GNUNET_TIME_Absolute new_exp;
- struct GNUNET_TIME_Absolute new_iat;
- struct GNUNET_TIME_Absolute new_nbf;
- struct IdentityToken *new_token;
- struct TokenAttr *cur_value;
- struct TokenAttr *attr;
- size_t token_metadata_len;
-
- priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
- GNUNET_IDENTITY_ego_get_public_key (ego_entry->ego,
- &pub_key);
-
- //Note: We need the token expiration time here. Not the record expiration
- //time.
- //There are two types of tokens: Token that expire on GNS level with
- //an absolute expiration time. Those are basically tokens that will
- //be automatically revoked on (record)expiration.
- //Tokens stored with relative expiration times will expire on the token level (token expiration)
- //but this service will reissue new tokens that can be retrieved from GNS
- //automatically.
-
- for (attr = token->attr_head; NULL != attr; attr = attr->next)
- {
- if (0 == strcmp (attr->name, "exp"))
- {
- sscanf (attr->val_head->value,
- "%lu",
- &token_exp.abs_value_us);
- } else if (0 == strcmp (attr->name, "nbf")) {
- sscanf (attr->val_head->value,
- "%lu",
- &token_nbf.abs_value_us);
- }
- }
- token_rel_exp = GNUNET_TIME_absolute_get_difference (token_nbf, token_exp);
+ GNUNET_break (NULL == GNUNET_PLUGIN_unload (db_lib_name,
+ TKT_database));
+ GNUNET_free (db_lib_name);
+ db_lib_name = NULL;
+ if (NULL != timeout_task)
+ GNUNET_SCHEDULER_cancel (timeout_task);
+ if (NULL != update_task)
+ GNUNET_SCHEDULER_cancel (update_task);
+ if (NULL != identity_handle)
+ GNUNET_IDENTITY_disconnect (identity_handle);
+ if (NULL != gns_handle)
+ GNUNET_GNS_disconnect (gns_handle);
+ if (NULL != credential_handle)
+ GNUNET_CREDENTIAL_disconnect (credential_handle);
+ if (NULL != ns_it)
+ GNUNET_NAMESTORE_zone_iteration_stop (ns_it);
+ if (NULL != ns_qe)
+ GNUNET_NAMESTORE_cancel (ns_qe);
+ if (NULL != ns_handle)
+ GNUNET_NAMESTORE_disconnect (ns_handle);
+ GNUNET_free_non_null (token);
+ GNUNET_free_non_null (label);
+
+}
+
+/**
+ * Shutdown task
+ *
+ * @param cls NULL
+ */
+static void
+do_shutdown (void *cls)
+{
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Shutting down...\n");
+ cleanup();
+}
- token_ttl = GNUNET_TIME_absolute_get_remaining (token_exp);
- if (0 != GNUNET_TIME_absolute_get_remaining (token_exp).rel_value_us)
+/**
+ * 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)
{
- //This token is not yet expired! Save and skip
- if (min_rel_exp.rel_value_us > token_ttl.rel_value_us)
- {
- min_rel_exp = token_ttl;
- }
- GNUNET_free (token);
- token = NULL;
- GNUNET_free (label);
- label = NULL;
- GNUNET_free (scopes);
- scopes = NULL;
- GNUNET_NAMESTORE_zone_iterator_next (ns_it);
+ 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;
}
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Token is expired. Create a new one\n");
- new_token = token_create (&pub_key,
- &token->aud_key);
- new_exp = GNUNET_TIME_relative_to_absolute (token_rel_exp);
- new_nbf = GNUNET_TIME_absolute_get ();
- new_iat = new_nbf;
- for (attr = token->attr_head; NULL != attr; attr = attr->next)
- {
- if (0 == strcmp (attr->name, "exp"))
- {
- token_add_attr_int (new_token, attr->name, new_exp.abs_value_us);
- }
- else if (0 == strcmp (attr->name, "nbf"))
- {
- token_add_attr_int (new_token, attr->name, new_nbf.abs_value_us);
- }
- else if (0 == strcmp (attr->name, "iat"))
- {
- token_add_attr_int (new_token, attr->name, new_iat.abs_value_us);
- }
- else if ((0 == strcmp (attr->name, "iss"))
- || (0 == strcmp (attr->name, "aud")))
- {
- //Omit
- }
- else if (0 == strcmp (attr->name, "sub"))
- {
- token_add_attr (new_token,
- attr->name,
- attr->val_head->value);
- }
- else
- {
- GNUNET_CRYPTO_hash (attr->name,
- strlen (attr->name),
- &key_hash);
- //Check if attr still exists. omit of not
- if (GNUNET_NO !=
- GNUNET_CONTAINER_multihashmap_contains (ego_entry->attr_map,
- &key_hash))
- {
- cur_value = GNUNET_CONTAINER_multihashmap_get (ego_entry->attr_map,
- &key_hash);
- GNUNET_CONTAINER_DLL_insert (new_token->attr_head,
- new_token->attr_tail,
- cur_value);
- }
- }
- }
+ abh->proc (abh->proc_cls, abh->abe_key);
+ GNUNET_free (abh);
+}
- // reassemble and set
- GNUNET_assert (token_serialize (new_token,
- priv_key,
- &new_ecdhe_privkey,
- &enc_token_str));
-
- token_record[0].data = enc_token_str;
- token_record[0].data_size = strlen (enc_token_str) + 1;
- token_record[0].expiration_time = rd_exp; //Old expiration time
- token_record[0].record_type = GNUNET_GNSRECORD_TYPE_ID_TOKEN;
- token_record[0].flags = GNUNET_GNSRECORD_RF_NONE;
-
- //Meta
- token_metadata_len = sizeof (struct GNUNET_CRYPTO_EcdhePrivateKey)
- + sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)
- + strlen (scopes) + 1; //With 0-Terminator
- token_metadata = GNUNET_malloc (token_metadata_len);
- write_ptr = token_metadata;
- memcpy (token_metadata, new_ecdhe_privkey, sizeof (struct GNUNET_CRYPTO_EcdhePrivateKey));
- write_ptr += sizeof (struct GNUNET_CRYPTO_EcdhePrivateKey);
- memcpy (write_ptr, &token->aud_key, sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
- write_ptr += sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey);
- memcpy (write_ptr, scopes, strlen (scopes) + 1); //with 0-Terminator;
-
- token_record[1].data = token_metadata;
- token_record[1].data_size = token_metadata_len;
- token_record[1].expiration_time = rd_exp;
- token_record[1].record_type = GNUNET_GNSRECORD_TYPE_ID_TOKEN_METADATA;
- token_record[1].flags = GNUNET_GNSRECORD_RF_PRIVATE;
-
- ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
- priv_key,
- label,
- 2,
- token_record,
- &store_token_cont,
- ego_entry);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, ">>> Updating Token w/ %s\n", new_token);
- token_destroy (new_token);
- token_destroy (token);
- GNUNET_free (new_ecdhe_privkey);
- GNUNET_free (enc_token_str);
- token = NULL;
- GNUNET_free (label);
- label = NULL;
- GNUNET_free (scopes);
- scopes = NULL;
+/**
+ * Generates and stores a new ABE key
+ */
+static void
+bootstrap_store_task (void *cls)
+{
+ struct AbeBootstrapHandle *abh = cls;
+ struct GNUNET_GNSRECORD_Data rd[1];
+ char *key;
+
+ rd[0].data_size = GNUNET_ABE_cpabe_serialize_master_key (abh->abe_key,
+ (void**)&key);
+ rd[0].data = key;
+ rd[0].record_type = GNUNET_GNSRECORD_TYPE_ABE_MASTER;
+ rd[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION | 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);
+ GNUNET_free (key);
}
+/**
+ * Error checking for ABE master
+ */
static void
-update_identities(void *cls,
- const struct GNUNET_SCHEDULER_TaskContext *tc);
+bootstrap_abe_error (void *cls)
+{
+ struct AbeBootstrapHandle *abh = cls;
+ GNUNET_free (abh);
+ abh->proc (abh->proc_cls, NULL);
+ GNUNET_free (abh);
+}
+
/**
- *
- * Cleanup attr_map
- *
- * @param cls NULL
- * @param key the key
- * @param value the json_t attribute value
- * @return GNUNET_YES
+ * Handle ABE lookup in namestore
*/
-static int
-clear_ego_attrs (void *cls,
- const struct GNUNET_HashCode *key,
- void *value)
-{
- struct TokenAttr *attr = value;
- struct TokenAttrValue *val;
- struct TokenAttrValue *tmp_val;
- for (val = attr->val_head; NULL != val;)
- {
- tmp_val = val->next;
- GNUNET_CONTAINER_DLL_remove (attr->val_head,
- attr->val_tail,
- val);
- GNUNET_free (val->value);
- GNUNET_free (val);
- val = tmp_val;
+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_ABE_AbeMasterKey *abe_key;
+
+ for (uint32_t i=0;i<rd_count;i++) {
+ if (GNUNET_GNSRECORD_TYPE_ABE_MASTER != rd[i].record_type)
+ continue;
+ abe_key = GNUNET_ABE_cpabe_deserialize_master_key (rd[i].data,
+ rd[i].data_size);
+ abh->proc (abh->proc_cls, abe_key);
+ GNUNET_free (abh);
+ return;
}
- GNUNET_free (attr->name);
- GNUNET_free (attr);
- return GNUNET_YES;
+ //No ABE master found, bootstrapping...
+ abh->abe_key = GNUNET_ABE_cpabe_create_master_key ();
+ GNUNET_SCHEDULER_add_now (&bootstrap_store_task, abh);
}
/**
- *
- * Update all ID_TOKEN records for an identity and store them
- *
- * @param cls the identity entry
- * @param zone the identity
- * @param lbl the name of the record
- * @param rd_count number of records
- * @param rd record data
- *
+ * Bootstrap ABE master if it does not yet exists.
+ * Will call the AbeBootstrapResult processor when done.
+ * will always recreate the ABE key of GNUNET_YES == recreate
*/
static void
-token_collect (void *cls,
- const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
- const char *lbl,
- unsigned int rd_count,
- const struct GNUNET_GNSRECORD_Data *rd)
-{
- struct EgoEntry *ego_entry = cls;
- const struct GNUNET_GNSRECORD_Data *token_record;
- const struct GNUNET_GNSRECORD_Data *token_metadata_record;
- struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key;
-
- if (NULL == lbl)
- {
- //Done
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- ">>> Updating Ego finished\n");
- //Clear attribute map for ego
- GNUNET_CONTAINER_multihashmap_iterate (ego_entry->attr_map,
- &clear_ego_attrs,
- ego_entry);
- GNUNET_CONTAINER_multihashmap_clear (ego_entry->attr_map);
- update_task = GNUNET_SCHEDULER_add_now (&update_identities,
- ego_entry->next);
- return;
- }
+bootstrap_abe (const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
+ AbeBootstrapResult proc,
+ void* cls,
+ int recreate)
+{
+ struct AbeBootstrapHandle *abh;
- //There should be only a single record for a token under a label
- if (2 != rd_count)
+ abh = GNUNET_new (struct AbeBootstrapHandle);
+ abh->proc = proc;
+ abh->proc_cls = cls;
+ abh->identity = *identity;
+ if (GNUNET_YES == recreate)
{
- GNUNET_NAMESTORE_zone_iterator_next (ns_it);
- return;
+ abh->abe_key = GNUNET_ABE_cpabe_create_master_key ();
+ GNUNET_SCHEDULER_add_now (&bootstrap_store_task, abh);
+ } else {
+ abh->ns_qe = GNUNET_NAMESTORE_records_lookup (ns_handle,
+ identity,
+ "+",
+ &bootstrap_abe_error,
+ abh,
+ &bootstrap_abe_result,
+ abh);
}
+}
+
+
+
+static int
+create_sym_key_from_ecdh(const struct GNUNET_HashCode *new_key_hash,
+ struct GNUNET_CRYPTO_SymmetricSessionKey *skey,
+ struct GNUNET_CRYPTO_SymmetricInitializationVector *iv)
+{
+ struct GNUNET_CRYPTO_HashAsciiEncoded new_key_hash_str;
+
+ GNUNET_CRYPTO_hash_to_enc (new_key_hash,
+ &new_key_hash_str);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating symmetric rsa key from %s\n", (char*)&new_key_hash_str);
+ static const char ctx_key[] = "gnuid-aes-ctx-key";
+ GNUNET_CRYPTO_kdf (skey, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
+ new_key_hash, sizeof (struct GNUNET_HashCode),
+ ctx_key, strlen (ctx_key),
+ NULL, 0);
+ static const char ctx_iv[] = "gnuid-aes-ctx-iv";
+ GNUNET_CRYPTO_kdf (iv, sizeof (struct GNUNET_CRYPTO_SymmetricInitializationVector),
+ new_key_hash, sizeof (struct GNUNET_HashCode),
+ ctx_iv, strlen (ctx_iv),
+ NULL, 0);
+ return GNUNET_OK;
+}
+
+static void
+cleanup_ticket_issue_handle (struct TicketIssueHandle *handle)
+{
+ if (NULL != handle->attrs)
+ GNUNET_IDENTITY_ATTRIBUTE_list_destroy (handle->attrs);
+ if (NULL != handle->ns_qe)
+ GNUNET_NAMESTORE_cancel (handle->ns_qe);
+ GNUNET_free (handle);
+}
- if (rd[0].record_type == GNUNET_GNSRECORD_TYPE_ID_TOKEN_METADATA)
+
+static void
+send_ticket_result (struct IdpClient *client,
+ uint32_t r_id,
+ const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket,
+ const struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs)
+{
+ struct TicketResultMessage *irm;
+ struct GNUNET_MQ_Envelope *env;
+ struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket_buf;
+
+ /* store ticket in DB */
+ if (GNUNET_OK != TKT_database->store_ticket (TKT_database->cls,
+ ticket,
+ attrs))
{
- token_metadata_record = &rd[0];
- token_record = &rd[1];
- } else {
- token_record = &rd[0];
- token_metadata_record = &rd[1];
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Unable to store ticket after issue\n");
+ GNUNET_break (0);
}
- if (token_metadata_record->record_type != GNUNET_GNSRECORD_TYPE_ID_TOKEN_METADATA)
+
+ env = GNUNET_MQ_msg_extra (irm,
+ sizeof (struct GNUNET_IDENTITY_PROVIDER_Ticket),
+ GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_RESULT);
+ ticket_buf = (struct GNUNET_IDENTITY_PROVIDER_Ticket *)&irm[1];
+ *ticket_buf = *ticket;
+ irm->id = htonl (r_id);
+ GNUNET_MQ_send (client->mq,
+ env);
+}
+
+static void
+store_ticket_issue_cont (void *cls,
+ int32_t success,
+ const char *emsg)
+{
+ struct TicketIssueHandle *handle = cls;
+
+ handle->ns_qe = NULL;
+ if (GNUNET_SYSERR == success)
{
- GNUNET_NAMESTORE_zone_iterator_next (ns_it);
+ cleanup_ticket_issue_handle (handle);
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n",
+ "Unknown Error\n");
+ GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
return;
}
- if (token_record->record_type == GNUNET_GNSRECORD_TYPE_ID_TOKEN)
+ send_ticket_result (handle->client,
+ handle->r_id,
+ &handle->ticket,
+ handle->attrs);
+ cleanup_ticket_issue_handle (handle);
+}
+
+
+
+int
+serialize_abe_keyinfo2 (const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket,
+ const struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs,
+ const struct GNUNET_ABE_AbeKey *rp_key,
+ struct GNUNET_CRYPTO_EcdhePrivateKey **ecdh_privkey,
+ char **result)
+{
+ struct GNUNET_CRYPTO_EcdhePublicKey ecdh_pubkey;
+ struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *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_ABE_cpabe_serialize_key (rp_key,
+ (void**)&serialized_key);
+ attrs_str_len = 0;
+ for (le = attrs->list_head; NULL != le; le = le->next) {
+ attrs_str_len += strlen (le->claim->name) + 1;
+ }
+ buf = GNUNET_malloc (attrs_str_len + size);
+ write_ptr = buf;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Writing attributes\n");
+ for (le = attrs->list_head; NULL != le; le = le->next) {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "%s\n", le->claim->name);
+
+
+ GNUNET_memcpy (write_ptr,
+ le->claim->name,
+ strlen (le->claim->name));
+ write_ptr[strlen (le->claim->name)] = ',';
+ write_ptr += strlen (le->claim->name) + 1;
+ }
+ write_ptr--;
+ write_ptr[0] = '\0'; //replace last , with a 0-terminator
+ write_ptr++;
+ GNUNET_memcpy (write_ptr,
+ serialized_key,
+ size);
+ GNUNET_free (serialized_key);
+ // 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,
+ &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);
+ GNUNET_free (buf);
+ return sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)+enc_size;
+}
+
+
+
+static void
+issue_ticket_after_abe_bootstrap (void *cls,
+ struct GNUNET_ABE_AbeMasterKey *abe_key)
+{
+ struct TicketIssueHandle *ih = cls;
+ struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *le;
+ struct GNUNET_CRYPTO_EcdhePrivateKey *ecdhe_privkey;
+ struct GNUNET_GNSRECORD_Data code_record[1];
+ struct GNUNET_ABE_AbeKey *rp_key;
+ char *code_record_data;
+ char **attrs;
+ char *label;
+ char *policy;
+ int attrs_len;
+ uint32_t 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 + 1)*sizeof (char*));
+ i = 0;
+ for (le = ih->attrs->list_head; NULL != le; le = le->next) {
+ GNUNET_asprintf (&policy, "%s_%lu",
+ le->claim->name,
+ le->claim->version);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Adding attribute to key: %s\n",
+ policy);
+ attrs[i] = policy;
+ i++;
+ }
+ attrs[i] = NULL;
+ rp_key = GNUNET_ABE_cpabe_create_key (abe_key,
+ attrs);
+
+ //TODO review this wireformat
+ code_record_len = serialize_abe_keyinfo2 (&ih->ticket,
+ ih->attrs,
+ 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);
+ //for (; i > 0; i--)
+ // GNUNET_free (attrs[i-1]);
+ GNUNET_free (ecdhe_privkey);
+ GNUNET_free (label);
+ GNUNET_free (attrs);
+ GNUNET_free (code_record_data);
+ GNUNET_ABE_cpabe_delete_key (rp_key,
+ GNUNET_YES);
+ GNUNET_ABE_cpabe_delete_master_key (abe_key);
+}
+
+
+static int
+check_issue_ticket_message(void *cls,
+ const struct IssueTicketMessage *im)
+{
+ uint16_t size;
+
+ size = ntohs (im->header.size);
+ if (size <= sizeof (struct IssueTicketMessage))
{
- GNUNET_NAMESTORE_zone_iterator_next (ns_it);
- return;
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
}
+ return GNUNET_OK;
+}
+
- //Get metadata and decrypt token
- ecdhe_privkey = *((struct GNUNET_CRYPTO_EcdhePrivateKey *)token_metadata_record->data);
- aud_key = (struct GNUNET_CRYPTO_EcdsaPublicKey *)&ecdhe_privkey+sizeof(struct GNUNET_CRYPTO_EcdhePrivateKey);
- scopes = GNUNET_strdup ((char*) aud_key+sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
+static void
+handle_issue_ticket_message (void *cls,
+ const struct IssueTicketMessage *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 = GNUNET_IDENTITY_ATTRIBUTE_list_deserialize ((char*)&im[1], attrs_len);
+ ih->r_id = ntohl (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_NO);
+ GNUNET_SERVICE_client_continue (idp->client);
- token_parse2 (token_record->data,
- &ecdhe_privkey,
- aud_key,
- &token);
+}
- label = GNUNET_strdup (lbl);
- rd_exp = token_record->expiration_time;
+/**********************************************************
+ * Revocation
+ **********************************************************/
- GNUNET_SCHEDULER_add_now (&handle_token_update, ego_entry);
+/**
+ * Cleanup revoke handle
+ *
+ * @param rh the ticket revocation handle
+ */
+static void
+cleanup_revoke_ticket_handle (struct TicketRevocationHandle *rh)
+{
+ if (NULL != rh->attrs)
+ GNUNET_IDENTITY_ATTRIBUTE_list_destroy (rh->attrs);
+ if (NULL != rh->rvk_attrs)
+ GNUNET_IDENTITY_ATTRIBUTE_list_destroy (rh->rvk_attrs);
+ if (NULL != rh->abe_key)
+ GNUNET_ABE_cpabe_delete_master_key (rh->abe_key);
+ if (NULL != rh->ns_qe)
+ GNUNET_NAMESTORE_cancel (rh->ns_qe);
+ if (NULL != rh->ns_it)
+ GNUNET_NAMESTORE_zone_iteration_stop (rh->ns_it);
+ GNUNET_free (rh);
}
/**
+ * Send revocation result
*
- * Collect all ID_ATTR records for an identity and store them
+ * @param rh ticket revocation handle
+ * @param success GNUNET_OK if successful result
+ */
+static void
+send_revocation_finished (struct TicketRevocationHandle *rh,
+ uint32_t success)
+{
+ struct GNUNET_MQ_Envelope *env;
+ struct RevokeTicketResultMessage *trm;
+
+ env = GNUNET_MQ_msg (trm,
+ GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_REVOKE_TICKET_RESULT);
+ trm->id = htonl (rh->r_id);
+ trm->success = htonl (success);
+ GNUNET_MQ_send (rh->client->mq,
+ env);
+ GNUNET_CONTAINER_DLL_remove (rh->client->revocation_list_head,
+ rh->client->revocation_list_tail,
+ rh);
+}
+
+
+/**
+ * Process ticket from database
*
- * @param cls the identity entry
- * @param zone the identity
- * @param lbl the name of the record
- * @param rd_count number of records
- * @param rd record data
+ * @param cls struct TicketIterationProcResult
+ * @param ticket the ticket
+ * @param attrs the attributes
+ */
+static void
+ticket_reissue_proc (void *cls,
+ const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket,
+ const struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs);
+
+static void
+revocation_reissue_tickets (struct TicketRevocationHandle *rh);
+
+
+static void reissue_next (void *cls)
+{
+ struct TicketRevocationHandle *rh = cls;
+ revocation_reissue_tickets (rh);
+}
+
+
+static void
+reissue_ticket_cont (void *cls,
+ int32_t success,
+ const char *emsg)
+{
+ struct TicketRevocationHandle *rh = cls;
+
+ rh->ns_qe = NULL;
+ if (GNUNET_SYSERR == success)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n",
+ "Unknown Error\n");
+ send_revocation_finished (rh, GNUNET_SYSERR);
+ cleanup_revoke_ticket_handle (rh);
+ return;
+ }
+ rh->offset++;
+ GNUNET_SCHEDULER_add_now (&reissue_next, rh);
+}
+
+
+/**
+ * Process ticket from database
*
+ * @param cls struct TicketIterationProcResult
+ * @param ticket the ticket
+ * @param attrs the attributes
*/
static void
-attribute_collect (void *cls,
- const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
- const char *lbl,
- unsigned int rd_count,
- const struct GNUNET_GNSRECORD_Data *rd)
-{
- struct EgoEntry *ego_entry = cls;
- struct GNUNET_HashCode key;
- struct TokenAttr *attr;
- struct TokenAttrValue *val;
- char *val_str;
- int i;
-
- if (NULL == lbl)
+ticket_reissue_proc (void *cls,
+ const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket,
+ const struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs)
+{
+ struct TicketRevocationHandle *rh = cls;
+ struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *le;
+ struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *le_rollover;
+ struct GNUNET_CRYPTO_EcdhePrivateKey *ecdhe_privkey;
+ struct GNUNET_GNSRECORD_Data code_record[1];
+ struct GNUNET_ABE_AbeKey *rp_key;
+ char *code_record_data;
+ char **attr_arr;
+ char *label;
+ char *policy;
+ int attrs_len;
+ uint32_t i;
+ int reissue_ticket;
+ size_t code_record_len;
+
+
+ if (NULL == ticket)
{
- //Done
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- ">>> Updating Attributes finished\n");
- ego_entry->attributes_dirty = GNUNET_NO;
- update_task = GNUNET_SCHEDULER_add_now (&update_identities, ego_entry);
+ "Iteration done\n");
return;
}
- if (0 == rd_count)
+ if (0 == memcmp (&ticket->audience,
+ &rh->ticket.audience,
+ sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)))
{
- GNUNET_NAMESTORE_zone_iterator_next (ns_it);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Do not reissue for this identity.!\n");
+
+ rh->offset++;
+ GNUNET_SCHEDULER_add_now (&reissue_next, rh);
return;
}
- GNUNET_CRYPTO_hash (lbl,
- strlen (lbl),
- &key);
- if (1 == rd_count)
+
+ /*
+ * Check if any attribute of this ticket intersects with a rollover attribute
+ */
+ reissue_ticket = GNUNET_NO;
+ for (le = attrs->list_head; NULL != le; le = le->next)
{
- if (rd->record_type == GNUNET_GNSRECORD_TYPE_ID_ATTR)
+ for (le_rollover = rh->rvk_attrs->list_head;
+ NULL != le_rollover;
+ le_rollover = le_rollover->next)
{
- val_str = GNUNET_GNSRECORD_value_to_string (rd->record_type,
- rd->data,
- rd->data_size);
- attr = GNUNET_malloc (sizeof (struct TokenAttr));
- attr->name = GNUNET_strdup (lbl);
- val = GNUNET_malloc (sizeof (struct TokenAttrValue));
- val->value = val_str;
- GNUNET_CONTAINER_DLL_insert (attr->val_head,
- attr->val_tail,
- val);
- GNUNET_CONTAINER_multihashmap_put (ego_entry->attr_map,
- &key,
- attr,
- GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
+ if (0 == strcmp (le_rollover->claim->name,
+ le->claim->name))
+ {
+ reissue_ticket = GNUNET_YES;
+ le->claim->version = le_rollover->claim->version;
+ }
}
+ }
+
+ if (GNUNET_NO == reissue_ticket)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Skipping ticket.\n");
+
+ rh->offset++;
+ GNUNET_SCHEDULER_add_now (&reissue_next, rh);
+
- GNUNET_NAMESTORE_zone_iterator_next (ns_it);
return;
}
- attr = GNUNET_malloc (sizeof (struct TokenAttr));
- attr->name = GNUNET_strdup (lbl);
- for (i = 0; i < rd_count; i++)
+ //Create new ABE key for RP
+ attrs_len = 0;
+
+ /* If this is the RP we want to revoke attributes of, the do so */
+
+ for (le = attrs->list_head; NULL != le; le = le->next)
+ attrs_len++;
+ attr_arr = GNUNET_malloc ((attrs_len + 1)*sizeof (char*));
+ i = 0;
+ for (le = attrs->list_head; NULL != le; le = le->next) {
+ GNUNET_asprintf (&policy, "%s_%lu",
+ le->claim->name,
+ le->claim->version);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Recreating key with %s\n", policy);
+ attr_arr[i] = policy;
+ i++;
+ }
+ attr_arr[i] = NULL;
+ rp_key = GNUNET_ABE_cpabe_create_key (rh->abe_key,
+ attr_arr);
+
+ //TODO review this wireformat
+ code_record_len = serialize_abe_keyinfo2 (ticket,
+ attrs,
+ 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 (&ticket->rnd,
+ sizeof (uint64_t));
+ //Publish record
+ rh->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
+ &rh->identity,
+ label,
+ 1,
+ code_record,
+ &reissue_ticket_cont,
+ rh);
+ //for (; i > 0; i--)
+ // GNUNET_free (attr_arr[i-1]);
+ GNUNET_free (ecdhe_privkey);
+ GNUNET_free (label);
+ GNUNET_free (attr_arr);
+ GNUNET_free (code_record_data);
+ GNUNET_ABE_cpabe_delete_key (rp_key, GNUNET_YES);
+}
+
+
+/* Prototype for below function */
+static void
+attr_reenc_cont (void *cls,
+ int32_t success,
+ const char *emsg);
+
+static void
+revocation_reissue_tickets (struct TicketRevocationHandle *rh)
+{
+ int ret;
+ /* Done, issue new keys */
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Revocation Phase III: Reissuing Tickets\n");
+ if (GNUNET_SYSERR == (ret = TKT_database->iterate_tickets (TKT_database->cls,
+ &rh->ticket.identity,
+ GNUNET_NO,
+ rh->offset,
+ &ticket_reissue_proc,
+ rh)))
{
- if (rd[i].record_type == GNUNET_GNSRECORD_TYPE_ID_ATTR)
- {
- val_str = GNUNET_GNSRECORD_value_to_string (rd[i].record_type,
- rd[i].data,
- rd[i].data_size);
- val = GNUNET_malloc (sizeof (struct TokenAttrValue));
- val->value = val_str;
- GNUNET_CONTAINER_DLL_insert (attr->val_head,
- attr->val_tail,
- val);
- }
+ GNUNET_break (0);
+ }
+ if (GNUNET_NO == ret)
+ {
+ send_revocation_finished (rh, GNUNET_OK);
+ cleanup_revoke_ticket_handle (rh);
+ return;
}
- GNUNET_CONTAINER_multihashmap_put (ego_entry->attr_map,
- &key,
- attr,
- GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
- GNUNET_NAMESTORE_zone_iterator_next (ns_it);
- return;
}
/**
- *
- * Update identity information for ego. If attribute map is
- * dirty, first update the attributes.
- *
- * @param cls the ego to update
- * param tc task context
- *
+ * Revoke next attribte by reencryption with
+ * new ABE master
*/
static void
-update_identities(void *cls,
- const struct GNUNET_SCHEDULER_TaskContext *tc)
+reenc_next_attribute (struct TicketRevocationHandle *rh)
{
- struct EgoEntry *next_ego = cls;
- const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key;
- update_task = NULL;
- if (NULL == next_ego)
+ struct GNUNET_GNSRECORD_Data rd[1];
+ char* buf;
+ char* enc_buf;
+ size_t enc_size;
+ char* rd_buf;
+ size_t buf_size;
+ char* policy;
+ uint32_t attr_ver;
+
+ if (NULL == rh->attrs->list_head)
{
- if (min_rel_exp.rel_value_us < MIN_WAIT_TIME.rel_value_us)
- min_rel_exp = MIN_WAIT_TIME;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- ">>> Finished. Rescheduling in %d\n",
- min_rel_exp.rel_value_us);
- ns_it = NULL;
- //finished -> reschedule
- update_task = GNUNET_SCHEDULER_add_delayed (min_rel_exp,
- &update_identities,
- ego_head);
- min_rel_exp.rel_value_us = 0;
+ revocation_reissue_tickets (rh);
return;
}
- priv_key = GNUNET_IDENTITY_ego_get_private_key (next_ego->ego);
- if (GNUNET_YES == next_ego->attributes_dirty)
+ buf_size = GNUNET_IDENTITY_ATTRIBUTE_serialize_get_size (rh->attrs->list_head->claim);
+ buf = GNUNET_malloc (buf_size);
+ GNUNET_IDENTITY_ATTRIBUTE_serialize (rh->attrs->list_head->claim,
+ buf);
+ rh->attrs->list_head->claim->version++;
+ GNUNET_asprintf (&policy, "%s_%lu",
+ rh->attrs->list_head->claim->name,
+ rh->attrs->list_head->claim->version);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Encrypting with policy %s\n", policy);
+ /**
+ * Encrypt the attribute value and store in namestore
+ */
+ enc_size = GNUNET_ABE_cpabe_encrypt (buf,
+ buf_size,
+ policy, //Policy
+ rh->abe_key,
+ (void**)&enc_buf);
+ GNUNET_free (buf);
+ GNUNET_free (policy);
+ rd[0].data_size = enc_size + sizeof (uint32_t);
+ rd_buf = GNUNET_malloc (rd[0].data_size);
+ attr_ver = htonl (rh->attrs->list_head->claim->version);
+ GNUNET_memcpy (rd_buf,
+ &attr_ver,
+ sizeof (uint32_t));
+ GNUNET_memcpy (rd_buf+sizeof (uint32_t),
+ enc_buf,
+ enc_size);
+ rd[0].data = rd_buf;
+ rd[0].record_type = GNUNET_GNSRECORD_TYPE_ID_ATTR;
+ rd[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
+ rd[0].expiration_time = GNUNET_TIME_UNIT_HOURS.rel_value_us; //TODO sane?
+ rh->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
+ &rh->identity,
+ rh->attrs->list_head->claim->name,
+ 1,
+ rd,
+ &attr_reenc_cont,
+ rh);
+ GNUNET_free (enc_buf);
+ GNUNET_free (rd_buf);
+}
+
+/**
+ * Namestore callback after revoked attribute
+ * is stored
+ */
+static void
+attr_reenc_cont (void *cls,
+ int32_t success,
+ const char *emsg)
+{
+ struct TicketRevocationHandle *rh = cls;
+ struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *le;
+
+ if (GNUNET_SYSERR == success)
{
- //Starting over. We must update the Attributes for they might have changed.
- ns_it = GNUNET_NAMESTORE_zone_iteration_start (ns_handle,
- priv_key,
- &attribute_collect,
- next_ego);
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Failed to reencrypt attribute %s\n",
+ emsg);
+ GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
+ return;
+ }
+ if (NULL == rh->attrs->list_head)
+ {
+ revocation_reissue_tickets (rh);
+ return;
+ }
+ le = rh->attrs->list_head;
+ GNUNET_CONTAINER_DLL_remove (rh->attrs->list_head,
+ rh->attrs->list_tail,
+ le);
+ GNUNET_assert (NULL != rh->rvk_attrs);
+ GNUNET_CONTAINER_DLL_insert (rh->rvk_attrs->list_head,
+ rh->rvk_attrs->list_tail,
+ le);
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Re-encrypting next attribute\n");
+ reenc_next_attribute (rh);
+}
+
+
+static void
+process_attributes_to_update (void *cls,
+ const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket,
+ const struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs)
+{
+ struct TicketRevocationHandle *rh = cls;
+
+ rh->attrs = GNUNET_IDENTITY_ATTRIBUTE_list_dup (attrs);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Revocation Phase I: Collecting attributes\n");
+ /* Reencrypt all attributes with new key */
+ if (NULL == rh->attrs->list_head)
+ {
+ /* No attributes to reencrypt */
+ send_revocation_finished (rh, GNUNET_OK);
+ cleanup_revoke_ticket_handle (rh);
+ return;
+ } else {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Revocation Phase II: Re-encrypting attributes\n");
+ reenc_next_attribute (rh);
}
- else
+
+}
+
+
+
+static void
+get_ticket_after_abe_bootstrap (void *cls,
+ struct GNUNET_ABE_AbeMasterKey *abe_key)
+{
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Finished ABE bootstrap\n");
+ struct TicketRevocationHandle *rh = cls;
+ rh->abe_key = abe_key;
+ TKT_database->get_ticket_attributes (TKT_database->cls,
+ &rh->ticket,
+ &process_attributes_to_update,
+ rh);
+}
+
+static int
+check_revoke_ticket_message(void *cls,
+ const struct RevokeTicketMessage *im)
+{
+ uint16_t size;
+
+ size = ntohs (im->header.size);
+ if (size <= sizeof (struct RevokeTicketMessage))
{
- //Ego will be dirty next time
- next_ego->attributes_dirty = GNUNET_YES;
- ns_it = GNUNET_NAMESTORE_zone_iteration_start (ns_handle,
- priv_key,
- &token_collect,
- next_ego);
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
}
+ return GNUNET_OK;
}
+static void
+handle_revoke_ticket_message (void *cls,
+ const struct RevokeTicketMessage *rm)
+{
+ struct TicketRevocationHandle *rh;
+ struct IdpClient *idp = cls;
+ struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket;
+
+ rh = GNUNET_new (struct TicketRevocationHandle);
+ ticket = (struct GNUNET_IDENTITY_PROVIDER_Ticket*)&rm[1];
+ rh->rvk_attrs = GNUNET_new (struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList);
+ rh->ticket = *ticket;
+ rh->r_id = ntohl (rm->id);
+ rh->client = idp;
+ rh->identity = rm->identity;
+ GNUNET_CRYPTO_ecdsa_key_get_public (&rh->identity,
+ &rh->ticket.identity);
+ GNUNET_CONTAINER_DLL_insert (idp->revocation_list_head,
+ idp->revocation_list_tail,
+ rh);
+ bootstrap_abe (&rh->identity, &get_ticket_after_abe_bootstrap, rh, GNUNET_NO);
+ GNUNET_SERVICE_client_continue (idp->client);
+
+}
-/**
- * Function called initially to start update task
- */
static void
-init_cont ()
+cleanup_consume_ticket_handle (struct ConsumeTicketHandle *handle)
{
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, ">>> Starting Service\n");
- //Initially iterate all itenties and refresh all tokens
- update_task = GNUNET_SCHEDULER_add_now (&update_identities, ego_head);
+ if (NULL != handle->key)
+ GNUNET_ABE_cpabe_delete_key (handle->key,
+ GNUNET_YES);
+ if (NULL != handle->attrs)
+ GNUNET_IDENTITY_ATTRIBUTE_list_destroy (handle->attrs);
+ GNUNET_free (handle);
}
-/**
- * Initial ego collection function.
- *
- * @param cls NULL
- * @param ego ego
- * @param ctx context
- * @param identifier ego name
- */
+
+
+static int
+check_consume_ticket_message(void *cls,
+ const struct ConsumeTicketMessage *cm)
+{
+ uint16_t size;
+
+ size = ntohs (cm->header.size);
+ if (size <= sizeof (struct ConsumeTicketMessage))
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ return GNUNET_OK;
+}
+
+static void
+process_parallel_lookup2 (void *cls, uint32_t rd_count,
+ const struct GNUNET_GNSRECORD_Data *rd)
+{
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Parallel lookup finished (count=%u)\n", rd_count);
+ struct ParallelLookup *parallel_lookup = cls;
+ struct ConsumeTicketHandle *handle = parallel_lookup->handle;
+ struct ConsumeTicketResultMessage *crm;
+ struct GNUNET_MQ_Envelope *env;
+ struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *attr_le;
+ struct GNUNET_TIME_Absolute decrypt_duration;
+ char *data;
+ char *data_tmp;
+ ssize_t attr_len;
+ size_t attrs_len;
+
+ GNUNET_CONTAINER_DLL_remove (handle->parallel_lookups_head,
+ handle->parallel_lookups_tail,
+ parallel_lookup);
+ GNUNET_free (parallel_lookup->label);
+
+ GNUNET_STATISTICS_update (stats,
+ "attribute_lookup_time_total",
+ GNUNET_TIME_absolute_get_duration (parallel_lookup->lookup_start_time).rel_value_us,
+ GNUNET_YES);
+ GNUNET_STATISTICS_update (stats,
+ "attribute_lookups_count",
+ 1,
+ GNUNET_YES);
+
+
+ GNUNET_free (parallel_lookup);
+ if (1 != rd_count)
+ GNUNET_break(0);//TODO
+ if (rd->record_type == GNUNET_GNSRECORD_TYPE_ID_ATTR)
+ {
+ decrypt_duration = GNUNET_TIME_absolute_get ();
+ attr_len = GNUNET_ABE_cpabe_decrypt (rd->data + sizeof (uint32_t),
+ rd->data_size - sizeof (uint32_t),
+ handle->key,
+ (void**)&data);
+ if (GNUNET_SYSERR != attr_len)
+ {
+ GNUNET_STATISTICS_update (stats,
+ "abe_decrypt_time_total",
+ GNUNET_TIME_absolute_get_duration (decrypt_duration).rel_value_us,
+ GNUNET_YES);
+ GNUNET_STATISTICS_update (stats,
+ "abe_decrypt_count",
+ 1,
+ GNUNET_YES);
+
+ attr_le = GNUNET_new (struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry);
+ attr_le->claim = GNUNET_IDENTITY_ATTRIBUTE_deserialize (data,
+ attr_len);
+ attr_le->claim->version = ntohl(*(uint32_t*)rd->data);
+ GNUNET_CONTAINER_DLL_insert (handle->attrs->list_head,
+ handle->attrs->list_tail,
+ attr_le);
+ GNUNET_free (data);
+ }
+ }
+ if (NULL != handle->parallel_lookups_head)
+ return; //Wait for more
+ /* Else we are done */
+
+ /* Store ticket in DB */
+ if (GNUNET_OK != TKT_database->store_ticket (TKT_database->cls,
+ &handle->ticket,
+ handle->attrs))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Unable to store ticket after consume\n");
+ GNUNET_break (0);
+ }
+
+ GNUNET_SCHEDULER_cancel (handle->kill_task);
+ attrs_len = GNUNET_IDENTITY_ATTRIBUTE_list_serialize_get_size (handle->attrs);
+ env = GNUNET_MQ_msg_extra (crm,
+ attrs_len,
+ GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_CONSUME_TICKET_RESULT);
+ crm->id = htonl (handle->r_id);
+ crm->attrs_len = htons (attrs_len);
+ crm->identity = handle->ticket.identity;
+ data_tmp = (char *) &crm[1];
+ GNUNET_IDENTITY_ATTRIBUTE_list_serialize (handle->attrs,
+ data_tmp);
+ GNUNET_MQ_send (handle->client->mq, env);
+ cleanup_consume_ticket_handle (handle);
+}
+
+void
+abort_parallel_lookups2 (void *cls)
+{
+ struct ConsumeTicketHandle *handle = cls;
+ struct ParallelLookup *lu;
+ struct ParallelLookup *tmp;
+ struct AttributeResultMessage *arm;
+ struct GNUNET_MQ_Envelope *env;
+
+ for (lu = handle->parallel_lookups_head;
+ NULL != lu;) {
+ GNUNET_GNS_lookup_cancel (lu->lookup_request);
+ GNUNET_free (lu->label);
+ tmp = lu->next;
+ GNUNET_CONTAINER_DLL_remove (handle->parallel_lookups_head,
+ handle->parallel_lookups_tail,
+ lu);
+ GNUNET_free (lu);
+ lu = tmp;
+ }
+ env = GNUNET_MQ_msg (arm,
+ GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_RESULT);
+ arm->id = htonl (handle->r_id);
+ arm->attr_len = htons (0);
+ GNUNET_MQ_send (handle->client->mq, env);
+
+}
+
+
static void
-list_ego (void *cls,
- struct GNUNET_IDENTITY_Ego *ego,
- void **ctx,
- const char *identifier)
+process_consume_abe_key (void *cls, uint32_t rd_count,
+ const struct GNUNET_GNSRECORD_Data *rd)
{
- struct EgoEntry *new_entry;
- if ((NULL == ego) && (STATE_INIT == state))
+ struct ConsumeTicketHandle *handle = cls;
+ struct GNUNET_HashCode new_key_hash;
+ struct GNUNET_CRYPTO_SymmetricSessionKey enc_key;
+ struct GNUNET_CRYPTO_SymmetricInitializationVector enc_iv;
+ struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_key;
+ struct ParallelLookup *parallel_lookup;
+ size_t size;
+ char *buf;
+ char *scope;
+ char *lookup_query;
+
+ handle->lookup_request = NULL;
+ if (1 != rd_count)
{
- state = STATE_POST_INIT;
- init_cont ();
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Number of keys %d != 1.",
+ rd_count);
+ cleanup_consume_ticket_handle (handle);
+ GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
return;
}
- if (STATE_INIT == state) {
- new_entry = GNUNET_malloc (sizeof (struct EgoEntry));
- new_entry->ego = ego;
- new_entry->attr_map = GNUNET_CONTAINER_multihashmap_create (5,
- GNUNET_NO);
- new_entry->attributes_dirty = GNUNET_YES;
- GNUNET_CONTAINER_DLL_insert_tail(ego_head, ego_tail, new_entry);
+
+ //Decrypt
+ ecdh_key = (struct GNUNET_CRYPTO_EcdhePublicKey *)rd->data;
+
+ buf = GNUNET_malloc (rd->data_size - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
+
+ //Calculate symmetric key from ecdh parameters
+ GNUNET_assert (GNUNET_OK ==
+ GNUNET_CRYPTO_ecdsa_ecdh (&handle->identity,
+ ecdh_key,
+ &new_key_hash));
+ create_sym_key_from_ecdh (&new_key_hash,
+ &enc_key,
+ &enc_iv);
+ size = GNUNET_CRYPTO_symmetric_decrypt (rd->data + sizeof (struct GNUNET_CRYPTO_EcdhePublicKey),
+ rd->data_size - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey),
+ &enc_key,
+ &enc_iv,
+ buf);
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Decrypted bytes: %zd Expected bytes: %zd\n",
+ size, rd->data_size - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
+ GNUNET_STATISTICS_update (stats,
+ "abe_key_lookup_time_total",
+ GNUNET_TIME_absolute_get_duration (handle->lookup_start_time).rel_value_us,
+ GNUNET_YES);
+ GNUNET_STATISTICS_update (stats,
+ "abe_key_lookups_count",
+ 1,
+ GNUNET_YES);
+ scopes = GNUNET_strdup (buf);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Scopes %s\n", scopes);
+ handle->key = GNUNET_ABE_cpabe_deserialize_key ((void*)(buf + strlen (scopes) + 1),
+ rd->data_size - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)
+ - strlen (scopes) - 1);
+
+ for (scope = strtok (scopes, ","); NULL != scope; scope = strtok (NULL, ","))
+ {
+ GNUNET_asprintf (&lookup_query,
+ "%s.gnu",
+ scope);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Looking up %s\n", lookup_query);
+ parallel_lookup = GNUNET_new (struct ParallelLookup);
+ parallel_lookup->handle = handle;
+ parallel_lookup->label = GNUNET_strdup (scope);
+ parallel_lookup->lookup_start_time = GNUNET_TIME_absolute_get();
+ parallel_lookup->lookup_request
+ = GNUNET_GNS_lookup (gns_handle,
+ lookup_query,
+ &handle->ticket.identity,
+ GNUNET_GNSRECORD_TYPE_ID_ATTR,
+ GNUNET_GNS_LO_DEFAULT,
+ &process_parallel_lookup2,
+ parallel_lookup);
+ GNUNET_CONTAINER_DLL_insert (handle->parallel_lookups_head,
+ handle->parallel_lookups_tail,
+ parallel_lookup);
+ GNUNET_free (lookup_query);
+ }
+ GNUNET_free (scopes);
+ GNUNET_free (buf);
+ handle->kill_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES,3),
+ &abort_parallel_lookups2,
+ handle);
+}
+
+
+static void
+handle_consume_ticket_message (void *cls,
+ const struct ConsumeTicketMessage *cm)
+{
+ struct ConsumeTicketHandle *ch;
+ struct IdpClient *idp = cls;
+ char* lookup_query;
+ char* rnd_label;
+
+ ch = GNUNET_new (struct ConsumeTicketHandle);
+ ch->r_id = ntohl (cm->id);
+ ch->client = idp;
+ ch->identity = cm->identity;
+ ch->attrs = GNUNET_new (struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList);
+ GNUNET_CRYPTO_ecdsa_key_get_public (&ch->identity,
+ &ch->identity_pub);
+ ch->ticket = *((struct GNUNET_IDENTITY_PROVIDER_Ticket*)&cm[1]);
+ rnd_label = GNUNET_STRINGS_data_to_string_alloc (&ch->ticket.rnd,
+ sizeof (uint64_t));
+ GNUNET_asprintf (&lookup_query,
+ "%s.gnu",
+ rnd_label);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Looking for ABE key under %s\n", lookup_query);
+ ch->lookup_start_time = GNUNET_TIME_absolute_get ();
+ ch->lookup_request
+ = GNUNET_GNS_lookup (gns_handle,
+ lookup_query,
+ &ch->ticket.identity,
+ GNUNET_GNSRECORD_TYPE_ABE_KEY,
+ GNUNET_GNS_LO_DEFAULT,
+ &process_consume_abe_key,
+ ch);
+ GNUNET_free (rnd_label);
+ GNUNET_free (lookup_query);
+ GNUNET_SERVICE_client_continue (idp->client);
+}
+
+static void
+cleanup_as_handle (struct AttributeStoreHandle *handle)
+{
+ if (NULL != handle->claim)
+ GNUNET_free (handle->claim);
+ if (NULL != handle->abe_key)
+ GNUNET_ABE_cpabe_delete_master_key (handle->abe_key);
+ GNUNET_free (handle);
+}
+
+static void
+attr_store_cont (void *cls,
+ int32_t success,
+ const char *emsg)
+{
+ struct AttributeStoreHandle *as_handle = cls;
+ struct GNUNET_MQ_Envelope *env;
+ struct AttributeStoreResultMessage *acr_msg;
+
+ if (GNUNET_SYSERR == success)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Failed to store attribute %s\n",
+ emsg);
+ cleanup_as_handle (as_handle);
+ GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
+ return;
}
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Sending ATTRIBUTE_STORE_RESPONSE message\n");
+ env = GNUNET_MQ_msg (acr_msg,
+ 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,
+ env);
+ cleanup_as_handle (as_handle);
}
-/**
- * Cleanup task
- */
static void
-cleanup()
+attr_store_task (void *cls)
{
- struct EgoEntry *ego_entry;
- struct EgoEntry *ego_tmp;
+ struct AttributeStoreHandle *as_handle = cls;
+ struct GNUNET_GNSRECORD_Data rd[1];
+ char* buf;
+ char* policy;
+ char* enc_buf;
+ char* rd_buf;
+ size_t enc_size;
+ size_t buf_size;
+ uint32_t attr_ver;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Cleaning up\n");
- if (NULL != nc)
- {
- GNUNET_SERVER_notification_context_destroy (nc);
- nc = NULL;
- }
- if (NULL != stats)
- {
- GNUNET_STATISTICS_destroy (stats, GNUNET_NO);
- stats = NULL;
- }
-
- if (NULL != timeout_task)
- GNUNET_SCHEDULER_cancel (timeout_task);
- if (NULL != update_task)
- GNUNET_SCHEDULER_cancel (update_task);
- if (NULL != identity_handle)
- GNUNET_IDENTITY_disconnect (identity_handle);
- if (NULL != gns_handle)
- GNUNET_GNS_disconnect (gns_handle);
- if (NULL != ns_it)
- GNUNET_NAMESTORE_zone_iteration_stop (ns_it);
- if (NULL != ns_qe)
- GNUNET_NAMESTORE_cancel (ns_qe);
- if (NULL != ns_handle)
- GNUNET_NAMESTORE_disconnect (ns_handle);
- if (NULL != token)
- GNUNET_free (token);
- if (NULL != label)
- GNUNET_free (label);
+ "Storing attribute\n");
+ buf_size = GNUNET_IDENTITY_ATTRIBUTE_serialize_get_size (as_handle->claim);
+ buf = GNUNET_malloc (buf_size);
- for (ego_entry = ego_head;
- NULL != ego_entry;)
- {
- ego_tmp = ego_entry;
- if (0 != GNUNET_CONTAINER_multihashmap_size (ego_tmp->attr_map))
- {
- GNUNET_CONTAINER_multihashmap_iterate (ego_tmp->attr_map,
- &clear_ego_attrs,
- ego_tmp);
+ GNUNET_IDENTITY_ATTRIBUTE_serialize (as_handle->claim,
+ buf);
- }
- GNUNET_CONTAINER_multihashmap_destroy (ego_tmp->attr_map);
- ego_entry = ego_entry->next;
- GNUNET_free (ego_tmp);
- }
+ GNUNET_asprintf (&policy,
+ "%s_%lu",
+ as_handle->claim->name,
+ as_handle->claim->version);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Encrypting with policy %s\n", policy);
+ /**
+ * Encrypt the attribute value and store in namestore
+ */
+ enc_size = GNUNET_ABE_cpabe_encrypt (buf,
+ buf_size,
+ policy, //Policy
+ as_handle->abe_key,
+ (void**)&enc_buf);
+ GNUNET_free (buf);
+ GNUNET_free (policy);
+ rd[0].data_size = enc_size + sizeof (uint32_t);
+ rd_buf = GNUNET_malloc (rd[0].data_size);
+ attr_ver = htonl (as_handle->claim->version);
+ GNUNET_memcpy (rd_buf,
+ &attr_ver,
+ sizeof (uint32_t));
+ GNUNET_memcpy (rd_buf+sizeof (uint32_t),
+ enc_buf,
+ enc_size);
+ rd[0].data = rd_buf;
+ rd[0].record_type = GNUNET_GNSRECORD_TYPE_ID_ATTR;
+ rd[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
+ rd[0].expiration_time = GNUNET_TIME_UNIT_HOURS.rel_value_us; //TODO sane?
+ as_handle->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
+ &as_handle->identity,
+ as_handle->claim->name,
+ 1,
+ rd,
+ &attr_store_cont,
+ as_handle);
+ GNUNET_free (enc_buf);
+ GNUNET_free (rd_buf);
}
-/**
- * Shutdown task
- *
- * @param cls NULL
- * @param tc task context
- */
+
static void
-do_shutdown (void *cls,
- const struct GNUNET_SCHEDULER_TaskContext *tc)
+store_after_abe_bootstrap (void *cls,
+ struct GNUNET_ABE_AbeMasterKey *abe_key)
{
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Shutting down...\n");
- cleanup();
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Finished ABE bootstrap\n");
+ struct AttributeStoreHandle *ash = cls;
+ ash->abe_key = abe_key;
+ GNUNET_SCHEDULER_add_now (&attr_store_task, ash);
}
-
-static struct GNUNET_IDENTITY_PROVIDER_ExchangeResultMessage*
-create_exchange_result_message (const char* token,
- const char* label)
+static int
+check_attribute_store_message(void *cls,
+ const struct AttributeStoreMessage *sam)
{
- struct GNUNET_IDENTITY_PROVIDER_ExchangeResultMessage *erm;
- uint16_t token_len = strlen (token) + 1;
- erm = GNUNET_malloc (sizeof (struct GNUNET_IDENTITY_PROVIDER_ExchangeResultMessage)
- + token_len);
- erm->header.type = htons (GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_EXCHANGE_RESULT);
- erm->header.size = htons (sizeof (struct GNUNET_IDENTITY_PROVIDER_ExchangeResultMessage)
- + token_len);
- memcpy (&erm[1], token, token_len);
- return erm;
+ uint16_t size;
+
+ size = ntohs (sam->header.size);
+ if (size <= sizeof (struct AttributeStoreMessage))
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ return GNUNET_OK;
}
-static struct GNUNET_IDENTITY_PROVIDER_IssueResultMessage*
-create_issue_result_message (const char* label,
- const char* ticket,
- const char* token)
-{
- struct GNUNET_IDENTITY_PROVIDER_IssueResultMessage *irm;
- char *tmp_str;
-
- irm = GNUNET_malloc (sizeof (struct GNUNET_IDENTITY_PROVIDER_IssueResultMessage)
- + strlen (label) + 1
- + strlen (ticket) + 1
- + strlen (token) + 1);
- irm->header.type = htons (GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ISSUE_RESULT);
- irm->header.size = htons (sizeof (struct GNUNET_IDENTITY_PROVIDER_IssueResultMessage)
- + strlen (label) + 1
- + strlen (ticket) + 1
- + strlen (token) + 1);
- GNUNET_asprintf (&tmp_str, "%s,%s,%s", label, ticket, token);
- memcpy (&irm[1], tmp_str, strlen (tmp_str) + 1);
- GNUNET_free (tmp_str);
- return irm;
+static void
+handle_attribute_store_message (void *cls,
+ const struct AttributeStoreMessage *sam)
+{
+ struct AttributeStoreHandle *as_handle;
+ struct IdpClient *idp = cls;
+ size_t data_len;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Received ATTRIBUTE_STORE message\n");
+
+ data_len = ntohs (sam->attr_len);
+
+ as_handle = GNUNET_new (struct AttributeStoreHandle);
+ as_handle->claim = GNUNET_IDENTITY_ATTRIBUTE_deserialize ((char*)&sam[1],
+ data_len);
+
+ 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, GNUNET_NO);
}
static void
-cleanup_issue_handle (struct IssueHandle *handle)
-{
- if (NULL != handle->attr_map)
- GNUNET_CONTAINER_multihashmap_destroy (handle->attr_map);
- if (NULL != handle->scopes)
- GNUNET_free (handle->scopes);
- if (NULL != handle->token)
- token_destroy (handle->token);
- if (NULL != handle->ticket)
- ticket_destroy (handle->ticket);
- if (NULL != handle->label)
- GNUNET_free (handle->label);
- GNUNET_free (handle);
+cleanup_iter_handle (struct AttributeIterator *ai)
+{
+ if (NULL != ai->abe_key)
+ GNUNET_ABE_cpabe_delete_master_key (ai->abe_key);
+ GNUNET_CONTAINER_DLL_remove (ai->client->op_head,
+ ai->client->op_tail,
+ ai);
+ GNUNET_free (ai);
}
static void
-store_token_issue_cont (void *cls,
- int32_t success,
- const char *emsg)
-{
- struct IssueHandle *handle = cls;
- struct GNUNET_IDENTITY_PROVIDER_IssueResultMessage *irm;
- char *ticket_str;
- char *token_str;
- handle->ns_qe = NULL;
- if (GNUNET_SYSERR == success)
- {
- cleanup_issue_handle (handle);
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n",
- "Unknown Error\n");
- GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
- return;
- }
- if (GNUNET_OK != ticket_serialize (handle->ticket,
- &handle->iss_key,
- &ticket_str))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n",
- "Error serializing ticket\n");
- cleanup_issue_handle (handle);
- GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
- return;
- }
- if (GNUNET_OK != token_to_string (handle->token,
- &handle->iss_key,
- &token_str))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n",
- "Error serializing token\n");
- GNUNET_free (ticket_str);
- cleanup_issue_handle (handle);
- GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
- return;
- }
- irm = create_issue_result_message (handle->label, ticket_str, token_str);
- GNUNET_SERVER_notification_context_unicast (nc,
- handle->client,
- &irm->header,
- GNUNET_NO);
- GNUNET_SERVER_client_set_user_context (handle->client, NULL);
- cleanup_issue_handle (handle);
- GNUNET_free (irm);
- GNUNET_free (ticket_str);
- GNUNET_free (token_str);
+attr_iter_error (void *cls)
+{
+ struct AttributeIterator *ai = cls;
+ //TODO
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Failed to iterate over attributes\n");
+ cleanup_iter_handle (ai);
+ GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
}
-/**
- * Build a GNUid token for identity
- * @param handle the handle
- * @param ego_entry the ego to build the token for
- * @param name name of the ego
- * @param token_aud token audience
- * @param token the resulting gnuid token
- * @return identifier string of token (label)
- */
static void
-sign_and_return_token (void *cls,
- const struct GNUNET_SCHEDULER_TaskContext *tc)
+attr_iter_finished (void *cls)
{
- struct GNUNET_CRYPTO_EcdsaPublicKey pub_key;
- struct GNUNET_CRYPTO_EcdhePrivateKey *ecdhe_privkey;
- struct IssueHandle *handle = cls;
- struct GNUNET_GNSRECORD_Data token_record[2];
- char *nonce_str;
- char *enc_token_str;
- char *token_metadata;
- char* write_ptr;
- uint64_t time;
- uint64_t exp_time;
- size_t token_metadata_len;
-
- //Remote nonce
- nonce_str = NULL;
- GNUNET_asprintf (&nonce_str, "%d", handle->nonce);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Request nonce: %s\n", nonce_str);
-
- GNUNET_CRYPTO_ecdsa_key_get_public (&handle->iss_key,
- &pub_key);
- handle->ticket = ticket_create (nonce_str,
- &pub_key,
- handle->label,
- &handle->aud_key);
-
- time = GNUNET_TIME_absolute_get().abs_value_us;
- exp_time = time + token_expiration_interval.rel_value_us;
-
- token_add_attr_int (handle->token, "nbf", time);
- token_add_attr_int (handle->token, "iat", time);
- token_add_attr_int (handle->token, "exp", exp_time);
- token_add_attr (handle->token, "nonce", nonce_str);
-
- //Token in a serialized encrypted format
- GNUNET_assert (token_serialize (handle->token,
- &handle->iss_key,
- &ecdhe_privkey,
- &enc_token_str));
-
- //Token record E,E_K (Token)
- token_record[0].data = enc_token_str;
- token_record[0].data_size = strlen (enc_token_str) + 1;
- token_record[0].expiration_time = exp_time;
- token_record[0].record_type = GNUNET_GNSRECORD_TYPE_ID_TOKEN;
- token_record[0].flags = GNUNET_GNSRECORD_RF_NONE;
-
-
- token_metadata_len = sizeof (struct GNUNET_CRYPTO_EcdhePrivateKey)
- + sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)
- + strlen (handle->scopes) + 1; //With 0-Terminator
- token_metadata = GNUNET_malloc (token_metadata_len);
- write_ptr = token_metadata;
- memcpy (token_metadata, ecdhe_privkey, sizeof (struct GNUNET_CRYPTO_EcdhePrivateKey));
- write_ptr += sizeof (struct GNUNET_CRYPTO_EcdhePrivateKey);
- memcpy (write_ptr, &handle->aud_key, sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
- write_ptr += sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey);
- memcpy (write_ptr, handle->scopes, strlen (handle->scopes) + 1); //with 0-Terminator;
-
- token_record[1].data = token_metadata;
- token_record[1].data_size = token_metadata_len;
- token_record[1].expiration_time = exp_time;
- token_record[1].record_type = GNUNET_GNSRECORD_TYPE_ID_TOKEN_METADATA;
- token_record[1].flags = GNUNET_GNSRECORD_RF_PRIVATE;
-
- //Persist token
- handle->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
- &handle->iss_key,
- handle->label,
- 2,
- token_record,
- &store_token_issue_cont,
- handle);
- GNUNET_free (ecdhe_privkey);
- GNUNET_free (nonce_str);
- GNUNET_free (enc_token_str);
- GNUNET_free (token_metadata);
+ struct AttributeIterator *ai = cls;
+ struct GNUNET_MQ_Envelope *env;
+ struct AttributeResultMessage *arm;
+
+ env = GNUNET_MQ_msg (arm,
+ GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_RESULT);
+ arm->id = htonl (ai->request_id);
+ arm->attr_len = htons (0);
+ GNUNET_MQ_send (ai->client->mq, env);
+ cleanup_iter_handle (ai);
}
-/**
- * Collect attributes for token
- */
static void
-attr_collect (void *cls,
+attr_iter_cb (void *cls,
const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
const char *label,
unsigned int rd_count,
const struct GNUNET_GNSRECORD_Data *rd)
{
- int i;
- char* data;
- struct IssueHandle *handle = cls;
- struct GNUNET_HashCode key;
-
- if (NULL == label)
+ struct AttributeIterator *ai = cls;
+ struct AttributeResultMessage *arm;
+ struct GNUNET_ABE_AbeKey *key;
+ struct GNUNET_MQ_Envelope *env;
+ ssize_t msg_extra_len;
+ char* attr_ser;
+ char* attrs[2];
+ char* data_tmp;
+ char* policy;
+ uint32_t attr_ver;
+
+ if (rd_count != 1)
{
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding attribute END: \n");
- handle->ns_it = NULL;
- GNUNET_SCHEDULER_add_now (&sign_and_return_token, handle);
+ GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it);
return;
}
- GNUNET_CRYPTO_hash (label,
- strlen (label),
- &key);
-
- if (0 == rd_count ||
- ( (NULL != handle->attr_map) &&
- (GNUNET_YES != GNUNET_CONTAINER_multihashmap_contains (handle->attr_map,
- &key))
- )
- )
- {
- GNUNET_NAMESTORE_zone_iterator_next (handle->ns_it);
+ if (GNUNET_GNSRECORD_TYPE_ID_ATTR != rd->record_type) {
+ GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it);
return;
}
+ attr_ver = ntohl(*((uint32_t*)rd->data));
+ GNUNET_asprintf (&policy, "%s_%lu",
+ label, attr_ver);
+ attrs[0] = policy;
+ attrs[1] = 0;
+ key = GNUNET_ABE_cpabe_create_key (ai->abe_key,
+ attrs);
+ msg_extra_len = GNUNET_ABE_cpabe_decrypt (rd->data+sizeof (uint32_t),
+ rd->data_size-sizeof (uint32_t),
+ key,
+ (void**)&attr_ser);
+
+ GNUNET_ABE_cpabe_delete_key (key,
+ GNUNET_YES);
+ //GNUNET_free (policy);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Found attribute: %s\n", label);
+ env = GNUNET_MQ_msg_extra (arm,
+ msg_extra_len,
+ GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_RESULT);
+ arm->id = htonl (ai->request_id);
+ arm->attr_len = htons (msg_extra_len);
+ GNUNET_CRYPTO_ecdsa_key_get_public (zone,
+ &arm->identity);
+ data_tmp = (char *) &arm[1];
+ GNUNET_memcpy (data_tmp,
+ attr_ser,
+ msg_extra_len);
+ GNUNET_MQ_send (ai->client->mq, env);
+ GNUNET_free (attr_ser);
+ GNUNET_ABE_cpabe_delete_master_key (ai->abe_key);
+ ai->abe_key = NULL;
+}
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding attribute: %s\n", label);
-
- if (1 == rd_count)
- {
- if (rd->record_type == GNUNET_GNSRECORD_TYPE_ID_ATTR)
- {
- data = GNUNET_GNSRECORD_value_to_string (rd->record_type,
- rd->data,
- rd->data_size);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding value: %s\n", data);
- token_add_attr (handle->token,
- label,
- data);
- GNUNET_free (data);
- }
- GNUNET_NAMESTORE_zone_iterator_next (handle->ns_it);
- return;
- }
- i = 0;
- for (; i < rd_count; i++)
- {
- if (rd->record_type == GNUNET_GNSRECORD_TYPE_ID_ATTR)
- {
- data = GNUNET_GNSRECORD_value_to_string (rd[i].record_type,
- rd[i].data,
- rd[i].data_size);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding value: %s\n", data);
- token_add_attr (handle->token, label, data);
- GNUNET_free (data);
- }
- }
+void
+iterate_after_abe_bootstrap (void *cls,
+ struct GNUNET_ABE_AbeMasterKey *abe_key)
+{
+ struct AttributeIterator *ai = cls;
+ ai->abe_key = abe_key;
+ ai->ns_it = GNUNET_NAMESTORE_zone_iteration_start (ns_handle,
+ &ai->identity,
+ &attr_iter_error,
+ ai,
+ &attr_iter_cb,
+ ai,
+ &attr_iter_finished,
+ ai);
+}
- GNUNET_NAMESTORE_zone_iterator_next (handle->ns_it);
+void
+iterate_next_after_abe_bootstrap (void *cls,
+ struct GNUNET_ABE_AbeMasterKey *abe_key)
+{
+ struct AttributeIterator *ai = cls;
+ ai->abe_key = abe_key;
+ GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it);
}
+
+
static void
-cleanup_exchange_handle (struct ExchangeHandle *handle)
+handle_iteration_start (void *cls,
+ const struct AttributeIterationStartMessage *ais_msg)
{
- if (NULL != handle->ticket)
- ticket_destroy (handle->ticket);
- if (NULL != handle->token)
- token_destroy (handle->token);
- GNUNET_free (handle);
+ struct IdpClient *idp = cls;
+ struct AttributeIterator *ai;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Received ATTRIBUTE_ITERATION_START message\n");
+ ai = GNUNET_new (struct AttributeIterator);
+ ai->request_id = ntohl (ais_msg->id);
+ ai->client = idp;
+ ai->identity = ais_msg->identity;
+
+ GNUNET_CONTAINER_DLL_insert (idp->op_head,
+ idp->op_tail,
+ ai);
+ bootstrap_abe (&ai->identity, &iterate_after_abe_bootstrap, ai, GNUNET_NO);
+ GNUNET_SERVICE_client_continue (idp->client);
}
+
static void
-process_lookup_result (void *cls, uint32_t rd_count,
- const struct GNUNET_GNSRECORD_Data *rd)
+handle_iteration_stop (void *cls,
+ const struct AttributeIterationStopMessage *ais_msg)
{
- struct ExchangeHandle *handle = cls;
- struct GNUNET_IDENTITY_PROVIDER_ExchangeResultMessage *erm;
- char* token_str;
- char* record_str;
+ struct IdpClient *idp = cls;
+ struct AttributeIterator *ai;
+ uint32_t rid;
- handle->lookup_request = NULL;
- if (2 != rd_count)
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Received `%s' message\n",
+ "ATTRIBUTE_ITERATION_STOP");
+ rid = ntohl (ais_msg->id);
+ for (ai = idp->op_head; NULL != ai; ai = ai->next)
+ if (ai->request_id == rid)
+ break;
+ if (NULL == ai)
{
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Number of tokens %d != 2.",
- rd_count);
- cleanup_exchange_handle (handle);
- GNUNET_SCHEDULER_add_now (&do_shutdown, handle);
+ GNUNET_break (0);
+ GNUNET_SERVICE_client_drop (idp->client);
return;
}
-
- record_str =
- GNUNET_GNSRECORD_value_to_string (GNUNET_GNSRECORD_TYPE_ID_TOKEN,
- rd->data,
- rd->data_size);
-
- //Decrypt and parse
- GNUNET_assert (GNUNET_OK == token_parse (record_str,
- &handle->aud_privkey,
- &handle->token));
-
- //Readable
- GNUNET_assert (GNUNET_OK == token_to_string (handle->token,
- &handle->aud_privkey,
- &token_str));
-
- erm = create_exchange_result_message (token_str,
- handle->label);
- GNUNET_SERVER_notification_context_unicast (nc,
- handle->client,
- &erm->header,
- GNUNET_NO);
- GNUNET_SERVER_client_set_user_context (handle->client, NULL);
-
- cleanup_exchange_handle (handle);
- GNUNET_free (record_str);
- GNUNET_free (token_str);
- GNUNET_free (erm);
-
+ GNUNET_CONTAINER_DLL_remove (idp->op_head,
+ idp->op_tail,
+ ai);
+ GNUNET_free (ai);
+ GNUNET_SERVICE_client_continue (idp->client);
}
-
-/**
- *
- * Handler for exchange message
- *
- * @param cls unused
- * @param client who sent the message
- * @param message the message
- */
static void
-handle_exchange_message (void *cls,
- struct GNUNET_SERVER_Client *client,
- const struct GNUNET_MessageHeader *message)
+handle_iteration_next (void *cls,
+ const struct AttributeIterationNextMessage *ais_msg)
{
- const struct GNUNET_IDENTITY_PROVIDER_ExchangeMessage *em;
- struct ExchangeHandle *xchange_handle;
- uint16_t size;
- const char *ticket;
- char *lookup_query;
+ struct IdpClient *idp = cls;
+ struct AttributeIterator *ai;
+ uint32_t rid;
- size = ntohs (message->size);
- if (size <= sizeof (struct GNUNET_IDENTITY_PROVIDER_ExchangeMessage))
- {
- GNUNET_break (0);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return;
- }
- em = (const struct GNUNET_IDENTITY_PROVIDER_ExchangeMessage *) message;
- ticket = (const char *) &em[1];
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Received EXCHANGE of `%s' from client\n",
- ticket);
- xchange_handle = GNUNET_malloc (sizeof (struct ExchangeHandle));
- xchange_handle->aud_privkey = em->aud_privkey;
-
- if (GNUNET_SYSERR == ticket_parse (ticket,
- &xchange_handle->aud_privkey,
- &xchange_handle->ticket))
+ "Received ATTRIBUTE_ITERATION_NEXT message\n");
+ rid = ntohl (ais_msg->id);
+ for (ai = idp->op_head; NULL != ai; ai = ai->next)
+ if (ai->request_id == rid)
+ break;
+ if (NULL == ai)
{
- GNUNET_free (xchange_handle);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+ GNUNET_break (0);
+ GNUNET_SERVICE_client_drop (idp->client);
return;
}
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Looking for token under %s\n",
- xchange_handle->ticket->payload->label);
- GNUNET_asprintf (&lookup_query,
- "%s.gnu",
- xchange_handle->ticket->payload->label);
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
- GNUNET_SERVER_notification_context_add (nc, client);
- GNUNET_SERVER_client_set_user_context (client, xchange_handle);
- xchange_handle->client = client;
- xchange_handle->lookup_request = GNUNET_GNS_lookup (gns_handle,
- lookup_query,
- &xchange_handle->ticket->payload->identity_key,
- GNUNET_GNSRECORD_TYPE_ID_TOKEN,
- GNUNET_GNS_LO_LOCAL_MASTER,
- NULL,
- &process_lookup_result,
- xchange_handle);
- GNUNET_free (lookup_query);
-
+ bootstrap_abe (&ai->identity,
+ &iterate_next_after_abe_bootstrap,
+ ai,
+ GNUNET_NO);
+ GNUNET_SERVICE_client_continue (idp->client);
}
+/**
+ * Ticket iteration processor result
+ */
+enum ZoneIterationResult
+{
+ /**
+ * Iteration start.
+ */
+ IT_START = 0,
+
+ /**
+ * Found tickets,
+ * Continue to iterate with next iteration_next call
+ */
+ IT_SUCCESS_MORE_AVAILABLE = 1,
+
+ /**
+ * Iteration complete
+ */
+ IT_SUCCESS_NOT_MORE_RESULTS_AVAILABLE = 2
+};
+
/**
- *
- * Look for existing token
- *
- * @param cls the identity entry
- * @param zone the identity
- * @param lbl the name of the record
- * @param rd_count number of records
- * @param rd record data
- *
+ * Context for ticket iteration
*/
-static void
-find_existing_token (void *cls,
- const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
- const char *lbl,
- unsigned int rd_count,
- const struct GNUNET_GNSRECORD_Data *rd)
-{
- struct IssueHandle *handle = cls;
- const struct GNUNET_GNSRECORD_Data *token_metadata_record;
- struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key;
- struct GNUNET_HashCode key;
- int scope_count_token;
- uint64_t rnd_key;
- char *scope;
- char *tmp_scopes;
+struct TicketIterationProcResult
+{
+ /**
+ * The ticket iteration handle
+ */
+ struct TicketIteration *ti;
- if (NULL == lbl)
- {
- //Done
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- ">>> No existing token found\n");
- //Label
- rnd_key =
- GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG,
- UINT64_MAX);
- GNUNET_STRINGS_base64_encode ((char*)&rnd_key,
- sizeof (uint64_t),
- &handle->label);
- handle->ns_it = NULL;
- handle->ns_it = GNUNET_NAMESTORE_zone_iteration_start (ns_handle,
- &handle->iss_key,
- &attr_collect,
- handle);
- return;
- }
+ /**
+ * Iteration result: iteration done?
+ * #IT_SUCCESS_MORE_AVAILABLE: if there may be more results overall but
+ * we got one for now and have sent it to the client
+ * #IT_SUCCESS_NOT_MORE_RESULTS_AVAILABLE: if there are no further results,
+ * #IT_START: if we are still trying to find a result.
+ */
+ int res_iteration_finished;
- //There should be only a single record for a token under a label
- if (2 != rd_count)
- {
- GNUNET_NAMESTORE_zone_iterator_next (handle->ns_it);
- return;
- }
+};
- if (rd[0].record_type == GNUNET_GNSRECORD_TYPE_ID_TOKEN_METADATA)
- {
- token_metadata_record = &rd[0];
- } else {
- token_metadata_record = &rd[1];
- }
- if (token_metadata_record->record_type != GNUNET_GNSRECORD_TYPE_ID_TOKEN_METADATA)
- {
- GNUNET_NAMESTORE_zone_iterator_next (handle->ns_it);
- return;
- }
- ecdhe_privkey = *((struct GNUNET_CRYPTO_EcdhePrivateKey *)token_metadata_record->data);
- aud_key =
- (struct GNUNET_CRYPTO_EcdsaPublicKey *)(token_metadata_record->data+sizeof(struct GNUNET_CRYPTO_EcdhePrivateKey));
- tmp_scopes = GNUNET_strdup ((char*) aud_key+sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
+static void
+cleanup_ticket_iter_handle (struct TicketIteration *ti)
+{
+ GNUNET_free (ti);
+}
- if (0 != memcmp (aud_key, &handle->aud_key,
- sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)))
+/**
+ * Process ticket from database
+ *
+ * @param cls struct TicketIterationProcResult
+ * @param ticket the ticket
+ * @param attrs the attributes
+ */
+static void
+ticket_iterate_proc (void *cls,
+ const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket,
+ const struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs)
+{
+ struct TicketIterationProcResult *proc = cls;
+
+ if (NULL == ticket)
{
- char *tmp2 = GNUNET_STRINGS_data_to_string_alloc (aud_key,
- sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
- //Audience does not match!
- char *tmp = GNUNET_GNSRECORD_value_to_string (GNUNET_GNSRECORD_TYPE_ID_TOKEN_METADATA,
- token_metadata_record->data,
- token_metadata_record->data_size);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Token does not match audience %s vs %s. Moving on\n",
- tmp2,
- tmp);
- GNUNET_free (tmp_scopes);
- GNUNET_NAMESTORE_zone_iterator_next (handle->ns_it);
+ "Iteration done\n");
+ proc->res_iteration_finished = IT_SUCCESS_NOT_MORE_RESULTS_AVAILABLE;
return;
}
+ proc->res_iteration_finished = IT_SUCCESS_MORE_AVAILABLE;
+ send_ticket_result (proc->ti->client,
+ proc->ti->r_id,
+ ticket,
+ attrs);
- scope = strtok (tmp_scopes, ",");
- scope_count_token = 0;
- while (NULL != scope)
- {
- GNUNET_CRYPTO_hash (scope,
- strlen (scope),
- &key);
+}
- if ((NULL != handle->attr_map) &&
- (GNUNET_YES != GNUNET_CONTAINER_multihashmap_contains (handle->attr_map, &key)))
+/**
+ * Perform ticket iteration step
+ *
+ * @param ti ticket iterator to process
+ */
+static void
+run_ticket_iteration_round (struct TicketIteration *ti)
+{
+ struct TicketIterationProcResult proc;
+ struct GNUNET_MQ_Envelope *env;
+ struct TicketResultMessage *trm;
+ int ret;
+
+ memset (&proc, 0, sizeof (proc));
+ proc.ti = ti;
+ proc.res_iteration_finished = IT_START;
+ while (IT_START == proc.res_iteration_finished)
+ {
+ if (GNUNET_SYSERR ==
+ (ret = TKT_database->iterate_tickets (TKT_database->cls,
+ &ti->identity,
+ ti->is_audience,
+ ti->offset,
+ &ticket_iterate_proc,
+ &proc)))
{
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Issued token does not include `%s'. Moving on\n", scope);
- GNUNET_free (tmp_scopes);
- GNUNET_NAMESTORE_zone_iterator_next (handle->ns_it);
- return;
+ GNUNET_break (0);
+ break;
}
- scope_count_token++;
- scope = strtok (NULL, ",");
+ if (GNUNET_NO == ret)
+ proc.res_iteration_finished = IT_SUCCESS_NOT_MORE_RESULTS_AVAILABLE;
+ ti->offset++;
}
- GNUNET_free (tmp_scopes);
- //All scopes in token are also in request. Now
- //Check length
- if (GNUNET_CONTAINER_multihashmap_size (handle->attr_map) == scope_count_token)
+ if (IT_SUCCESS_MORE_AVAILABLE == proc.res_iteration_finished)
{
- //We have an existing token
- handle->label = GNUNET_strdup (lbl);
- handle->ns_it = NULL;
- handle->ns_it = GNUNET_NAMESTORE_zone_iteration_start (ns_handle,
- &handle->iss_key,
- &attr_collect,
- handle);
-
- return;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "More results available\n");
+ return; /* more later */
}
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Nuber of attributes in token do not match request\n");
- //No luck
- GNUNET_NAMESTORE_zone_iterator_next (handle->ns_it);
+ /* send empty response to indicate end of list */
+ env = GNUNET_MQ_msg (trm,
+ GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_RESULT);
+ trm->id = htonl (ti->r_id);
+ GNUNET_MQ_send (ti->client->mq,
+ env);
+ GNUNET_CONTAINER_DLL_remove (ti->client->ticket_iter_head,
+ ti->client->ticket_iter_tail,
+ ti);
+ cleanup_ticket_iter_handle (ti);
}
-
-/**
- *
- * Handler for issue message
- *
- * @param cls unused
- * @param client who sent the message
- * @param message the message
- */
static void
-handle_issue_message (void *cls,
- struct GNUNET_SERVER_Client *client,
- const struct GNUNET_MessageHeader *message)
+handle_ticket_iteration_start (void *cls,
+ const struct TicketIterationStartMessage *tis_msg)
{
- const struct GNUNET_IDENTITY_PROVIDER_IssueMessage *im;
- const char *scopes;
+ struct IdpClient *client = cls;
+ struct TicketIteration *ti;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Received TICKET_ITERATION_START message\n");
+ ti = GNUNET_new (struct TicketIteration);
+ ti->r_id = ntohl (tis_msg->id);
+ ti->offset = 0;
+ ti->client = client;
+ ti->identity = tis_msg->identity;
+ ti->is_audience = ntohl (tis_msg->is_audience);
+
+ GNUNET_CONTAINER_DLL_insert (client->ticket_iter_head,
+ client->ticket_iter_tail,
+ ti);
+ run_ticket_iteration_round (ti);
+ GNUNET_SERVICE_client_continue (client->client);
+}
- uint16_t size;
- char *scopes_tmp;
- char *scope;
- struct GNUNET_HashCode key;
- struct IssueHandle *issue_handle;
- size = ntohs (message->size);
- if (size <= sizeof (struct GNUNET_IDENTITY_PROVIDER_IssueMessage))
+static void
+handle_ticket_iteration_stop (void *cls,
+ const struct TicketIterationStopMessage *tis_msg)
+{
+ struct IdpClient *client = cls;
+ struct TicketIteration *ti;
+ uint32_t rid;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Received `%s' message\n",
+ "TICKET_ITERATION_STOP");
+ rid = ntohl (tis_msg->id);
+ for (ti = client->ticket_iter_head; NULL != ti; ti = ti->next)
+ if (ti->r_id == rid)
+ break;
+ if (NULL == ti)
{
GNUNET_break (0);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+ GNUNET_SERVICE_client_drop (client->client);
return;
}
- im = (const struct GNUNET_IDENTITY_PROVIDER_IssueMessage *) message;
- scopes = (const char *) &im[1];
+ GNUNET_CONTAINER_DLL_remove (client->ticket_iter_head,
+ client->ticket_iter_tail,
+ ti);
+ cleanup_ticket_iter_handle (ti);
+ GNUNET_SERVICE_client_continue (client->client);
+}
+
+
+static void
+handle_ticket_iteration_next (void *cls,
+ const struct TicketIterationNextMessage *tis_msg)
+{
+ struct IdpClient *client = cls;
+ struct TicketIteration *ti;
+ uint32_t rid;
+
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Received ISSUE of `%s' from client\n",
- scope);
- issue_handle = GNUNET_malloc (sizeof (struct IssueHandle));
- issue_handle->attr_map = GNUNET_CONTAINER_multihashmap_create (5,
- GNUNET_NO);
- scopes_tmp = GNUNET_strdup (scopes);
- scope = strtok(scopes_tmp, ",");
- for (; NULL != scope; scope = strtok (NULL, ","))
+ "Received TICKET_ITERATION_NEXT message\n");
+ rid = ntohl (tis_msg->id);
+ for (ti = client->ticket_iter_head; NULL != ti; ti = ti->next)
+ if (ti->r_id == rid)
+ break;
+ if (NULL == ti)
{
- GNUNET_CRYPTO_hash (scope,
- strlen (scope),
- &key);
- GNUNET_CONTAINER_multihashmap_put (issue_handle->attr_map,
- &key,
- scope,
- GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE);
+ GNUNET_break (0);
+ GNUNET_SERVICE_client_drop (client->client);
+ return;
}
- GNUNET_free (scopes_tmp);
-
- issue_handle->aud_key = im->aud_key;
- issue_handle->iss_key = im->iss_key;
- GNUNET_CRYPTO_ecdsa_key_get_public (&im->iss_key,
- &issue_handle->iss_pkey);
- issue_handle->expiration = GNUNET_TIME_absolute_ntoh (im->expiration);
- issue_handle->nonce = ntohl (im->nonce);
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
- GNUNET_SERVER_notification_context_add (nc, client);
- GNUNET_SERVER_client_set_user_context (client, issue_handle);
- issue_handle->client = client;
- issue_handle->scopes = GNUNET_strdup (scopes);
- issue_handle->token = token_create (&issue_handle->iss_pkey,
- &issue_handle->aud_key);
-
- issue_handle->ns_it = GNUNET_NAMESTORE_zone_iteration_start (ns_handle,
- &im->iss_key,
- &find_existing_token,
- issue_handle);
+ run_ticket_iteration_round (ti);
+ GNUNET_SERVICE_client_continue (client->client);
}
+
+
+
/**
* Main function that will be run
*
* @param cls closure
- * @param args remaining command-line arguments
- * @param cfgfile name of the configuration file used (for saving, can be NULL)
- * @param c configuration
+ * @param c the configuration used
+ * @param server the service handle
*/
static void
-run (void *cls,
- struct GNUNET_SERVER_Handle *server,
- const struct GNUNET_CONFIGURATION_Handle *c)
-{
- static const struct GNUNET_SERVER_MessageHandler handlers[] = {
- {&handle_issue_message, NULL,
- GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ISSUE, 0},
- {&handle_exchange_message, NULL,
- GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_EXCHANGE, 0},
- {NULL, NULL, 0, 0}
- };
-
+run (void *cls,
+ const struct GNUNET_CONFIGURATION_Handle *c,
+ struct GNUNET_SERVICE_Handle *server)
+{
+ char *database;
cfg = c;
stats = GNUNET_STATISTICS_create ("identity-provider", cfg);
- GNUNET_SERVER_add_handlers (server, handlers);
- nc = GNUNET_SERVER_notification_context_create (server, 1);
//Connect to identity and namestore services
ns_handle = GNUNET_NAMESTORE_connect (cfg);
{
GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "error connecting to gns");
}
-
+ credential_handle = GNUNET_CREDENTIAL_connect (cfg);
+ if (NULL == credential_handle)
+ {
+ GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "error connecting to credential");
+ }
identity_handle = GNUNET_IDENTITY_connect (cfg,
- &list_ego,
+ NULL,
NULL);
+ /* Loading DB plugin */
+ if (GNUNET_OK !=
+ GNUNET_CONFIGURATION_get_value_string (cfg,
+ "identity-provider",
+ "database",
+ &database))
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "No database backend configured\n");
+ GNUNET_asprintf (&db_lib_name,
+ "libgnunet_plugin_identity_provider_%s",
+ database);
+ TKT_database = GNUNET_PLUGIN_load (db_lib_name,
+ (void *) cfg);
+ GNUNET_free (database);
+ if (NULL == TKT_database)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Could not load database backend `%s'\n",
+ db_lib_name);
+ GNUNET_SCHEDULER_shutdown ();
+ return;
+ }
- if (GNUNET_OK ==
+ if (GNUNET_OK ==
GNUNET_CONFIGURATION_get_value_time (cfg,
"identity-provider",
"TOKEN_EXPIRATION_INTERVAL",
token_expiration_interval = DEFAULT_TOKEN_EXPIRATION_INTERVAL;
}
- GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL,
- &do_shutdown, NULL);
+ GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL);
}
-
/**
+ * Called whenever a client is disconnected.
*
- * The main function
- *
- * @param argc number of arguments from the cli
- * @param argv command line arguments
- * @return 0 ok, 1 on error
+ * @param cls closure
+ * @param client identification of the client
+ * @param app_ctx @a client
+ */
+static void
+client_disconnect_cb (void *cls,
+ struct GNUNET_SERVICE_Client *client,
+ void *app_ctx)
+{
+ struct IdpClient *idp = app_ctx;
+ struct AttributeIterator *ai;
+ struct TicketIteration *ti;
+ struct TicketRevocationHandle *rh;
+
+ //TODO other operations
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Client %p disconnected\n",
+ client);
+
+ while (NULL != (ai = idp->op_head))
+ {
+ GNUNET_CONTAINER_DLL_remove (idp->op_head,
+ idp->op_tail,
+ ai);
+ GNUNET_free (ai);
+ }
+ while (NULL != (rh = idp->revocation_list_head))
+ {
+ GNUNET_CONTAINER_DLL_remove (idp->revocation_list_head,
+ idp->revocation_list_tail,
+ rh);
+ cleanup_revoke_ticket_handle (rh);
+ }
+ while (NULL != (ti = idp->ticket_iter_head))
+ {
+ GNUNET_CONTAINER_DLL_remove (idp->ticket_iter_head,
+ idp->ticket_iter_tail,
+ ti);
+ cleanup_ticket_iter_handle (ti);
+ }
+ GNUNET_free (idp);
+}
+
+
+/**
+ * Add a client to our list of active clients.
*
+ * @param cls NULL
+ * @param client client to add
+ * @param mq message queue for @a client
+ * @return internal namestore client structure for this client
*/
-int
-main (int argc, char *const *argv)
+static void *
+client_connect_cb (void *cls,
+ struct GNUNET_SERVICE_Client *client,
+ struct GNUNET_MQ_Handle *mq)
{
- return (GNUNET_OK ==
- GNUNET_SERVICE_run (argc, argv, "identity-provider",
- GNUNET_SERVICE_OPTION_NONE,
- &run, NULL)) ? 0 : 1;
+ struct IdpClient *idp;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Client %p connected\n",
+ client);
+ idp = GNUNET_new (struct IdpClient);
+ idp->client = client;
+ idp->mq = mq;
+ return idp;
}
-/* end of gnunet-rest-server.c */
+
+
+/**
+ * Define "main" method using service macro.
+ */
+GNUNET_SERVICE_MAIN
+("identity-provider",
+ GNUNET_SERVICE_OPTION_NONE,
+ &run,
+ &client_connect_cb,
+ &client_disconnect_cb,
+ NULL,
+ GNUNET_MQ_hd_var_size (attribute_store_message,
+ GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_STORE,
+ struct AttributeStoreMessage,
+ NULL),
+ GNUNET_MQ_hd_fixed_size (iteration_start,
+ GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_START,
+ struct AttributeIterationStartMessage,
+ NULL),
+ GNUNET_MQ_hd_fixed_size (iteration_next,
+ GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_NEXT,
+ struct AttributeIterationNextMessage,
+ NULL),
+ GNUNET_MQ_hd_fixed_size (iteration_stop,
+ GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_STOP,
+ struct AttributeIterationStopMessage,
+ NULL),
+ GNUNET_MQ_hd_var_size (issue_ticket_message,
+ GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ISSUE_TICKET,
+ struct IssueTicketMessage,
+ NULL),
+ GNUNET_MQ_hd_var_size (consume_ticket_message,
+ GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_CONSUME_TICKET,
+ struct ConsumeTicketMessage,
+ NULL),
+ GNUNET_MQ_hd_fixed_size (ticket_iteration_start,
+ GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_START,
+ struct TicketIterationStartMessage,
+ NULL),
+ GNUNET_MQ_hd_fixed_size (ticket_iteration_next,
+ GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_NEXT,
+ struct TicketIterationNextMessage,
+ NULL),
+ GNUNET_MQ_hd_fixed_size (ticket_iteration_stop,
+ GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_STOP,
+ struct TicketIterationStopMessage,
+ NULL),
+ GNUNET_MQ_hd_var_size (revoke_ticket_message,
+ GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_REVOKE_TICKET,
+ struct RevokeTicketMessage,
+ NULL),
+ GNUNET_MQ_handler_end());
+/* end of gnunet-service-identity-provider.c */