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;
708 abh->proc (abh->proc_cls, NULL);
714 * Handle ABE lookup in namestore
717 bootstrap_abe_result (void *cls,
718 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
720 unsigned int rd_count,
721 const struct GNUNET_GNSRECORD_Data *rd)
723 struct AbeBootstrapHandle *abh = cls;
724 struct GNUNET_ABE_AbeMasterKey *abe_key;
726 for (uint32_t i=0;i<rd_count;i++) {
727 if (GNUNET_GNSRECORD_TYPE_ABE_MASTER != rd[i].record_type)
729 abe_key = GNUNET_ABE_cpabe_deserialize_master_key (rd[i].data,
731 abh->proc (abh->proc_cls, abe_key);
736 //No ABE master found, bootstrapping...
737 abh->abe_key = GNUNET_ABE_cpabe_create_master_key ();
738 GNUNET_SCHEDULER_add_now (&bootstrap_store_task, abh);
742 * Bootstrap ABE master if it does not yet exists.
743 * Will call the AbeBootstrapResult processor when done.
744 * will always recreate the ABE key of GNUNET_YES == recreate
747 bootstrap_abe (const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
748 AbeBootstrapResult proc,
752 struct AbeBootstrapHandle *abh;
754 abh = GNUNET_new (struct AbeBootstrapHandle);
757 abh->identity = *identity;
758 if (GNUNET_YES == recreate)
760 abh->abe_key = GNUNET_ABE_cpabe_create_master_key ();
761 GNUNET_SCHEDULER_add_now (&bootstrap_store_task, abh);
763 abh->ns_qe = GNUNET_NAMESTORE_records_lookup (ns_handle,
766 &bootstrap_abe_error,
768 &bootstrap_abe_result,
776 create_sym_key_from_ecdh(const struct GNUNET_HashCode *new_key_hash,
777 struct GNUNET_CRYPTO_SymmetricSessionKey *skey,
778 struct GNUNET_CRYPTO_SymmetricInitializationVector *iv)
780 struct GNUNET_CRYPTO_HashAsciiEncoded new_key_hash_str;
782 GNUNET_CRYPTO_hash_to_enc (new_key_hash,
784 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating symmetric rsa key from %s\n", (char*)&new_key_hash_str);
785 static const char ctx_key[] = "gnuid-aes-ctx-key";
786 GNUNET_CRYPTO_kdf (skey, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
787 new_key_hash, sizeof (struct GNUNET_HashCode),
788 ctx_key, strlen (ctx_key),
790 static const char ctx_iv[] = "gnuid-aes-ctx-iv";
791 GNUNET_CRYPTO_kdf (iv, sizeof (struct GNUNET_CRYPTO_SymmetricInitializationVector),
792 new_key_hash, sizeof (struct GNUNET_HashCode),
793 ctx_iv, strlen (ctx_iv),
799 cleanup_ticket_issue_handle (struct TicketIssueHandle *handle)
801 if (NULL != handle->attrs)
802 GNUNET_IDENTITY_ATTRIBUTE_list_destroy (handle->attrs);
803 if (NULL != handle->ns_qe)
804 GNUNET_NAMESTORE_cancel (handle->ns_qe);
805 GNUNET_free (handle);
810 send_ticket_result (struct IdpClient *client,
812 const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket,
813 const struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs)
815 struct TicketResultMessage *irm;
816 struct GNUNET_MQ_Envelope *env;
817 struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket_buf;
819 /* store ticket in DB */
820 if (GNUNET_OK != TKT_database->store_ticket (TKT_database->cls,
824 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
825 "Unable to store ticket after issue\n");
829 env = GNUNET_MQ_msg_extra (irm,
830 sizeof (struct GNUNET_IDENTITY_PROVIDER_Ticket),
831 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_RESULT);
832 ticket_buf = (struct GNUNET_IDENTITY_PROVIDER_Ticket *)&irm[1];
833 *ticket_buf = *ticket;
834 irm->id = htonl (r_id);
835 GNUNET_MQ_send (client->mq,
840 store_ticket_issue_cont (void *cls,
844 struct TicketIssueHandle *handle = cls;
846 handle->ns_qe = NULL;
847 if (GNUNET_SYSERR == success)
849 cleanup_ticket_issue_handle (handle);
850 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n",
852 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
855 send_ticket_result (handle->client,
859 cleanup_ticket_issue_handle (handle);
865 serialize_abe_keyinfo2 (const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket,
866 const struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs,
867 const struct GNUNET_ABE_AbeKey *rp_key,
868 struct GNUNET_CRYPTO_EcdhePrivateKey **ecdh_privkey,
871 struct GNUNET_CRYPTO_EcdhePublicKey ecdh_pubkey;
872 struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *le;
874 char *serialized_key;
880 struct GNUNET_CRYPTO_SymmetricSessionKey skey;
881 struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
882 struct GNUNET_HashCode new_key_hash;
885 size = GNUNET_ABE_cpabe_serialize_key (rp_key,
886 (void**)&serialized_key);
888 for (le = attrs->list_head; NULL != le; le = le->next) {
889 attrs_str_len += strlen (le->claim->name) + 1;
891 buf = GNUNET_malloc (attrs_str_len + size);
893 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
894 "Writing attributes\n");
895 for (le = attrs->list_head; NULL != le; le = le->next) {
896 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
897 "%s\n", le->claim->name);
900 GNUNET_memcpy (write_ptr,
902 strlen (le->claim->name));
903 write_ptr[strlen (le->claim->name)] = ',';
904 write_ptr += strlen (le->claim->name) + 1;
907 write_ptr[0] = '\0'; //replace last , with a 0-terminator
909 GNUNET_memcpy (write_ptr,
912 GNUNET_free (serialized_key);
913 // ECDH keypair E = eG
914 *ecdh_privkey = GNUNET_CRYPTO_ecdhe_key_create();
915 GNUNET_CRYPTO_ecdhe_key_get_public (*ecdh_privkey,
917 enc_keyinfo = GNUNET_malloc (size + attrs_str_len);
918 // Derived key K = H(eB)
919 GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecdh_ecdsa (*ecdh_privkey,
922 create_sym_key_from_ecdh(&new_key_hash, &skey, &iv);
923 enc_size = GNUNET_CRYPTO_symmetric_encrypt (buf,
924 size + attrs_str_len,
927 *result = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)+
929 GNUNET_memcpy (*result,
931 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
932 GNUNET_memcpy (*result + sizeof (struct GNUNET_CRYPTO_EcdhePublicKey),
935 GNUNET_free (enc_keyinfo);
937 return sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)+enc_size;
943 issue_ticket_after_abe_bootstrap (void *cls,
944 struct GNUNET_ABE_AbeMasterKey *abe_key)
946 struct TicketIssueHandle *ih = cls;
947 struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *le;
948 struct GNUNET_CRYPTO_EcdhePrivateKey *ecdhe_privkey;
949 struct GNUNET_GNSRECORD_Data code_record[1];
950 struct GNUNET_ABE_AbeKey *rp_key;
951 char *code_record_data;
957 size_t code_record_len;
959 //Create new ABE key for RP
961 for (le = ih->attrs->list_head; NULL != le; le = le->next)
963 attrs = GNUNET_malloc ((attrs_len + 1)*sizeof (char*));
965 for (le = ih->attrs->list_head; NULL != le; le = le->next) {
966 GNUNET_asprintf (&policy, "%s_%lu",
969 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
970 "Adding attribute to key: %s\n",
976 rp_key = GNUNET_ABE_cpabe_create_key (abe_key,
979 //TODO review this wireformat
980 code_record_len = serialize_abe_keyinfo2 (&ih->ticket,
985 code_record[0].data = code_record_data;
986 code_record[0].data_size = code_record_len;
987 code_record[0].expiration_time = GNUNET_TIME_UNIT_DAYS.rel_value_us;
988 code_record[0].record_type = GNUNET_GNSRECORD_TYPE_ABE_KEY;
989 code_record[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
991 label = GNUNET_STRINGS_data_to_string_alloc (&ih->ticket.rnd,
994 ih->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
999 &store_ticket_issue_cont,
1001 //for (; i > 0; i--)
1002 // GNUNET_free (attrs[i-1]);
1003 GNUNET_free (ecdhe_privkey);
1004 GNUNET_free (label);
1005 GNUNET_free (attrs);
1006 GNUNET_free (code_record_data);
1007 GNUNET_ABE_cpabe_delete_key (rp_key,
1009 GNUNET_ABE_cpabe_delete_master_key (abe_key);
1014 check_issue_ticket_message(void *cls,
1015 const struct IssueTicketMessage *im)
1019 size = ntohs (im->header.size);
1020 if (size <= sizeof (struct IssueTicketMessage))
1023 return GNUNET_SYSERR;
1030 handle_issue_ticket_message (void *cls,
1031 const struct IssueTicketMessage *im)
1033 struct TicketIssueHandle *ih;
1034 struct IdpClient *idp = cls;
1037 ih = GNUNET_new (struct TicketIssueHandle);
1038 attrs_len = ntohs (im->attr_len);
1039 ih->attrs = GNUNET_IDENTITY_ATTRIBUTE_list_deserialize ((char*)&im[1], attrs_len);
1040 ih->r_id = ntohl (im->id);
1042 ih->identity = im->identity;
1043 GNUNET_CRYPTO_ecdsa_key_get_public (&ih->identity,
1044 &ih->ticket.identity);
1045 ih->ticket.audience = im->rp;
1047 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG,
1049 bootstrap_abe (&ih->identity, &issue_ticket_after_abe_bootstrap, ih, GNUNET_NO);
1050 GNUNET_SERVICE_client_continue (idp->client);
1054 /**********************************************************
1056 **********************************************************/
1059 * Cleanup revoke handle
1061 * @param rh the ticket revocation handle
1064 cleanup_revoke_ticket_handle (struct TicketRevocationHandle *rh)
1066 if (NULL != rh->attrs)
1067 GNUNET_IDENTITY_ATTRIBUTE_list_destroy (rh->attrs);
1068 if (NULL != rh->rvk_attrs)
1069 GNUNET_IDENTITY_ATTRIBUTE_list_destroy (rh->rvk_attrs);
1070 if (NULL != rh->abe_key)
1071 GNUNET_ABE_cpabe_delete_master_key (rh->abe_key);
1072 if (NULL != rh->ns_qe)
1073 GNUNET_NAMESTORE_cancel (rh->ns_qe);
1074 if (NULL != rh->ns_it)
1075 GNUNET_NAMESTORE_zone_iteration_stop (rh->ns_it);
1081 * Send revocation result
1083 * @param rh ticket revocation handle
1084 * @param success GNUNET_OK if successful result
1087 send_revocation_finished (struct TicketRevocationHandle *rh,
1090 struct GNUNET_MQ_Envelope *env;
1091 struct RevokeTicketResultMessage *trm;
1093 env = GNUNET_MQ_msg (trm,
1094 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_REVOKE_TICKET_RESULT);
1095 trm->id = htonl (rh->r_id);
1096 trm->success = htonl (success);
1097 GNUNET_MQ_send (rh->client->mq,
1099 GNUNET_CONTAINER_DLL_remove (rh->client->revocation_list_head,
1100 rh->client->revocation_list_tail,
1106 * Process ticket from database
1108 * @param cls struct TicketIterationProcResult
1109 * @param ticket the ticket
1110 * @param attrs the attributes
1113 ticket_reissue_proc (void *cls,
1114 const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket,
1115 const struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs);
1118 revocation_reissue_tickets (struct TicketRevocationHandle *rh);
1121 static void reissue_next (void *cls)
1123 struct TicketRevocationHandle *rh = cls;
1124 revocation_reissue_tickets (rh);
1129 reissue_ticket_cont (void *cls,
1133 struct TicketRevocationHandle *rh = cls;
1136 if (GNUNET_SYSERR == success)
1138 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n",
1140 send_revocation_finished (rh, GNUNET_SYSERR);
1141 cleanup_revoke_ticket_handle (rh);
1145 GNUNET_SCHEDULER_add_now (&reissue_next, rh);
1150 * Process ticket from database
1152 * @param cls struct TicketIterationProcResult
1153 * @param ticket the ticket
1154 * @param attrs the attributes
1157 ticket_reissue_proc (void *cls,
1158 const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket,
1159 const struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs)
1161 struct TicketRevocationHandle *rh = cls;
1162 struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *le;
1163 struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *le_rollover;
1164 struct GNUNET_CRYPTO_EcdhePrivateKey *ecdhe_privkey;
1165 struct GNUNET_GNSRECORD_Data code_record[1];
1166 struct GNUNET_ABE_AbeKey *rp_key;
1167 char *code_record_data;
1174 size_t code_record_len;
1179 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1180 "Iteration done\n");
1184 if (0 == memcmp (&ticket->audience,
1185 &rh->ticket.audience,
1186 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)))
1188 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1189 "Do not reissue for this identity.!\n");
1192 GNUNET_SCHEDULER_add_now (&reissue_next, rh);
1197 * Check if any attribute of this ticket intersects with a rollover attribute
1199 reissue_ticket = GNUNET_NO;
1200 for (le = attrs->list_head; NULL != le; le = le->next)
1202 for (le_rollover = rh->rvk_attrs->list_head;
1203 NULL != le_rollover;
1204 le_rollover = le_rollover->next)
1206 if (0 == strcmp (le_rollover->claim->name,
1209 reissue_ticket = GNUNET_YES;
1210 le->claim->version = le_rollover->claim->version;
1215 if (GNUNET_NO == reissue_ticket)
1217 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1218 "Skipping ticket.\n");
1221 GNUNET_SCHEDULER_add_now (&reissue_next, rh);
1227 //Create new ABE key for RP
1230 /* If this is the RP we want to revoke attributes of, the do so */
1232 for (le = attrs->list_head; NULL != le; le = le->next)
1234 attr_arr = GNUNET_malloc ((attrs_len + 1)*sizeof (char*));
1236 for (le = attrs->list_head; NULL != le; le = le->next) {
1237 GNUNET_asprintf (&policy, "%s_%lu",
1239 le->claim->version);
1240 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1241 "Recreating key with %s\n", policy);
1242 attr_arr[i] = policy;
1246 rp_key = GNUNET_ABE_cpabe_create_key (rh->abe_key,
1249 //TODO review this wireformat
1250 code_record_len = serialize_abe_keyinfo2 (ticket,
1255 code_record[0].data = code_record_data;
1256 code_record[0].data_size = code_record_len;
1257 code_record[0].expiration_time = GNUNET_TIME_UNIT_DAYS.rel_value_us;
1258 code_record[0].record_type = GNUNET_GNSRECORD_TYPE_ABE_KEY;
1259 code_record[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
1261 label = GNUNET_STRINGS_data_to_string_alloc (&ticket->rnd,
1264 rh->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
1269 &reissue_ticket_cont,
1271 //for (; i > 0; i--)
1272 // GNUNET_free (attr_arr[i-1]);
1273 GNUNET_free (ecdhe_privkey);
1274 GNUNET_free (label);
1275 GNUNET_free (attr_arr);
1276 GNUNET_free (code_record_data);
1277 GNUNET_ABE_cpabe_delete_key (rp_key, GNUNET_YES);
1281 /* Prototype for below function */
1283 attr_reenc_cont (void *cls,
1288 revocation_reissue_tickets (struct TicketRevocationHandle *rh)
1291 /* Done, issue new keys */
1292 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1293 "Revocation Phase III: Reissuing Tickets\n");
1294 if (GNUNET_SYSERR == (ret = TKT_database->iterate_tickets (TKT_database->cls,
1295 &rh->ticket.identity,
1298 &ticket_reissue_proc,
1303 if (GNUNET_NO == ret)
1305 send_revocation_finished (rh, GNUNET_OK);
1306 cleanup_revoke_ticket_handle (rh);
1312 * Revoke next attribte by reencryption with
1316 reenc_next_attribute (struct TicketRevocationHandle *rh)
1318 struct GNUNET_GNSRECORD_Data rd[1];
1327 if (NULL == rh->attrs->list_head)
1329 revocation_reissue_tickets (rh);
1332 buf_size = GNUNET_IDENTITY_ATTRIBUTE_serialize_get_size (rh->attrs->list_head->claim);
1333 buf = GNUNET_malloc (buf_size);
1334 GNUNET_IDENTITY_ATTRIBUTE_serialize (rh->attrs->list_head->claim,
1336 rh->attrs->list_head->claim->version++;
1337 GNUNET_asprintf (&policy, "%s_%lu",
1338 rh->attrs->list_head->claim->name,
1339 rh->attrs->list_head->claim->version);
1340 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1341 "Encrypting with policy %s\n", policy);
1343 * Encrypt the attribute value and store in namestore
1345 enc_size = GNUNET_ABE_cpabe_encrypt (buf,
1351 GNUNET_free (policy);
1352 rd[0].data_size = enc_size + sizeof (uint32_t);
1353 rd_buf = GNUNET_malloc (rd[0].data_size);
1354 attr_ver = htonl (rh->attrs->list_head->claim->version);
1355 GNUNET_memcpy (rd_buf,
1358 GNUNET_memcpy (rd_buf+sizeof (uint32_t),
1361 rd[0].data = rd_buf;
1362 rd[0].record_type = GNUNET_GNSRECORD_TYPE_ID_ATTR;
1363 rd[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
1364 rd[0].expiration_time = GNUNET_TIME_UNIT_HOURS.rel_value_us; //TODO sane?
1365 rh->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
1367 rh->attrs->list_head->claim->name,
1372 GNUNET_free (enc_buf);
1373 GNUNET_free (rd_buf);
1377 * Namestore callback after revoked attribute
1381 attr_reenc_cont (void *cls,
1385 struct TicketRevocationHandle *rh = cls;
1386 struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *le;
1388 if (GNUNET_SYSERR == success)
1390 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1391 "Failed to reencrypt attribute %s\n",
1393 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1396 if (NULL == rh->attrs->list_head)
1398 revocation_reissue_tickets (rh);
1401 le = rh->attrs->list_head;
1402 GNUNET_CONTAINER_DLL_remove (rh->attrs->list_head,
1403 rh->attrs->list_tail,
1405 GNUNET_assert (NULL != rh->rvk_attrs);
1406 GNUNET_CONTAINER_DLL_insert (rh->rvk_attrs->list_head,
1407 rh->rvk_attrs->list_tail,
1411 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1412 "Re-encrypting next attribute\n");
1413 reenc_next_attribute (rh);
1418 process_attributes_to_update (void *cls,
1419 const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket,
1420 const struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs)
1422 struct TicketRevocationHandle *rh = cls;
1424 rh->attrs = GNUNET_IDENTITY_ATTRIBUTE_list_dup (attrs);
1425 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1426 "Revocation Phase I: Collecting attributes\n");
1427 /* Reencrypt all attributes with new key */
1428 if (NULL == rh->attrs->list_head)
1430 /* No attributes to reencrypt */
1431 send_revocation_finished (rh, GNUNET_OK);
1432 cleanup_revoke_ticket_handle (rh);
1435 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1436 "Revocation Phase II: Re-encrypting attributes\n");
1437 reenc_next_attribute (rh);
1445 get_ticket_after_abe_bootstrap (void *cls,
1446 struct GNUNET_ABE_AbeMasterKey *abe_key)
1448 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1449 "Finished ABE bootstrap\n");
1450 struct TicketRevocationHandle *rh = cls;
1451 rh->abe_key = abe_key;
1452 TKT_database->get_ticket_attributes (TKT_database->cls,
1454 &process_attributes_to_update,
1459 check_revoke_ticket_message(void *cls,
1460 const struct RevokeTicketMessage *im)
1464 size = ntohs (im->header.size);
1465 if (size <= sizeof (struct RevokeTicketMessage))
1468 return GNUNET_SYSERR;
1474 handle_revoke_ticket_message (void *cls,
1475 const struct RevokeTicketMessage *rm)
1477 struct TicketRevocationHandle *rh;
1478 struct IdpClient *idp = cls;
1479 struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket;
1481 rh = GNUNET_new (struct TicketRevocationHandle);
1482 ticket = (struct GNUNET_IDENTITY_PROVIDER_Ticket*)&rm[1];
1483 rh->rvk_attrs = GNUNET_new (struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList);
1484 rh->ticket = *ticket;
1485 rh->r_id = ntohl (rm->id);
1487 rh->identity = rm->identity;
1488 GNUNET_CRYPTO_ecdsa_key_get_public (&rh->identity,
1489 &rh->ticket.identity);
1490 GNUNET_CONTAINER_DLL_insert (idp->revocation_list_head,
1491 idp->revocation_list_tail,
1493 bootstrap_abe (&rh->identity, &get_ticket_after_abe_bootstrap, rh, GNUNET_NO);
1494 GNUNET_SERVICE_client_continue (idp->client);
1500 cleanup_consume_ticket_handle (struct ConsumeTicketHandle *handle)
1502 if (NULL != handle->key)
1503 GNUNET_ABE_cpabe_delete_key (handle->key,
1505 if (NULL != handle->attrs)
1506 GNUNET_IDENTITY_ATTRIBUTE_list_destroy (handle->attrs);
1507 GNUNET_free (handle);
1513 check_consume_ticket_message(void *cls,
1514 const struct ConsumeTicketMessage *cm)
1518 size = ntohs (cm->header.size);
1519 if (size <= sizeof (struct ConsumeTicketMessage))
1522 return GNUNET_SYSERR;
1528 process_parallel_lookup2 (void *cls, uint32_t rd_count,
1529 const struct GNUNET_GNSRECORD_Data *rd)
1531 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1532 "Parallel lookup finished (count=%u)\n", rd_count);
1533 struct ParallelLookup *parallel_lookup = cls;
1534 struct ConsumeTicketHandle *handle = parallel_lookup->handle;
1535 struct ConsumeTicketResultMessage *crm;
1536 struct GNUNET_MQ_Envelope *env;
1537 struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *attr_le;
1538 struct GNUNET_TIME_Absolute decrypt_duration;
1544 GNUNET_CONTAINER_DLL_remove (handle->parallel_lookups_head,
1545 handle->parallel_lookups_tail,
1547 GNUNET_free (parallel_lookup->label);
1549 GNUNET_STATISTICS_update (stats,
1550 "attribute_lookup_time_total",
1551 GNUNET_TIME_absolute_get_duration (parallel_lookup->lookup_start_time).rel_value_us,
1553 GNUNET_STATISTICS_update (stats,
1554 "attribute_lookups_count",
1559 GNUNET_free (parallel_lookup);
1561 GNUNET_break(0);//TODO
1562 if (rd->record_type == GNUNET_GNSRECORD_TYPE_ID_ATTR)
1564 decrypt_duration = GNUNET_TIME_absolute_get ();
1565 attr_len = GNUNET_ABE_cpabe_decrypt (rd->data + sizeof (uint32_t),
1566 rd->data_size - sizeof (uint32_t),
1569 if (GNUNET_SYSERR != attr_len)
1571 GNUNET_STATISTICS_update (stats,
1572 "abe_decrypt_time_total",
1573 GNUNET_TIME_absolute_get_duration (decrypt_duration).rel_value_us,
1575 GNUNET_STATISTICS_update (stats,
1576 "abe_decrypt_count",
1580 attr_le = GNUNET_new (struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry);
1581 attr_le->claim = GNUNET_IDENTITY_ATTRIBUTE_deserialize (data,
1583 attr_le->claim->version = ntohl(*(uint32_t*)rd->data);
1584 GNUNET_CONTAINER_DLL_insert (handle->attrs->list_head,
1585 handle->attrs->list_tail,
1590 if (NULL != handle->parallel_lookups_head)
1591 return; //Wait for more
1592 /* Else we are done */
1594 /* Store ticket in DB */
1595 if (GNUNET_OK != TKT_database->store_ticket (TKT_database->cls,
1599 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1600 "Unable to store ticket after consume\n");
1604 GNUNET_SCHEDULER_cancel (handle->kill_task);
1605 attrs_len = GNUNET_IDENTITY_ATTRIBUTE_list_serialize_get_size (handle->attrs);
1606 env = GNUNET_MQ_msg_extra (crm,
1608 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_CONSUME_TICKET_RESULT);
1609 crm->id = htonl (handle->r_id);
1610 crm->attrs_len = htons (attrs_len);
1611 crm->identity = handle->ticket.identity;
1612 data_tmp = (char *) &crm[1];
1613 GNUNET_IDENTITY_ATTRIBUTE_list_serialize (handle->attrs,
1615 GNUNET_MQ_send (handle->client->mq, env);
1616 cleanup_consume_ticket_handle (handle);
1620 abort_parallel_lookups2 (void *cls)
1622 struct ConsumeTicketHandle *handle = cls;
1623 struct ParallelLookup *lu;
1624 struct ParallelLookup *tmp;
1625 struct AttributeResultMessage *arm;
1626 struct GNUNET_MQ_Envelope *env;
1628 for (lu = handle->parallel_lookups_head;
1630 GNUNET_GNS_lookup_cancel (lu->lookup_request);
1631 GNUNET_free (lu->label);
1633 GNUNET_CONTAINER_DLL_remove (handle->parallel_lookups_head,
1634 handle->parallel_lookups_tail,
1639 env = GNUNET_MQ_msg (arm,
1640 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_RESULT);
1641 arm->id = htonl (handle->r_id);
1642 arm->attr_len = htons (0);
1643 GNUNET_MQ_send (handle->client->mq, env);
1649 process_consume_abe_key (void *cls, uint32_t rd_count,
1650 const struct GNUNET_GNSRECORD_Data *rd)
1652 struct ConsumeTicketHandle *handle = cls;
1653 struct GNUNET_HashCode new_key_hash;
1654 struct GNUNET_CRYPTO_SymmetricSessionKey enc_key;
1655 struct GNUNET_CRYPTO_SymmetricInitializationVector enc_iv;
1656 struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_key;
1657 struct ParallelLookup *parallel_lookup;
1663 handle->lookup_request = NULL;
1666 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1667 "Number of keys %d != 1.",
1669 cleanup_consume_ticket_handle (handle);
1670 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1675 ecdh_key = (struct GNUNET_CRYPTO_EcdhePublicKey *)rd->data;
1677 buf = GNUNET_malloc (rd->data_size - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
1679 //Calculate symmetric key from ecdh parameters
1680 GNUNET_assert (GNUNET_OK ==
1681 GNUNET_CRYPTO_ecdsa_ecdh (&handle->identity,
1684 create_sym_key_from_ecdh (&new_key_hash,
1687 size = GNUNET_CRYPTO_symmetric_decrypt (rd->data + sizeof (struct GNUNET_CRYPTO_EcdhePublicKey),
1688 rd->data_size - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey),
1693 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1694 "Decrypted bytes: %zd Expected bytes: %zd\n",
1695 size, rd->data_size - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
1696 GNUNET_STATISTICS_update (stats,
1697 "abe_key_lookup_time_total",
1698 GNUNET_TIME_absolute_get_duration (handle->lookup_start_time).rel_value_us,
1700 GNUNET_STATISTICS_update (stats,
1701 "abe_key_lookups_count",
1704 scopes = GNUNET_strdup (buf);
1705 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1706 "Scopes %s\n", scopes);
1707 handle->key = GNUNET_ABE_cpabe_deserialize_key ((void*)(buf + strlen (scopes) + 1),
1708 rd->data_size - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)
1709 - strlen (scopes) - 1);
1711 for (scope = strtok (scopes, ","); NULL != scope; scope = strtok (NULL, ","))
1713 GNUNET_asprintf (&lookup_query,
1716 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1717 "Looking up %s\n", lookup_query);
1718 parallel_lookup = GNUNET_new (struct ParallelLookup);
1719 parallel_lookup->handle = handle;
1720 parallel_lookup->label = GNUNET_strdup (scope);
1721 parallel_lookup->lookup_start_time = GNUNET_TIME_absolute_get();
1722 parallel_lookup->lookup_request
1723 = GNUNET_GNS_lookup (gns_handle,
1725 &handle->ticket.identity,
1726 GNUNET_GNSRECORD_TYPE_ID_ATTR,
1727 GNUNET_GNS_LO_DEFAULT,
1728 &process_parallel_lookup2,
1730 GNUNET_CONTAINER_DLL_insert (handle->parallel_lookups_head,
1731 handle->parallel_lookups_tail,
1733 GNUNET_free (lookup_query);
1735 GNUNET_free (scopes);
1737 handle->kill_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES,3),
1738 &abort_parallel_lookups2,
1744 handle_consume_ticket_message (void *cls,
1745 const struct ConsumeTicketMessage *cm)
1747 struct ConsumeTicketHandle *ch;
1748 struct IdpClient *idp = cls;
1752 ch = GNUNET_new (struct ConsumeTicketHandle);
1753 ch->r_id = ntohl (cm->id);
1755 ch->identity = cm->identity;
1756 ch->attrs = GNUNET_new (struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList);
1757 GNUNET_CRYPTO_ecdsa_key_get_public (&ch->identity,
1759 ch->ticket = *((struct GNUNET_IDENTITY_PROVIDER_Ticket*)&cm[1]);
1760 rnd_label = GNUNET_STRINGS_data_to_string_alloc (&ch->ticket.rnd,
1762 GNUNET_asprintf (&lookup_query,
1765 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1766 "Looking for ABE key under %s\n", lookup_query);
1767 ch->lookup_start_time = GNUNET_TIME_absolute_get ();
1769 = GNUNET_GNS_lookup (gns_handle,
1771 &ch->ticket.identity,
1772 GNUNET_GNSRECORD_TYPE_ABE_KEY,
1773 GNUNET_GNS_LO_DEFAULT,
1774 &process_consume_abe_key,
1776 GNUNET_free (rnd_label);
1777 GNUNET_free (lookup_query);
1778 GNUNET_SERVICE_client_continue (idp->client);
1782 cleanup_as_handle (struct AttributeStoreHandle *handle)
1784 if (NULL != handle->claim)
1785 GNUNET_free (handle->claim);
1786 if (NULL != handle->abe_key)
1787 GNUNET_ABE_cpabe_delete_master_key (handle->abe_key);
1788 GNUNET_free (handle);
1792 attr_store_cont (void *cls,
1796 struct AttributeStoreHandle *as_handle = cls;
1797 struct GNUNET_MQ_Envelope *env;
1798 struct AttributeStoreResultMessage *acr_msg;
1800 if (GNUNET_SYSERR == success)
1802 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1803 "Failed to store attribute %s\n",
1805 cleanup_as_handle (as_handle);
1806 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1810 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1811 "Sending ATTRIBUTE_STORE_RESPONSE message\n");
1812 env = GNUNET_MQ_msg (acr_msg,
1813 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_STORE_RESPONSE);
1814 acr_msg->id = htonl (as_handle->r_id);
1815 acr_msg->op_result = htonl (GNUNET_OK);
1816 GNUNET_MQ_send (as_handle->client->mq,
1818 cleanup_as_handle (as_handle);
1822 attr_store_task (void *cls)
1824 struct AttributeStoreHandle *as_handle = cls;
1825 struct GNUNET_GNSRECORD_Data rd[1];
1834 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1835 "Storing attribute\n");
1836 buf_size = GNUNET_IDENTITY_ATTRIBUTE_serialize_get_size (as_handle->claim);
1837 buf = GNUNET_malloc (buf_size);
1839 GNUNET_IDENTITY_ATTRIBUTE_serialize (as_handle->claim,
1842 GNUNET_asprintf (&policy,
1844 as_handle->claim->name,
1845 as_handle->claim->version);
1846 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1847 "Encrypting with policy %s\n", policy);
1849 * Encrypt the attribute value and store in namestore
1851 enc_size = GNUNET_ABE_cpabe_encrypt (buf,
1857 GNUNET_free (policy);
1858 rd[0].data_size = enc_size + sizeof (uint32_t);
1859 rd_buf = GNUNET_malloc (rd[0].data_size);
1860 attr_ver = htonl (as_handle->claim->version);
1861 GNUNET_memcpy (rd_buf,
1864 GNUNET_memcpy (rd_buf+sizeof (uint32_t),
1867 rd[0].data = rd_buf;
1868 rd[0].record_type = GNUNET_GNSRECORD_TYPE_ID_ATTR;
1869 rd[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
1870 rd[0].expiration_time = GNUNET_TIME_UNIT_HOURS.rel_value_us; //TODO sane?
1871 as_handle->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
1872 &as_handle->identity,
1873 as_handle->claim->name,
1878 GNUNET_free (enc_buf);
1879 GNUNET_free (rd_buf);
1884 store_after_abe_bootstrap (void *cls,
1885 struct GNUNET_ABE_AbeMasterKey *abe_key)
1887 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1888 "Finished ABE bootstrap\n");
1889 struct AttributeStoreHandle *ash = cls;
1890 ash->abe_key = abe_key;
1891 GNUNET_SCHEDULER_add_now (&attr_store_task, ash);
1895 check_attribute_store_message(void *cls,
1896 const struct AttributeStoreMessage *sam)
1900 size = ntohs (sam->header.size);
1901 if (size <= sizeof (struct AttributeStoreMessage))
1904 return GNUNET_SYSERR;
1911 handle_attribute_store_message (void *cls,
1912 const struct AttributeStoreMessage *sam)
1914 struct AttributeStoreHandle *as_handle;
1915 struct IdpClient *idp = cls;
1917 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1918 "Received ATTRIBUTE_STORE message\n");
1920 data_len = ntohs (sam->attr_len);
1922 as_handle = GNUNET_new (struct AttributeStoreHandle);
1923 as_handle->claim = GNUNET_IDENTITY_ATTRIBUTE_deserialize ((char*)&sam[1],
1926 as_handle->r_id = ntohl (sam->id);
1927 as_handle->identity = sam->identity;
1928 GNUNET_CRYPTO_ecdsa_key_get_public (&sam->identity,
1929 &as_handle->identity_pkey);
1931 GNUNET_SERVICE_client_continue (idp->client);
1932 as_handle->client = idp;
1933 bootstrap_abe (&as_handle->identity, &store_after_abe_bootstrap, as_handle, GNUNET_NO);
1937 cleanup_iter_handle (struct AttributeIterator *ai)
1939 if (NULL != ai->abe_key)
1940 GNUNET_ABE_cpabe_delete_master_key (ai->abe_key);
1941 GNUNET_CONTAINER_DLL_remove (ai->client->op_head,
1942 ai->client->op_tail,
1948 attr_iter_error (void *cls)
1950 struct AttributeIterator *ai = cls;
1952 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1953 "Failed to iterate over attributes\n");
1954 cleanup_iter_handle (ai);
1955 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1959 attr_iter_finished (void *cls)
1961 struct AttributeIterator *ai = cls;
1962 struct GNUNET_MQ_Envelope *env;
1963 struct AttributeResultMessage *arm;
1965 env = GNUNET_MQ_msg (arm,
1966 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_RESULT);
1967 arm->id = htonl (ai->request_id);
1968 arm->attr_len = htons (0);
1969 GNUNET_MQ_send (ai->client->mq, env);
1970 cleanup_iter_handle (ai);
1974 attr_iter_cb (void *cls,
1975 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
1977 unsigned int rd_count,
1978 const struct GNUNET_GNSRECORD_Data *rd)
1980 struct AttributeIterator *ai = cls;
1981 struct AttributeResultMessage *arm;
1982 struct GNUNET_ABE_AbeKey *key;
1983 struct GNUNET_MQ_Envelope *env;
1984 ssize_t msg_extra_len;
1993 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it);
1997 if (GNUNET_GNSRECORD_TYPE_ID_ATTR != rd->record_type) {
1998 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it);
2001 attr_ver = ntohl(*((uint32_t*)rd->data));
2002 GNUNET_asprintf (&policy, "%s_%lu",
2006 key = GNUNET_ABE_cpabe_create_key (ai->abe_key,
2008 msg_extra_len = GNUNET_ABE_cpabe_decrypt (rd->data+sizeof (uint32_t),
2009 rd->data_size-sizeof (uint32_t),
2013 GNUNET_ABE_cpabe_delete_key (key,
2015 //GNUNET_free (policy);
2016 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2017 "Found attribute: %s\n", label);
2018 env = GNUNET_MQ_msg_extra (arm,
2020 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_RESULT);
2021 arm->id = htonl (ai->request_id);
2022 arm->attr_len = htons (msg_extra_len);
2023 GNUNET_CRYPTO_ecdsa_key_get_public (zone,
2025 data_tmp = (char *) &arm[1];
2026 GNUNET_memcpy (data_tmp,
2029 GNUNET_MQ_send (ai->client->mq, env);
2030 GNUNET_free (attr_ser);
2031 GNUNET_ABE_cpabe_delete_master_key (ai->abe_key);
2037 iterate_after_abe_bootstrap (void *cls,
2038 struct GNUNET_ABE_AbeMasterKey *abe_key)
2040 struct AttributeIterator *ai = cls;
2041 ai->abe_key = abe_key;
2042 ai->ns_it = GNUNET_NAMESTORE_zone_iteration_start (ns_handle,
2048 &attr_iter_finished,
2053 iterate_next_after_abe_bootstrap (void *cls,
2054 struct GNUNET_ABE_AbeMasterKey *abe_key)
2056 struct AttributeIterator *ai = cls;
2057 ai->abe_key = abe_key;
2058 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it);
2064 handle_iteration_start (void *cls,
2065 const struct AttributeIterationStartMessage *ais_msg)
2067 struct IdpClient *idp = cls;
2068 struct AttributeIterator *ai;
2070 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2071 "Received ATTRIBUTE_ITERATION_START message\n");
2072 ai = GNUNET_new (struct AttributeIterator);
2073 ai->request_id = ntohl (ais_msg->id);
2075 ai->identity = ais_msg->identity;
2077 GNUNET_CONTAINER_DLL_insert (idp->op_head,
2080 bootstrap_abe (&ai->identity, &iterate_after_abe_bootstrap, ai, GNUNET_NO);
2081 GNUNET_SERVICE_client_continue (idp->client);
2086 handle_iteration_stop (void *cls,
2087 const struct AttributeIterationStopMessage *ais_msg)
2089 struct IdpClient *idp = cls;
2090 struct AttributeIterator *ai;
2093 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2094 "Received `%s' message\n",
2095 "ATTRIBUTE_ITERATION_STOP");
2096 rid = ntohl (ais_msg->id);
2097 for (ai = idp->op_head; NULL != ai; ai = ai->next)
2098 if (ai->request_id == rid)
2103 GNUNET_SERVICE_client_drop (idp->client);
2106 GNUNET_CONTAINER_DLL_remove (idp->op_head,
2110 GNUNET_SERVICE_client_continue (idp->client);
2115 handle_iteration_next (void *cls,
2116 const struct AttributeIterationNextMessage *ais_msg)
2118 struct IdpClient *idp = cls;
2119 struct AttributeIterator *ai;
2122 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2123 "Received ATTRIBUTE_ITERATION_NEXT message\n");
2124 rid = ntohl (ais_msg->id);
2125 for (ai = idp->op_head; NULL != ai; ai = ai->next)
2126 if (ai->request_id == rid)
2131 GNUNET_SERVICE_client_drop (idp->client);
2134 bootstrap_abe (&ai->identity,
2135 &iterate_next_after_abe_bootstrap,
2138 GNUNET_SERVICE_client_continue (idp->client);
2142 * Ticket iteration processor result
2144 enum ZoneIterationResult
2153 * Continue to iterate with next iteration_next call
2155 IT_SUCCESS_MORE_AVAILABLE = 1,
2158 * Iteration complete
2160 IT_SUCCESS_NOT_MORE_RESULTS_AVAILABLE = 2
2165 * Context for ticket iteration
2167 struct TicketIterationProcResult
2170 * The ticket iteration handle
2172 struct TicketIteration *ti;
2175 * Iteration result: iteration done?
2176 * #IT_SUCCESS_MORE_AVAILABLE: if there may be more results overall but
2177 * we got one for now and have sent it to the client
2178 * #IT_SUCCESS_NOT_MORE_RESULTS_AVAILABLE: if there are no further results,
2179 * #IT_START: if we are still trying to find a result.
2181 int res_iteration_finished;
2186 cleanup_ticket_iter_handle (struct TicketIteration *ti)
2192 * Process ticket from database
2194 * @param cls struct TicketIterationProcResult
2195 * @param ticket the ticket
2196 * @param attrs the attributes
2199 ticket_iterate_proc (void *cls,
2200 const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket,
2201 const struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs)
2203 struct TicketIterationProcResult *proc = cls;
2207 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2208 "Iteration done\n");
2209 proc->res_iteration_finished = IT_SUCCESS_NOT_MORE_RESULTS_AVAILABLE;
2212 proc->res_iteration_finished = IT_SUCCESS_MORE_AVAILABLE;
2213 send_ticket_result (proc->ti->client,
2221 * Perform ticket iteration step
2223 * @param ti ticket iterator to process
2226 run_ticket_iteration_round (struct TicketIteration *ti)
2228 struct TicketIterationProcResult proc;
2229 struct GNUNET_MQ_Envelope *env;
2230 struct TicketResultMessage *trm;
2233 memset (&proc, 0, sizeof (proc));
2235 proc.res_iteration_finished = IT_START;
2236 while (IT_START == proc.res_iteration_finished)
2238 if (GNUNET_SYSERR ==
2239 (ret = TKT_database->iterate_tickets (TKT_database->cls,
2243 &ticket_iterate_proc,
2249 if (GNUNET_NO == ret)
2250 proc.res_iteration_finished = IT_SUCCESS_NOT_MORE_RESULTS_AVAILABLE;
2253 if (IT_SUCCESS_MORE_AVAILABLE == proc.res_iteration_finished)
2255 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2256 "More results available\n");
2257 return; /* more later */
2259 /* send empty response to indicate end of list */
2260 env = GNUNET_MQ_msg (trm,
2261 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_RESULT);
2262 trm->id = htonl (ti->r_id);
2263 GNUNET_MQ_send (ti->client->mq,
2265 GNUNET_CONTAINER_DLL_remove (ti->client->ticket_iter_head,
2266 ti->client->ticket_iter_tail,
2268 cleanup_ticket_iter_handle (ti);
2272 handle_ticket_iteration_start (void *cls,
2273 const struct TicketIterationStartMessage *tis_msg)
2275 struct IdpClient *client = cls;
2276 struct TicketIteration *ti;
2278 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2279 "Received TICKET_ITERATION_START message\n");
2280 ti = GNUNET_new (struct TicketIteration);
2281 ti->r_id = ntohl (tis_msg->id);
2283 ti->client = client;
2284 ti->identity = tis_msg->identity;
2285 ti->is_audience = ntohl (tis_msg->is_audience);
2287 GNUNET_CONTAINER_DLL_insert (client->ticket_iter_head,
2288 client->ticket_iter_tail,
2290 run_ticket_iteration_round (ti);
2291 GNUNET_SERVICE_client_continue (client->client);
2296 handle_ticket_iteration_stop (void *cls,
2297 const struct TicketIterationStopMessage *tis_msg)
2299 struct IdpClient *client = cls;
2300 struct TicketIteration *ti;
2303 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2304 "Received `%s' message\n",
2305 "TICKET_ITERATION_STOP");
2306 rid = ntohl (tis_msg->id);
2307 for (ti = client->ticket_iter_head; NULL != ti; ti = ti->next)
2308 if (ti->r_id == rid)
2313 GNUNET_SERVICE_client_drop (client->client);
2316 GNUNET_CONTAINER_DLL_remove (client->ticket_iter_head,
2317 client->ticket_iter_tail,
2319 cleanup_ticket_iter_handle (ti);
2320 GNUNET_SERVICE_client_continue (client->client);
2325 handle_ticket_iteration_next (void *cls,
2326 const struct TicketIterationNextMessage *tis_msg)
2328 struct IdpClient *client = cls;
2329 struct TicketIteration *ti;
2332 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2333 "Received TICKET_ITERATION_NEXT message\n");
2334 rid = ntohl (tis_msg->id);
2335 for (ti = client->ticket_iter_head; NULL != ti; ti = ti->next)
2336 if (ti->r_id == rid)
2341 GNUNET_SERVICE_client_drop (client->client);
2344 run_ticket_iteration_round (ti);
2345 GNUNET_SERVICE_client_continue (client->client);
2352 * Main function that will be run
2354 * @param cls closure
2355 * @param c the configuration used
2356 * @param server the service handle
2360 const struct GNUNET_CONFIGURATION_Handle *c,
2361 struct GNUNET_SERVICE_Handle *server)
2366 stats = GNUNET_STATISTICS_create ("identity-provider", cfg);
2368 //Connect to identity and namestore services
2369 ns_handle = GNUNET_NAMESTORE_connect (cfg);
2370 if (NULL == ns_handle)
2372 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "error connecting to namestore");
2375 gns_handle = GNUNET_GNS_connect (cfg);
2376 if (NULL == gns_handle)
2378 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "error connecting to gns");
2380 credential_handle = GNUNET_CREDENTIAL_connect (cfg);
2381 if (NULL == credential_handle)
2383 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "error connecting to credential");
2385 identity_handle = GNUNET_IDENTITY_connect (cfg,
2388 /* Loading DB plugin */
2390 GNUNET_CONFIGURATION_get_value_string (cfg,
2391 "identity-provider",
2394 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2395 "No database backend configured\n");
2396 GNUNET_asprintf (&db_lib_name,
2397 "libgnunet_plugin_identity_provider_%s",
2399 TKT_database = GNUNET_PLUGIN_load (db_lib_name,
2401 GNUNET_free (database);
2402 if (NULL == TKT_database)
2404 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2405 "Could not load database backend `%s'\n",
2407 GNUNET_SCHEDULER_shutdown ();
2412 GNUNET_CONFIGURATION_get_value_time (cfg,
2413 "identity-provider",
2414 "TOKEN_EXPIRATION_INTERVAL",
2415 &token_expiration_interval))
2417 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2418 "Time window for zone iteration: %s\n",
2419 GNUNET_STRINGS_relative_time_to_string (token_expiration_interval,
2422 token_expiration_interval = DEFAULT_TOKEN_EXPIRATION_INTERVAL;
2425 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL);
2429 * Called whenever a client is disconnected.
2431 * @param cls closure
2432 * @param client identification of the client
2433 * @param app_ctx @a client
2436 client_disconnect_cb (void *cls,
2437 struct GNUNET_SERVICE_Client *client,
2440 struct IdpClient *idp = app_ctx;
2441 struct AttributeIterator *ai;
2442 struct TicketIteration *ti;
2443 struct TicketRevocationHandle *rh;
2445 //TODO other operations
2447 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2448 "Client %p disconnected\n",
2451 while (NULL != (ai = idp->op_head))
2453 GNUNET_CONTAINER_DLL_remove (idp->op_head,
2458 while (NULL != (rh = idp->revocation_list_head))
2460 GNUNET_CONTAINER_DLL_remove (idp->revocation_list_head,
2461 idp->revocation_list_tail,
2463 cleanup_revoke_ticket_handle (rh);
2465 while (NULL != (ti = idp->ticket_iter_head))
2467 GNUNET_CONTAINER_DLL_remove (idp->ticket_iter_head,
2468 idp->ticket_iter_tail,
2470 cleanup_ticket_iter_handle (ti);
2477 * Add a client to our list of active clients.
2480 * @param client client to add
2481 * @param mq message queue for @a client
2482 * @return internal namestore client structure for this client
2485 client_connect_cb (void *cls,
2486 struct GNUNET_SERVICE_Client *client,
2487 struct GNUNET_MQ_Handle *mq)
2489 struct IdpClient *idp;
2490 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2491 "Client %p connected\n",
2493 idp = GNUNET_new (struct IdpClient);
2494 idp->client = client;
2502 * Define "main" method using service macro.
2505 ("identity-provider",
2506 GNUNET_SERVICE_OPTION_NONE,
2509 &client_disconnect_cb,
2511 GNUNET_MQ_hd_var_size (attribute_store_message,
2512 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_STORE,
2513 struct AttributeStoreMessage,
2515 GNUNET_MQ_hd_fixed_size (iteration_start,
2516 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_START,
2517 struct AttributeIterationStartMessage,
2519 GNUNET_MQ_hd_fixed_size (iteration_next,
2520 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_NEXT,
2521 struct AttributeIterationNextMessage,
2523 GNUNET_MQ_hd_fixed_size (iteration_stop,
2524 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_STOP,
2525 struct AttributeIterationStopMessage,
2527 GNUNET_MQ_hd_var_size (issue_ticket_message,
2528 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ISSUE_TICKET,
2529 struct IssueTicketMessage,
2531 GNUNET_MQ_hd_var_size (consume_ticket_message,
2532 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_CONSUME_TICKET,
2533 struct ConsumeTicketMessage,
2535 GNUNET_MQ_hd_fixed_size (ticket_iteration_start,
2536 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_START,
2537 struct TicketIterationStartMessage,
2539 GNUNET_MQ_hd_fixed_size (ticket_iteration_next,
2540 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_NEXT,
2541 struct TicketIterationNextMessage,
2543 GNUNET_MQ_hd_fixed_size (ticket_iteration_stop,
2544 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_STOP,
2545 struct TicketIterationStopMessage,
2547 GNUNET_MQ_hd_var_size (revoke_ticket_message,
2548 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_REVOKE_TICKET,
2549 struct RevokeTicketMessage,
2551 GNUNET_MQ_handler_end());
2552 /* end of gnunet-service-identity-provider.c */