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_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;
236 * An attribute iteration operation.
238 struct AttributeIterator
241 * Next element in the DLL
243 struct AttributeIterator *next;
246 * Previous element in the DLL
248 struct AttributeIterator *prev;
251 * IDP client which intiated this zone iteration
253 struct IdpClient *client;
256 * Key of the zone we are iterating over.
258 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
261 * The issuer egos ABE master key
263 struct GNUNET_ABE_AbeMasterKey *abe_key;
268 struct GNUNET_NAMESTORE_ZoneIterator *ns_it;
271 * The operation id fot the zone iteration in the response for the client
288 struct GNUNET_SERVICE_Client *client;
291 * Message queue for transmission to @e client
293 struct GNUNET_MQ_Handle *mq;
297 * Attribute iteration operations in
298 * progress initiated by this client
300 struct AttributeIterator *op_head;
304 * Attribute iteration operations
305 * in progress initiated by this client
307 struct AttributeIterator *op_tail;
310 * Head of DLL of ticket iteration ops
312 struct TicketIteration *ticket_iter_head;
315 * Tail of DLL of ticket iteration ops
317 struct TicketIteration *ticket_iter_tail;
321 * Head of DLL of ticket revocation ops
323 struct TicketRevocationHandle *revocation_list_head;
326 * Tail of DLL of ticket revocation ops
328 struct TicketRevocationHandle *revocation_list_tail;
333 struct AttributeStoreHandle
339 struct IdpClient *client;
344 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
349 struct GNUNET_CRYPTO_EcdsaPublicKey identity_pkey;
352 * The issuer egos ABE master key
354 struct GNUNET_ABE_AbeMasterKey *abe_key;
359 struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
362 * The attribute to store
364 struct GNUNET_IDENTITY_ATTRIBUTE_Claim *claim;
374 struct ParallelLookup;
376 struct ConsumeTicketHandle
382 struct IdpClient *client;
387 struct GNUNET_IDENTITY_PROVIDER_Ticket ticket;
392 struct GNUNET_GNS_LookupRequest *lookup_request;
397 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
402 struct GNUNET_CRYPTO_EcdsaPublicKey identity_pub;
407 struct ParallelLookup *parallel_lookups_head;
412 struct ParallelLookup *parallel_lookups_tail;
417 struct GNUNET_SCHEDULER_Task *kill_task;
422 struct GNUNET_ABE_AbeKey *key;
427 struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs;
432 struct GNUNET_TIME_Absolute lookup_start_time;
441 * Handle for a parallel GNS lookup job
443 struct ParallelLookup
446 struct ParallelLookup *next;
449 struct ParallelLookup *prev;
451 /* The GNS request */
452 struct GNUNET_GNS_LookupRequest *lookup_request;
454 /* The handle the return to */
455 struct ConsumeTicketHandle *handle;
460 struct GNUNET_TIME_Absolute lookup_start_time;
462 /* The label to look up */
467 * Ticket revocation request handle
469 struct TicketRevocationHandle
474 struct TicketRevocationHandle *next;
479 struct TicketRevocationHandle *prev;
484 struct IdpClient *client;
487 * Attributes to reissue
489 struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs;
492 * Attributes to revoke
494 struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *rvk_attrs;
499 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
504 struct GNUNET_IDENTITY_PROVIDER_Ticket ticket;
509 struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
514 struct GNUNET_NAMESTORE_ZoneIterator *ns_it;
519 struct GNUNET_ABE_AbeMasterKey *abe_key;
535 * Ticket issue request handle
537 struct TicketIssueHandle
543 struct IdpClient *client;
546 * Attributes to issue
548 struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs;
553 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
558 struct GNUNET_IDENTITY_PROVIDER_Ticket ticket;
563 struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
573 * DLL for ego handles to egos containing the ID_ATTRS in a map in json_t format
581 struct EgoEntry *next;
586 struct EgoEntry *prev;
591 struct GNUNET_IDENTITY_Ego *ego;
594 * Attribute map. Contains the attributes as json_t
596 struct GNUNET_CONTAINER_MultiHashMap *attr_map;
606 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
610 GNUNET_STATISTICS_destroy (stats, GNUNET_NO);
613 GNUNET_break (NULL == GNUNET_PLUGIN_unload (db_lib_name,
615 GNUNET_free (db_lib_name);
617 if (NULL != timeout_task)
618 GNUNET_SCHEDULER_cancel (timeout_task);
619 if (NULL != update_task)
620 GNUNET_SCHEDULER_cancel (update_task);
621 if (NULL != identity_handle)
622 GNUNET_IDENTITY_disconnect (identity_handle);
623 if (NULL != gns_handle)
624 GNUNET_GNS_disconnect (gns_handle);
625 if (NULL != credential_handle)
626 GNUNET_CREDENTIAL_disconnect (credential_handle);
628 GNUNET_NAMESTORE_zone_iteration_stop (ns_it);
630 GNUNET_NAMESTORE_cancel (ns_qe);
631 if (NULL != ns_handle)
632 GNUNET_NAMESTORE_disconnect (ns_handle);
633 GNUNET_free_non_null (token);
634 GNUNET_free_non_null (label);
644 do_shutdown (void *cls)
646 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
647 "Shutting down...\n");
652 * Finished storing newly bootstrapped ABE key
655 bootstrap_store_cont (void *cls,
659 struct AbeBootstrapHandle *abh = cls;
660 if (GNUNET_SYSERR == success)
662 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
663 "Failed to bootstrap ABE master %s\n",
665 abh->proc (abh->proc_cls, NULL);
666 GNUNET_free (abh->abe_key);
670 abh->proc (abh->proc_cls, abh->abe_key);
675 * Generates and stores a new ABE key
678 bootstrap_store_task (void *cls)
680 struct AbeBootstrapHandle *abh = cls;
681 struct GNUNET_GNSRECORD_Data rd[1];
684 rd[0].data_size = GNUNET_ABE_cpabe_serialize_master_key (abh->abe_key,
687 rd[0].record_type = GNUNET_GNSRECORD_TYPE_ABE_MASTER;
688 rd[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION | GNUNET_GNSRECORD_RF_PRIVATE;
689 rd[0].expiration_time = GNUNET_TIME_UNIT_HOURS.rel_value_us; //TODO sane?
690 abh->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
695 &bootstrap_store_cont,
701 * Error checking for ABE master
704 bootstrap_abe_error (void *cls)
706 struct AbeBootstrapHandle *abh = cls;
707 abh->proc (abh->proc_cls, NULL);
713 * Handle ABE lookup in namestore
716 bootstrap_abe_result (void *cls,
717 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
719 unsigned int rd_count,
720 const struct GNUNET_GNSRECORD_Data *rd)
722 struct AbeBootstrapHandle *abh = cls;
723 struct GNUNET_ABE_AbeMasterKey *abe_key;
725 for (uint32_t i=0;i<rd_count;i++) {
726 if (GNUNET_GNSRECORD_TYPE_ABE_MASTER != rd[i].record_type)
728 abe_key = GNUNET_ABE_cpabe_deserialize_master_key (rd[i].data,
730 abh->proc (abh->proc_cls, abe_key);
735 //No ABE master found, bootstrapping...
736 abh->abe_key = GNUNET_ABE_cpabe_create_master_key ();
737 GNUNET_SCHEDULER_add_now (&bootstrap_store_task, abh);
741 * Bootstrap ABE master if it does not yet exists.
742 * Will call the AbeBootstrapResult processor when done.
743 * will always recreate the ABE key of GNUNET_YES == recreate
746 bootstrap_abe (const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
747 AbeBootstrapResult proc,
751 struct AbeBootstrapHandle *abh;
753 abh = GNUNET_new (struct AbeBootstrapHandle);
756 abh->identity = *identity;
757 if (GNUNET_YES == recreate)
759 abh->abe_key = GNUNET_ABE_cpabe_create_master_key ();
760 GNUNET_SCHEDULER_add_now (&bootstrap_store_task, abh);
762 abh->ns_qe = GNUNET_NAMESTORE_records_lookup (ns_handle,
765 &bootstrap_abe_error,
767 &bootstrap_abe_result,
775 create_sym_key_from_ecdh(const struct GNUNET_HashCode *new_key_hash,
776 struct GNUNET_CRYPTO_SymmetricSessionKey *skey,
777 struct GNUNET_CRYPTO_SymmetricInitializationVector *iv)
779 struct GNUNET_CRYPTO_HashAsciiEncoded new_key_hash_str;
781 GNUNET_CRYPTO_hash_to_enc (new_key_hash,
783 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating symmetric rsa key from %s\n", (char*)&new_key_hash_str);
784 static const char ctx_key[] = "gnuid-aes-ctx-key";
785 GNUNET_CRYPTO_kdf (skey, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
786 new_key_hash, sizeof (struct GNUNET_HashCode),
787 ctx_key, strlen (ctx_key),
789 static const char ctx_iv[] = "gnuid-aes-ctx-iv";
790 GNUNET_CRYPTO_kdf (iv, sizeof (struct GNUNET_CRYPTO_SymmetricInitializationVector),
791 new_key_hash, sizeof (struct GNUNET_HashCode),
792 ctx_iv, strlen (ctx_iv),
798 cleanup_ticket_issue_handle (struct TicketIssueHandle *handle)
800 if (NULL != handle->attrs)
801 GNUNET_IDENTITY_ATTRIBUTE_list_destroy (handle->attrs);
802 if (NULL != handle->ns_qe)
803 GNUNET_NAMESTORE_cancel (handle->ns_qe);
804 GNUNET_free (handle);
809 send_ticket_result (struct IdpClient *client,
811 const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket,
812 const struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs)
814 struct TicketResultMessage *irm;
815 struct GNUNET_MQ_Envelope *env;
816 struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket_buf;
818 /* store ticket in DB */
819 if (GNUNET_OK != TKT_database->store_ticket (TKT_database->cls,
823 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
824 "Unable to store ticket after issue\n");
828 env = GNUNET_MQ_msg_extra (irm,
829 sizeof (struct GNUNET_IDENTITY_PROVIDER_Ticket),
830 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_RESULT);
831 ticket_buf = (struct GNUNET_IDENTITY_PROVIDER_Ticket *)&irm[1];
832 *ticket_buf = *ticket;
833 irm->id = htonl (r_id);
834 GNUNET_MQ_send (client->mq,
839 store_ticket_issue_cont (void *cls,
843 struct TicketIssueHandle *handle = cls;
845 handle->ns_qe = NULL;
846 if (GNUNET_SYSERR == success)
848 cleanup_ticket_issue_handle (handle);
849 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n",
851 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
854 send_ticket_result (handle->client,
858 cleanup_ticket_issue_handle (handle);
864 serialize_abe_keyinfo2 (const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket,
865 const struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs,
866 const struct GNUNET_ABE_AbeKey *rp_key,
867 struct GNUNET_CRYPTO_EcdhePrivateKey **ecdh_privkey,
870 struct GNUNET_CRYPTO_EcdhePublicKey ecdh_pubkey;
871 struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *le;
873 char *serialized_key;
879 struct GNUNET_CRYPTO_SymmetricSessionKey skey;
880 struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
881 struct GNUNET_HashCode new_key_hash;
884 size = GNUNET_ABE_cpabe_serialize_key (rp_key,
885 (void**)&serialized_key);
887 for (le = attrs->list_head; NULL != le; le = le->next) {
888 attrs_str_len += strlen (le->claim->name) + 1;
890 buf = GNUNET_malloc (attrs_str_len + size);
892 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
893 "Writing attributes\n");
894 for (le = attrs->list_head; NULL != le; le = le->next) {
895 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
896 "%s\n", le->claim->name);
899 GNUNET_memcpy (write_ptr,
901 strlen (le->claim->name));
902 write_ptr[strlen (le->claim->name)] = ',';
903 write_ptr += strlen (le->claim->name) + 1;
906 write_ptr[0] = '\0'; //replace last , with a 0-terminator
908 GNUNET_memcpy (write_ptr,
911 GNUNET_free (serialized_key);
912 // ECDH keypair E = eG
913 *ecdh_privkey = GNUNET_CRYPTO_ecdhe_key_create();
914 GNUNET_CRYPTO_ecdhe_key_get_public (*ecdh_privkey,
916 enc_keyinfo = GNUNET_malloc (size + attrs_str_len);
917 // Derived key K = H(eB)
918 GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecdh_ecdsa (*ecdh_privkey,
921 create_sym_key_from_ecdh(&new_key_hash, &skey, &iv);
922 enc_size = GNUNET_CRYPTO_symmetric_encrypt (buf,
923 size + attrs_str_len,
926 *result = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)+
928 GNUNET_memcpy (*result,
930 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
931 GNUNET_memcpy (*result + sizeof (struct GNUNET_CRYPTO_EcdhePublicKey),
934 GNUNET_free (enc_keyinfo);
936 return sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)+enc_size;
942 issue_ticket_after_abe_bootstrap (void *cls,
943 struct GNUNET_ABE_AbeMasterKey *abe_key)
945 struct TicketIssueHandle *ih = cls;
946 struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *le;
947 struct GNUNET_CRYPTO_EcdhePrivateKey *ecdhe_privkey;
948 struct GNUNET_GNSRECORD_Data code_record[1];
949 struct GNUNET_ABE_AbeKey *rp_key;
950 char *code_record_data;
956 size_t code_record_len;
958 //Create new ABE key for RP
960 for (le = ih->attrs->list_head; NULL != le; le = le->next)
962 attrs = GNUNET_malloc ((attrs_len + 1)*sizeof (char*));
964 for (le = ih->attrs->list_head; NULL != le; le = le->next) {
965 GNUNET_asprintf (&policy, "%s_%lu",
968 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
969 "Adding attribute to key: %s\n",
975 rp_key = GNUNET_ABE_cpabe_create_key (abe_key,
978 //TODO review this wireformat
979 code_record_len = serialize_abe_keyinfo2 (&ih->ticket,
984 code_record[0].data = code_record_data;
985 code_record[0].data_size = code_record_len;
986 code_record[0].expiration_time = GNUNET_TIME_UNIT_DAYS.rel_value_us;
987 code_record[0].record_type = GNUNET_GNSRECORD_TYPE_ABE_KEY;
988 code_record[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
990 label = GNUNET_STRINGS_data_to_string_alloc (&ih->ticket.rnd,
993 ih->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
998 &store_ticket_issue_cont,
1000 //for (; i > 0; i--)
1001 // GNUNET_free (attrs[i-1]);
1002 GNUNET_free (ecdhe_privkey);
1003 GNUNET_free (label);
1004 GNUNET_free (attrs);
1005 GNUNET_free (code_record_data);
1006 GNUNET_ABE_cpabe_delete_key (rp_key,
1008 GNUNET_ABE_cpabe_delete_master_key (abe_key);
1013 check_issue_ticket_message(void *cls,
1014 const struct IssueTicketMessage *im)
1018 size = ntohs (im->header.size);
1019 if (size <= sizeof (struct IssueTicketMessage))
1022 return GNUNET_SYSERR;
1029 handle_issue_ticket_message (void *cls,
1030 const struct IssueTicketMessage *im)
1032 struct TicketIssueHandle *ih;
1033 struct IdpClient *idp = cls;
1036 ih = GNUNET_new (struct TicketIssueHandle);
1037 attrs_len = ntohs (im->attr_len);
1038 ih->attrs = GNUNET_IDENTITY_ATTRIBUTE_list_deserialize ((char*)&im[1], attrs_len);
1039 ih->r_id = ntohl (im->id);
1041 ih->identity = im->identity;
1042 GNUNET_CRYPTO_ecdsa_key_get_public (&ih->identity,
1043 &ih->ticket.identity);
1044 ih->ticket.audience = im->rp;
1046 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG,
1048 bootstrap_abe (&ih->identity, &issue_ticket_after_abe_bootstrap, ih, GNUNET_NO);
1049 GNUNET_SERVICE_client_continue (idp->client);
1053 /**********************************************************
1055 **********************************************************/
1058 * Cleanup revoke handle
1060 * @param rh the ticket revocation handle
1063 cleanup_revoke_ticket_handle (struct TicketRevocationHandle *rh)
1065 if (NULL != rh->attrs)
1066 GNUNET_IDENTITY_ATTRIBUTE_list_destroy (rh->attrs);
1067 if (NULL != rh->rvk_attrs)
1068 GNUNET_IDENTITY_ATTRIBUTE_list_destroy (rh->rvk_attrs);
1069 if (NULL != rh->abe_key)
1070 GNUNET_ABE_cpabe_delete_master_key (rh->abe_key);
1071 if (NULL != rh->ns_qe)
1072 GNUNET_NAMESTORE_cancel (rh->ns_qe);
1073 if (NULL != rh->ns_it)
1074 GNUNET_NAMESTORE_zone_iteration_stop (rh->ns_it);
1080 * Send revocation result
1082 * @param rh ticket revocation handle
1083 * @param success GNUNET_OK if successful result
1086 send_revocation_finished (struct TicketRevocationHandle *rh,
1089 struct GNUNET_MQ_Envelope *env;
1090 struct RevokeTicketResultMessage *trm;
1092 env = GNUNET_MQ_msg (trm,
1093 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_REVOKE_TICKET_RESULT);
1094 trm->id = htonl (rh->r_id);
1095 trm->success = htonl (success);
1096 GNUNET_MQ_send (rh->client->mq,
1098 GNUNET_CONTAINER_DLL_remove (rh->client->revocation_list_head,
1099 rh->client->revocation_list_tail,
1105 * Process ticket from database
1107 * @param cls struct TicketIterationProcResult
1108 * @param ticket the ticket
1109 * @param attrs the attributes
1112 ticket_reissue_proc (void *cls,
1113 const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket,
1114 const struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs);
1117 revocation_reissue_tickets (struct TicketRevocationHandle *rh);
1120 static void reissue_next (void *cls)
1122 struct TicketRevocationHandle *rh = cls;
1123 revocation_reissue_tickets (rh);
1128 reissue_ticket_cont (void *cls,
1132 struct TicketRevocationHandle *rh = cls;
1135 if (GNUNET_SYSERR == success)
1137 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n",
1139 send_revocation_finished (rh, GNUNET_SYSERR);
1140 cleanup_revoke_ticket_handle (rh);
1144 GNUNET_SCHEDULER_add_now (&reissue_next, rh);
1149 * Process ticket from database
1151 * @param cls struct TicketIterationProcResult
1152 * @param ticket the ticket
1153 * @param attrs the attributes
1156 ticket_reissue_proc (void *cls,
1157 const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket,
1158 const struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs)
1160 struct TicketRevocationHandle *rh = cls;
1161 struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *le;
1162 struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *le_rollover;
1163 struct GNUNET_CRYPTO_EcdhePrivateKey *ecdhe_privkey;
1164 struct GNUNET_GNSRECORD_Data code_record[1];
1165 struct GNUNET_ABE_AbeKey *rp_key;
1166 char *code_record_data;
1173 size_t code_record_len;
1178 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1179 "Iteration done\n");
1183 if (0 == memcmp (&ticket->audience,
1184 &rh->ticket.audience,
1185 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)))
1187 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1188 "Do not reissue for this identity.!\n");
1191 GNUNET_SCHEDULER_add_now (&reissue_next, rh);
1196 * Check if any attribute of this ticket intersects with a rollover attribute
1198 reissue_ticket = GNUNET_NO;
1199 for (le = attrs->list_head; NULL != le; le = le->next)
1201 for (le_rollover = rh->rvk_attrs->list_head;
1202 NULL != le_rollover;
1203 le_rollover = le_rollover->next)
1205 if (0 == strcmp (le_rollover->claim->name,
1208 reissue_ticket = GNUNET_YES;
1209 le->claim->version = le_rollover->claim->version;
1214 if (GNUNET_NO == reissue_ticket)
1216 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1217 "Skipping ticket.\n");
1220 GNUNET_SCHEDULER_add_now (&reissue_next, rh);
1226 //Create new ABE key for RP
1229 /* If this is the RP we want to revoke attributes of, the do so */
1231 for (le = attrs->list_head; NULL != le; le = le->next)
1233 attr_arr = GNUNET_malloc ((attrs_len + 1)*sizeof (char*));
1235 for (le = attrs->list_head; NULL != le; le = le->next) {
1236 GNUNET_asprintf (&policy, "%s_%lu",
1238 le->claim->version);
1239 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1240 "Recreating key with %s\n", policy);
1241 attr_arr[i] = policy;
1245 rp_key = GNUNET_ABE_cpabe_create_key (rh->abe_key,
1248 //TODO review this wireformat
1249 code_record_len = serialize_abe_keyinfo2 (ticket,
1254 code_record[0].data = code_record_data;
1255 code_record[0].data_size = code_record_len;
1256 code_record[0].expiration_time = GNUNET_TIME_UNIT_DAYS.rel_value_us;
1257 code_record[0].record_type = GNUNET_GNSRECORD_TYPE_ABE_KEY;
1258 code_record[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
1260 label = GNUNET_STRINGS_data_to_string_alloc (&ticket->rnd,
1263 rh->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
1268 &reissue_ticket_cont,
1270 //for (; i > 0; i--)
1271 // GNUNET_free (attr_arr[i-1]);
1272 GNUNET_free (ecdhe_privkey);
1273 GNUNET_free (label);
1274 GNUNET_free (attr_arr);
1275 GNUNET_free (code_record_data);
1276 GNUNET_ABE_cpabe_delete_key (rp_key, GNUNET_YES);
1280 /* Prototype for below function */
1282 attr_reenc_cont (void *cls,
1287 revocation_reissue_tickets (struct TicketRevocationHandle *rh)
1290 /* Done, issue new keys */
1291 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1292 "Revocation Phase III: Reissuing Tickets\n");
1293 if (GNUNET_SYSERR == (ret = TKT_database->iterate_tickets (TKT_database->cls,
1294 &rh->ticket.identity,
1297 &ticket_reissue_proc,
1302 if (GNUNET_NO == ret)
1304 send_revocation_finished (rh, GNUNET_OK);
1305 cleanup_revoke_ticket_handle (rh);
1311 * Revoke next attribte by reencryption with
1315 reenc_next_attribute (struct TicketRevocationHandle *rh)
1317 struct GNUNET_GNSRECORD_Data rd[1];
1326 if (NULL == rh->attrs->list_head)
1328 revocation_reissue_tickets (rh);
1331 buf_size = GNUNET_IDENTITY_ATTRIBUTE_serialize_get_size (rh->attrs->list_head->claim);
1332 buf = GNUNET_malloc (buf_size);
1333 GNUNET_IDENTITY_ATTRIBUTE_serialize (rh->attrs->list_head->claim,
1335 rh->attrs->list_head->claim->version++;
1336 GNUNET_asprintf (&policy, "%s_%lu",
1337 rh->attrs->list_head->claim->name,
1338 rh->attrs->list_head->claim->version);
1339 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1340 "Encrypting with policy %s\n", policy);
1342 * Encrypt the attribute value and store in namestore
1344 enc_size = GNUNET_ABE_cpabe_encrypt (buf,
1350 if (GNUNET_SYSERR == enc_size)
1352 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1353 "Unable to re-encrypt with policy %s\n",
1355 GNUNET_free (policy);
1356 send_revocation_finished (rh, GNUNET_SYSERR);
1357 cleanup_revoke_ticket_handle (rh);
1360 GNUNET_free (policy);
1362 rd[0].data_size = enc_size + sizeof (uint32_t);
1363 rd_buf = GNUNET_malloc (rd[0].data_size);
1364 attr_ver = htonl (rh->attrs->list_head->claim->version);
1365 GNUNET_memcpy (rd_buf,
1368 GNUNET_memcpy (rd_buf+sizeof (uint32_t),
1371 rd[0].data = rd_buf;
1372 rd[0].record_type = GNUNET_GNSRECORD_TYPE_ID_ATTR;
1373 rd[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
1374 rd[0].expiration_time = GNUNET_TIME_UNIT_HOURS.rel_value_us; //TODO sane?
1375 rh->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
1377 rh->attrs->list_head->claim->name,
1382 GNUNET_free (enc_buf);
1383 GNUNET_free (rd_buf);
1387 * Namestore callback after revoked attribute
1391 attr_reenc_cont (void *cls,
1395 struct TicketRevocationHandle *rh = cls;
1396 struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *le;
1398 if (GNUNET_SYSERR == success)
1400 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1401 "Failed to reencrypt attribute %s\n",
1403 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1406 if (NULL == rh->attrs->list_head)
1408 revocation_reissue_tickets (rh);
1411 le = rh->attrs->list_head;
1412 GNUNET_CONTAINER_DLL_remove (rh->attrs->list_head,
1413 rh->attrs->list_tail,
1415 GNUNET_assert (NULL != rh->rvk_attrs);
1416 GNUNET_CONTAINER_DLL_insert (rh->rvk_attrs->list_head,
1417 rh->rvk_attrs->list_tail,
1421 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1422 "Re-encrypting next attribute\n");
1423 reenc_next_attribute (rh);
1428 process_attributes_to_update (void *cls,
1429 const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket,
1430 const struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs)
1432 struct TicketRevocationHandle *rh = cls;
1434 rh->attrs = GNUNET_IDENTITY_ATTRIBUTE_list_dup (attrs);
1435 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1436 "Revocation Phase I: Collecting attributes\n");
1437 /* Reencrypt all attributes with new key */
1438 if (NULL == rh->attrs->list_head)
1440 /* No attributes to reencrypt */
1441 send_revocation_finished (rh, GNUNET_OK);
1442 cleanup_revoke_ticket_handle (rh);
1445 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1446 "Revocation Phase II: Re-encrypting attributes\n");
1447 reenc_next_attribute (rh);
1455 get_ticket_after_abe_bootstrap (void *cls,
1456 struct GNUNET_ABE_AbeMasterKey *abe_key)
1458 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1459 "Finished ABE bootstrap\n");
1460 struct TicketRevocationHandle *rh = cls;
1461 rh->abe_key = abe_key;
1462 TKT_database->get_ticket_attributes (TKT_database->cls,
1464 &process_attributes_to_update,
1469 check_revoke_ticket_message(void *cls,
1470 const struct RevokeTicketMessage *im)
1474 size = ntohs (im->header.size);
1475 if (size <= sizeof (struct RevokeTicketMessage))
1478 return GNUNET_SYSERR;
1484 handle_revoke_ticket_message (void *cls,
1485 const struct RevokeTicketMessage *rm)
1487 struct TicketRevocationHandle *rh;
1488 struct IdpClient *idp = cls;
1489 struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket;
1491 rh = GNUNET_new (struct TicketRevocationHandle);
1492 ticket = (struct GNUNET_IDENTITY_PROVIDER_Ticket*)&rm[1];
1493 rh->rvk_attrs = GNUNET_new (struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList);
1494 rh->ticket = *ticket;
1495 rh->r_id = ntohl (rm->id);
1497 rh->identity = rm->identity;
1498 GNUNET_CRYPTO_ecdsa_key_get_public (&rh->identity,
1499 &rh->ticket.identity);
1500 GNUNET_CONTAINER_DLL_insert (idp->revocation_list_head,
1501 idp->revocation_list_tail,
1503 bootstrap_abe (&rh->identity, &get_ticket_after_abe_bootstrap, rh, GNUNET_NO);
1504 GNUNET_SERVICE_client_continue (idp->client);
1510 cleanup_consume_ticket_handle (struct ConsumeTicketHandle *handle)
1512 if (NULL != handle->key)
1513 GNUNET_ABE_cpabe_delete_key (handle->key,
1515 if (NULL != handle->attrs)
1516 GNUNET_IDENTITY_ATTRIBUTE_list_destroy (handle->attrs);
1517 GNUNET_free (handle);
1523 check_consume_ticket_message(void *cls,
1524 const struct ConsumeTicketMessage *cm)
1528 size = ntohs (cm->header.size);
1529 if (size <= sizeof (struct ConsumeTicketMessage))
1532 return GNUNET_SYSERR;
1538 process_parallel_lookup2 (void *cls, uint32_t rd_count,
1539 const struct GNUNET_GNSRECORD_Data *rd)
1541 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1542 "Parallel lookup finished (count=%u)\n", rd_count);
1543 struct ParallelLookup *parallel_lookup = cls;
1544 struct ConsumeTicketHandle *handle = parallel_lookup->handle;
1545 struct ConsumeTicketResultMessage *crm;
1546 struct GNUNET_MQ_Envelope *env;
1547 struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *attr_le;
1548 struct GNUNET_TIME_Absolute decrypt_duration;
1554 GNUNET_CONTAINER_DLL_remove (handle->parallel_lookups_head,
1555 handle->parallel_lookups_tail,
1557 GNUNET_free (parallel_lookup->label);
1559 GNUNET_STATISTICS_update (stats,
1560 "attribute_lookup_time_total",
1561 GNUNET_TIME_absolute_get_duration (parallel_lookup->lookup_start_time).rel_value_us,
1563 GNUNET_STATISTICS_update (stats,
1564 "attribute_lookups_count",
1569 GNUNET_free (parallel_lookup);
1571 GNUNET_break(0);//TODO
1572 if (rd->record_type == GNUNET_GNSRECORD_TYPE_ID_ATTR)
1574 decrypt_duration = GNUNET_TIME_absolute_get ();
1575 attr_len = GNUNET_ABE_cpabe_decrypt (rd->data + sizeof (uint32_t),
1576 rd->data_size - sizeof (uint32_t),
1579 if (GNUNET_SYSERR != attr_len)
1581 GNUNET_STATISTICS_update (stats,
1582 "abe_decrypt_time_total",
1583 GNUNET_TIME_absolute_get_duration (decrypt_duration).rel_value_us,
1585 GNUNET_STATISTICS_update (stats,
1586 "abe_decrypt_count",
1590 attr_le = GNUNET_new (struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry);
1591 attr_le->claim = GNUNET_IDENTITY_ATTRIBUTE_deserialize (data,
1593 attr_le->claim->version = ntohl(*(uint32_t*)rd->data);
1594 GNUNET_CONTAINER_DLL_insert (handle->attrs->list_head,
1595 handle->attrs->list_tail,
1600 if (NULL != handle->parallel_lookups_head)
1601 return; //Wait for more
1602 /* Else we are done */
1604 /* Store ticket in DB */
1605 if (GNUNET_OK != TKT_database->store_ticket (TKT_database->cls,
1609 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1610 "Unable to store ticket after consume\n");
1614 GNUNET_SCHEDULER_cancel (handle->kill_task);
1615 attrs_len = GNUNET_IDENTITY_ATTRIBUTE_list_serialize_get_size (handle->attrs);
1616 env = GNUNET_MQ_msg_extra (crm,
1618 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_CONSUME_TICKET_RESULT);
1619 crm->id = htonl (handle->r_id);
1620 crm->attrs_len = htons (attrs_len);
1621 crm->identity = handle->ticket.identity;
1622 data_tmp = (char *) &crm[1];
1623 GNUNET_IDENTITY_ATTRIBUTE_list_serialize (handle->attrs,
1625 GNUNET_MQ_send (handle->client->mq, env);
1626 cleanup_consume_ticket_handle (handle);
1630 abort_parallel_lookups2 (void *cls)
1632 struct ConsumeTicketHandle *handle = cls;
1633 struct ParallelLookup *lu;
1634 struct ParallelLookup *tmp;
1635 struct AttributeResultMessage *arm;
1636 struct GNUNET_MQ_Envelope *env;
1638 for (lu = handle->parallel_lookups_head;
1640 GNUNET_GNS_lookup_cancel (lu->lookup_request);
1641 GNUNET_free (lu->label);
1643 GNUNET_CONTAINER_DLL_remove (handle->parallel_lookups_head,
1644 handle->parallel_lookups_tail,
1649 env = GNUNET_MQ_msg (arm,
1650 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_RESULT);
1651 arm->id = htonl (handle->r_id);
1652 arm->attr_len = htons (0);
1653 GNUNET_MQ_send (handle->client->mq, env);
1659 process_consume_abe_key (void *cls, uint32_t rd_count,
1660 const struct GNUNET_GNSRECORD_Data *rd)
1662 struct ConsumeTicketHandle *handle = cls;
1663 struct GNUNET_HashCode new_key_hash;
1664 struct GNUNET_CRYPTO_SymmetricSessionKey enc_key;
1665 struct GNUNET_CRYPTO_SymmetricInitializationVector enc_iv;
1666 struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_key;
1667 struct ParallelLookup *parallel_lookup;
1673 handle->lookup_request = NULL;
1676 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1677 "Number of keys %d != 1.",
1679 cleanup_consume_ticket_handle (handle);
1680 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1685 ecdh_key = (struct GNUNET_CRYPTO_EcdhePublicKey *)rd->data;
1687 buf = GNUNET_malloc (rd->data_size - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
1689 //Calculate symmetric key from ecdh parameters
1690 GNUNET_assert (GNUNET_OK ==
1691 GNUNET_CRYPTO_ecdsa_ecdh (&handle->identity,
1694 create_sym_key_from_ecdh (&new_key_hash,
1697 size = GNUNET_CRYPTO_symmetric_decrypt (rd->data + sizeof (struct GNUNET_CRYPTO_EcdhePublicKey),
1698 rd->data_size - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey),
1703 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1704 "Decrypted bytes: %zd Expected bytes: %zd\n",
1705 size, rd->data_size - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
1706 GNUNET_STATISTICS_update (stats,
1707 "abe_key_lookup_time_total",
1708 GNUNET_TIME_absolute_get_duration (handle->lookup_start_time).rel_value_us,
1710 GNUNET_STATISTICS_update (stats,
1711 "abe_key_lookups_count",
1714 scopes = GNUNET_strdup (buf);
1715 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1716 "Scopes %s\n", scopes);
1717 handle->key = GNUNET_ABE_cpabe_deserialize_key ((void*)(buf + strlen (scopes) + 1),
1718 rd->data_size - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)
1719 - strlen (scopes) - 1);
1721 for (scope = strtok (scopes, ","); NULL != scope; scope = strtok (NULL, ","))
1723 GNUNET_asprintf (&lookup_query,
1726 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1727 "Looking up %s\n", lookup_query);
1728 parallel_lookup = GNUNET_new (struct ParallelLookup);
1729 parallel_lookup->handle = handle;
1730 parallel_lookup->label = GNUNET_strdup (scope);
1731 parallel_lookup->lookup_start_time = GNUNET_TIME_absolute_get();
1732 parallel_lookup->lookup_request
1733 = GNUNET_GNS_lookup (gns_handle,
1735 &handle->ticket.identity,
1736 GNUNET_GNSRECORD_TYPE_ID_ATTR,
1737 GNUNET_GNS_LO_DEFAULT,
1738 &process_parallel_lookup2,
1740 GNUNET_CONTAINER_DLL_insert (handle->parallel_lookups_head,
1741 handle->parallel_lookups_tail,
1743 GNUNET_free (lookup_query);
1745 GNUNET_free (scopes);
1747 handle->kill_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES,3),
1748 &abort_parallel_lookups2,
1754 handle_consume_ticket_message (void *cls,
1755 const struct ConsumeTicketMessage *cm)
1757 struct ConsumeTicketHandle *ch;
1758 struct IdpClient *idp = cls;
1762 ch = GNUNET_new (struct ConsumeTicketHandle);
1763 ch->r_id = ntohl (cm->id);
1765 ch->identity = cm->identity;
1766 ch->attrs = GNUNET_new (struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList);
1767 GNUNET_CRYPTO_ecdsa_key_get_public (&ch->identity,
1769 ch->ticket = *((struct GNUNET_IDENTITY_PROVIDER_Ticket*)&cm[1]);
1770 rnd_label = GNUNET_STRINGS_data_to_string_alloc (&ch->ticket.rnd,
1772 GNUNET_asprintf (&lookup_query,
1775 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1776 "Looking for ABE key under %s\n", lookup_query);
1777 ch->lookup_start_time = GNUNET_TIME_absolute_get ();
1779 = GNUNET_GNS_lookup (gns_handle,
1781 &ch->ticket.identity,
1782 GNUNET_GNSRECORD_TYPE_ABE_KEY,
1783 GNUNET_GNS_LO_DEFAULT,
1784 &process_consume_abe_key,
1786 GNUNET_free (rnd_label);
1787 GNUNET_free (lookup_query);
1788 GNUNET_SERVICE_client_continue (idp->client);
1792 cleanup_as_handle (struct AttributeStoreHandle *handle)
1794 if (NULL != handle->claim)
1795 GNUNET_free (handle->claim);
1796 if (NULL != handle->abe_key)
1797 GNUNET_ABE_cpabe_delete_master_key (handle->abe_key);
1798 GNUNET_free (handle);
1802 attr_store_cont (void *cls,
1806 struct AttributeStoreHandle *as_handle = cls;
1807 struct GNUNET_MQ_Envelope *env;
1808 struct AttributeStoreResultMessage *acr_msg;
1810 if (GNUNET_SYSERR == success)
1812 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1813 "Failed to store attribute %s\n",
1815 cleanup_as_handle (as_handle);
1816 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1820 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1821 "Sending ATTRIBUTE_STORE_RESPONSE message\n");
1822 env = GNUNET_MQ_msg (acr_msg,
1823 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_STORE_RESPONSE);
1824 acr_msg->id = htonl (as_handle->r_id);
1825 acr_msg->op_result = htonl (GNUNET_OK);
1826 GNUNET_MQ_send (as_handle->client->mq,
1828 cleanup_as_handle (as_handle);
1832 attr_store_task (void *cls)
1834 struct AttributeStoreHandle *as_handle = cls;
1835 struct GNUNET_GNSRECORD_Data rd[1];
1844 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1845 "Storing attribute\n");
1846 buf_size = GNUNET_IDENTITY_ATTRIBUTE_serialize_get_size (as_handle->claim);
1847 buf = GNUNET_malloc (buf_size);
1849 GNUNET_IDENTITY_ATTRIBUTE_serialize (as_handle->claim,
1852 GNUNET_asprintf (&policy,
1854 as_handle->claim->name,
1855 as_handle->claim->version);
1856 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1857 "Encrypting with policy %s\n", policy);
1859 * Encrypt the attribute value and store in namestore
1861 enc_size = GNUNET_ABE_cpabe_encrypt (buf,
1866 if (GNUNET_SYSERR == enc_size)
1868 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1869 "Failed to encrypt with policy %s\n",
1871 cleanup_as_handle (as_handle);
1873 GNUNET_free (policy);
1874 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1878 GNUNET_free (policy);
1879 rd[0].data_size = enc_size + sizeof (uint32_t);
1880 rd_buf = GNUNET_malloc (rd[0].data_size);
1881 attr_ver = htonl (as_handle->claim->version);
1882 GNUNET_memcpy (rd_buf,
1885 GNUNET_memcpy (rd_buf+sizeof (uint32_t),
1888 rd[0].data = rd_buf;
1889 rd[0].record_type = GNUNET_GNSRECORD_TYPE_ID_ATTR;
1890 rd[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
1891 rd[0].expiration_time = GNUNET_TIME_UNIT_HOURS.rel_value_us; //TODO sane?
1892 as_handle->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
1893 &as_handle->identity,
1894 as_handle->claim->name,
1899 GNUNET_free (enc_buf);
1900 GNUNET_free (rd_buf);
1905 store_after_abe_bootstrap (void *cls,
1906 struct GNUNET_ABE_AbeMasterKey *abe_key)
1908 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1909 "Finished ABE bootstrap\n");
1910 struct AttributeStoreHandle *ash = cls;
1911 ash->abe_key = abe_key;
1912 GNUNET_SCHEDULER_add_now (&attr_store_task, ash);
1916 check_attribute_store_message(void *cls,
1917 const struct AttributeStoreMessage *sam)
1921 size = ntohs (sam->header.size);
1922 if (size <= sizeof (struct AttributeStoreMessage))
1925 return GNUNET_SYSERR;
1932 handle_attribute_store_message (void *cls,
1933 const struct AttributeStoreMessage *sam)
1935 struct AttributeStoreHandle *as_handle;
1936 struct IdpClient *idp = cls;
1938 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1939 "Received ATTRIBUTE_STORE message\n");
1941 data_len = ntohs (sam->attr_len);
1943 as_handle = GNUNET_new (struct AttributeStoreHandle);
1944 as_handle->claim = GNUNET_IDENTITY_ATTRIBUTE_deserialize ((char*)&sam[1],
1947 as_handle->r_id = ntohl (sam->id);
1948 as_handle->identity = sam->identity;
1949 GNUNET_CRYPTO_ecdsa_key_get_public (&sam->identity,
1950 &as_handle->identity_pkey);
1952 GNUNET_SERVICE_client_continue (idp->client);
1953 as_handle->client = idp;
1954 bootstrap_abe (&as_handle->identity, &store_after_abe_bootstrap, as_handle, GNUNET_NO);
1958 cleanup_iter_handle (struct AttributeIterator *ai)
1960 if (NULL != ai->abe_key)
1961 GNUNET_ABE_cpabe_delete_master_key (ai->abe_key);
1962 GNUNET_CONTAINER_DLL_remove (ai->client->op_head,
1963 ai->client->op_tail,
1969 attr_iter_error (void *cls)
1971 struct AttributeIterator *ai = cls;
1973 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1974 "Failed to iterate over attributes\n");
1975 cleanup_iter_handle (ai);
1976 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1980 attr_iter_finished (void *cls)
1982 struct AttributeIterator *ai = cls;
1983 struct GNUNET_MQ_Envelope *env;
1984 struct AttributeResultMessage *arm;
1986 env = GNUNET_MQ_msg (arm,
1987 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_RESULT);
1988 arm->id = htonl (ai->request_id);
1989 arm->attr_len = htons (0);
1990 GNUNET_MQ_send (ai->client->mq, env);
1991 cleanup_iter_handle (ai);
1995 attr_iter_cb (void *cls,
1996 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
1998 unsigned int rd_count,
1999 const struct GNUNET_GNSRECORD_Data *rd)
2001 struct AttributeIterator *ai = cls;
2002 struct AttributeResultMessage *arm;
2003 struct GNUNET_ABE_AbeKey *key;
2004 struct GNUNET_MQ_Envelope *env;
2005 ssize_t msg_extra_len;
2014 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it);
2018 if (GNUNET_GNSRECORD_TYPE_ID_ATTR != rd->record_type) {
2019 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it);
2022 attr_ver = ntohl(*((uint32_t*)rd->data));
2023 GNUNET_asprintf (&policy, "%s_%lu",
2027 key = GNUNET_ABE_cpabe_create_key (ai->abe_key,
2029 msg_extra_len = GNUNET_ABE_cpabe_decrypt (rd->data+sizeof (uint32_t),
2030 rd->data_size-sizeof (uint32_t),
2033 if (GNUNET_SYSERR == msg_extra_len) {
2034 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it);
2038 GNUNET_ABE_cpabe_delete_key (key,
2040 //GNUNET_free (policy);
2041 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2042 "Found attribute: %s\n", label);
2043 env = GNUNET_MQ_msg_extra (arm,
2045 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_RESULT);
2046 arm->id = htonl (ai->request_id);
2047 arm->attr_len = htons (msg_extra_len);
2048 GNUNET_CRYPTO_ecdsa_key_get_public (zone,
2050 data_tmp = (char *) &arm[1];
2051 GNUNET_memcpy (data_tmp,
2054 GNUNET_MQ_send (ai->client->mq, env);
2055 GNUNET_free (attr_ser);
2056 GNUNET_ABE_cpabe_delete_master_key (ai->abe_key);
2062 iterate_after_abe_bootstrap (void *cls,
2063 struct GNUNET_ABE_AbeMasterKey *abe_key)
2065 struct AttributeIterator *ai = cls;
2066 ai->abe_key = abe_key;
2067 ai->ns_it = GNUNET_NAMESTORE_zone_iteration_start (ns_handle,
2073 &attr_iter_finished,
2078 iterate_next_after_abe_bootstrap (void *cls,
2079 struct GNUNET_ABE_AbeMasterKey *abe_key)
2081 struct AttributeIterator *ai = cls;
2082 ai->abe_key = abe_key;
2083 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it);
2089 handle_iteration_start (void *cls,
2090 const struct AttributeIterationStartMessage *ais_msg)
2092 struct IdpClient *idp = cls;
2093 struct AttributeIterator *ai;
2095 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2096 "Received ATTRIBUTE_ITERATION_START message\n");
2097 ai = GNUNET_new (struct AttributeIterator);
2098 ai->request_id = ntohl (ais_msg->id);
2100 ai->identity = ais_msg->identity;
2102 GNUNET_CONTAINER_DLL_insert (idp->op_head,
2105 bootstrap_abe (&ai->identity, &iterate_after_abe_bootstrap, ai, GNUNET_NO);
2106 GNUNET_SERVICE_client_continue (idp->client);
2111 handle_iteration_stop (void *cls,
2112 const struct AttributeIterationStopMessage *ais_msg)
2114 struct IdpClient *idp = cls;
2115 struct AttributeIterator *ai;
2118 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2119 "Received `%s' message\n",
2120 "ATTRIBUTE_ITERATION_STOP");
2121 rid = ntohl (ais_msg->id);
2122 for (ai = idp->op_head; NULL != ai; ai = ai->next)
2123 if (ai->request_id == rid)
2128 GNUNET_SERVICE_client_drop (idp->client);
2131 GNUNET_CONTAINER_DLL_remove (idp->op_head,
2135 GNUNET_SERVICE_client_continue (idp->client);
2140 handle_iteration_next (void *cls,
2141 const struct AttributeIterationNextMessage *ais_msg)
2143 struct IdpClient *idp = cls;
2144 struct AttributeIterator *ai;
2147 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2148 "Received ATTRIBUTE_ITERATION_NEXT message\n");
2149 rid = ntohl (ais_msg->id);
2150 for (ai = idp->op_head; NULL != ai; ai = ai->next)
2151 if (ai->request_id == rid)
2156 GNUNET_SERVICE_client_drop (idp->client);
2159 bootstrap_abe (&ai->identity,
2160 &iterate_next_after_abe_bootstrap,
2163 GNUNET_SERVICE_client_continue (idp->client);
2167 * Ticket iteration processor result
2169 enum ZoneIterationResult
2178 * Continue to iterate with next iteration_next call
2180 IT_SUCCESS_MORE_AVAILABLE = 1,
2183 * Iteration complete
2185 IT_SUCCESS_NOT_MORE_RESULTS_AVAILABLE = 2
2190 * Context for ticket iteration
2192 struct TicketIterationProcResult
2195 * The ticket iteration handle
2197 struct TicketIteration *ti;
2200 * Iteration result: iteration done?
2201 * #IT_SUCCESS_MORE_AVAILABLE: if there may be more results overall but
2202 * we got one for now and have sent it to the client
2203 * #IT_SUCCESS_NOT_MORE_RESULTS_AVAILABLE: if there are no further results,
2204 * #IT_START: if we are still trying to find a result.
2206 int res_iteration_finished;
2211 cleanup_ticket_iter_handle (struct TicketIteration *ti)
2217 * Process ticket from database
2219 * @param cls struct TicketIterationProcResult
2220 * @param ticket the ticket
2221 * @param attrs the attributes
2224 ticket_iterate_proc (void *cls,
2225 const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket,
2226 const struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs)
2228 struct TicketIterationProcResult *proc = cls;
2232 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2233 "Iteration done\n");
2234 proc->res_iteration_finished = IT_SUCCESS_NOT_MORE_RESULTS_AVAILABLE;
2237 proc->res_iteration_finished = IT_SUCCESS_MORE_AVAILABLE;
2238 send_ticket_result (proc->ti->client,
2246 * Perform ticket iteration step
2248 * @param ti ticket iterator to process
2251 run_ticket_iteration_round (struct TicketIteration *ti)
2253 struct TicketIterationProcResult proc;
2254 struct GNUNET_MQ_Envelope *env;
2255 struct TicketResultMessage *trm;
2258 memset (&proc, 0, sizeof (proc));
2260 proc.res_iteration_finished = IT_START;
2261 while (IT_START == proc.res_iteration_finished)
2263 if (GNUNET_SYSERR ==
2264 (ret = TKT_database->iterate_tickets (TKT_database->cls,
2268 &ticket_iterate_proc,
2274 if (GNUNET_NO == ret)
2275 proc.res_iteration_finished = IT_SUCCESS_NOT_MORE_RESULTS_AVAILABLE;
2278 if (IT_SUCCESS_MORE_AVAILABLE == proc.res_iteration_finished)
2280 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2281 "More results available\n");
2282 return; /* more later */
2284 /* send empty response to indicate end of list */
2285 env = GNUNET_MQ_msg (trm,
2286 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_RESULT);
2287 trm->id = htonl (ti->r_id);
2288 GNUNET_MQ_send (ti->client->mq,
2290 GNUNET_CONTAINER_DLL_remove (ti->client->ticket_iter_head,
2291 ti->client->ticket_iter_tail,
2293 cleanup_ticket_iter_handle (ti);
2297 handle_ticket_iteration_start (void *cls,
2298 const struct TicketIterationStartMessage *tis_msg)
2300 struct IdpClient *client = cls;
2301 struct TicketIteration *ti;
2303 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2304 "Received TICKET_ITERATION_START message\n");
2305 ti = GNUNET_new (struct TicketIteration);
2306 ti->r_id = ntohl (tis_msg->id);
2308 ti->client = client;
2309 ti->identity = tis_msg->identity;
2310 ti->is_audience = ntohl (tis_msg->is_audience);
2312 GNUNET_CONTAINER_DLL_insert (client->ticket_iter_head,
2313 client->ticket_iter_tail,
2315 run_ticket_iteration_round (ti);
2316 GNUNET_SERVICE_client_continue (client->client);
2321 handle_ticket_iteration_stop (void *cls,
2322 const struct TicketIterationStopMessage *tis_msg)
2324 struct IdpClient *client = cls;
2325 struct TicketIteration *ti;
2328 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2329 "Received `%s' message\n",
2330 "TICKET_ITERATION_STOP");
2331 rid = ntohl (tis_msg->id);
2332 for (ti = client->ticket_iter_head; NULL != ti; ti = ti->next)
2333 if (ti->r_id == rid)
2338 GNUNET_SERVICE_client_drop (client->client);
2341 GNUNET_CONTAINER_DLL_remove (client->ticket_iter_head,
2342 client->ticket_iter_tail,
2344 cleanup_ticket_iter_handle (ti);
2345 GNUNET_SERVICE_client_continue (client->client);
2350 handle_ticket_iteration_next (void *cls,
2351 const struct TicketIterationNextMessage *tis_msg)
2353 struct IdpClient *client = cls;
2354 struct TicketIteration *ti;
2357 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2358 "Received TICKET_ITERATION_NEXT message\n");
2359 rid = ntohl (tis_msg->id);
2360 for (ti = client->ticket_iter_head; NULL != ti; ti = ti->next)
2361 if (ti->r_id == rid)
2366 GNUNET_SERVICE_client_drop (client->client);
2369 run_ticket_iteration_round (ti);
2370 GNUNET_SERVICE_client_continue (client->client);
2377 * Main function that will be run
2379 * @param cls closure
2380 * @param c the configuration used
2381 * @param server the service handle
2385 const struct GNUNET_CONFIGURATION_Handle *c,
2386 struct GNUNET_SERVICE_Handle *server)
2391 stats = GNUNET_STATISTICS_create ("identity-provider", cfg);
2393 //Connect to identity and namestore services
2394 ns_handle = GNUNET_NAMESTORE_connect (cfg);
2395 if (NULL == ns_handle)
2397 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "error connecting to namestore");
2400 gns_handle = GNUNET_GNS_connect (cfg);
2401 if (NULL == gns_handle)
2403 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "error connecting to gns");
2405 credential_handle = GNUNET_CREDENTIAL_connect (cfg);
2406 if (NULL == credential_handle)
2408 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "error connecting to credential");
2410 identity_handle = GNUNET_IDENTITY_connect (cfg,
2413 /* Loading DB plugin */
2415 GNUNET_CONFIGURATION_get_value_string (cfg,
2416 "identity-provider",
2419 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2420 "No database backend configured\n");
2421 GNUNET_asprintf (&db_lib_name,
2422 "libgnunet_plugin_identity_provider_%s",
2424 TKT_database = GNUNET_PLUGIN_load (db_lib_name,
2426 GNUNET_free (database);
2427 if (NULL == TKT_database)
2429 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2430 "Could not load database backend `%s'\n",
2432 GNUNET_SCHEDULER_shutdown ();
2437 GNUNET_CONFIGURATION_get_value_time (cfg,
2438 "identity-provider",
2439 "TOKEN_EXPIRATION_INTERVAL",
2440 &token_expiration_interval))
2442 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2443 "Time window for zone iteration: %s\n",
2444 GNUNET_STRINGS_relative_time_to_string (token_expiration_interval,
2447 token_expiration_interval = DEFAULT_TOKEN_EXPIRATION_INTERVAL;
2450 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL);
2454 * Called whenever a client is disconnected.
2456 * @param cls closure
2457 * @param client identification of the client
2458 * @param app_ctx @a client
2461 client_disconnect_cb (void *cls,
2462 struct GNUNET_SERVICE_Client *client,
2465 struct IdpClient *idp = app_ctx;
2466 struct AttributeIterator *ai;
2467 struct TicketIteration *ti;
2468 struct TicketRevocationHandle *rh;
2470 //TODO other operations
2472 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2473 "Client %p disconnected\n",
2476 while (NULL != (ai = idp->op_head))
2478 GNUNET_CONTAINER_DLL_remove (idp->op_head,
2483 while (NULL != (rh = idp->revocation_list_head))
2485 GNUNET_CONTAINER_DLL_remove (idp->revocation_list_head,
2486 idp->revocation_list_tail,
2488 cleanup_revoke_ticket_handle (rh);
2490 while (NULL != (ti = idp->ticket_iter_head))
2492 GNUNET_CONTAINER_DLL_remove (idp->ticket_iter_head,
2493 idp->ticket_iter_tail,
2495 cleanup_ticket_iter_handle (ti);
2502 * Add a client to our list of active clients.
2505 * @param client client to add
2506 * @param mq message queue for @a client
2507 * @return internal namestore client structure for this client
2510 client_connect_cb (void *cls,
2511 struct GNUNET_SERVICE_Client *client,
2512 struct GNUNET_MQ_Handle *mq)
2514 struct IdpClient *idp;
2515 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2516 "Client %p connected\n",
2518 idp = GNUNET_new (struct IdpClient);
2519 idp->client = client;
2527 * Define "main" method using service macro.
2530 ("identity-provider",
2531 GNUNET_SERVICE_OPTION_NONE,
2534 &client_disconnect_cb,
2536 GNUNET_MQ_hd_var_size (attribute_store_message,
2537 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_STORE,
2538 struct AttributeStoreMessage,
2540 GNUNET_MQ_hd_fixed_size (iteration_start,
2541 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_START,
2542 struct AttributeIterationStartMessage,
2544 GNUNET_MQ_hd_fixed_size (iteration_next,
2545 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_NEXT,
2546 struct AttributeIterationNextMessage,
2548 GNUNET_MQ_hd_fixed_size (iteration_stop,
2549 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_STOP,
2550 struct AttributeIterationStopMessage,
2552 GNUNET_MQ_hd_var_size (issue_ticket_message,
2553 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ISSUE_TICKET,
2554 struct IssueTicketMessage,
2556 GNUNET_MQ_hd_var_size (consume_ticket_message,
2557 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_CONSUME_TICKET,
2558 struct ConsumeTicketMessage,
2560 GNUNET_MQ_hd_fixed_size (ticket_iteration_start,
2561 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_START,
2562 struct TicketIterationStartMessage,
2564 GNUNET_MQ_hd_fixed_size (ticket_iteration_next,
2565 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_NEXT,
2566 struct TicketIterationNextMessage,
2568 GNUNET_MQ_hd_fixed_size (ticket_iteration_stop,
2569 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_STOP,
2570 struct TicketIterationStopMessage,
2572 GNUNET_MQ_hd_var_size (revoke_ticket_message,
2573 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_REVOKE_TICKET,
2574 struct RevokeTicketMessage,
2576 GNUNET_MQ_handler_end());
2577 /* end of gnunet-service-identity-provider.c */