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
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 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 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
21 * @author Martin Schanzenbach
22 * @file src/identity-provider/gnunet-service-identity-provider.c
23 * @brief Identity Token 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_identity_provider_plugin.h"
38 #include "gnunet_identity_attribute_lib.h"
39 #include "gnunet_signatures.h"
40 #include "identity_provider.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_IDENTITY_PROVIDER_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_STATISTICS_Handle *stats_handle;
105 static struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
110 static struct GNUNET_NAMESTORE_ZoneIterator *ns_it;
115 static struct GNUNET_SCHEDULER_Task *timeout_task;
120 static struct GNUNET_SCHEDULER_Task *update_task;
124 * Currently processed token
126 static struct IdentityToken *token;
129 * Label for currently processed token
134 * Scopes for processed token
139 * Handle to the statistics service.
141 static struct GNUNET_STATISTICS_Handle *stats;
146 static const struct GNUNET_CONFIGURATION_Handle *cfg;
154 * A ticket iteration operation.
156 struct TicketIteration
161 struct TicketIteration *next;
166 struct TicketIteration *prev;
169 * Client which intiated this zone iteration
171 struct IdpClient *client;
174 * Key of the identity we are iterating over.
176 struct GNUNET_CRYPTO_EcdsaPublicKey identity;
179 * Identity is audience
181 uint32_t is_audience;
184 * The operation id fot the iteration in the response for the client
189 * Offset of the iteration used to address next result of the
190 * iteration in the store
192 * Initialy set to 0 in handle_iteration_start
193 * Incremented with by every call to handle_iteration_next
202 * Callback after an ABE bootstrap
205 * @param abe_key the ABE key that exists or was created
208 (*AbeBootstrapResult) (void *cls,
209 struct GNUNET_ABE_AbeMasterKey *abe_key);
212 struct AbeBootstrapHandle
215 * Function to call when finished
217 AbeBootstrapResult proc;
225 * Key of the zone we are iterating over.
227 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
230 * Namestore Queue Entry
232 struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
235 * The issuer egos ABE master key
237 struct GNUNET_ABE_AbeMasterKey *abe_key;
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 *op_head;
309 * Attribute iteration operations
310 * in progress initiated by this client
312 struct AttributeIterator *op_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;
326 * Head of DLL of ticket revocation ops
328 struct TicketRevocationHandle *revocation_list_head;
331 * Tail of DLL of ticket revocation ops
333 struct TicketRevocationHandle *revocation_list_tail;
338 struct AttributeStoreHandle
344 struct IdpClient *client;
349 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
354 struct GNUNET_CRYPTO_EcdsaPublicKey identity_pkey;
357 * The issuer egos ABE master key
359 struct GNUNET_ABE_AbeMasterKey *abe_key;
364 struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
367 * The attribute to store
369 struct GNUNET_IDENTITY_ATTRIBUTE_Claim *claim;
379 struct ParallelLookup;
381 struct ConsumeTicketHandle
387 struct IdpClient *client;
392 struct GNUNET_IDENTITY_PROVIDER_Ticket ticket;
397 struct GNUNET_GNS_LookupRequest *lookup_request;
402 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
407 struct GNUNET_CRYPTO_EcdsaPublicKey identity_pub;
412 struct ParallelLookup *parallel_lookups_head;
417 struct ParallelLookup *parallel_lookups_tail;
422 struct GNUNET_SCHEDULER_Task *kill_task;
427 struct GNUNET_ABE_AbeKey *key;
432 struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs;
437 struct GNUNET_TIME_Absolute lookup_start_time;
446 * Handle for a parallel GNS lookup job
448 struct ParallelLookup
451 struct ParallelLookup *next;
454 struct ParallelLookup *prev;
456 /* The GNS request */
457 struct GNUNET_GNS_LookupRequest *lookup_request;
459 /* The handle the return to */
460 struct ConsumeTicketHandle *handle;
465 struct GNUNET_TIME_Absolute lookup_start_time;
467 /* The label to look up */
472 * Ticket revocation request handle
474 struct TicketRevocationHandle
479 struct TicketRevocationHandle *next;
484 struct TicketRevocationHandle *prev;
489 struct IdpClient *client;
492 * Attributes to reissue
494 struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs;
497 * Attributes to revoke
499 struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *rvk_attrs;
504 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
509 struct GNUNET_IDENTITY_PROVIDER_Ticket ticket;
514 struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
519 struct GNUNET_NAMESTORE_ZoneIterator *ns_it;
524 struct GNUNET_ABE_AbeMasterKey *abe_key;
540 * Ticket issue request handle
542 struct TicketIssueHandle
548 struct IdpClient *client;
551 * Attributes to issue
553 struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs;
558 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
563 struct GNUNET_IDENTITY_PROVIDER_Ticket ticket;
568 struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
578 * DLL for ego handles to egos containing the ID_ATTRS in a map in json_t format
586 struct EgoEntry *next;
591 struct EgoEntry *prev;
596 struct GNUNET_IDENTITY_Ego *ego;
599 * Attribute map. Contains the attributes as json_t
601 struct GNUNET_CONTAINER_MultiHashMap *attr_map;
611 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
615 GNUNET_STATISTICS_destroy (stats, GNUNET_NO);
618 GNUNET_break (NULL == GNUNET_PLUGIN_unload (db_lib_name,
620 GNUNET_free (db_lib_name);
622 if (NULL != timeout_task)
623 GNUNET_SCHEDULER_cancel (timeout_task);
624 if (NULL != update_task)
625 GNUNET_SCHEDULER_cancel (update_task);
626 if (NULL != identity_handle)
627 GNUNET_IDENTITY_disconnect (identity_handle);
628 if (NULL != gns_handle)
629 GNUNET_GNS_disconnect (gns_handle);
630 if (NULL != credential_handle)
631 GNUNET_CREDENTIAL_disconnect (credential_handle);
633 GNUNET_NAMESTORE_zone_iteration_stop (ns_it);
635 GNUNET_NAMESTORE_cancel (ns_qe);
636 if (NULL != ns_handle)
637 GNUNET_NAMESTORE_disconnect (ns_handle);
638 if (NULL != stats_handle)
639 GNUNET_STATISTICS_destroy (stats_handle, GNUNET_NO);
640 GNUNET_free_non_null (token);
641 GNUNET_free_non_null (label);
651 do_shutdown (void *cls)
653 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
654 "Shutting down...\n");
659 * Finished storing newly bootstrapped ABE key
662 bootstrap_store_cont (void *cls,
666 struct AbeBootstrapHandle *abh = cls;
667 if (GNUNET_SYSERR == success)
669 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
670 "Failed to bootstrap ABE master %s\n",
672 abh->proc (abh->proc_cls, NULL);
673 GNUNET_free (abh->abe_key);
677 abh->proc (abh->proc_cls, abh->abe_key);
682 * Generates and stores a new ABE key
685 bootstrap_store_task (void *cls)
687 struct AbeBootstrapHandle *abh = cls;
688 struct GNUNET_GNSRECORD_Data rd[1];
691 rd[0].data_size = GNUNET_ABE_cpabe_serialize_master_key (abh->abe_key,
694 rd[0].record_type = GNUNET_GNSRECORD_TYPE_ABE_MASTER;
695 rd[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION | GNUNET_GNSRECORD_RF_PRIVATE;
696 rd[0].expiration_time = GNUNET_TIME_UNIT_HOURS.rel_value_us; //TODO sane?
697 abh->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
702 &bootstrap_store_cont,
708 * Error checking for ABE master
711 bootstrap_abe_error (void *cls)
713 struct AbeBootstrapHandle *abh = cls;
715 abh->proc (abh->proc_cls, NULL);
721 * Handle ABE lookup in namestore
724 bootstrap_abe_result (void *cls,
725 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
727 unsigned int rd_count,
728 const struct GNUNET_GNSRECORD_Data *rd)
730 struct AbeBootstrapHandle *abh = cls;
731 struct GNUNET_ABE_AbeMasterKey *abe_key;
733 for (uint32_t i=0;i<rd_count;i++) {
734 if (GNUNET_GNSRECORD_TYPE_ABE_MASTER != rd[i].record_type)
736 abe_key = GNUNET_ABE_cpabe_deserialize_master_key (rd[i].data,
738 abh->proc (abh->proc_cls, abe_key);
743 //No ABE master found, bootstrapping...
744 abh->abe_key = GNUNET_ABE_cpabe_create_master_key ();
745 GNUNET_SCHEDULER_add_now (&bootstrap_store_task, abh);
749 * Bootstrap ABE master if it does not yet exists.
750 * Will call the AbeBootstrapResult processor when done.
751 * will always recreate the ABE key of GNUNET_YES == recreate
754 bootstrap_abe (const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
755 AbeBootstrapResult proc,
759 struct AbeBootstrapHandle *abh;
761 abh = GNUNET_new (struct AbeBootstrapHandle);
764 abh->identity = *identity;
765 if (GNUNET_YES == recreate)
767 abh->abe_key = GNUNET_ABE_cpabe_create_master_key ();
768 GNUNET_SCHEDULER_add_now (&bootstrap_store_task, abh);
770 abh->ns_qe = GNUNET_NAMESTORE_records_lookup (ns_handle,
773 &bootstrap_abe_error,
775 &bootstrap_abe_result,
783 create_sym_key_from_ecdh(const struct GNUNET_HashCode *new_key_hash,
784 struct GNUNET_CRYPTO_SymmetricSessionKey *skey,
785 struct GNUNET_CRYPTO_SymmetricInitializationVector *iv)
787 struct GNUNET_CRYPTO_HashAsciiEncoded new_key_hash_str;
789 GNUNET_CRYPTO_hash_to_enc (new_key_hash,
791 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating symmetric rsa key from %s\n", (char*)&new_key_hash_str);
792 static const char ctx_key[] = "gnuid-aes-ctx-key";
793 GNUNET_CRYPTO_kdf (skey, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
794 new_key_hash, sizeof (struct GNUNET_HashCode),
795 ctx_key, strlen (ctx_key),
797 static const char ctx_iv[] = "gnuid-aes-ctx-iv";
798 GNUNET_CRYPTO_kdf (iv, sizeof (struct GNUNET_CRYPTO_SymmetricInitializationVector),
799 new_key_hash, sizeof (struct GNUNET_HashCode),
800 ctx_iv, strlen (ctx_iv),
806 cleanup_ticket_issue_handle (struct TicketIssueHandle *handle)
808 if (NULL != handle->attrs)
809 GNUNET_IDENTITY_ATTRIBUTE_list_destroy (handle->attrs);
810 if (NULL != handle->ns_qe)
811 GNUNET_NAMESTORE_cancel (handle->ns_qe);
812 GNUNET_free (handle);
817 send_ticket_result (struct IdpClient *client,
819 const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket,
820 const struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs)
822 struct TicketResultMessage *irm;
823 struct GNUNET_MQ_Envelope *env;
824 struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket_buf;
826 /* store ticket in DB */
827 if (GNUNET_OK != TKT_database->store_ticket (TKT_database->cls,
831 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
832 "Unable to store ticket after issue\n");
836 env = GNUNET_MQ_msg_extra (irm,
837 sizeof (struct GNUNET_IDENTITY_PROVIDER_Ticket),
838 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_RESULT);
839 ticket_buf = (struct GNUNET_IDENTITY_PROVIDER_Ticket *)&irm[1];
840 *ticket_buf = *ticket;
841 irm->id = htonl (r_id);
842 GNUNET_MQ_send (client->mq,
847 store_ticket_issue_cont (void *cls,
851 struct TicketIssueHandle *handle = cls;
853 handle->ns_qe = NULL;
854 if (GNUNET_SYSERR == success)
856 cleanup_ticket_issue_handle (handle);
857 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n",
859 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
862 send_ticket_result (handle->client,
866 cleanup_ticket_issue_handle (handle);
872 serialize_abe_keyinfo2 (const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket,
873 const struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs,
874 const struct GNUNET_ABE_AbeKey *rp_key,
875 struct GNUNET_CRYPTO_EcdhePrivateKey **ecdh_privkey,
878 struct GNUNET_CRYPTO_EcdhePublicKey ecdh_pubkey;
879 struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *le;
881 char *serialized_key;
887 struct GNUNET_CRYPTO_SymmetricSessionKey skey;
888 struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
889 struct GNUNET_HashCode new_key_hash;
892 size = GNUNET_ABE_cpabe_serialize_key (rp_key,
893 (void**)&serialized_key);
895 for (le = attrs->list_head; NULL != le; le = le->next) {
896 attrs_str_len += strlen (le->claim->name) + 1;
898 buf = GNUNET_malloc (attrs_str_len + size);
900 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
901 "Writing attributes\n");
902 for (le = attrs->list_head; NULL != le; le = le->next) {
903 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
904 "%s\n", le->claim->name);
907 GNUNET_memcpy (write_ptr,
909 strlen (le->claim->name));
910 write_ptr[strlen (le->claim->name)] = ',';
911 write_ptr += strlen (le->claim->name) + 1;
914 write_ptr[0] = '\0'; //replace last , with a 0-terminator
916 GNUNET_memcpy (write_ptr,
919 GNUNET_free (serialized_key);
920 // ECDH keypair E = eG
921 *ecdh_privkey = GNUNET_CRYPTO_ecdhe_key_create();
922 GNUNET_CRYPTO_ecdhe_key_get_public (*ecdh_privkey,
924 enc_keyinfo = GNUNET_malloc (size + attrs_str_len);
925 // Derived key K = H(eB)
926 GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecdh_ecdsa (*ecdh_privkey,
929 create_sym_key_from_ecdh(&new_key_hash, &skey, &iv);
930 enc_size = GNUNET_CRYPTO_symmetric_encrypt (buf,
931 size + attrs_str_len,
934 *result = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)+
936 GNUNET_memcpy (*result,
938 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
939 GNUNET_memcpy (*result + sizeof (struct GNUNET_CRYPTO_EcdhePublicKey),
942 GNUNET_free (enc_keyinfo);
944 return sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)+enc_size;
950 issue_ticket_after_abe_bootstrap (void *cls,
951 struct GNUNET_ABE_AbeMasterKey *abe_key)
953 struct TicketIssueHandle *ih = cls;
954 struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *le;
955 struct GNUNET_CRYPTO_EcdhePrivateKey *ecdhe_privkey;
956 struct GNUNET_GNSRECORD_Data code_record[1];
957 struct GNUNET_ABE_AbeKey *rp_key;
958 char *code_record_data;
964 size_t code_record_len;
966 //Create new ABE key for RP
968 for (le = ih->attrs->list_head; NULL != le; le = le->next)
970 attrs = GNUNET_malloc ((attrs_len + 1)*sizeof (char*));
972 for (le = ih->attrs->list_head; NULL != le; le = le->next) {
973 GNUNET_asprintf (&policy, "%s_%lu",
976 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
977 "Adding attribute to key: %s\n",
983 rp_key = GNUNET_ABE_cpabe_create_key (abe_key,
986 //TODO review this wireformat
987 code_record_len = serialize_abe_keyinfo2 (&ih->ticket,
992 code_record[0].data = code_record_data;
993 code_record[0].data_size = code_record_len;
994 code_record[0].expiration_time = GNUNET_TIME_UNIT_DAYS.rel_value_us;
995 code_record[0].record_type = GNUNET_GNSRECORD_TYPE_ABE_KEY;
996 code_record[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
998 label = GNUNET_STRINGS_data_to_string_alloc (&ih->ticket.rnd,
1001 ih->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
1006 &store_ticket_issue_cont,
1008 //for (; i > 0; i--)
1009 // GNUNET_free (attrs[i-1]);
1010 GNUNET_free (ecdhe_privkey);
1011 GNUNET_free (label);
1012 GNUNET_free (attrs);
1013 GNUNET_free (code_record_data);
1014 GNUNET_ABE_cpabe_delete_key (rp_key,
1016 GNUNET_ABE_cpabe_delete_master_key (abe_key);
1021 check_issue_ticket_message(void *cls,
1022 const struct IssueTicketMessage *im)
1026 size = ntohs (im->header.size);
1027 if (size <= sizeof (struct IssueTicketMessage))
1030 return GNUNET_SYSERR;
1037 handle_issue_ticket_message (void *cls,
1038 const struct IssueTicketMessage *im)
1040 struct TicketIssueHandle *ih;
1041 struct IdpClient *idp = cls;
1044 ih = GNUNET_new (struct TicketIssueHandle);
1045 attrs_len = ntohs (im->attr_len);
1046 ih->attrs = GNUNET_IDENTITY_ATTRIBUTE_list_deserialize ((char*)&im[1], attrs_len);
1047 ih->r_id = ntohl (im->id);
1049 ih->identity = im->identity;
1050 GNUNET_CRYPTO_ecdsa_key_get_public (&ih->identity,
1051 &ih->ticket.identity);
1052 ih->ticket.audience = im->rp;
1054 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG,
1056 bootstrap_abe (&ih->identity, &issue_ticket_after_abe_bootstrap, ih, GNUNET_NO);
1057 GNUNET_SERVICE_client_continue (idp->client);
1061 /**********************************************************
1063 **********************************************************/
1066 * Cleanup revoke handle
1068 * @param rh the ticket revocation handle
1071 cleanup_revoke_ticket_handle (struct TicketRevocationHandle *rh)
1073 if (NULL != rh->attrs)
1074 GNUNET_IDENTITY_ATTRIBUTE_list_destroy (rh->attrs);
1075 if (NULL != rh->rvk_attrs)
1076 GNUNET_IDENTITY_ATTRIBUTE_list_destroy (rh->rvk_attrs);
1077 if (NULL != rh->abe_key)
1078 GNUNET_ABE_cpabe_delete_master_key (rh->abe_key);
1079 if (NULL != rh->ns_qe)
1080 GNUNET_NAMESTORE_cancel (rh->ns_qe);
1081 if (NULL != rh->ns_it)
1082 GNUNET_NAMESTORE_zone_iteration_stop (rh->ns_it);
1088 * Send revocation result
1090 * @param rh ticket revocation handle
1091 * @param success GNUNET_OK if successful result
1094 send_revocation_finished (struct TicketRevocationHandle *rh,
1097 struct GNUNET_MQ_Envelope *env;
1098 struct RevokeTicketResultMessage *trm;
1100 env = GNUNET_MQ_msg (trm,
1101 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_REVOKE_TICKET_RESULT);
1102 trm->id = htonl (rh->r_id);
1103 trm->success = htonl (success);
1104 GNUNET_MQ_send (rh->client->mq,
1106 GNUNET_CONTAINER_DLL_remove (rh->client->revocation_list_head,
1107 rh->client->revocation_list_tail,
1113 * Process ticket from database
1115 * @param cls struct TicketIterationProcResult
1116 * @param ticket the ticket
1117 * @param attrs the attributes
1120 ticket_reissue_proc (void *cls,
1121 const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket,
1122 const struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs);
1125 revocation_reissue_tickets (struct TicketRevocationHandle *rh);
1128 static void reissue_next (void *cls)
1130 struct TicketRevocationHandle *rh = cls;
1131 revocation_reissue_tickets (rh);
1136 reissue_ticket_cont (void *cls,
1140 struct TicketRevocationHandle *rh = cls;
1143 if (GNUNET_SYSERR == success)
1145 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n",
1147 send_revocation_finished (rh, GNUNET_SYSERR);
1148 cleanup_revoke_ticket_handle (rh);
1152 GNUNET_SCHEDULER_add_now (&reissue_next, rh);
1157 * Process ticket from database
1159 * @param cls struct TicketIterationProcResult
1160 * @param ticket the ticket
1161 * @param attrs the attributes
1164 ticket_reissue_proc (void *cls,
1165 const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket,
1166 const struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs)
1168 struct TicketRevocationHandle *rh = cls;
1169 struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *le;
1170 struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *le_rollover;
1171 struct GNUNET_CRYPTO_EcdhePrivateKey *ecdhe_privkey;
1172 struct GNUNET_GNSRECORD_Data code_record[1];
1173 struct GNUNET_ABE_AbeKey *rp_key;
1174 char *code_record_data;
1181 size_t code_record_len;
1186 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1187 "Iteration done\n");
1191 if (0 == memcmp (&ticket->audience,
1192 &rh->ticket.audience,
1193 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)))
1195 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1196 "Do not reissue for this identity.!\n");
1199 GNUNET_SCHEDULER_add_now (&reissue_next, rh);
1204 * Check if any attribute of this ticket intersects with a rollover attribute
1206 reissue_ticket = GNUNET_NO;
1207 for (le = attrs->list_head; NULL != le; le = le->next)
1209 for (le_rollover = rh->rvk_attrs->list_head;
1210 NULL != le_rollover;
1211 le_rollover = le_rollover->next)
1213 if (0 == strcmp (le_rollover->claim->name,
1216 reissue_ticket = GNUNET_YES;
1217 le->claim->version = le_rollover->claim->version;
1222 if (GNUNET_NO == reissue_ticket)
1224 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1225 "Skipping ticket.\n");
1228 GNUNET_SCHEDULER_add_now (&reissue_next, rh);
1234 //Create new ABE key for RP
1237 /* If this is the RP we want to revoke attributes of, the do so */
1239 for (le = attrs->list_head; NULL != le; le = le->next)
1241 attr_arr = GNUNET_malloc ((attrs_len + 1)*sizeof (char*));
1243 for (le = attrs->list_head; NULL != le; le = le->next) {
1244 GNUNET_asprintf (&policy, "%s_%lu",
1246 le->claim->version);
1247 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1248 "Recreating key with %s\n", policy);
1249 attr_arr[i] = policy;
1253 rp_key = GNUNET_ABE_cpabe_create_key (rh->abe_key,
1256 //TODO review this wireformat
1257 code_record_len = serialize_abe_keyinfo2 (ticket,
1262 code_record[0].data = code_record_data;
1263 code_record[0].data_size = code_record_len;
1264 code_record[0].expiration_time = GNUNET_TIME_UNIT_DAYS.rel_value_us;
1265 code_record[0].record_type = GNUNET_GNSRECORD_TYPE_ABE_KEY;
1266 code_record[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
1268 label = GNUNET_STRINGS_data_to_string_alloc (&ticket->rnd,
1271 rh->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
1276 &reissue_ticket_cont,
1278 //for (; i > 0; i--)
1279 // GNUNET_free (attr_arr[i-1]);
1280 GNUNET_free (ecdhe_privkey);
1281 GNUNET_free (label);
1282 GNUNET_free (attr_arr);
1283 GNUNET_free (code_record_data);
1284 GNUNET_ABE_cpabe_delete_key (rp_key, GNUNET_YES);
1288 /* Prototype for below function */
1290 attr_reenc_cont (void *cls,
1295 revocation_reissue_tickets (struct TicketRevocationHandle *rh)
1298 /* Done, issue new keys */
1299 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1300 "Revocation Phase III: Reissuing Tickets\n");
1301 if (GNUNET_SYSERR == (ret = TKT_database->iterate_tickets (TKT_database->cls,
1302 &rh->ticket.identity,
1305 &ticket_reissue_proc,
1310 if (GNUNET_NO == ret)
1312 send_revocation_finished (rh, GNUNET_OK);
1313 cleanup_revoke_ticket_handle (rh);
1319 * Revoke next attribte by reencryption with
1323 reenc_next_attribute (struct TicketRevocationHandle *rh)
1325 struct GNUNET_GNSRECORD_Data rd[1];
1334 if (NULL == rh->attrs->list_head)
1336 revocation_reissue_tickets (rh);
1339 buf_size = GNUNET_IDENTITY_ATTRIBUTE_serialize_get_size (rh->attrs->list_head->claim);
1340 buf = GNUNET_malloc (buf_size);
1341 GNUNET_IDENTITY_ATTRIBUTE_serialize (rh->attrs->list_head->claim,
1343 rh->attrs->list_head->claim->version++;
1344 GNUNET_asprintf (&policy, "%s_%lu",
1345 rh->attrs->list_head->claim->name,
1346 rh->attrs->list_head->claim->version);
1347 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1348 "Encrypting with policy %s\n", policy);
1350 * Encrypt the attribute value and store in namestore
1352 enc_size = GNUNET_ABE_cpabe_encrypt (buf,
1358 GNUNET_free (policy);
1359 rd[0].data_size = enc_size + sizeof (uint32_t);
1360 rd_buf = GNUNET_malloc (rd[0].data_size);
1361 attr_ver = htonl (rh->attrs->list_head->claim->version);
1362 GNUNET_memcpy (rd_buf,
1365 GNUNET_memcpy (rd_buf+sizeof (uint32_t),
1368 rd[0].data = rd_buf;
1369 rd[0].record_type = GNUNET_GNSRECORD_TYPE_ID_ATTR;
1370 rd[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
1371 rd[0].expiration_time = GNUNET_TIME_UNIT_HOURS.rel_value_us; //TODO sane?
1372 rh->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
1374 rh->attrs->list_head->claim->name,
1379 GNUNET_free (enc_buf);
1380 GNUNET_free (rd_buf);
1384 * Namestore callback after revoked attribute
1388 attr_reenc_cont (void *cls,
1392 struct TicketRevocationHandle *rh = cls;
1393 struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *le;
1395 if (GNUNET_SYSERR == success)
1397 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1398 "Failed to reencrypt attribute %s\n",
1400 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1403 if (NULL == rh->attrs->list_head)
1405 revocation_reissue_tickets (rh);
1408 le = rh->attrs->list_head;
1409 GNUNET_CONTAINER_DLL_remove (rh->attrs->list_head,
1410 rh->attrs->list_tail,
1412 GNUNET_assert (NULL != rh->rvk_attrs);
1413 GNUNET_CONTAINER_DLL_insert (rh->rvk_attrs->list_head,
1414 rh->rvk_attrs->list_tail,
1418 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1419 "Re-encrypting next attribute\n");
1420 reenc_next_attribute (rh);
1425 process_attributes_to_update (void *cls,
1426 const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket,
1427 const struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs)
1429 struct TicketRevocationHandle *rh = cls;
1431 rh->attrs = GNUNET_IDENTITY_ATTRIBUTE_list_dup (attrs);
1432 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1433 "Revocation Phase I: Collecting attributes\n");
1434 /* Reencrypt all attributes with new key */
1435 if (NULL == rh->attrs->list_head)
1437 /* No attributes to reencrypt */
1438 send_revocation_finished (rh, GNUNET_OK);
1439 cleanup_revoke_ticket_handle (rh);
1442 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1443 "Revocation Phase II: Re-encrypting attributes\n");
1444 reenc_next_attribute (rh);
1452 get_ticket_after_abe_bootstrap (void *cls,
1453 struct GNUNET_ABE_AbeMasterKey *abe_key)
1455 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1456 "Finished ABE bootstrap\n");
1457 struct TicketRevocationHandle *rh = cls;
1458 rh->abe_key = abe_key;
1459 TKT_database->get_ticket_attributes (TKT_database->cls,
1461 &process_attributes_to_update,
1466 check_revoke_ticket_message(void *cls,
1467 const struct RevokeTicketMessage *im)
1471 size = ntohs (im->header.size);
1472 if (size <= sizeof (struct RevokeTicketMessage))
1475 return GNUNET_SYSERR;
1481 handle_revoke_ticket_message (void *cls,
1482 const struct RevokeTicketMessage *rm)
1484 struct TicketRevocationHandle *rh;
1485 struct IdpClient *idp = cls;
1486 struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket;
1488 rh = GNUNET_new (struct TicketRevocationHandle);
1489 ticket = (struct GNUNET_IDENTITY_PROVIDER_Ticket*)&rm[1];
1490 rh->rvk_attrs = GNUNET_new (struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList);
1491 rh->ticket = *ticket;
1492 rh->r_id = ntohl (rm->id);
1494 rh->identity = rm->identity;
1495 GNUNET_CRYPTO_ecdsa_key_get_public (&rh->identity,
1496 &rh->ticket.identity);
1497 GNUNET_CONTAINER_DLL_insert (idp->revocation_list_head,
1498 idp->revocation_list_tail,
1500 bootstrap_abe (&rh->identity, &get_ticket_after_abe_bootstrap, rh, GNUNET_NO);
1501 GNUNET_SERVICE_client_continue (idp->client);
1507 cleanup_consume_ticket_handle (struct ConsumeTicketHandle *handle)
1509 if (NULL != handle->key)
1510 GNUNET_ABE_cpabe_delete_key (handle->key,
1512 if (NULL != handle->attrs)
1513 GNUNET_IDENTITY_ATTRIBUTE_list_destroy (handle->attrs);
1514 GNUNET_free (handle);
1520 check_consume_ticket_message(void *cls,
1521 const struct ConsumeTicketMessage *cm)
1525 size = ntohs (cm->header.size);
1526 if (size <= sizeof (struct ConsumeTicketMessage))
1529 return GNUNET_SYSERR;
1535 process_parallel_lookup2 (void *cls, uint32_t rd_count,
1536 const struct GNUNET_GNSRECORD_Data *rd)
1538 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1539 "Parallel lookup finished (count=%u)\n", rd_count);
1540 struct ParallelLookup *parallel_lookup = cls;
1541 struct ConsumeTicketHandle *handle = parallel_lookup->handle;
1542 struct ConsumeTicketResultMessage *crm;
1543 struct GNUNET_MQ_Envelope *env;
1544 struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *attr_le;
1545 struct GNUNET_TIME_Absolute decrypt_duration;
1551 GNUNET_CONTAINER_DLL_remove (handle->parallel_lookups_head,
1552 handle->parallel_lookups_tail,
1554 GNUNET_free (parallel_lookup->label);
1556 GNUNET_STATISTICS_update (stats_handle,
1557 "attribute_lookup_time_total",
1558 GNUNET_TIME_absolute_get_duration (parallel_lookup->lookup_start_time).rel_value_us,
1560 GNUNET_STATISTICS_update (stats_handle,
1561 "attribute_lookups_count",
1566 GNUNET_free (parallel_lookup);
1568 GNUNET_break(0);//TODO
1569 if (rd->record_type == GNUNET_GNSRECORD_TYPE_ID_ATTR)
1571 decrypt_duration = GNUNET_TIME_absolute_get ();
1572 attr_len = GNUNET_ABE_cpabe_decrypt (rd->data + sizeof (uint32_t),
1573 rd->data_size - sizeof (uint32_t),
1576 if (GNUNET_SYSERR != attr_len)
1578 GNUNET_STATISTICS_update (stats_handle,
1579 "abe_decrypt_time_total",
1580 GNUNET_TIME_absolute_get_duration (decrypt_duration).rel_value_us,
1582 GNUNET_STATISTICS_update (stats_handle,
1583 "abe_decrypt_count",
1587 attr_le = GNUNET_new (struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry);
1588 attr_le->claim = GNUNET_IDENTITY_ATTRIBUTE_deserialize (data,
1590 attr_le->claim->version = ntohl(*(uint32_t*)rd->data);
1591 GNUNET_CONTAINER_DLL_insert (handle->attrs->list_head,
1592 handle->attrs->list_tail,
1597 if (NULL != handle->parallel_lookups_head)
1598 return; //Wait for more
1599 /* Else we are done */
1601 /* Store ticket in DB */
1602 if (GNUNET_OK != TKT_database->store_ticket (TKT_database->cls,
1606 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1607 "Unable to store ticket after consume\n");
1611 GNUNET_SCHEDULER_cancel (handle->kill_task);
1612 attrs_len = GNUNET_IDENTITY_ATTRIBUTE_list_serialize_get_size (handle->attrs);
1613 env = GNUNET_MQ_msg_extra (crm,
1615 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_CONSUME_TICKET_RESULT);
1616 crm->id = htonl (handle->r_id);
1617 crm->attrs_len = htons (attrs_len);
1618 crm->identity = handle->ticket.identity;
1619 data_tmp = (char *) &crm[1];
1620 GNUNET_IDENTITY_ATTRIBUTE_list_serialize (handle->attrs,
1622 GNUNET_MQ_send (handle->client->mq, env);
1623 cleanup_consume_ticket_handle (handle);
1627 abort_parallel_lookups2 (void *cls)
1629 struct ConsumeTicketHandle *handle = cls;
1630 struct ParallelLookup *lu;
1631 struct ParallelLookup *tmp;
1632 struct AttributeResultMessage *arm;
1633 struct GNUNET_MQ_Envelope *env;
1635 for (lu = handle->parallel_lookups_head;
1637 GNUNET_GNS_lookup_cancel (lu->lookup_request);
1638 GNUNET_free (lu->label);
1640 GNUNET_CONTAINER_DLL_remove (handle->parallel_lookups_head,
1641 handle->parallel_lookups_tail,
1646 env = GNUNET_MQ_msg (arm,
1647 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_RESULT);
1648 arm->id = htonl (handle->r_id);
1649 arm->attr_len = htons (0);
1650 GNUNET_MQ_send (handle->client->mq, env);
1656 process_consume_abe_key (void *cls, uint32_t rd_count,
1657 const struct GNUNET_GNSRECORD_Data *rd)
1659 struct ConsumeTicketHandle *handle = cls;
1660 struct GNUNET_HashCode new_key_hash;
1661 struct GNUNET_CRYPTO_SymmetricSessionKey enc_key;
1662 struct GNUNET_CRYPTO_SymmetricInitializationVector enc_iv;
1663 struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_key;
1664 struct ParallelLookup *parallel_lookup;
1670 handle->lookup_request = NULL;
1673 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1674 "Number of keys %d != 1.",
1676 cleanup_consume_ticket_handle (handle);
1677 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1682 ecdh_key = (struct GNUNET_CRYPTO_EcdhePublicKey *)rd->data;
1684 buf = GNUNET_malloc (rd->data_size - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
1686 //Calculate symmetric key from ecdh parameters
1687 GNUNET_assert (GNUNET_OK ==
1688 GNUNET_CRYPTO_ecdsa_ecdh (&handle->identity,
1691 create_sym_key_from_ecdh (&new_key_hash,
1694 size = GNUNET_CRYPTO_symmetric_decrypt (rd->data + sizeof (struct GNUNET_CRYPTO_EcdhePublicKey),
1695 rd->data_size - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey),
1700 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1701 "Decrypted bytes: %zd Expected bytes: %zd\n",
1702 size, rd->data_size - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
1703 GNUNET_STATISTICS_update (stats_handle,
1704 "abe_key_lookup_time_total",
1705 GNUNET_TIME_absolute_get_duration (handle->lookup_start_time).rel_value_us,
1707 GNUNET_STATISTICS_update (stats_handle,
1708 "abe_key_lookups_count",
1711 scopes = GNUNET_strdup (buf);
1712 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1713 "Scopes %s\n", scopes);
1714 handle->key = GNUNET_ABE_cpabe_deserialize_key ((void*)(buf + strlen (scopes) + 1),
1715 rd->data_size - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)
1716 - strlen (scopes) - 1);
1718 for (scope = strtok (scopes, ","); NULL != scope; scope = strtok (NULL, ","))
1720 GNUNET_asprintf (&lookup_query,
1723 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1724 "Looking up %s\n", lookup_query);
1725 parallel_lookup = GNUNET_new (struct ParallelLookup);
1726 parallel_lookup->handle = handle;
1727 parallel_lookup->label = GNUNET_strdup (scope);
1728 parallel_lookup->lookup_start_time = GNUNET_TIME_absolute_get();
1729 parallel_lookup->lookup_request
1730 = GNUNET_GNS_lookup (gns_handle,
1732 &handle->ticket.identity,
1733 GNUNET_GNSRECORD_TYPE_ID_ATTR,
1734 GNUNET_GNS_LO_DEFAULT,
1735 &process_parallel_lookup2,
1737 GNUNET_CONTAINER_DLL_insert (handle->parallel_lookups_head,
1738 handle->parallel_lookups_tail,
1740 GNUNET_free (lookup_query);
1742 GNUNET_free (scopes);
1744 handle->kill_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES,3),
1745 &abort_parallel_lookups2,
1751 handle_consume_ticket_message (void *cls,
1752 const struct ConsumeTicketMessage *cm)
1754 struct ConsumeTicketHandle *ch;
1755 struct IdpClient *idp = cls;
1759 ch = GNUNET_new (struct ConsumeTicketHandle);
1760 ch->r_id = ntohl (cm->id);
1762 ch->identity = cm->identity;
1763 ch->attrs = GNUNET_new (struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList);
1764 GNUNET_CRYPTO_ecdsa_key_get_public (&ch->identity,
1766 ch->ticket = *((struct GNUNET_IDENTITY_PROVIDER_Ticket*)&cm[1]);
1767 rnd_label = GNUNET_STRINGS_data_to_string_alloc (&ch->ticket.rnd,
1769 GNUNET_asprintf (&lookup_query,
1772 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1773 "Looking for ABE key under %s\n", lookup_query);
1774 ch->lookup_start_time = GNUNET_TIME_absolute_get ();
1776 = GNUNET_GNS_lookup (gns_handle,
1778 &ch->ticket.identity,
1779 GNUNET_GNSRECORD_TYPE_ABE_KEY,
1780 GNUNET_GNS_LO_DEFAULT,
1781 &process_consume_abe_key,
1783 GNUNET_free (rnd_label);
1784 GNUNET_free (lookup_query);
1785 GNUNET_SERVICE_client_continue (idp->client);
1789 cleanup_as_handle (struct AttributeStoreHandle *handle)
1791 if (NULL != handle->claim)
1792 GNUNET_free (handle->claim);
1793 if (NULL != handle->abe_key)
1794 GNUNET_ABE_cpabe_delete_master_key (handle->abe_key);
1795 GNUNET_free (handle);
1799 attr_store_cont (void *cls,
1803 struct AttributeStoreHandle *as_handle = cls;
1804 struct GNUNET_MQ_Envelope *env;
1805 struct AttributeStoreResultMessage *acr_msg;
1807 if (GNUNET_SYSERR == success)
1809 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1810 "Failed to store attribute %s\n",
1812 cleanup_as_handle (as_handle);
1813 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1817 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1818 "Sending ATTRIBUTE_STORE_RESPONSE message\n");
1819 env = GNUNET_MQ_msg (acr_msg,
1820 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_STORE_RESPONSE);
1821 acr_msg->id = htonl (as_handle->r_id);
1822 acr_msg->op_result = htonl (GNUNET_OK);
1823 GNUNET_MQ_send (as_handle->client->mq,
1825 cleanup_as_handle (as_handle);
1829 attr_store_task (void *cls)
1831 struct AttributeStoreHandle *as_handle = cls;
1832 struct GNUNET_GNSRECORD_Data rd[1];
1841 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1842 "Storing attribute\n");
1843 buf_size = GNUNET_IDENTITY_ATTRIBUTE_serialize_get_size (as_handle->claim);
1844 buf = GNUNET_malloc (buf_size);
1846 GNUNET_IDENTITY_ATTRIBUTE_serialize (as_handle->claim,
1849 GNUNET_asprintf (&policy,
1851 as_handle->claim->name,
1852 as_handle->claim->version);
1853 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1854 "Encrypting with policy %s\n", policy);
1856 * Encrypt the attribute value and store in namestore
1858 enc_size = GNUNET_ABE_cpabe_encrypt (buf,
1864 GNUNET_free (policy);
1865 rd[0].data_size = enc_size + sizeof (uint32_t);
1866 rd_buf = GNUNET_malloc (rd[0].data_size);
1867 attr_ver = htonl (as_handle->claim->version);
1868 GNUNET_memcpy (rd_buf,
1871 GNUNET_memcpy (rd_buf+sizeof (uint32_t),
1874 rd[0].data = rd_buf;
1875 rd[0].record_type = GNUNET_GNSRECORD_TYPE_ID_ATTR;
1876 rd[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
1877 rd[0].expiration_time = GNUNET_TIME_UNIT_HOURS.rel_value_us; //TODO sane?
1878 as_handle->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
1879 &as_handle->identity,
1880 as_handle->claim->name,
1885 GNUNET_free (enc_buf);
1886 GNUNET_free (rd_buf);
1891 store_after_abe_bootstrap (void *cls,
1892 struct GNUNET_ABE_AbeMasterKey *abe_key)
1894 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1895 "Finished ABE bootstrap\n");
1896 struct AttributeStoreHandle *ash = cls;
1897 ash->abe_key = abe_key;
1898 GNUNET_SCHEDULER_add_now (&attr_store_task, ash);
1902 check_attribute_store_message(void *cls,
1903 const struct AttributeStoreMessage *sam)
1907 size = ntohs (sam->header.size);
1908 if (size <= sizeof (struct AttributeStoreMessage))
1911 return GNUNET_SYSERR;
1918 handle_attribute_store_message (void *cls,
1919 const struct AttributeStoreMessage *sam)
1921 struct AttributeStoreHandle *as_handle;
1922 struct IdpClient *idp = cls;
1924 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1925 "Received ATTRIBUTE_STORE message\n");
1927 data_len = ntohs (sam->attr_len);
1929 as_handle = GNUNET_new (struct AttributeStoreHandle);
1930 as_handle->claim = GNUNET_IDENTITY_ATTRIBUTE_deserialize ((char*)&sam[1],
1933 as_handle->r_id = ntohl (sam->id);
1934 as_handle->identity = sam->identity;
1935 GNUNET_CRYPTO_ecdsa_key_get_public (&sam->identity,
1936 &as_handle->identity_pkey);
1938 GNUNET_SERVICE_client_continue (idp->client);
1939 as_handle->client = idp;
1940 bootstrap_abe (&as_handle->identity, &store_after_abe_bootstrap, as_handle, GNUNET_NO);
1944 cleanup_iter_handle (struct AttributeIterator *ai)
1946 if (NULL != ai->abe_key)
1947 GNUNET_ABE_cpabe_delete_master_key (ai->abe_key);
1948 GNUNET_CONTAINER_DLL_remove (ai->client->op_head,
1949 ai->client->op_tail,
1955 attr_iter_error (void *cls)
1957 struct AttributeIterator *ai = cls;
1959 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1960 "Failed to iterate over attributes\n");
1961 cleanup_iter_handle (ai);
1962 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1966 attr_iter_finished (void *cls)
1968 struct AttributeIterator *ai = cls;
1969 struct GNUNET_MQ_Envelope *env;
1970 struct AttributeResultMessage *arm;
1972 env = GNUNET_MQ_msg (arm,
1973 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_RESULT);
1974 arm->id = htonl (ai->request_id);
1975 arm->attr_len = htons (0);
1976 GNUNET_MQ_send (ai->client->mq, env);
1977 cleanup_iter_handle (ai);
1981 attr_iter_cb (void *cls,
1982 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
1984 unsigned int rd_count,
1985 const struct GNUNET_GNSRECORD_Data *rd)
1987 struct AttributeIterator *ai = cls;
1988 struct AttributeResultMessage *arm;
1989 struct GNUNET_ABE_AbeKey *key;
1990 struct GNUNET_MQ_Envelope *env;
1991 ssize_t msg_extra_len;
2000 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it);
2004 if (GNUNET_GNSRECORD_TYPE_ID_ATTR != rd->record_type) {
2005 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it);
2008 attr_ver = ntohl(*((uint32_t*)rd->data));
2009 GNUNET_asprintf (&policy, "%s_%lu",
2013 key = GNUNET_ABE_cpabe_create_key (ai->abe_key,
2015 msg_extra_len = GNUNET_ABE_cpabe_decrypt (rd->data+sizeof (uint32_t),
2016 rd->data_size-sizeof (uint32_t),
2020 GNUNET_ABE_cpabe_delete_key (key,
2022 //GNUNET_free (policy);
2023 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2024 "Found attribute: %s\n", label);
2025 env = GNUNET_MQ_msg_extra (arm,
2027 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_RESULT);
2028 arm->id = htonl (ai->request_id);
2029 arm->attr_len = htons (msg_extra_len);
2030 GNUNET_CRYPTO_ecdsa_key_get_public (zone,
2032 data_tmp = (char *) &arm[1];
2033 GNUNET_memcpy (data_tmp,
2036 GNUNET_MQ_send (ai->client->mq, env);
2037 GNUNET_free (attr_ser);
2038 GNUNET_ABE_cpabe_delete_master_key (ai->abe_key);
2044 iterate_after_abe_bootstrap (void *cls,
2045 struct GNUNET_ABE_AbeMasterKey *abe_key)
2047 struct AttributeIterator *ai = cls;
2048 ai->abe_key = abe_key;
2049 ai->ns_it = GNUNET_NAMESTORE_zone_iteration_start (ns_handle,
2055 &attr_iter_finished,
2060 iterate_next_after_abe_bootstrap (void *cls,
2061 struct GNUNET_ABE_AbeMasterKey *abe_key)
2063 struct AttributeIterator *ai = cls;
2064 ai->abe_key = abe_key;
2065 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it);
2071 handle_iteration_start (void *cls,
2072 const struct AttributeIterationStartMessage *ais_msg)
2074 struct IdpClient *idp = cls;
2075 struct AttributeIterator *ai;
2077 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2078 "Received ATTRIBUTE_ITERATION_START message\n");
2079 ai = GNUNET_new (struct AttributeIterator);
2080 ai->request_id = ntohl (ais_msg->id);
2082 ai->identity = ais_msg->identity;
2084 GNUNET_CONTAINER_DLL_insert (idp->op_head,
2087 bootstrap_abe (&ai->identity, &iterate_after_abe_bootstrap, ai, GNUNET_NO);
2088 GNUNET_SERVICE_client_continue (idp->client);
2093 handle_iteration_stop (void *cls,
2094 const struct AttributeIterationStopMessage *ais_msg)
2096 struct IdpClient *idp = cls;
2097 struct AttributeIterator *ai;
2100 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2101 "Received `%s' message\n",
2102 "ATTRIBUTE_ITERATION_STOP");
2103 rid = ntohl (ais_msg->id);
2104 for (ai = idp->op_head; NULL != ai; ai = ai->next)
2105 if (ai->request_id == rid)
2110 GNUNET_SERVICE_client_drop (idp->client);
2113 GNUNET_CONTAINER_DLL_remove (idp->op_head,
2117 GNUNET_SERVICE_client_continue (idp->client);
2122 handle_iteration_next (void *cls,
2123 const struct AttributeIterationNextMessage *ais_msg)
2125 struct IdpClient *idp = cls;
2126 struct AttributeIterator *ai;
2129 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2130 "Received ATTRIBUTE_ITERATION_NEXT message\n");
2131 rid = ntohl (ais_msg->id);
2132 for (ai = idp->op_head; NULL != ai; ai = ai->next)
2133 if (ai->request_id == rid)
2138 GNUNET_SERVICE_client_drop (idp->client);
2141 bootstrap_abe (&ai->identity,
2142 &iterate_next_after_abe_bootstrap,
2145 GNUNET_SERVICE_client_continue (idp->client);
2149 * Ticket iteration processor result
2151 enum ZoneIterationResult
2160 * Continue to iterate with next iteration_next call
2162 IT_SUCCESS_MORE_AVAILABLE = 1,
2165 * Iteration complete
2167 IT_SUCCESS_NOT_MORE_RESULTS_AVAILABLE = 2
2172 * Context for ticket iteration
2174 struct TicketIterationProcResult
2177 * The ticket iteration handle
2179 struct TicketIteration *ti;
2182 * Iteration result: iteration done?
2183 * #IT_SUCCESS_MORE_AVAILABLE: if there may be more results overall but
2184 * we got one for now and have sent it to the client
2185 * #IT_SUCCESS_NOT_MORE_RESULTS_AVAILABLE: if there are no further results,
2186 * #IT_START: if we are still trying to find a result.
2188 int res_iteration_finished;
2193 cleanup_ticket_iter_handle (struct TicketIteration *ti)
2199 * Process ticket from database
2201 * @param cls struct TicketIterationProcResult
2202 * @param ticket the ticket
2203 * @param attrs the attributes
2206 ticket_iterate_proc (void *cls,
2207 const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket,
2208 const struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs)
2210 struct TicketIterationProcResult *proc = cls;
2214 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2215 "Iteration done\n");
2216 proc->res_iteration_finished = IT_SUCCESS_NOT_MORE_RESULTS_AVAILABLE;
2219 proc->res_iteration_finished = IT_SUCCESS_MORE_AVAILABLE;
2220 send_ticket_result (proc->ti->client,
2228 * Perform ticket iteration step
2230 * @param ti ticket iterator to process
2233 run_ticket_iteration_round (struct TicketIteration *ti)
2235 struct TicketIterationProcResult proc;
2236 struct GNUNET_MQ_Envelope *env;
2237 struct TicketResultMessage *trm;
2240 memset (&proc, 0, sizeof (proc));
2242 proc.res_iteration_finished = IT_START;
2243 while (IT_START == proc.res_iteration_finished)
2245 if (GNUNET_SYSERR ==
2246 (ret = TKT_database->iterate_tickets (TKT_database->cls,
2250 &ticket_iterate_proc,
2256 if (GNUNET_NO == ret)
2257 proc.res_iteration_finished = IT_SUCCESS_NOT_MORE_RESULTS_AVAILABLE;
2260 if (IT_SUCCESS_MORE_AVAILABLE == proc.res_iteration_finished)
2262 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2263 "More results available\n");
2264 return; /* more later */
2266 /* send empty response to indicate end of list */
2267 env = GNUNET_MQ_msg (trm,
2268 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_RESULT);
2269 trm->id = htonl (ti->r_id);
2270 GNUNET_MQ_send (ti->client->mq,
2272 GNUNET_CONTAINER_DLL_remove (ti->client->ticket_iter_head,
2273 ti->client->ticket_iter_tail,
2275 cleanup_ticket_iter_handle (ti);
2279 handle_ticket_iteration_start (void *cls,
2280 const struct TicketIterationStartMessage *tis_msg)
2282 struct IdpClient *client = cls;
2283 struct TicketIteration *ti;
2285 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2286 "Received TICKET_ITERATION_START message\n");
2287 ti = GNUNET_new (struct TicketIteration);
2288 ti->r_id = ntohl (tis_msg->id);
2290 ti->client = client;
2291 ti->identity = tis_msg->identity;
2292 ti->is_audience = ntohl (tis_msg->is_audience);
2294 GNUNET_CONTAINER_DLL_insert (client->ticket_iter_head,
2295 client->ticket_iter_tail,
2297 run_ticket_iteration_round (ti);
2298 GNUNET_SERVICE_client_continue (client->client);
2303 handle_ticket_iteration_stop (void *cls,
2304 const struct TicketIterationStopMessage *tis_msg)
2306 struct IdpClient *client = cls;
2307 struct TicketIteration *ti;
2310 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2311 "Received `%s' message\n",
2312 "TICKET_ITERATION_STOP");
2313 rid = ntohl (tis_msg->id);
2314 for (ti = client->ticket_iter_head; NULL != ti; ti = ti->next)
2315 if (ti->r_id == rid)
2320 GNUNET_SERVICE_client_drop (client->client);
2323 GNUNET_CONTAINER_DLL_remove (client->ticket_iter_head,
2324 client->ticket_iter_tail,
2326 cleanup_ticket_iter_handle (ti);
2327 GNUNET_SERVICE_client_continue (client->client);
2332 handle_ticket_iteration_next (void *cls,
2333 const struct TicketIterationNextMessage *tis_msg)
2335 struct IdpClient *client = cls;
2336 struct TicketIteration *ti;
2339 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2340 "Received TICKET_ITERATION_NEXT message\n");
2341 rid = ntohl (tis_msg->id);
2342 for (ti = client->ticket_iter_head; NULL != ti; ti = ti->next)
2343 if (ti->r_id == rid)
2348 GNUNET_SERVICE_client_drop (client->client);
2351 run_ticket_iteration_round (ti);
2352 GNUNET_SERVICE_client_continue (client->client);
2359 * Main function that will be run
2361 * @param cls closure
2362 * @param c the configuration used
2363 * @param server the service handle
2367 const struct GNUNET_CONFIGURATION_Handle *c,
2368 struct GNUNET_SERVICE_Handle *server)
2373 stats = GNUNET_STATISTICS_create ("identity-provider", cfg);
2375 //Connect to identity and namestore services
2376 ns_handle = GNUNET_NAMESTORE_connect (cfg);
2377 if (NULL == ns_handle)
2379 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "error connecting to namestore");
2382 gns_handle = GNUNET_GNS_connect (cfg);
2383 if (NULL == gns_handle)
2385 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "error connecting to gns");
2387 credential_handle = GNUNET_CREDENTIAL_connect (cfg);
2388 if (NULL == credential_handle)
2390 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "error connecting to credential");
2392 identity_handle = GNUNET_IDENTITY_connect (cfg,
2395 stats_handle = GNUNET_STATISTICS_create ("identity-provider",
2397 /* Loading DB plugin */
2399 GNUNET_CONFIGURATION_get_value_string (cfg,
2400 "identity-provider",
2403 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2404 "No database backend configured\n");
2405 GNUNET_asprintf (&db_lib_name,
2406 "libgnunet_plugin_identity_provider_%s",
2408 TKT_database = GNUNET_PLUGIN_load (db_lib_name,
2410 GNUNET_free (database);
2411 if (NULL == TKT_database)
2413 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2414 "Could not load database backend `%s'\n",
2416 GNUNET_SCHEDULER_shutdown ();
2421 GNUNET_CONFIGURATION_get_value_time (cfg,
2422 "identity-provider",
2423 "TOKEN_EXPIRATION_INTERVAL",
2424 &token_expiration_interval))
2426 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2427 "Time window for zone iteration: %s\n",
2428 GNUNET_STRINGS_relative_time_to_string (token_expiration_interval,
2431 token_expiration_interval = DEFAULT_TOKEN_EXPIRATION_INTERVAL;
2434 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL);
2438 * Called whenever a client is disconnected.
2440 * @param cls closure
2441 * @param client identification of the client
2442 * @param app_ctx @a client
2445 client_disconnect_cb (void *cls,
2446 struct GNUNET_SERVICE_Client *client,
2449 struct IdpClient *idp = app_ctx;
2450 struct AttributeIterator *ai;
2451 struct TicketIteration *ti;
2452 struct TicketRevocationHandle *rh;
2454 //TODO other operations
2456 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2457 "Client %p disconnected\n",
2460 while (NULL != (ai = idp->op_head))
2462 GNUNET_CONTAINER_DLL_remove (idp->op_head,
2467 while (NULL != (rh = idp->revocation_list_head))
2469 GNUNET_CONTAINER_DLL_remove (idp->revocation_list_head,
2470 idp->revocation_list_tail,
2472 cleanup_revoke_ticket_handle (rh);
2474 while (NULL != (ti = idp->ticket_iter_head))
2476 GNUNET_CONTAINER_DLL_remove (idp->ticket_iter_head,
2477 idp->ticket_iter_tail,
2479 cleanup_ticket_iter_handle (ti);
2486 * Add a client to our list of active clients.
2489 * @param client client to add
2490 * @param mq message queue for @a client
2491 * @return internal namestore client structure for this client
2494 client_connect_cb (void *cls,
2495 struct GNUNET_SERVICE_Client *client,
2496 struct GNUNET_MQ_Handle *mq)
2498 struct IdpClient *idp;
2499 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2500 "Client %p connected\n",
2502 idp = GNUNET_new (struct IdpClient);
2503 idp->client = client;
2511 * Define "main" method using service macro.
2514 ("identity-provider",
2515 GNUNET_SERVICE_OPTION_NONE,
2518 &client_disconnect_cb,
2520 GNUNET_MQ_hd_var_size (attribute_store_message,
2521 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_STORE,
2522 struct AttributeStoreMessage,
2524 GNUNET_MQ_hd_fixed_size (iteration_start,
2525 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_START,
2526 struct AttributeIterationStartMessage,
2528 GNUNET_MQ_hd_fixed_size (iteration_next,
2529 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_NEXT,
2530 struct AttributeIterationNextMessage,
2532 GNUNET_MQ_hd_fixed_size (iteration_stop,
2533 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_STOP,
2534 struct AttributeIterationStopMessage,
2536 GNUNET_MQ_hd_var_size (issue_ticket_message,
2537 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ISSUE_TICKET,
2538 struct IssueTicketMessage,
2540 GNUNET_MQ_hd_var_size (consume_ticket_message,
2541 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_CONSUME_TICKET,
2542 struct ConsumeTicketMessage,
2544 GNUNET_MQ_hd_fixed_size (ticket_iteration_start,
2545 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_START,
2546 struct TicketIterationStartMessage,
2548 GNUNET_MQ_hd_fixed_size (ticket_iteration_next,
2549 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_NEXT,
2550 struct TicketIterationNextMessage,
2552 GNUNET_MQ_hd_fixed_size (ticket_iteration_stop,
2553 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_STOP,
2554 struct TicketIterationStopMessage,
2556 GNUNET_MQ_hd_var_size (revoke_ticket_message,
2557 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_REVOKE_TICKET,
2558 struct RevokeTicketMessage,
2560 GNUNET_MQ_handler_end());
2561 /* end of gnunet-service-identity-provider.c */