2 This file is part of GNUnet.
3 Copyright (C) 2012-2015 GNUnet e.V.
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
18 SPDX-License-Identifier: AGPL3.0-or-later
21 * @author Martin Schanzenbach
22 * @file src/reclaim/gnunet-service-reclaim.c
23 * @brief reclaim Service
27 #include "gnunet_util_lib.h"
28 #include "gnunet_constants.h"
29 #include "gnunet_protocols.h"
30 #include "gnunet_identity_service.h"
31 #include "gnunet_gnsrecord_lib.h"
32 #include "gnunet_namestore_service.h"
33 #include "gnunet_abe_lib.h"
34 #include "gnunet_credential_service.h"
35 #include "gnunet_statistics_service.h"
36 #include "gnunet_gns_service.h"
37 #include "gnunet_reclaim_plugin.h"
38 #include "gnunet_reclaim_attribute_lib.h"
39 #include "gnunet_signatures.h"
48 * Normal operation state
50 #define STATE_POST_INIT 1
53 * Minimum interval between updates
55 #define MIN_WAIT_TIME GNUNET_TIME_UNIT_MINUTES
58 * Standard token expiration time
60 #define DEFAULT_TOKEN_EXPIRATION_INTERVAL GNUNET_TIME_UNIT_HOURS
65 static struct GNUNET_IDENTITY_Handle *identity_handle;
70 static struct GNUNET_RECLAIM_PluginFunctions *TKT_database;
75 static char *db_lib_name;
78 * Token expiration interval
80 static struct GNUNET_TIME_Relative token_expiration_interval;
85 static struct GNUNET_NAMESTORE_Handle *ns_handle;
90 static struct GNUNET_GNS_Handle *gns_handle;
95 static struct GNUNET_CREDENTIAL_Handle *credential_handle;
100 static struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
105 static struct GNUNET_NAMESTORE_ZoneIterator *ns_it;
110 static struct GNUNET_SCHEDULER_Task *timeout_task;
115 static struct GNUNET_SCHEDULER_Task *update_task;
119 * Currently processed token
121 static struct IdentityToken *token;
124 * Label for currently processed token
129 * Scopes for processed token
134 * Handle to the statistics service.
136 static struct GNUNET_STATISTICS_Handle *stats;
141 static const struct GNUNET_CONFIGURATION_Handle *cfg;
149 * A ticket iteration operation.
151 struct TicketIteration
156 struct TicketIteration *next;
161 struct TicketIteration *prev;
164 * Client which intiated this zone iteration
166 struct IdpClient *client;
169 * Key of the identity we are iterating over.
171 struct GNUNET_CRYPTO_EcdsaPublicKey identity;
174 * Identity is audience
176 uint32_t is_audience;
179 * The operation id fot the iteration in the response for the client
184 * Offset of the iteration used to address next result of the
185 * iteration in the store
187 * Initialy set to 0 in handle_iteration_start
188 * Incremented with by every call to handle_iteration_next
197 * Callback after an ABE bootstrap
200 * @param abe_key the ABE key that exists or was created
203 (*AbeBootstrapResult) (void *cls,
204 struct GNUNET_ABE_AbeMasterKey *abe_key);
207 struct AbeBootstrapHandle
210 * Function to call when finished
212 AbeBootstrapResult proc;
220 * Key of the zone we are iterating over.
222 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
225 * Namestore Queue Entry
227 struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
230 * The issuer egos ABE master key
232 struct GNUNET_ABE_AbeMasterKey *abe_key;
235 * Recreate master keys
241 * An attribute iteration operation.
243 struct AttributeIterator
246 * Next element in the DLL
248 struct AttributeIterator *next;
251 * Previous element in the DLL
253 struct AttributeIterator *prev;
256 * IDP client which intiated this zone iteration
258 struct IdpClient *client;
261 * Key of the zone we are iterating over.
263 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
266 * The issuer egos ABE master key
268 struct GNUNET_ABE_AbeMasterKey *abe_key;
273 struct GNUNET_NAMESTORE_ZoneIterator *ns_it;
276 * The operation id fot the zone iteration in the response for the client
293 struct GNUNET_SERVICE_Client *client;
296 * Message queue for transmission to @e client
298 struct GNUNET_MQ_Handle *mq;
302 * Attribute iteration operations in
303 * progress initiated by this client
305 struct AttributeIterator *attr_iter_head;
309 * Attribute iteration operations
310 * in progress initiated by this client
312 struct AttributeIterator *attr_iter_tail;
315 * Head of DLL of ticket iteration ops
317 struct TicketIteration *ticket_iter_head;
320 * Tail of DLL of ticket iteration ops
322 struct TicketIteration *ticket_iter_tail;
325 * Head of DLL of ticket revocation ops
327 struct TicketRevocationHandle *revoke_op_head;
330 * Tail of DLL of ticket revocation ops
332 struct TicketRevocationHandle *revoke_op_tail;
335 * Head of DLL of ticket issue ops
337 struct TicketIssueHandle *issue_op_head;
340 * Tail of DLL of ticket issue ops
342 struct TicketIssueHandle *issue_op_tail;
345 * Head of DLL of ticket consume ops
347 struct ConsumeTicketHandle *consume_op_head;
350 * Tail of DLL of ticket consume ops
352 struct ConsumeTicketHandle *consume_op_tail;
355 * Head of DLL of attribute store ops
357 struct AttributeStoreHandle *store_op_head;
360 * Tail of DLL of attribute store ops
362 struct AttributeStoreHandle *store_op_tail;
366 struct AttributeStoreHandle
371 struct AttributeStoreHandle *next;
376 struct AttributeStoreHandle *prev;
381 struct IdpClient *client;
386 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
391 struct GNUNET_CRYPTO_EcdsaPublicKey identity_pkey;
394 * The issuer egos ABE master key
396 struct GNUNET_ABE_AbeMasterKey *abe_key;
401 struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
404 * The attribute to store
406 struct GNUNET_RECLAIM_ATTRIBUTE_Claim *claim;
409 * The attribute expiration interval
411 struct GNUNET_TIME_Relative exp;
421 struct ParallelLookup;
423 struct ConsumeTicketHandle
428 struct ConsumeTicketHandle *next;
433 struct ConsumeTicketHandle *prev;
438 struct IdpClient *client;
443 struct GNUNET_RECLAIM_Ticket ticket;
448 struct GNUNET_GNS_LookupRequest *lookup_request;
453 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
458 struct GNUNET_CRYPTO_EcdsaPublicKey identity_pub;
463 struct ParallelLookup *parallel_lookups_head;
468 struct ParallelLookup *parallel_lookups_tail;
473 struct GNUNET_SCHEDULER_Task *kill_task;
478 struct GNUNET_ABE_AbeKey *key;
483 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs;
488 struct GNUNET_TIME_Absolute lookup_start_time;
497 * Handle for a parallel GNS lookup job
499 struct ParallelLookup
502 struct ParallelLookup *next;
505 struct ParallelLookup *prev;
507 /* The GNS request */
508 struct GNUNET_GNS_LookupRequest *lookup_request;
510 /* The handle the return to */
511 struct ConsumeTicketHandle *handle;
516 struct GNUNET_TIME_Absolute lookup_start_time;
518 /* The label to look up */
523 * Ticket revocation request handle
525 struct TicketRevocationHandle
530 struct TicketRevocationHandle *prev;
535 struct TicketRevocationHandle *next;
540 struct IdpClient *client;
543 * Attributes to reissue
545 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs;
548 * Attributes to revoke
550 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *rvk_attrs;
555 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
560 struct GNUNET_RECLAIM_Ticket ticket;
565 struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
570 struct GNUNET_NAMESTORE_ZoneIterator *ns_it;
575 struct GNUNET_ABE_AbeMasterKey *abe_key;
591 * Ticket issue request handle
593 struct TicketIssueHandle
598 struct TicketIssueHandle *prev;
603 struct TicketIssueHandle *next;
608 struct IdpClient *client;
611 * Attributes to issue
613 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs;
618 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
623 struct GNUNET_RECLAIM_Ticket ticket;
628 struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
638 * DLL for ego handles to egos containing the ID_ATTRS in a map in json_t format
646 struct EgoEntry *next;
651 struct EgoEntry *prev;
656 struct GNUNET_IDENTITY_Ego *ego;
659 * Attribute map. Contains the attributes as json_t
661 struct GNUNET_CONTAINER_MultiHashMap *attr_map;
671 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
676 GNUNET_STATISTICS_destroy (stats, GNUNET_NO);
679 GNUNET_break (NULL == GNUNET_PLUGIN_unload (db_lib_name,
681 GNUNET_free (db_lib_name);
683 if (NULL != timeout_task)
684 GNUNET_SCHEDULER_cancel (timeout_task);
685 if (NULL != update_task)
686 GNUNET_SCHEDULER_cancel (update_task);
687 if (NULL != identity_handle)
688 GNUNET_IDENTITY_disconnect (identity_handle);
689 if (NULL != gns_handle)
690 GNUNET_GNS_disconnect (gns_handle);
691 if (NULL != credential_handle)
692 GNUNET_CREDENTIAL_disconnect (credential_handle);
694 GNUNET_NAMESTORE_zone_iteration_stop (ns_it);
696 GNUNET_NAMESTORE_cancel (ns_qe);
697 if (NULL != ns_handle)
698 GNUNET_NAMESTORE_disconnect (ns_handle);
699 GNUNET_free_non_null (token);
700 GNUNET_free_non_null (label);
710 do_shutdown (void *cls)
712 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
713 "Shutting down...\n");
718 * Finished storing newly bootstrapped ABE key
721 bootstrap_store_cont (void *cls,
725 struct AbeBootstrapHandle *abh = cls;
726 if (GNUNET_SYSERR == success)
728 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
729 "Failed to bootstrap ABE master %s\n",
731 abh->proc (abh->proc_cls, NULL);
732 GNUNET_free (abh->abe_key);
736 abh->proc (abh->proc_cls, abh->abe_key);
742 * Error checking for ABE master
745 bootstrap_abe_error (void *cls)
747 struct AbeBootstrapHandle *abh = cls;
748 abh->proc (abh->proc_cls, NULL);
754 * Handle ABE lookup in namestore
757 bootstrap_abe_result (void *cls,
758 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
760 unsigned int rd_count,
761 const struct GNUNET_GNSRECORD_Data *rd)
763 struct AbeBootstrapHandle *abh = cls;
764 struct GNUNET_ABE_AbeMasterKey *abe_key;
766 for (uint32_t i=0;i<rd_count;i++) {
767 if (GNUNET_GNSRECORD_TYPE_ABE_MASTER != rd[i].record_type)
769 if (GNUNET_YES == abh->recreate)
771 abe_key = GNUNET_ABE_cpabe_deserialize_master_key (rd[i].data,
773 abh->proc (abh->proc_cls, abe_key);
778 //No ABE master found, bootstrapping...
779 abh->abe_key = GNUNET_ABE_cpabe_create_master_key ();
782 struct GNUNET_GNSRECORD_Data rdn[rd_count+1];
784 unsigned int rd_count_new = rd_count + 1;
786 for (uint32_t i=0;i<rd_count;i++) {
787 if ((GNUNET_YES == abh->recreate) &&
788 (GNUNET_GNSRECORD_TYPE_ABE_MASTER == rd[i].record_type))
790 rdn[i].data_size = GNUNET_ABE_cpabe_serialize_master_key (abh->abe_key,
793 rdn[i].record_type = GNUNET_GNSRECORD_TYPE_ABE_MASTER;
794 rdn[i].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION | GNUNET_GNSRECORD_RF_PRIVATE;
795 rdn[i].expiration_time = GNUNET_TIME_UNIT_HOURS.rel_value_us; //TODO sane?
796 rd_count_new = rd_count;
798 GNUNET_memcpy (&rdn[i],
800 sizeof (struct GNUNET_GNSRECORD_Data));
803 if (rd_count < rd_count_new) {
804 rdn[rd_count].data_size = GNUNET_ABE_cpabe_serialize_master_key (abh->abe_key,
806 rdn[rd_count].data = key;
807 rdn[rd_count].record_type = GNUNET_GNSRECORD_TYPE_ABE_MASTER;
808 rdn[rd_count].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION | GNUNET_GNSRECORD_RF_PRIVATE;
809 rdn[rd_count].expiration_time = GNUNET_TIME_UNIT_HOURS.rel_value_us; //TODO sane?
812 abh->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
817 &bootstrap_store_cont,
824 * Bootstrap ABE master if it does not yet exists.
825 * Will call the AbeBootstrapResult processor when done.
826 * will always recreate the ABE key of GNUNET_YES == recreate
829 bootstrap_abe (const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
830 AbeBootstrapResult proc,
834 struct AbeBootstrapHandle *abh;
836 abh = GNUNET_new (struct AbeBootstrapHandle);
839 abh->identity = *identity;
840 if (GNUNET_YES == recreate)
842 abh->abe_key = GNUNET_ABE_cpabe_create_master_key ();
843 abh->recreate = GNUNET_YES;
845 abh->recreate = GNUNET_NO;
847 abh->ns_qe = GNUNET_NAMESTORE_records_lookup (ns_handle,
850 &bootstrap_abe_error,
852 &bootstrap_abe_result,
859 create_sym_key_from_ecdh(const struct GNUNET_HashCode *new_key_hash,
860 struct GNUNET_CRYPTO_SymmetricSessionKey *skey,
861 struct GNUNET_CRYPTO_SymmetricInitializationVector *iv)
863 struct GNUNET_CRYPTO_HashAsciiEncoded new_key_hash_str;
865 GNUNET_CRYPTO_hash_to_enc (new_key_hash,
867 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating symmetric rsa key from %s\n", (char*)&new_key_hash_str);
868 static const char ctx_key[] = "gnuid-aes-ctx-key";
869 GNUNET_CRYPTO_kdf (skey, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
870 new_key_hash, sizeof (struct GNUNET_HashCode),
871 ctx_key, strlen (ctx_key),
873 static const char ctx_iv[] = "gnuid-aes-ctx-iv";
874 GNUNET_CRYPTO_kdf (iv, sizeof (struct GNUNET_CRYPTO_SymmetricInitializationVector),
875 new_key_hash, sizeof (struct GNUNET_HashCode),
876 ctx_iv, strlen (ctx_iv),
882 * Cleanup ticket consume handle
883 * @param handle the handle to clean up
886 cleanup_ticket_issue_handle (struct TicketIssueHandle *handle)
888 if (NULL != handle->attrs)
889 GNUNET_RECLAIM_ATTRIBUTE_list_destroy (handle->attrs);
890 if (NULL != handle->ns_qe)
891 GNUNET_NAMESTORE_cancel (handle->ns_qe);
892 GNUNET_free (handle);
897 send_ticket_result (struct IdpClient *client,
899 const struct GNUNET_RECLAIM_Ticket *ticket,
900 const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs)
902 struct TicketResultMessage *irm;
903 struct GNUNET_MQ_Envelope *env;
904 struct GNUNET_RECLAIM_Ticket *ticket_buf;
906 /* store ticket in DB */
907 if (GNUNET_OK != TKT_database->store_ticket (TKT_database->cls,
911 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
912 "Unable to store ticket after issue\n");
916 env = GNUNET_MQ_msg_extra (irm,
917 sizeof (struct GNUNET_RECLAIM_Ticket),
918 GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT);
919 ticket_buf = (struct GNUNET_RECLAIM_Ticket *)&irm[1];
920 *ticket_buf = *ticket;
921 irm->id = htonl (r_id);
922 GNUNET_MQ_send (client->mq,
927 store_ticket_issue_cont (void *cls,
931 struct TicketIssueHandle *handle = cls;
933 handle->ns_qe = NULL;
934 GNUNET_CONTAINER_DLL_remove (handle->client->issue_op_head,
935 handle->client->issue_op_tail,
937 if (GNUNET_SYSERR == success)
939 cleanup_ticket_issue_handle (handle);
940 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n",
942 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
945 send_ticket_result (handle->client,
949 cleanup_ticket_issue_handle (handle);
955 serialize_abe_keyinfo2 (const struct GNUNET_RECLAIM_Ticket *ticket,
956 const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs,
957 const struct GNUNET_ABE_AbeKey *rp_key,
958 struct GNUNET_CRYPTO_EcdhePrivateKey **ecdh_privkey,
961 struct GNUNET_CRYPTO_EcdhePublicKey ecdh_pubkey;
962 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le;
964 char *serialized_key;
970 struct GNUNET_CRYPTO_SymmetricSessionKey skey;
971 struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
972 struct GNUNET_HashCode new_key_hash;
975 size = GNUNET_ABE_cpabe_serialize_key (rp_key,
976 (void**)&serialized_key);
978 for (le = attrs->list_head; NULL != le; le = le->next) {
979 attrs_str_len += strlen (le->claim->name) + 1;
981 buf = GNUNET_malloc (attrs_str_len + size);
983 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
984 "Writing attributes\n");
985 for (le = attrs->list_head; NULL != le; le = le->next) {
986 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
987 "%s\n", le->claim->name);
990 GNUNET_memcpy (write_ptr,
992 strlen (le->claim->name));
993 write_ptr[strlen (le->claim->name)] = ',';
994 write_ptr += strlen (le->claim->name) + 1;
997 write_ptr[0] = '\0'; //replace last , with a 0-terminator
999 GNUNET_memcpy (write_ptr,
1002 GNUNET_free (serialized_key);
1003 // ECDH keypair E = eG
1004 *ecdh_privkey = GNUNET_CRYPTO_ecdhe_key_create();
1005 GNUNET_CRYPTO_ecdhe_key_get_public (*ecdh_privkey,
1007 enc_keyinfo = GNUNET_malloc (size + attrs_str_len);
1008 // Derived key K = H(eB)
1009 GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecdh_ecdsa (*ecdh_privkey,
1012 create_sym_key_from_ecdh(&new_key_hash, &skey, &iv);
1013 enc_size = GNUNET_CRYPTO_symmetric_encrypt (buf,
1014 size + attrs_str_len,
1017 *result = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)+
1019 GNUNET_memcpy (*result,
1021 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
1022 GNUNET_memcpy (*result + sizeof (struct GNUNET_CRYPTO_EcdhePublicKey),
1025 GNUNET_free (enc_keyinfo);
1027 return sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)+enc_size;
1033 issue_ticket_after_abe_bootstrap (void *cls,
1034 struct GNUNET_ABE_AbeMasterKey *abe_key)
1036 struct TicketIssueHandle *ih = cls;
1037 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le;
1038 struct GNUNET_CRYPTO_EcdhePrivateKey *ecdhe_privkey;
1039 struct GNUNET_GNSRECORD_Data code_record[1];
1040 struct GNUNET_ABE_AbeKey *rp_key;
1041 char *code_record_data;
1047 size_t code_record_len;
1049 //Create new ABE key for RP
1051 for (le = ih->attrs->list_head; NULL != le; le = le->next)
1053 attrs = GNUNET_malloc ((attrs_len + 1)*sizeof (char*));
1055 for (le = ih->attrs->list_head; NULL != le; le = le->next) {
1056 GNUNET_asprintf (&policy, "%s_%lu",
1058 le->claim->version);
1059 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1060 "Adding attribute to key: %s\n",
1066 rp_key = GNUNET_ABE_cpabe_create_key (abe_key,
1069 //TODO review this wireformat
1070 code_record_len = serialize_abe_keyinfo2 (&ih->ticket,
1075 code_record[0].data = code_record_data;
1076 code_record[0].data_size = code_record_len;
1077 code_record[0].expiration_time = GNUNET_TIME_UNIT_DAYS.rel_value_us;
1078 code_record[0].record_type = GNUNET_GNSRECORD_TYPE_ABE_KEY;
1079 code_record[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
1081 label = GNUNET_STRINGS_data_to_string_alloc (&ih->ticket.rnd,
1084 ih->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
1089 &store_ticket_issue_cont,
1091 //for (; i > 0; i--)
1092 // GNUNET_free (attrs[i-1]);
1093 GNUNET_free (ecdhe_privkey);
1094 GNUNET_free (label);
1095 GNUNET_free (attrs);
1096 GNUNET_free (code_record_data);
1097 GNUNET_ABE_cpabe_delete_key (rp_key,
1099 GNUNET_ABE_cpabe_delete_master_key (abe_key);
1104 check_issue_ticket_message(void *cls,
1105 const struct IssueTicketMessage *im)
1109 size = ntohs (im->header.size);
1110 if (size <= sizeof (struct IssueTicketMessage))
1113 return GNUNET_SYSERR;
1120 handle_issue_ticket_message (void *cls,
1121 const struct IssueTicketMessage *im)
1123 struct TicketIssueHandle *ih;
1124 struct IdpClient *idp = cls;
1127 ih = GNUNET_new (struct TicketIssueHandle);
1128 attrs_len = ntohs (im->attr_len);
1129 ih->attrs = GNUNET_RECLAIM_ATTRIBUTE_list_deserialize ((char*)&im[1], attrs_len);
1130 ih->r_id = ntohl (im->id);
1132 ih->identity = im->identity;
1133 GNUNET_CRYPTO_ecdsa_key_get_public (&ih->identity,
1134 &ih->ticket.identity);
1135 ih->ticket.audience = im->rp;
1137 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG,
1139 GNUNET_CONTAINER_DLL_insert (idp->issue_op_head,
1142 bootstrap_abe (&ih->identity, &issue_ticket_after_abe_bootstrap, ih, GNUNET_NO);
1143 GNUNET_SERVICE_client_continue (idp->client);
1147 /**********************************************************
1149 **********************************************************/
1152 * Cleanup revoke handle
1154 * @param rh the ticket revocation handle
1157 cleanup_revoke_ticket_handle (struct TicketRevocationHandle *rh)
1159 if (NULL != rh->attrs)
1160 GNUNET_RECLAIM_ATTRIBUTE_list_destroy (rh->attrs);
1161 if (NULL != rh->rvk_attrs)
1162 GNUNET_RECLAIM_ATTRIBUTE_list_destroy (rh->rvk_attrs);
1163 if (NULL != rh->abe_key)
1164 GNUNET_ABE_cpabe_delete_master_key (rh->abe_key);
1165 if (NULL != rh->ns_qe)
1166 GNUNET_NAMESTORE_cancel (rh->ns_qe);
1167 if (NULL != rh->ns_it)
1168 GNUNET_NAMESTORE_zone_iteration_stop (rh->ns_it);
1174 * Send revocation result
1176 * @param rh ticket revocation handle
1177 * @param success GNUNET_OK if successful result
1180 send_revocation_finished (struct TicketRevocationHandle *rh,
1183 struct GNUNET_MQ_Envelope *env;
1184 struct RevokeTicketResultMessage *trm;
1186 GNUNET_break(TKT_database->delete_ticket (TKT_database->cls,
1189 env = GNUNET_MQ_msg (trm,
1190 GNUNET_MESSAGE_TYPE_RECLAIM_REVOKE_TICKET_RESULT);
1191 trm->id = htonl (rh->r_id);
1192 trm->success = htonl (success);
1193 GNUNET_MQ_send (rh->client->mq,
1195 GNUNET_CONTAINER_DLL_remove (rh->client->revoke_op_head,
1196 rh->client->revoke_op_tail,
1202 * Process ticket from database
1204 * @param cls struct TicketIterationProcResult
1205 * @param ticket the ticket
1206 * @param attrs the attributes
1209 ticket_reissue_proc (void *cls,
1210 const struct GNUNET_RECLAIM_Ticket *ticket,
1211 const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs);
1214 revocation_reissue_tickets (struct TicketRevocationHandle *rh);
1217 static void reissue_next (void *cls)
1219 struct TicketRevocationHandle *rh = cls;
1220 revocation_reissue_tickets (rh);
1225 reissue_ticket_cont (void *cls,
1229 struct TicketRevocationHandle *rh = cls;
1232 if (GNUNET_SYSERR == success)
1234 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n",
1236 send_revocation_finished (rh, GNUNET_SYSERR);
1237 cleanup_revoke_ticket_handle (rh);
1241 GNUNET_SCHEDULER_add_now (&reissue_next, rh);
1246 * Process ticket from database
1248 * @param cls struct TicketIterationProcResult
1249 * @param ticket the ticket
1250 * @param attrs the attributes
1253 ticket_reissue_proc (void *cls,
1254 const struct GNUNET_RECLAIM_Ticket *ticket,
1255 const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs)
1257 struct TicketRevocationHandle *rh = cls;
1258 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le;
1259 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le_rollover;
1260 struct GNUNET_CRYPTO_EcdhePrivateKey *ecdhe_privkey;
1261 struct GNUNET_GNSRECORD_Data code_record[1];
1262 struct GNUNET_ABE_AbeKey *rp_key;
1263 char *code_record_data;
1270 size_t code_record_len;
1275 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1276 "Iteration done\n");
1280 if (0 == memcmp (&ticket->audience,
1281 &rh->ticket.audience,
1282 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)))
1284 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1285 "Do not reissue for this identity.!\n");
1286 label = GNUNET_STRINGS_data_to_string_alloc (&rh->ticket.rnd,
1289 rh->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
1294 &reissue_ticket_cont,
1297 GNUNET_free (label);
1302 * Check if any attribute of this ticket intersects with a rollover attribute
1304 reissue_ticket = GNUNET_NO;
1305 for (le = attrs->list_head; NULL != le; le = le->next)
1307 for (le_rollover = rh->rvk_attrs->list_head;
1308 NULL != le_rollover;
1309 le_rollover = le_rollover->next)
1311 if (0 == strcmp (le_rollover->claim->name,
1314 reissue_ticket = GNUNET_YES;
1315 le->claim->version = le_rollover->claim->version;
1320 if (GNUNET_NO == reissue_ticket)
1322 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1323 "Skipping ticket.\n");
1326 GNUNET_SCHEDULER_add_now (&reissue_next, rh);
1332 //Create new ABE key for RP
1335 /* If this is the RP we want to revoke attributes of, the do so */
1337 for (le = attrs->list_head; NULL != le; le = le->next)
1339 attr_arr = GNUNET_malloc ((attrs_len + 1)*sizeof (char*));
1341 for (le = attrs->list_head; NULL != le; le = le->next) {
1342 GNUNET_asprintf (&policy, "%s_%lu",
1344 le->claim->version);
1345 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1346 "Recreating key with %s\n", policy);
1347 attr_arr[i] = policy;
1351 rp_key = GNUNET_ABE_cpabe_create_key (rh->abe_key,
1354 //TODO review this wireformat
1355 code_record_len = serialize_abe_keyinfo2 (ticket,
1360 code_record[0].data = code_record_data;
1361 code_record[0].data_size = code_record_len;
1362 code_record[0].expiration_time = GNUNET_TIME_UNIT_DAYS.rel_value_us;
1363 code_record[0].record_type = GNUNET_GNSRECORD_TYPE_ABE_KEY;
1364 code_record[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
1366 label = GNUNET_STRINGS_data_to_string_alloc (&ticket->rnd,
1369 rh->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
1374 &reissue_ticket_cont,
1376 //for (; i > 0; i--)
1377 // GNUNET_free (attr_arr[i-1]);
1378 GNUNET_free (ecdhe_privkey);
1379 GNUNET_free (label);
1380 GNUNET_free (attr_arr);
1381 GNUNET_free (code_record_data);
1382 GNUNET_ABE_cpabe_delete_key (rp_key, GNUNET_YES);
1386 /* Prototype for below function */
1388 attr_reenc_cont (void *cls,
1393 revocation_reissue_tickets (struct TicketRevocationHandle *rh)
1396 /* Done, issue new keys */
1397 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1398 "Revocation Phase III: Reissuing Tickets\n");
1399 if (GNUNET_SYSERR == (ret = TKT_database->iterate_tickets (TKT_database->cls,
1400 &rh->ticket.identity,
1403 &ticket_reissue_proc,
1408 if (GNUNET_NO == ret)
1410 send_revocation_finished (rh, GNUNET_OK);
1411 cleanup_revoke_ticket_handle (rh);
1417 * Failed to check for attribute
1420 check_attr_error (void *cls)
1422 struct TicketRevocationHandle *rh = cls;
1423 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1424 "Unable to check for existing attribute\n");
1426 send_revocation_finished (rh, GNUNET_SYSERR);
1427 cleanup_revoke_ticket_handle (rh);
1432 * Revoke next attribte by reencryption with
1436 reenc_next_attribute (void *cls);
1439 * Check for existing attribute and overwrite
1442 check_attr_cb (void *cls,
1443 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
1445 unsigned int rd_count,
1446 const struct GNUNET_GNSRECORD_Data *rd_old)
1448 struct TicketRevocationHandle *rh = cls;
1449 struct GNUNET_GNSRECORD_Data rd[1];
1459 if (1 != rd_count) {
1460 GNUNET_SCHEDULER_add_now (&reenc_next_attribute,
1465 buf_size = GNUNET_RECLAIM_ATTRIBUTE_serialize_get_size (rh->attrs->list_head->claim);
1466 buf = GNUNET_malloc (buf_size);
1467 rh->attrs->list_head->claim->version++;
1468 GNUNET_RECLAIM_ATTRIBUTE_serialize (rh->attrs->list_head->claim,
1470 GNUNET_asprintf (&policy, "%s_%lu",
1471 rh->attrs->list_head->claim->name,
1472 rh->attrs->list_head->claim->version);
1473 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1474 "Encrypting with policy %s\n", policy);
1476 * Encrypt the attribute value and store in namestore
1478 enc_size = GNUNET_ABE_cpabe_encrypt (buf,
1484 if (GNUNET_SYSERR == enc_size)
1486 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1487 "Unable to re-encrypt with policy %s\n",
1489 GNUNET_free (policy);
1490 send_revocation_finished (rh, GNUNET_SYSERR);
1491 cleanup_revoke_ticket_handle (rh);
1494 GNUNET_free (policy);
1496 rd[0].data_size = enc_size + sizeof (uint32_t);
1497 rd_buf = GNUNET_malloc (rd[0].data_size);
1498 attr_ver = htonl (rh->attrs->list_head->claim->version);
1499 GNUNET_memcpy (rd_buf,
1502 GNUNET_memcpy (rd_buf+sizeof (uint32_t),
1505 rd[0].data = rd_buf;
1506 rd[0].record_type = GNUNET_GNSRECORD_TYPE_ID_ATTR;
1507 rd[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
1508 rd[0].expiration_time = rd_old[0].expiration_time;
1509 rh->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
1511 rh->attrs->list_head->claim->name,
1516 GNUNET_free (enc_buf);
1517 GNUNET_free (rd_buf);
1522 * Revoke next attribte by reencryption with
1526 reenc_next_attribute (void *cls)
1528 struct TicketRevocationHandle *rh = cls;
1529 if (NULL == rh->attrs->list_head)
1531 revocation_reissue_tickets (rh);
1534 /* First check if attribute still exists */
1535 rh->ns_qe = GNUNET_NAMESTORE_records_lookup (ns_handle,
1537 rh->attrs->list_head->claim->name,
1546 * Namestore callback after revoked attribute
1550 attr_reenc_cont (void *cls,
1554 struct TicketRevocationHandle *rh = cls;
1555 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le;
1558 if (GNUNET_SYSERR == success)
1560 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1561 "Failed to reencrypt attribute %s\n",
1563 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1566 if (NULL == rh->attrs->list_head)
1568 revocation_reissue_tickets (rh);
1571 le = rh->attrs->list_head;
1572 GNUNET_CONTAINER_DLL_remove (rh->attrs->list_head,
1573 rh->attrs->list_tail,
1575 GNUNET_assert (NULL != rh->rvk_attrs);
1576 GNUNET_CONTAINER_DLL_insert (rh->rvk_attrs->list_head,
1577 rh->rvk_attrs->list_tail,
1581 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1582 "Re-encrypting next attribute\n");
1583 reenc_next_attribute (rh);
1588 process_attributes_to_update (void *cls,
1589 const struct GNUNET_RECLAIM_Ticket *ticket,
1590 const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs)
1592 struct TicketRevocationHandle *rh = cls;
1594 rh->attrs = GNUNET_RECLAIM_ATTRIBUTE_list_dup (attrs);
1595 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1596 "Revocation Phase I: Collecting attributes\n");
1597 /* Reencrypt all attributes with new key */
1598 if (NULL == rh->attrs->list_head)
1600 /* No attributes to reencrypt */
1601 send_revocation_finished (rh, GNUNET_OK);
1602 cleanup_revoke_ticket_handle (rh);
1605 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1606 "Revocation Phase II: Re-encrypting attributes\n");
1607 reenc_next_attribute (rh);
1615 get_ticket_after_abe_bootstrap (void *cls,
1616 struct GNUNET_ABE_AbeMasterKey *abe_key)
1618 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1619 "Finished ABE bootstrap\n");
1620 struct TicketRevocationHandle *rh = cls;
1621 rh->abe_key = abe_key;
1622 TKT_database->get_ticket_attributes (TKT_database->cls,
1624 &process_attributes_to_update,
1629 check_revoke_ticket_message(void *cls,
1630 const struct RevokeTicketMessage *im)
1634 size = ntohs (im->header.size);
1635 if (size <= sizeof (struct RevokeTicketMessage))
1638 return GNUNET_SYSERR;
1644 handle_revoke_ticket_message (void *cls,
1645 const struct RevokeTicketMessage *rm)
1647 struct TicketRevocationHandle *rh;
1648 struct IdpClient *idp = cls;
1649 struct GNUNET_RECLAIM_Ticket *ticket;
1651 rh = GNUNET_new (struct TicketRevocationHandle);
1652 ticket = (struct GNUNET_RECLAIM_Ticket*)&rm[1];
1653 rh->rvk_attrs = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList);
1654 rh->ticket = *ticket;
1655 rh->r_id = ntohl (rm->id);
1657 rh->identity = rm->identity;
1658 GNUNET_CRYPTO_ecdsa_key_get_public (&rh->identity,
1659 &rh->ticket.identity);
1660 GNUNET_CONTAINER_DLL_insert (idp->revoke_op_head,
1661 idp->revoke_op_tail,
1663 bootstrap_abe (&rh->identity, &get_ticket_after_abe_bootstrap, rh, GNUNET_NO);
1664 GNUNET_SERVICE_client_continue (idp->client);
1669 * Cleanup ticket consume handle
1670 * @param handle the handle to clean up
1673 cleanup_consume_ticket_handle (struct ConsumeTicketHandle *handle)
1675 struct ParallelLookup *lu;
1676 struct ParallelLookup *tmp;
1677 if (NULL != handle->lookup_request)
1678 GNUNET_GNS_lookup_cancel (handle->lookup_request);
1679 for (lu = handle->parallel_lookups_head;
1681 GNUNET_GNS_lookup_cancel (lu->lookup_request);
1682 GNUNET_free (lu->label);
1684 GNUNET_CONTAINER_DLL_remove (handle->parallel_lookups_head,
1685 handle->parallel_lookups_tail,
1691 if (NULL != handle->key)
1692 GNUNET_ABE_cpabe_delete_key (handle->key,
1694 if (NULL != handle->attrs)
1695 GNUNET_RECLAIM_ATTRIBUTE_list_destroy (handle->attrs);
1696 GNUNET_free (handle);
1702 check_consume_ticket_message(void *cls,
1703 const struct ConsumeTicketMessage *cm)
1707 size = ntohs (cm->header.size);
1708 if (size <= sizeof (struct ConsumeTicketMessage))
1711 return GNUNET_SYSERR;
1717 process_parallel_lookup2 (void *cls, uint32_t rd_count,
1718 const struct GNUNET_GNSRECORD_Data *rd)
1720 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1721 "Parallel lookup finished (count=%u)\n", rd_count);
1722 struct ParallelLookup *parallel_lookup = cls;
1723 struct ConsumeTicketHandle *handle = parallel_lookup->handle;
1724 struct ConsumeTicketResultMessage *crm;
1725 struct GNUNET_MQ_Envelope *env;
1726 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *attr_le;
1727 struct GNUNET_TIME_Absolute decrypt_duration;
1733 GNUNET_CONTAINER_DLL_remove (handle->parallel_lookups_head,
1734 handle->parallel_lookups_tail,
1736 GNUNET_free (parallel_lookup->label);
1738 GNUNET_STATISTICS_update (stats,
1739 "attribute_lookup_time_total",
1740 GNUNET_TIME_absolute_get_duration (parallel_lookup->lookup_start_time).rel_value_us,
1742 GNUNET_STATISTICS_update (stats,
1743 "attribute_lookups_count",
1748 GNUNET_free (parallel_lookup);
1750 GNUNET_break(0);//TODO
1751 if (rd->record_type == GNUNET_GNSRECORD_TYPE_ID_ATTR)
1753 decrypt_duration = GNUNET_TIME_absolute_get ();
1754 attr_len = GNUNET_ABE_cpabe_decrypt (rd->data + sizeof (uint32_t),
1755 rd->data_size - sizeof (uint32_t),
1758 if (GNUNET_SYSERR != attr_len)
1760 GNUNET_STATISTICS_update (stats,
1761 "abe_decrypt_time_total",
1762 GNUNET_TIME_absolute_get_duration (decrypt_duration).rel_value_us,
1764 GNUNET_STATISTICS_update (stats,
1765 "abe_decrypt_count",
1769 attr_le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry);
1770 attr_le->claim = GNUNET_RECLAIM_ATTRIBUTE_deserialize (data,
1772 attr_le->claim->version = ntohl(*(uint32_t*)rd->data);
1773 GNUNET_CONTAINER_DLL_insert (handle->attrs->list_head,
1774 handle->attrs->list_tail,
1779 if (NULL != handle->parallel_lookups_head)
1780 return; //Wait for more
1781 /* Else we are done */
1783 /* Store ticket in DB */
1784 if (GNUNET_OK != TKT_database->store_ticket (TKT_database->cls,
1788 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1789 "Unable to store ticket after consume\n");
1793 GNUNET_SCHEDULER_cancel (handle->kill_task);
1794 attrs_len = GNUNET_RECLAIM_ATTRIBUTE_list_serialize_get_size (handle->attrs);
1795 env = GNUNET_MQ_msg_extra (crm,
1797 GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET_RESULT);
1798 crm->id = htonl (handle->r_id);
1799 crm->attrs_len = htons (attrs_len);
1800 crm->identity = handle->ticket.identity;
1801 data_tmp = (char *) &crm[1];
1802 GNUNET_RECLAIM_ATTRIBUTE_list_serialize (handle->attrs,
1804 GNUNET_MQ_send (handle->client->mq, env);
1805 GNUNET_CONTAINER_DLL_remove (handle->client->consume_op_head,
1806 handle->client->consume_op_tail,
1808 cleanup_consume_ticket_handle (handle);
1812 abort_parallel_lookups2 (void *cls)
1814 struct ConsumeTicketHandle *handle = cls;
1815 struct ParallelLookup *lu;
1816 struct ParallelLookup *tmp;
1817 struct AttributeResultMessage *arm;
1818 struct GNUNET_MQ_Envelope *env;
1820 handle->kill_task = NULL;
1821 for (lu = handle->parallel_lookups_head;
1823 GNUNET_GNS_lookup_cancel (lu->lookup_request);
1824 GNUNET_free (lu->label);
1826 GNUNET_CONTAINER_DLL_remove (handle->parallel_lookups_head,
1827 handle->parallel_lookups_tail,
1832 env = GNUNET_MQ_msg (arm,
1833 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT);
1834 arm->id = htonl (handle->r_id);
1835 arm->attr_len = htons (0);
1836 GNUNET_MQ_send (handle->client->mq, env);
1842 process_consume_abe_key (void *cls, uint32_t rd_count,
1843 const struct GNUNET_GNSRECORD_Data *rd)
1845 struct ConsumeTicketHandle *handle = cls;
1846 struct GNUNET_HashCode new_key_hash;
1847 struct GNUNET_CRYPTO_SymmetricSessionKey enc_key;
1848 struct GNUNET_CRYPTO_SymmetricInitializationVector enc_iv;
1849 struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_key;
1850 struct ParallelLookup *parallel_lookup;
1855 handle->lookup_request = NULL;
1858 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1859 "Number of keys %d != 1.",
1861 cleanup_consume_ticket_handle (handle);
1862 GNUNET_CONTAINER_DLL_remove (handle->client->consume_op_head,
1863 handle->client->consume_op_tail,
1865 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1870 ecdh_key = (struct GNUNET_CRYPTO_EcdhePublicKey *)rd->data;
1872 buf = GNUNET_malloc (rd->data_size - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
1874 //Calculate symmetric key from ecdh parameters
1875 GNUNET_assert (GNUNET_OK ==
1876 GNUNET_CRYPTO_ecdsa_ecdh (&handle->identity,
1879 create_sym_key_from_ecdh (&new_key_hash,
1882 size = GNUNET_CRYPTO_symmetric_decrypt (rd->data + sizeof (struct GNUNET_CRYPTO_EcdhePublicKey),
1883 rd->data_size - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey),
1888 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1889 "Decrypted bytes: %zd Expected bytes: %zd\n",
1890 size, rd->data_size - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
1891 GNUNET_STATISTICS_update (stats,
1892 "abe_key_lookup_time_total",
1893 GNUNET_TIME_absolute_get_duration (handle->lookup_start_time).rel_value_us,
1895 GNUNET_STATISTICS_update (stats,
1896 "abe_key_lookups_count",
1899 scopes = GNUNET_strdup (buf);
1900 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1901 "Scopes %s\n", scopes);
1902 handle->key = GNUNET_ABE_cpabe_deserialize_key ((void*)(buf + strlen (scopes) + 1),
1903 rd->data_size - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)
1904 - strlen (scopes) - 1);
1906 for (scope = strtok (scopes, ","); NULL != scope; scope = strtok (NULL, ","))
1908 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1909 "Looking up %s\n", scope);
1910 parallel_lookup = GNUNET_new (struct ParallelLookup);
1911 parallel_lookup->handle = handle;
1912 parallel_lookup->label = GNUNET_strdup (scope);
1913 parallel_lookup->lookup_start_time = GNUNET_TIME_absolute_get();
1914 parallel_lookup->lookup_request
1915 = GNUNET_GNS_lookup (gns_handle,
1917 &handle->ticket.identity,
1918 GNUNET_GNSRECORD_TYPE_ID_ATTR,
1919 GNUNET_GNS_LO_DEFAULT,
1920 &process_parallel_lookup2,
1922 GNUNET_CONTAINER_DLL_insert (handle->parallel_lookups_head,
1923 handle->parallel_lookups_tail,
1926 GNUNET_free (scopes);
1928 handle->kill_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES,3),
1929 &abort_parallel_lookups2,
1935 handle_consume_ticket_message (void *cls,
1936 const struct ConsumeTicketMessage *cm)
1938 struct ConsumeTicketHandle *ch;
1939 struct IdpClient *idp = cls;
1942 ch = GNUNET_new (struct ConsumeTicketHandle);
1943 ch->r_id = ntohl (cm->id);
1945 ch->identity = cm->identity;
1946 ch->attrs = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList);
1947 GNUNET_CRYPTO_ecdsa_key_get_public (&ch->identity,
1949 ch->ticket = *((struct GNUNET_RECLAIM_Ticket*)&cm[1]);
1950 rnd_label = GNUNET_STRINGS_data_to_string_alloc (&ch->ticket.rnd,
1952 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1953 "Looking for ABE key under %s\n", rnd_label);
1954 ch->lookup_start_time = GNUNET_TIME_absolute_get ();
1956 = GNUNET_GNS_lookup (gns_handle,
1958 &ch->ticket.identity,
1959 GNUNET_GNSRECORD_TYPE_ABE_KEY,
1960 GNUNET_GNS_LO_DEFAULT,
1961 &process_consume_abe_key,
1963 GNUNET_CONTAINER_DLL_insert (idp->consume_op_head,
1964 idp->consume_op_tail,
1966 GNUNET_free (rnd_label);
1967 GNUNET_SERVICE_client_continue (idp->client);
1971 * Cleanup attribute store handle
1973 * @param handle handle to clean up
1976 cleanup_as_handle (struct AttributeStoreHandle *handle)
1978 if (NULL != handle->ns_qe)
1979 GNUNET_NAMESTORE_cancel (handle->ns_qe);
1980 if (NULL != handle->claim)
1981 GNUNET_free (handle->claim);
1982 if (NULL != handle->abe_key)
1983 GNUNET_ABE_cpabe_delete_master_key (handle->abe_key);
1984 GNUNET_free (handle);
1988 attr_store_cont (void *cls,
1992 struct AttributeStoreHandle *as_handle = cls;
1993 struct GNUNET_MQ_Envelope *env;
1994 struct AttributeStoreResultMessage *acr_msg;
1996 as_handle->ns_qe = NULL;
1997 GNUNET_CONTAINER_DLL_remove (as_handle->client->store_op_head,
1998 as_handle->client->store_op_tail,
2001 if (GNUNET_SYSERR == success)
2003 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2004 "Failed to store attribute %s\n",
2006 cleanup_as_handle (as_handle);
2007 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
2011 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2012 "Sending ATTRIBUTE_STORE_RESPONSE message\n");
2013 env = GNUNET_MQ_msg (acr_msg,
2014 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_STORE_RESPONSE);
2015 acr_msg->id = htonl (as_handle->r_id);
2016 acr_msg->op_result = htonl (GNUNET_OK);
2017 GNUNET_MQ_send (as_handle->client->mq,
2019 cleanup_as_handle (as_handle);
2023 attr_store_task (void *cls)
2025 struct AttributeStoreHandle *as_handle = cls;
2026 struct GNUNET_GNSRECORD_Data rd[1];
2035 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2036 "Storing attribute\n");
2037 buf_size = GNUNET_RECLAIM_ATTRIBUTE_serialize_get_size (as_handle->claim);
2038 buf = GNUNET_malloc (buf_size);
2040 GNUNET_RECLAIM_ATTRIBUTE_serialize (as_handle->claim,
2043 GNUNET_asprintf (&policy,
2045 as_handle->claim->name,
2046 as_handle->claim->version);
2047 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2048 "Encrypting with policy %s\n", policy);
2050 * Encrypt the attribute value and store in namestore
2052 enc_size = GNUNET_ABE_cpabe_encrypt (buf,
2057 if (GNUNET_SYSERR == enc_size)
2059 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2060 "Failed to encrypt with policy %s\n",
2062 GNUNET_CONTAINER_DLL_remove (as_handle->client->store_op_head,
2063 as_handle->client->store_op_tail,
2066 cleanup_as_handle (as_handle);
2068 GNUNET_free (policy);
2069 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
2073 GNUNET_free (policy);
2074 rd[0].data_size = enc_size + sizeof (uint32_t);
2075 rd_buf = GNUNET_malloc (rd[0].data_size);
2076 attr_ver = htonl (as_handle->claim->version);
2077 GNUNET_memcpy (rd_buf,
2080 GNUNET_memcpy (rd_buf+sizeof (uint32_t),
2083 rd[0].data = rd_buf;
2084 rd[0].record_type = GNUNET_GNSRECORD_TYPE_ID_ATTR;
2085 rd[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
2086 rd[0].expiration_time = as_handle->exp.rel_value_us;
2087 as_handle->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
2088 &as_handle->identity,
2089 as_handle->claim->name,
2094 GNUNET_free (enc_buf);
2095 GNUNET_free (rd_buf);
2100 store_after_abe_bootstrap (void *cls,
2101 struct GNUNET_ABE_AbeMasterKey *abe_key)
2103 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2104 "Finished ABE bootstrap\n");
2105 struct AttributeStoreHandle *ash = cls;
2106 ash->abe_key = abe_key;
2107 GNUNET_SCHEDULER_add_now (&attr_store_task, ash);
2111 check_attribute_store_message(void *cls,
2112 const struct AttributeStoreMessage *sam)
2116 size = ntohs (sam->header.size);
2117 if (size <= sizeof (struct AttributeStoreMessage))
2120 return GNUNET_SYSERR;
2127 handle_attribute_store_message (void *cls,
2128 const struct AttributeStoreMessage *sam)
2130 struct AttributeStoreHandle *as_handle;
2131 struct IdpClient *idp = cls;
2133 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2134 "Received ATTRIBUTE_STORE message\n");
2136 data_len = ntohs (sam->attr_len);
2138 as_handle = GNUNET_new (struct AttributeStoreHandle);
2139 as_handle->claim = GNUNET_RECLAIM_ATTRIBUTE_deserialize ((char*)&sam[1],
2142 as_handle->r_id = ntohl (sam->id);
2143 as_handle->identity = sam->identity;
2144 as_handle->exp.rel_value_us = GNUNET_ntohll (sam->exp);
2145 GNUNET_CRYPTO_ecdsa_key_get_public (&sam->identity,
2146 &as_handle->identity_pkey);
2148 GNUNET_SERVICE_client_continue (idp->client);
2149 as_handle->client = idp;
2150 GNUNET_CONTAINER_DLL_insert (idp->store_op_head,
2153 bootstrap_abe (&as_handle->identity, &store_after_abe_bootstrap, as_handle, GNUNET_NO);
2157 cleanup_attribute_iter_handle (struct AttributeIterator *ai)
2159 if (NULL != ai->abe_key)
2160 GNUNET_ABE_cpabe_delete_master_key (ai->abe_key);
2165 attr_iter_error (void *cls)
2167 struct AttributeIterator *ai = cls;
2169 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2170 "Failed to iterate over attributes\n");
2171 GNUNET_CONTAINER_DLL_remove (ai->client->attr_iter_head,
2172 ai->client->attr_iter_tail,
2174 cleanup_attribute_iter_handle (ai);
2175 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
2179 attr_iter_finished (void *cls)
2181 struct AttributeIterator *ai = cls;
2182 struct GNUNET_MQ_Envelope *env;
2183 struct AttributeResultMessage *arm;
2185 env = GNUNET_MQ_msg (arm,
2186 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT);
2187 arm->id = htonl (ai->request_id);
2188 arm->attr_len = htons (0);
2189 GNUNET_MQ_send (ai->client->mq, env);
2190 GNUNET_CONTAINER_DLL_remove (ai->client->attr_iter_head,
2191 ai->client->attr_iter_tail,
2193 cleanup_attribute_iter_handle (ai);
2197 attr_iter_cb (void *cls,
2198 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
2200 unsigned int rd_count,
2201 const struct GNUNET_GNSRECORD_Data *rd)
2203 struct AttributeIterator *ai = cls;
2204 struct AttributeResultMessage *arm;
2205 struct GNUNET_ABE_AbeKey *key;
2206 struct GNUNET_MQ_Envelope *env;
2207 ssize_t msg_extra_len;
2216 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it,
2221 if (GNUNET_GNSRECORD_TYPE_ID_ATTR != rd->record_type)
2223 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it,
2227 attr_ver = ntohl(*((uint32_t*)rd->data));
2228 GNUNET_asprintf (&policy, "%s_%lu",
2232 key = GNUNET_ABE_cpabe_create_key (ai->abe_key,
2234 msg_extra_len = GNUNET_ABE_cpabe_decrypt (rd->data+sizeof (uint32_t),
2235 rd->data_size-sizeof (uint32_t),
2238 if (GNUNET_SYSERR == msg_extra_len)
2240 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it,
2245 GNUNET_ABE_cpabe_delete_key (key,
2247 //GNUNET_free (policy);
2248 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2249 "Found attribute: %s\n", label);
2250 env = GNUNET_MQ_msg_extra (arm,
2252 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT);
2253 arm->id = htonl (ai->request_id);
2254 arm->attr_len = htons (msg_extra_len);
2255 GNUNET_CRYPTO_ecdsa_key_get_public (zone,
2257 data_tmp = (char *) &arm[1];
2258 GNUNET_memcpy (data_tmp,
2261 GNUNET_MQ_send (ai->client->mq, env);
2262 GNUNET_free (attr_ser);
2263 GNUNET_ABE_cpabe_delete_master_key (ai->abe_key);
2269 iterate_after_abe_bootstrap (void *cls,
2270 struct GNUNET_ABE_AbeMasterKey *abe_key)
2272 struct AttributeIterator *ai = cls;
2273 ai->abe_key = abe_key;
2274 ai->ns_it = GNUNET_NAMESTORE_zone_iteration_start (ns_handle,
2280 &attr_iter_finished,
2286 iterate_next_after_abe_bootstrap (void *cls,
2287 struct GNUNET_ABE_AbeMasterKey *abe_key)
2289 struct AttributeIterator *ai = cls;
2290 ai->abe_key = abe_key;
2291 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it,
2298 handle_iteration_start (void *cls,
2299 const struct AttributeIterationStartMessage *ais_msg)
2301 struct IdpClient *idp = cls;
2302 struct AttributeIterator *ai;
2304 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2305 "Received ATTRIBUTE_ITERATION_START message\n");
2306 ai = GNUNET_new (struct AttributeIterator);
2307 ai->request_id = ntohl (ais_msg->id);
2309 ai->identity = ais_msg->identity;
2311 GNUNET_CONTAINER_DLL_insert (idp->attr_iter_head,
2312 idp->attr_iter_tail,
2314 bootstrap_abe (&ai->identity, &iterate_after_abe_bootstrap, ai, GNUNET_NO);
2315 GNUNET_SERVICE_client_continue (idp->client);
2320 handle_iteration_stop (void *cls,
2321 const struct AttributeIterationStopMessage *ais_msg)
2323 struct IdpClient *idp = cls;
2324 struct AttributeIterator *ai;
2327 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2328 "Received `%s' message\n",
2329 "ATTRIBUTE_ITERATION_STOP");
2330 rid = ntohl (ais_msg->id);
2331 for (ai = idp->attr_iter_head; NULL != ai; ai = ai->next)
2332 if (ai->request_id == rid)
2337 GNUNET_SERVICE_client_drop (idp->client);
2340 GNUNET_CONTAINER_DLL_remove (idp->attr_iter_head,
2341 idp->attr_iter_tail,
2344 GNUNET_SERVICE_client_continue (idp->client);
2349 handle_iteration_next (void *cls,
2350 const struct AttributeIterationNextMessage *ais_msg)
2352 struct IdpClient *idp = cls;
2353 struct AttributeIterator *ai;
2356 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2357 "Received ATTRIBUTE_ITERATION_NEXT message\n");
2358 rid = ntohl (ais_msg->id);
2359 for (ai = idp->attr_iter_head; NULL != ai; ai = ai->next)
2360 if (ai->request_id == rid)
2365 GNUNET_SERVICE_client_drop (idp->client);
2368 bootstrap_abe (&ai->identity,
2369 &iterate_next_after_abe_bootstrap,
2372 GNUNET_SERVICE_client_continue (idp->client);
2376 * Ticket iteration processor result
2378 enum ZoneIterationResult
2387 * Continue to iterate with next iteration_next call
2389 IT_SUCCESS_MORE_AVAILABLE = 1,
2392 * Iteration complete
2394 IT_SUCCESS_NOT_MORE_RESULTS_AVAILABLE = 2
2399 * Context for ticket iteration
2401 struct TicketIterationProcResult
2404 * The ticket iteration handle
2406 struct TicketIteration *ti;
2409 * Iteration result: iteration done?
2410 * #IT_SUCCESS_MORE_AVAILABLE: if there may be more results overall but
2411 * we got one for now and have sent it to the client
2412 * #IT_SUCCESS_NOT_MORE_RESULTS_AVAILABLE: if there are no further results,
2413 * #IT_START: if we are still trying to find a result.
2415 int res_iteration_finished;
2420 cleanup_ticket_iter_handle (struct TicketIteration *ti)
2426 * Process ticket from database
2428 * @param cls struct TicketIterationProcResult
2429 * @param ticket the ticket
2430 * @param attrs the attributes
2433 ticket_iterate_proc (void *cls,
2434 const struct GNUNET_RECLAIM_Ticket *ticket,
2435 const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs)
2437 struct TicketIterationProcResult *proc = cls;
2441 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2442 "Iteration done\n");
2443 proc->res_iteration_finished = IT_SUCCESS_NOT_MORE_RESULTS_AVAILABLE;
2446 proc->res_iteration_finished = IT_SUCCESS_MORE_AVAILABLE;
2447 send_ticket_result (proc->ti->client,
2455 * Perform ticket iteration step
2457 * @param ti ticket iterator to process
2460 run_ticket_iteration_round (struct TicketIteration *ti)
2462 struct TicketIterationProcResult proc;
2463 struct GNUNET_MQ_Envelope *env;
2464 struct TicketResultMessage *trm;
2467 memset (&proc, 0, sizeof (proc));
2469 proc.res_iteration_finished = IT_START;
2470 while (IT_START == proc.res_iteration_finished)
2472 if (GNUNET_SYSERR ==
2473 (ret = TKT_database->iterate_tickets (TKT_database->cls,
2477 &ticket_iterate_proc,
2483 if (GNUNET_NO == ret)
2484 proc.res_iteration_finished = IT_SUCCESS_NOT_MORE_RESULTS_AVAILABLE;
2487 if (IT_SUCCESS_MORE_AVAILABLE == proc.res_iteration_finished)
2489 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2490 "More results available\n");
2491 return; /* more later */
2493 /* send empty response to indicate end of list */
2494 env = GNUNET_MQ_msg (trm,
2495 GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT);
2496 trm->id = htonl (ti->r_id);
2497 GNUNET_MQ_send (ti->client->mq,
2499 GNUNET_CONTAINER_DLL_remove (ti->client->ticket_iter_head,
2500 ti->client->ticket_iter_tail,
2502 cleanup_ticket_iter_handle (ti);
2506 handle_ticket_iteration_start (void *cls,
2507 const struct TicketIterationStartMessage *tis_msg)
2509 struct IdpClient *client = cls;
2510 struct TicketIteration *ti;
2512 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2513 "Received TICKET_ITERATION_START message\n");
2514 ti = GNUNET_new (struct TicketIteration);
2515 ti->r_id = ntohl (tis_msg->id);
2517 ti->client = client;
2518 ti->identity = tis_msg->identity;
2519 ti->is_audience = ntohl (tis_msg->is_audience);
2521 GNUNET_CONTAINER_DLL_insert (client->ticket_iter_head,
2522 client->ticket_iter_tail,
2524 run_ticket_iteration_round (ti);
2525 GNUNET_SERVICE_client_continue (client->client);
2530 handle_ticket_iteration_stop (void *cls,
2531 const struct TicketIterationStopMessage *tis_msg)
2533 struct IdpClient *client = cls;
2534 struct TicketIteration *ti;
2537 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2538 "Received `%s' message\n",
2539 "TICKET_ITERATION_STOP");
2540 rid = ntohl (tis_msg->id);
2541 for (ti = client->ticket_iter_head; NULL != ti; ti = ti->next)
2542 if (ti->r_id == rid)
2547 GNUNET_SERVICE_client_drop (client->client);
2550 GNUNET_CONTAINER_DLL_remove (client->ticket_iter_head,
2551 client->ticket_iter_tail,
2553 cleanup_ticket_iter_handle (ti);
2554 GNUNET_SERVICE_client_continue (client->client);
2559 handle_ticket_iteration_next (void *cls,
2560 const struct TicketIterationNextMessage *tis_msg)
2562 struct IdpClient *client = cls;
2563 struct TicketIteration *ti;
2566 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2567 "Received TICKET_ITERATION_NEXT message\n");
2568 rid = ntohl (tis_msg->id);
2569 for (ti = client->ticket_iter_head; NULL != ti; ti = ti->next)
2570 if (ti->r_id == rid)
2575 GNUNET_SERVICE_client_drop (client->client);
2578 run_ticket_iteration_round (ti);
2579 GNUNET_SERVICE_client_continue (client->client);
2586 * Main function that will be run
2588 * @param cls closure
2589 * @param c the configuration used
2590 * @param server the service handle
2594 const struct GNUNET_CONFIGURATION_Handle *c,
2595 struct GNUNET_SERVICE_Handle *server)
2600 stats = GNUNET_STATISTICS_create ("reclaim", cfg);
2602 //Connect to identity and namestore services
2603 ns_handle = GNUNET_NAMESTORE_connect (cfg);
2604 if (NULL == ns_handle)
2606 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "error connecting to namestore");
2609 gns_handle = GNUNET_GNS_connect (cfg);
2610 if (NULL == gns_handle)
2612 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "error connecting to gns");
2614 credential_handle = GNUNET_CREDENTIAL_connect (cfg);
2615 if (NULL == credential_handle)
2617 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "error connecting to credential");
2619 identity_handle = GNUNET_IDENTITY_connect (cfg,
2622 /* Loading DB plugin */
2624 GNUNET_CONFIGURATION_get_value_string (cfg,
2628 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2629 "No database backend configured\n");
2630 GNUNET_asprintf (&db_lib_name,
2631 "libgnunet_plugin_reclaim_%s",
2633 TKT_database = GNUNET_PLUGIN_load (db_lib_name,
2635 GNUNET_free (database);
2636 if (NULL == TKT_database)
2638 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2639 "Could not load database backend `%s'\n",
2641 GNUNET_SCHEDULER_shutdown ();
2646 GNUNET_CONFIGURATION_get_value_time (cfg,
2648 "TOKEN_EXPIRATION_INTERVAL",
2649 &token_expiration_interval))
2651 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2652 "Time window for zone iteration: %s\n",
2653 GNUNET_STRINGS_relative_time_to_string (token_expiration_interval,
2656 token_expiration_interval = DEFAULT_TOKEN_EXPIRATION_INTERVAL;
2659 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL);
2663 * Called whenever a client is disconnected.
2665 * @param cls closure
2666 * @param client identification of the client
2667 * @param app_ctx @a client
2670 client_disconnect_cb (void *cls,
2671 struct GNUNET_SERVICE_Client *client,
2674 struct IdpClient *idp = app_ctx;
2675 struct AttributeIterator *ai;
2676 struct TicketIteration *ti;
2677 struct TicketRevocationHandle *rh;
2678 struct TicketIssueHandle *iss;
2679 struct ConsumeTicketHandle *ct;
2680 struct AttributeStoreHandle *as;
2682 //TODO other operations
2684 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2685 "Client %p disconnected\n",
2688 while (NULL != (iss = idp->issue_op_head))
2690 GNUNET_CONTAINER_DLL_remove (idp->issue_op_head,
2693 cleanup_ticket_issue_handle (iss);
2695 while (NULL != (ct = idp->consume_op_head))
2697 GNUNET_CONTAINER_DLL_remove (idp->consume_op_head,
2698 idp->consume_op_tail,
2700 cleanup_consume_ticket_handle (ct);
2702 while (NULL != (as = idp->store_op_head))
2704 GNUNET_CONTAINER_DLL_remove (idp->store_op_head,
2707 cleanup_as_handle (as);
2710 while (NULL != (ai = idp->attr_iter_head))
2712 GNUNET_CONTAINER_DLL_remove (idp->attr_iter_head,
2713 idp->attr_iter_tail,
2715 cleanup_attribute_iter_handle (ai);
2717 while (NULL != (rh = idp->revoke_op_head))
2719 GNUNET_CONTAINER_DLL_remove (idp->revoke_op_head,
2720 idp->revoke_op_tail,
2722 cleanup_revoke_ticket_handle (rh);
2724 while (NULL != (ti = idp->ticket_iter_head))
2726 GNUNET_CONTAINER_DLL_remove (idp->ticket_iter_head,
2727 idp->ticket_iter_tail,
2729 cleanup_ticket_iter_handle (ti);
2736 * Add a client to our list of active clients.
2739 * @param client client to add
2740 * @param mq message queue for @a client
2741 * @return internal namestore client structure for this client
2744 client_connect_cb (void *cls,
2745 struct GNUNET_SERVICE_Client *client,
2746 struct GNUNET_MQ_Handle *mq)
2748 struct IdpClient *idp;
2749 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2750 "Client %p connected\n",
2752 idp = GNUNET_new (struct IdpClient);
2753 idp->client = client;
2761 * Define "main" method using service macro.
2765 GNUNET_SERVICE_OPTION_NONE,
2768 &client_disconnect_cb,
2770 GNUNET_MQ_hd_var_size (attribute_store_message,
2771 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_STORE,
2772 struct AttributeStoreMessage,
2774 GNUNET_MQ_hd_fixed_size (iteration_start,
2775 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_START,
2776 struct AttributeIterationStartMessage,
2778 GNUNET_MQ_hd_fixed_size (iteration_next,
2779 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_NEXT,
2780 struct AttributeIterationNextMessage,
2782 GNUNET_MQ_hd_fixed_size (iteration_stop,
2783 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_STOP,
2784 struct AttributeIterationStopMessage,
2786 GNUNET_MQ_hd_var_size (issue_ticket_message,
2787 GNUNET_MESSAGE_TYPE_RECLAIM_ISSUE_TICKET,
2788 struct IssueTicketMessage,
2790 GNUNET_MQ_hd_var_size (consume_ticket_message,
2791 GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET,
2792 struct ConsumeTicketMessage,
2794 GNUNET_MQ_hd_fixed_size (ticket_iteration_start,
2795 GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_START,
2796 struct TicketIterationStartMessage,
2798 GNUNET_MQ_hd_fixed_size (ticket_iteration_next,
2799 GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_NEXT,
2800 struct TicketIterationNextMessage,
2802 GNUNET_MQ_hd_fixed_size (ticket_iteration_stop,
2803 GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_STOP,
2804 struct TicketIterationStopMessage,
2806 GNUNET_MQ_hd_var_size (revoke_ticket_message,
2807 GNUNET_MESSAGE_TYPE_RECLAIM_REVOKE_TICKET,
2808 struct RevokeTicketMessage,
2810 GNUNET_MQ_handler_end());
2811 /* end of gnunet-service-reclaim.c */