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_credential_service.h"
34 #include "gnunet_statistics_service.h"
35 #include "gnunet_gns_service.h"
36 #include "gnunet_identity_provider_plugin.h"
37 #include "gnunet_signatures.h"
38 #include "identity_provider.h"
39 #include "identity_attribute.h"
47 * Normal operation state
49 #define STATE_POST_INIT 1
52 * Minimum interval between updates
54 #define MIN_WAIT_TIME GNUNET_TIME_UNIT_MINUTES
57 * Standard token expiration time
59 #define DEFAULT_TOKEN_EXPIRATION_INTERVAL GNUNET_TIME_UNIT_HOURS
64 static struct GNUNET_IDENTITY_Handle *identity_handle;
69 static struct GNUNET_IDENTITY_PROVIDER_PluginFunctions *TKT_database;
74 static char *db_lib_name;
77 * Token expiration interval
79 static struct GNUNET_TIME_Relative token_expiration_interval;
84 static struct GNUNET_NAMESTORE_Handle *ns_handle;
89 static struct GNUNET_GNS_Handle *gns_handle;
94 static struct GNUNET_CREDENTIAL_Handle *credential_handle;
99 static struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
104 static struct GNUNET_NAMESTORE_ZoneIterator *ns_it;
109 static struct GNUNET_SCHEDULER_Task *timeout_task;
114 static struct GNUNET_SCHEDULER_Task *update_task;
118 * Currently processed token
120 static struct IdentityToken *token;
123 * Label for currently processed token
128 * Scopes for processed token
133 * Handle to the statistics service.
135 static struct GNUNET_STATISTICS_Handle *stats;
140 static const struct GNUNET_CONFIGURATION_Handle *cfg;
148 * A ticket iteration operation.
150 struct TicketIteration
155 struct TicketIteration *next;
160 struct TicketIteration *prev;
163 * Client which intiated this zone iteration
165 struct IdpClient *client;
168 * Key of the identity we are iterating over.
170 struct GNUNET_CRYPTO_EcdsaPublicKey identity;
173 * Identity is audience
175 uint32_t is_audience;
178 * The operation id fot the iteration in the response for the client
183 * Offset of the iteration used to address next result of the
184 * iteration in the store
186 * Initialy set to 0 in handle_iteration_start
187 * Incremented with by every call to handle_iteration_next
196 * Callback after an ABE bootstrap
199 * @param abe_key the ABE key that exists or was created
202 (*AbeBootstrapResult) (void *cls,
203 struct GNUNET_CRYPTO_AbeMasterKey *abe_key);
206 struct AbeBootstrapHandle
209 * Function to call when finished
211 AbeBootstrapResult proc;
219 * Key of the zone we are iterating over.
221 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
224 * Namestore Queue Entry
226 struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
229 * The issuer egos ABE master key
231 struct GNUNET_CRYPTO_AbeMasterKey *abe_key;
235 * An attribute iteration operation.
237 struct AttributeIterator
240 * Next element in the DLL
242 struct AttributeIterator *next;
245 * Previous element in the DLL
247 struct AttributeIterator *prev;
250 * IDP client which intiated this zone iteration
252 struct IdpClient *client;
255 * Key of the zone we are iterating over.
257 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
260 * The issuer egos ABE master key
262 struct GNUNET_CRYPTO_AbeMasterKey *abe_key;
267 struct GNUNET_NAMESTORE_ZoneIterator *ns_it;
270 * The operation id fot the zone iteration in the response for the client
287 struct GNUNET_SERVICE_Client *client;
290 * Message queue for transmission to @e client
292 struct GNUNET_MQ_Handle *mq;
296 * Attribute iteration operations in
297 * progress initiated by this client
299 struct AttributeIterator *op_head;
303 * Attribute iteration operations
304 * in progress initiated by this client
306 struct AttributeIterator *op_tail;
309 * Head of DLL of ticket iteration ops
311 struct TicketIteration *ticket_iter_head;
314 * Tail of DLL of ticket iteration ops
316 struct TicketIteration *ticket_iter_tail;
321 struct AttributeStoreHandle
327 struct IdpClient *client;
332 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
337 struct GNUNET_CRYPTO_EcdsaPublicKey identity_pkey;
340 * The issuer egos ABE master key
342 struct GNUNET_CRYPTO_AbeMasterKey *abe_key;
347 struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
350 * The attribute to store
352 struct GNUNET_IDENTITY_PROVIDER_Attribute *attribute;
362 struct ParallelLookup;
364 struct ConsumeTicketHandle
370 struct IdpClient *client;
375 struct GNUNET_IDENTITY_PROVIDER_Ticket ticket;
380 struct GNUNET_GNS_LookupRequest *lookup_request;
385 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
390 struct GNUNET_CRYPTO_EcdsaPublicKey identity_pub;
395 struct ParallelLookup *parallel_lookups_head;
400 struct ParallelLookup *parallel_lookups_tail;
405 struct GNUNET_SCHEDULER_Task *kill_task;
410 struct GNUNET_CRYPTO_AbeKey *key;
415 struct GNUNET_IDENTITY_PROVIDER_AttributeList *attrs;
424 * Handle for a parallel GNS lookup job
426 struct ParallelLookup
429 struct ParallelLookup *next;
432 struct ParallelLookup *prev;
434 /* The GNS request */
435 struct GNUNET_GNS_LookupRequest *lookup_request;
437 /* The handle the return to */
438 struct ConsumeTicketHandle *handle;
440 /* The label to look up */
445 * Ticket revocation request handle
447 struct TicketRevocationHandle
453 struct IdpClient *client;
456 * Attributes to issue
458 struct GNUNET_IDENTITY_PROVIDER_AttributeList *attrs;
463 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
468 struct GNUNET_IDENTITY_PROVIDER_Ticket ticket;
473 struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
478 struct GNUNET_NAMESTORE_ZoneIterator *ns_it;
483 struct GNUNET_CRYPTO_AbeMasterKey *abe_key;
499 * Ticket issue request handle
501 struct TicketIssueHandle
507 struct IdpClient *client;
510 * Attributes to issue
512 struct GNUNET_IDENTITY_PROVIDER_AttributeList *attrs;
517 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
522 struct GNUNET_IDENTITY_PROVIDER_Ticket ticket;
527 struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
537 * DLL for ego handles to egos containing the ID_ATTRS in a map in json_t format
545 struct EgoEntry *next;
550 struct EgoEntry *prev;
555 struct GNUNET_IDENTITY_Ego *ego;
558 * Attribute map. Contains the attributes as json_t
560 struct GNUNET_CONTAINER_MultiHashMap *attr_map;
570 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
574 GNUNET_STATISTICS_destroy (stats, GNUNET_NO);
577 GNUNET_break (NULL == GNUNET_PLUGIN_unload (db_lib_name,
579 GNUNET_free (db_lib_name);
581 if (NULL != timeout_task)
582 GNUNET_SCHEDULER_cancel (timeout_task);
583 if (NULL != update_task)
584 GNUNET_SCHEDULER_cancel (update_task);
585 if (NULL != identity_handle)
586 GNUNET_IDENTITY_disconnect (identity_handle);
587 if (NULL != gns_handle)
588 GNUNET_GNS_disconnect (gns_handle);
589 if (NULL != credential_handle)
590 GNUNET_CREDENTIAL_disconnect (credential_handle);
592 GNUNET_NAMESTORE_zone_iteration_stop (ns_it);
594 GNUNET_NAMESTORE_cancel (ns_qe);
595 if (NULL != ns_handle)
596 GNUNET_NAMESTORE_disconnect (ns_handle);
608 * @param tc task context
611 do_shutdown (void *cls)
613 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
614 "Shutting down...\n");
619 * Finished storing newly bootstrapped ABE key
622 bootstrap_store_cont (void *cls,
626 struct AbeBootstrapHandle *abh = cls;
627 if (GNUNET_SYSERR == success)
629 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
630 "Failed to bootstrap ABE master %s\n",
632 abh->proc (abh->proc_cls, NULL);
633 GNUNET_free (abh->abe_key);
637 abh->proc (abh->proc_cls, abh->abe_key);
642 * Generates and stores a new ABE key
645 bootstrap_store_task (void *cls)
647 struct AbeBootstrapHandle *abh = cls;
648 struct GNUNET_GNSRECORD_Data rd[1];
650 rd[0].data_size = GNUNET_CRYPTO_cpabe_serialize_master_key (abh->abe_key,
651 (void**)&rd[0].data);
652 rd[0].record_type = GNUNET_GNSRECORD_TYPE_ABE_MASTER;
653 rd[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION | GNUNET_GNSRECORD_RF_PRIVATE;
654 rd[0].expiration_time = GNUNET_TIME_UNIT_HOURS.rel_value_us; //TODO sane?
655 abh->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
660 &bootstrap_store_cont,
665 * Error checking for ABE master
668 bootstrap_abe_error (void *cls)
670 struct AbeBootstrapHandle *abh = cls;
672 abh->proc (abh->proc_cls, NULL);
678 * Handle ABE lookup in namestore
681 bootstrap_abe_result (void *cls,
682 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
684 unsigned int rd_count,
685 const struct GNUNET_GNSRECORD_Data *rd)
687 struct AbeBootstrapHandle *abh = cls;
688 struct GNUNET_CRYPTO_AbeMasterKey *abe_key;
691 for (i=0;i<rd_count;i++) {
692 if (GNUNET_GNSRECORD_TYPE_ABE_MASTER != rd[i].record_type)
694 abe_key = GNUNET_CRYPTO_cpabe_deserialize_master_key ((void**)rd[i].data,
696 abh->proc (abh->proc_cls, abe_key);
701 //No ABE master found, bootstrapping...
702 abh->abe_key = GNUNET_CRYPTO_cpabe_create_master_key ();
703 GNUNET_SCHEDULER_add_now (&bootstrap_store_task, abh);
707 * Bootstrap ABE master if it does not yet exists.
708 * Will call the AbeBootstrapResult processor when done.
709 * will always recreate the ABE key of GNUNET_YES == recreate
712 bootstrap_abe (const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
713 AbeBootstrapResult proc,
717 struct AbeBootstrapHandle *abh;
719 abh = GNUNET_new (struct AbeBootstrapHandle);
722 abh->identity = *identity;
723 if (GNUNET_YES == recreate)
725 abh->abe_key = GNUNET_CRYPTO_cpabe_create_master_key ();
726 GNUNET_SCHEDULER_add_now (&bootstrap_store_task, abh);
728 abh->ns_qe = GNUNET_NAMESTORE_records_lookup (ns_handle,
731 &bootstrap_abe_error,
733 &bootstrap_abe_result,
741 create_sym_key_from_ecdh(const struct GNUNET_HashCode *new_key_hash,
742 struct GNUNET_CRYPTO_SymmetricSessionKey *skey,
743 struct GNUNET_CRYPTO_SymmetricInitializationVector *iv)
745 struct GNUNET_CRYPTO_HashAsciiEncoded new_key_hash_str;
747 GNUNET_CRYPTO_hash_to_enc (new_key_hash,
749 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating symmetric rsa key from %s\n", (char*)&new_key_hash_str);
750 static const char ctx_key[] = "gnuid-aes-ctx-key";
751 GNUNET_CRYPTO_kdf (skey, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
752 new_key_hash, sizeof (struct GNUNET_HashCode),
753 ctx_key, strlen (ctx_key),
755 static const char ctx_iv[] = "gnuid-aes-ctx-iv";
756 GNUNET_CRYPTO_kdf (iv, sizeof (struct GNUNET_CRYPTO_SymmetricInitializationVector),
757 new_key_hash, sizeof (struct GNUNET_HashCode),
758 ctx_iv, strlen (ctx_iv),
764 cleanup_ticket_issue_handle (struct TicketIssueHandle *handle)
766 if (NULL != handle->attrs)
767 attribute_list_destroy (handle->attrs);
768 if (NULL != handle->ns_qe)
769 GNUNET_NAMESTORE_cancel (handle->ns_qe);
770 GNUNET_free (handle);
775 send_ticket_result (struct IdpClient *client,
777 const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket,
778 const struct GNUNET_IDENTITY_PROVIDER_AttributeList *attrs)
780 struct TicketResultMessage *irm;
781 struct GNUNET_MQ_Envelope *env;
782 struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket_buf;
784 /* store ticket in DB */
785 if (GNUNET_OK != TKT_database->store_ticket (TKT_database->cls,
789 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
790 "Unable to store ticket after issue\n");
794 env = GNUNET_MQ_msg_extra (irm,
795 sizeof (struct GNUNET_IDENTITY_PROVIDER_Ticket),
796 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_RESULT);
797 ticket_buf = (struct GNUNET_IDENTITY_PROVIDER_Ticket *)&irm[1];
798 *ticket_buf = *ticket;
799 irm->id = htonl (r_id);
800 GNUNET_MQ_send (client->mq,
805 store_ticket_issue_cont (void *cls,
809 struct TicketIssueHandle *handle = cls;
811 handle->ns_qe = NULL;
812 if (GNUNET_SYSERR == success)
814 cleanup_ticket_issue_handle (handle);
815 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n",
817 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
820 send_ticket_result (handle->client,
824 cleanup_ticket_issue_handle (handle);
830 serialize_abe_keyinfo2 (const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket,
831 const struct GNUNET_IDENTITY_PROVIDER_AttributeList *attrs,
832 const struct GNUNET_CRYPTO_AbeKey *rp_key,
833 struct GNUNET_CRYPTO_EcdhePrivateKey **ecdh_privkey,
836 struct GNUNET_CRYPTO_EcdhePublicKey ecdh_pubkey;
837 struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry *le;
839 char *serialized_key;
845 struct GNUNET_CRYPTO_SymmetricSessionKey skey;
846 struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
847 struct GNUNET_HashCode new_key_hash;
850 size = GNUNET_CRYPTO_cpabe_serialize_key (rp_key,
851 (void**)&serialized_key);
853 for (le = attrs->list_head; NULL != le; le = le->next) {
854 attrs_str_len += strlen (le->attribute->name) + 1;
856 buf = GNUNET_malloc (attrs_str_len + size);
858 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
859 "Writing attributes\n");
860 for (le = attrs->list_head; NULL != le; le = le->next) {
861 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
862 "%s\n", le->attribute->name);
865 GNUNET_memcpy (write_ptr,
867 strlen (le->attribute->name));
868 write_ptr[strlen (le->attribute->name)] = ',';
869 write_ptr += strlen (le->attribute->name) + 1;
872 write_ptr[0] = '\0'; //replace last , with a 0-terminator
874 GNUNET_memcpy (write_ptr,
877 // ECDH keypair E = eG
878 *ecdh_privkey = GNUNET_CRYPTO_ecdhe_key_create();
879 GNUNET_CRYPTO_ecdhe_key_get_public (*ecdh_privkey,
881 enc_keyinfo = GNUNET_malloc (size + attrs_str_len);
882 // Derived key K = H(eB)
883 GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecdh_ecdsa (*ecdh_privkey,
886 create_sym_key_from_ecdh(&new_key_hash, &skey, &iv);
887 enc_size = GNUNET_CRYPTO_symmetric_encrypt (buf,
888 size + attrs_str_len,
891 *result = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)+
893 GNUNET_memcpy (*result,
895 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
896 GNUNET_memcpy (*result + sizeof (struct GNUNET_CRYPTO_EcdhePublicKey),
899 GNUNET_free (enc_keyinfo);
900 return sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)+enc_size;
906 issue_ticket_after_abe_bootstrap (void *cls,
907 struct GNUNET_CRYPTO_AbeMasterKey *abe_key)
909 struct TicketIssueHandle *ih = cls;
910 struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry *le;
911 struct GNUNET_CRYPTO_EcdhePrivateKey *ecdhe_privkey;
912 struct GNUNET_GNSRECORD_Data code_record[1];
913 struct GNUNET_CRYPTO_AbeKey *rp_key;
914 char *code_record_data;
919 size_t code_record_len;
921 //Create new ABE key for RP
923 for (le = ih->attrs->list_head; NULL != le; le = le->next)
925 attrs = GNUNET_malloc ((attrs_len + 1)*sizeof (char*));
927 for (le = ih->attrs->list_head; NULL != le; le = le->next) {
928 attrs[i] = (char*) le->attribute->name;
932 rp_key = GNUNET_CRYPTO_cpabe_create_key (abe_key,
935 //TODO review this wireformat
936 code_record_len = serialize_abe_keyinfo2 (&ih->ticket,
941 code_record[0].data = code_record_data;
942 code_record[0].data_size = code_record_len;
943 code_record[0].expiration_time = GNUNET_TIME_UNIT_DAYS.rel_value_us;
944 code_record[0].record_type = GNUNET_GNSRECORD_TYPE_ABE_KEY;
945 code_record[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
947 label = GNUNET_STRINGS_data_to_string_alloc (&ih->ticket.rnd,
950 ih->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
955 &store_ticket_issue_cont,
957 GNUNET_free (ecdhe_privkey);
960 GNUNET_free (code_record_data);
965 * Checks a ticket issue message
967 * @param cls client sending the message
968 * @param im message of type `struct TicketIssueMessage`
969 * @return #GNUNET_OK if @a im is well-formed
972 check_issue_ticket_message(void *cls,
973 const struct IssueTicketMessage *im)
977 size = ntohs (im->header.size);
978 if (size <= sizeof (struct IssueTicketMessage))
981 return GNUNET_SYSERR;
989 * Handler for ticket issue message
992 * @param client who sent the message
993 * @param message the message
996 handle_issue_ticket_message (void *cls,
997 const struct IssueTicketMessage *im)
999 struct TicketIssueHandle *ih;
1000 struct IdpClient *idp = cls;
1003 ih = GNUNET_new (struct TicketIssueHandle);
1004 attrs_len = ntohs (im->attr_len);
1005 ih->attrs = attribute_list_deserialize ((char*)&im[1], attrs_len);
1006 ih->r_id = ntohl (im->id);
1008 ih->identity = im->identity;
1009 GNUNET_CRYPTO_ecdsa_key_get_public (&ih->identity,
1010 &ih->ticket.identity);
1011 ih->ticket.audience = im->rp;
1013 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG,
1015 bootstrap_abe (&ih->identity, &issue_ticket_after_abe_bootstrap, ih, GNUNET_NO);
1016 GNUNET_SERVICE_client_continue (idp->client);
1021 * Process ticket from database
1023 * @param cls struct TicketIterationProcResult
1024 * @param ticket the ticket
1025 * @param attrs the attributes
1028 ticket_reissue_proc (void *cls,
1029 const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket,
1030 const struct GNUNET_IDENTITY_PROVIDER_AttributeList *attrs);
1034 reissue_ticket_cont (void *cls,
1038 struct TicketRevocationHandle *rh = cls;
1041 if (GNUNET_SYSERR == success)
1043 //TODO cleanup_ticket_revocation_handle (handle);
1044 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n",
1046 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1050 GNUNET_assert (GNUNET_SYSERR !=
1051 TKT_database->iterate_tickets (TKT_database->cls,
1052 &rh->ticket.identity,
1055 &ticket_reissue_proc,
1062 * Process ticket from database
1064 * @param cls struct TicketIterationProcResult
1065 * @param ticket the ticket
1066 * @param attrs the attributes
1069 ticket_reissue_proc (void *cls,
1070 const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket,
1071 const struct GNUNET_IDENTITY_PROVIDER_AttributeList *attrs)
1073 struct TicketRevocationHandle *rh = cls;
1074 struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry *le;
1075 struct GNUNET_CRYPTO_EcdhePrivateKey *ecdhe_privkey;
1076 struct GNUNET_GNSRECORD_Data code_record[1];
1077 struct GNUNET_CRYPTO_AbeKey *rp_key;
1078 char *code_record_data;
1083 size_t code_record_len;
1088 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1089 "Iteration done\n");
1094 //Create new ABE key for RP
1096 for (le = attrs->list_head; NULL != le; le = le->next)
1098 attr_arr = GNUNET_malloc ((attrs_len + 1)*sizeof (char*));
1100 for (le = attrs->list_head; NULL != le; le = le->next) {
1101 attr_arr[i] = (char*) le->attribute->name;
1105 rp_key = GNUNET_CRYPTO_cpabe_create_key (rh->abe_key,
1108 //TODO review this wireformat
1109 code_record_len = serialize_abe_keyinfo2 (&rh->ticket,
1114 code_record[0].data = code_record_data;
1115 code_record[0].data_size = code_record_len;
1116 code_record[0].expiration_time = GNUNET_TIME_UNIT_DAYS.rel_value_us;
1117 code_record[0].record_type = GNUNET_GNSRECORD_TYPE_ABE_KEY;
1118 code_record[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
1120 label = GNUNET_STRINGS_data_to_string_alloc (&ticket->rnd,
1123 rh->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
1128 &reissue_ticket_cont,
1130 GNUNET_free (ecdhe_privkey);
1131 GNUNET_free (label);
1132 GNUNET_free (attr_arr);
1133 GNUNET_free (code_record_data);
1139 attr_reenc_cont (void *cls,
1143 struct TicketRevocationHandle *rh = cls;
1144 struct GNUNET_GNSRECORD_Data rd[1];
1149 if (GNUNET_SYSERR == success)
1151 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1152 "Failed to reencrypt attribute %s\n",
1154 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1157 GNUNET_CONTAINER_DLL_remove (rh->attrs->list_head,
1158 rh->attrs->list_tail,
1159 rh->attrs->list_head);
1160 if (NULL == rh->attrs->list_head)
1162 /* Done, issue new keys */
1163 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
1164 "Revocation Phase IV: Reissuing Tickets\n");
1165 if (GNUNET_SYSERR ==
1166 (ret = TKT_database->iterate_tickets (TKT_database->cls,
1167 &rh->ticket.identity,
1170 &ticket_reissue_proc,
1177 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1178 "Re-encrypting attribute\n");
1179 buf_size = attribute_serialize_get_size (rh->attrs->list_head->attribute);
1180 buf = GNUNET_malloc (buf_size);
1182 attribute_serialize (rh->attrs->list_head->attribute,
1186 * Encrypt the attribute value and store in namestore
1188 rd[0].data_size = GNUNET_CRYPTO_cpabe_encrypt (buf,
1190 rh->attrs->list_head->attribute->name, //Policy
1192 (void**)&rd[0].data);
1194 rd[0].record_type = GNUNET_GNSRECORD_TYPE_ID_ATTR;
1195 rd[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
1196 rd[0].expiration_time = GNUNET_TIME_UNIT_HOURS.rel_value_us; //TODO sane?
1197 rh->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
1199 rh->attrs->list_head->attribute->name,
1204 GNUNET_free ((void*)rd[0].data);
1210 reenc_after_abe_bootstrap (void *cls,
1211 struct GNUNET_CRYPTO_AbeMasterKey *abe_key)
1213 struct TicketRevocationHandle *rh = cls;
1214 struct GNUNET_GNSRECORD_Data rd[1];
1219 rh->abe_key = abe_key;
1220 GNUNET_assert (NULL != abe_key);
1222 if (NULL == rh->attrs->list_head)
1224 /* No attributes to reencrypt, this is odd... */
1227 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
1228 "Revocation Phase III: Re-encrypting attributes\n");
1229 buf_size = attribute_serialize_get_size (rh->attrs->list_head->attribute);
1230 buf = GNUNET_malloc (buf_size);
1232 attribute_serialize (rh->attrs->list_head->attribute,
1236 * Encrypt the attribute value and store in namestore
1238 rd[0].data_size = GNUNET_CRYPTO_cpabe_encrypt (buf,
1240 rh->attrs->list_head->attribute->name, //Policy
1242 (void**)&rd[0].data);
1244 rd[0].record_type = GNUNET_GNSRECORD_TYPE_ID_ATTR;
1245 rd[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
1246 rd[0].expiration_time = GNUNET_TIME_UNIT_HOURS.rel_value_us; //TODO sane?
1247 rh->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
1249 rh->attrs->list_head->attribute->name,
1254 GNUNET_free ((void*)rd[0].data);
1261 revoke_collect_iter_error (void *cls)
1263 //struct AttributeIterator *ai = cls;
1265 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1266 "Failed to iterate over attributes\n");
1267 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1271 revoke_collect_iter_finished (void *cls)
1273 struct TicketRevocationHandle *rh = cls;
1274 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
1275 "Revocation Phase II: Invalidating old ABE Master\n");
1276 /* Bootstrap new abe key */
1277 bootstrap_abe (&rh->identity, &reenc_after_abe_bootstrap, rh, GNUNET_YES);
1281 revoke_collect_iter_cb (void *cls,
1282 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
1284 unsigned int rd_count,
1285 const struct GNUNET_GNSRECORD_Data *rd)
1287 struct TicketRevocationHandle *rh = cls;
1288 struct GNUNET_CRYPTO_AbeKey *key;
1289 struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry *le;
1296 GNUNET_NAMESTORE_zone_iterator_next (rh->ns_it);
1300 if (GNUNET_GNSRECORD_TYPE_ID_ATTR != rd->record_type) {
1301 GNUNET_NAMESTORE_zone_iterator_next (rh->ns_it);
1304 attrs[0] = (char*)label;
1306 key = GNUNET_CRYPTO_cpabe_create_key (rh->abe_key,
1308 attr_len = GNUNET_CRYPTO_cpabe_decrypt (rd->data,
1312 GNUNET_CRYPTO_cpabe_delete_key (key);
1313 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1314 "Attribute to reencrypt: %s\n", label);
1315 le = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry);
1316 le->attribute = attribute_deserialize (attr_ser, attr_len);
1317 GNUNET_CONTAINER_DLL_insert_tail (rh->attrs->list_head,
1318 rh->attrs->list_tail,
1320 GNUNET_NAMESTORE_zone_iterator_next (rh->ns_it);
1325 collect_after_abe_bootstrap (void *cls,
1326 struct GNUNET_CRYPTO_AbeMasterKey *abe_key)
1328 struct TicketRevocationHandle *rh = cls;
1331 GNUNET_assert (NULL != abe_key);
1332 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
1333 "Revocation Phase I: Collecting attributes\n");
1334 /* Reencrypt all attributes with new key */
1335 rh->ns_it = GNUNET_NAMESTORE_zone_iteration_start (ns_handle,
1337 &revoke_collect_iter_error,
1339 &revoke_collect_iter_cb,
1341 &revoke_collect_iter_finished,
1348 * Checks a ticket revocation message
1350 * @param cls client sending the message
1351 * @param im message of type `struct RevokeTicketMessage`
1352 * @return #GNUNET_OK if @a im is well-formed
1355 check_revoke_ticket_message(void *cls,
1356 const struct RevokeTicketMessage *im)
1360 size = ntohs (im->header.size);
1361 if (size <= sizeof (struct RevokeTicketMessage))
1364 return GNUNET_SYSERR;
1372 * Handler for ticket revocation message
1375 * @param client who sent the message
1376 * @param message the message
1379 handle_revoke_ticket_message (void *cls,
1380 const struct RevokeTicketMessage *rm)
1382 struct TicketRevocationHandle *rh;
1383 struct IdpClient *idp = cls;
1384 struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket;
1387 rh = GNUNET_new (struct TicketRevocationHandle);
1388 attrs_len = ntohs (rm->attrs_len);
1389 ticket = (struct GNUNET_IDENTITY_PROVIDER_Ticket*)&rm[1];
1391 rh->attrs = attribute_list_deserialize ((char*)&ticket[1], attrs_len);
1392 rh->ticket = *ticket;
1393 rh->r_id = ntohl (rm->id);
1395 rh->identity = rm->identity;
1396 GNUNET_CRYPTO_ecdsa_key_get_public (&rh->identity,
1397 &rh->ticket.identity);
1398 bootstrap_abe (&rh->identity, &collect_after_abe_bootstrap, rh, GNUNET_NO);
1399 GNUNET_SERVICE_client_continue (idp->client);
1405 cleanup_as_handle (struct AttributeStoreHandle *handle)
1407 if (NULL != handle->attribute)
1408 GNUNET_free (handle->attribute);
1409 if (NULL != handle->abe_key)
1410 GNUNET_free (handle->abe_key);
1411 GNUNET_free (handle);
1415 * Checks a ticket consume message
1417 * @param cls client sending the message
1418 * @param im message of type `struct ConsumeTicketMessage`
1419 * @return #GNUNET_OK if @a im is well-formed
1422 check_consume_ticket_message(void *cls,
1423 const struct ConsumeTicketMessage *cm)
1427 size = ntohs (cm->header.size);
1428 if (size <= sizeof (struct ConsumeTicketMessage))
1431 return GNUNET_SYSERR;
1437 process_parallel_lookup2 (void *cls, uint32_t rd_count,
1438 const struct GNUNET_GNSRECORD_Data *rd)
1440 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1441 "Parallel lookup finished (count=%u)\n", rd_count);
1442 struct ParallelLookup *parallel_lookup = cls;
1443 struct ConsumeTicketHandle *handle = parallel_lookup->handle;
1444 struct ConsumeTicketResultMessage *crm;
1445 struct GNUNET_MQ_Envelope *env;
1446 struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry *attr_le;
1452 GNUNET_CONTAINER_DLL_remove (handle->parallel_lookups_head,
1453 handle->parallel_lookups_tail,
1455 GNUNET_free (parallel_lookup->label);
1456 GNUNET_free (parallel_lookup);
1458 GNUNET_break(0);//TODO
1459 if (rd->record_type == GNUNET_GNSRECORD_TYPE_ID_ATTR)
1461 attr_len = GNUNET_CRYPTO_cpabe_decrypt (rd->data,
1465 attr_le = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry);
1466 attr_le->attribute = attribute_deserialize (data,
1468 GNUNET_CONTAINER_DLL_insert (handle->attrs->list_head,
1469 handle->attrs->list_tail,
1473 if (NULL != handle->parallel_lookups_head)
1474 return; //Wait for more
1475 /* Else we are done */
1477 /* Store ticket in DB */
1478 if (GNUNET_OK != TKT_database->store_ticket (TKT_database->cls,
1482 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1483 "Unable to store ticket after consume\n");
1487 GNUNET_SCHEDULER_cancel (handle->kill_task);
1488 attrs_len = attribute_list_serialize_get_size (handle->attrs);
1489 env = GNUNET_MQ_msg_extra (crm,
1491 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_CONSUME_TICKET_RESULT);
1492 crm->id = htonl (handle->r_id);
1493 crm->attrs_len = htons (attrs_len);
1494 crm->identity = handle->ticket.identity;
1495 data_tmp = (char *) &crm[1];
1496 attribute_list_serialize (handle->attrs,
1498 GNUNET_MQ_send (handle->client->mq, env);
1502 abort_parallel_lookups2 (void *cls)
1504 struct ConsumeTicketHandle *handle = cls;
1505 struct ParallelLookup *lu;
1506 struct ParallelLookup *tmp;
1507 struct AttributeResultMessage *arm;
1508 struct GNUNET_MQ_Envelope *env;
1510 for (lu = handle->parallel_lookups_head;
1512 GNUNET_GNS_lookup_cancel (lu->lookup_request);
1513 GNUNET_free (lu->label);
1515 GNUNET_CONTAINER_DLL_remove (handle->parallel_lookups_head,
1516 handle->parallel_lookups_tail,
1521 env = GNUNET_MQ_msg (arm,
1522 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_RESULT);
1523 arm->id = htonl (handle->r_id);
1524 arm->attr_len = htons (0);
1525 GNUNET_MQ_send (handle->client->mq, env);
1530 cleanup_consume_ticket_handle (struct ConsumeTicketHandle *handle)
1532 if (NULL != handle->key)
1533 GNUNET_free (handle->key);
1534 GNUNET_free (handle);
1539 process_consume_abe_key (void *cls, uint32_t rd_count,
1540 const struct GNUNET_GNSRECORD_Data *rd)
1542 struct ConsumeTicketHandle *handle = cls;
1543 struct GNUNET_HashCode new_key_hash;
1544 struct GNUNET_CRYPTO_SymmetricSessionKey enc_key;
1545 struct GNUNET_CRYPTO_SymmetricInitializationVector enc_iv;
1546 struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_key;
1547 struct ParallelLookup *parallel_lookup;
1553 handle->lookup_request = NULL;
1556 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1557 "Number of keys %d != 1.",
1559 cleanup_consume_ticket_handle (handle);
1560 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1565 ecdh_key = (struct GNUNET_CRYPTO_EcdhePublicKey *)rd->data;
1567 buf = GNUNET_malloc (rd->data_size - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
1569 //Calculate symmetric key from ecdh parameters
1570 GNUNET_assert (GNUNET_OK ==
1571 GNUNET_CRYPTO_ecdsa_ecdh (&handle->identity,
1574 create_sym_key_from_ecdh (&new_key_hash,
1577 size = GNUNET_CRYPTO_symmetric_decrypt (rd->data + sizeof (struct GNUNET_CRYPTO_EcdhePublicKey),
1578 rd->data_size - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey),
1583 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1584 "Decrypted bytes: %zd Expected bytes: %zd\n",
1585 size, rd->data_size - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
1587 scopes = GNUNET_strdup (buf);
1588 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1589 "Scopes %s\n", scopes);
1590 handle->key = GNUNET_CRYPTO_cpabe_deserialize_key ((void*)(buf + strlen (scopes) + 1),
1591 rd->data_size - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)
1592 - strlen (scopes) - 1);
1594 for (scope = strtok (scopes, ","); NULL != scope; scope = strtok (NULL, ","))
1596 GNUNET_asprintf (&lookup_query,
1599 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1600 "Looking up %s\n", lookup_query);
1601 parallel_lookup = GNUNET_new (struct ParallelLookup);
1602 parallel_lookup->handle = handle;
1603 parallel_lookup->label = GNUNET_strdup (scope);
1604 parallel_lookup->lookup_request
1605 = GNUNET_GNS_lookup (gns_handle,
1607 &handle->ticket.identity,
1608 GNUNET_GNSRECORD_TYPE_ID_ATTR,
1609 GNUNET_GNS_LO_LOCAL_MASTER,
1610 &process_parallel_lookup2,
1612 GNUNET_CONTAINER_DLL_insert (handle->parallel_lookups_head,
1613 handle->parallel_lookups_tail,
1615 GNUNET_free (lookup_query);
1617 handle->kill_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES,3),
1618 &abort_parallel_lookups2,
1625 * Handler for ticket issue message
1628 * @param client who sent the message
1629 * @param message the message
1632 handle_consume_ticket_message (void *cls,
1633 const struct ConsumeTicketMessage *cm)
1635 struct ConsumeTicketHandle *ch;
1636 struct IdpClient *idp = cls;
1640 ch = GNUNET_new (struct ConsumeTicketHandle);
1641 ch->r_id = ntohl (cm->id);
1643 ch->identity = cm->identity;
1644 ch->attrs = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_AttributeList);
1645 GNUNET_CRYPTO_ecdsa_key_get_public (&ch->identity,
1647 ch->ticket = *((struct GNUNET_IDENTITY_PROVIDER_Ticket*)&cm[1]);
1648 rnd_label = GNUNET_STRINGS_data_to_string_alloc (&ch->ticket.rnd,
1650 GNUNET_asprintf (&lookup_query,
1653 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1654 "Looking for ABE key under %s\n", lookup_query);
1657 = GNUNET_GNS_lookup (gns_handle,
1659 &ch->ticket.identity,
1660 GNUNET_GNSRECORD_TYPE_ABE_KEY,
1661 GNUNET_GNS_LO_LOCAL_MASTER,
1662 &process_consume_abe_key,
1664 GNUNET_free (rnd_label);
1665 GNUNET_free (lookup_query);
1666 GNUNET_SERVICE_client_continue (idp->client);
1670 attr_store_cont (void *cls,
1674 struct AttributeStoreHandle *as_handle = cls;
1675 struct GNUNET_MQ_Envelope *env;
1676 struct AttributeStoreResponseMessage *acr_msg;
1678 if (GNUNET_SYSERR == success)
1680 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1681 "Failed to store attribute %s\n",
1683 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1687 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1688 "Sending ATTRIBUTE_STORE_RESPONSE message\n");
1689 env = GNUNET_MQ_msg (acr_msg,
1690 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_STORE_RESPONSE);
1691 acr_msg->id = htonl (as_handle->r_id);
1692 acr_msg->op_result = htonl (GNUNET_OK);
1693 GNUNET_MQ_send (as_handle->client->mq,
1695 cleanup_as_handle (as_handle);
1699 attr_store_task (void *cls)
1701 struct AttributeStoreHandle *as_handle = cls;
1702 struct GNUNET_GNSRECORD_Data rd[1];
1706 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1707 "Storing attribute\n");
1708 buf_size = attribute_serialize_get_size (as_handle->attribute);
1709 buf = GNUNET_malloc (buf_size);
1711 attribute_serialize (as_handle->attribute,
1715 * Encrypt the attribute value and store in namestore
1717 rd[0].data_size = GNUNET_CRYPTO_cpabe_encrypt (buf,
1719 as_handle->attribute->name, //Policy
1721 (void**)&rd[0].data);
1723 rd[0].record_type = GNUNET_GNSRECORD_TYPE_ID_ATTR;
1724 rd[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
1725 rd[0].expiration_time = GNUNET_TIME_UNIT_HOURS.rel_value_us; //TODO sane?
1726 as_handle->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
1727 &as_handle->identity,
1728 as_handle->attribute->name,
1733 GNUNET_free ((void*)rd[0].data);
1739 store_after_abe_bootstrap (void *cls,
1740 struct GNUNET_CRYPTO_AbeMasterKey *abe_key)
1742 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1743 "Finished ABE bootstrap\n");
1744 struct AttributeStoreHandle *ash = cls;
1745 ash->abe_key = abe_key;
1746 GNUNET_SCHEDULER_add_now (&attr_store_task, ash);
1750 * Checks a store message
1752 * @param cls client sending the message
1753 * @param sam message of type `struct AttributeStoreMessage`
1754 * @return #GNUNET_OK if @a im is well-formed
1757 check_attribute_store_message(void *cls,
1758 const struct AttributeStoreMessage *sam)
1762 size = ntohs (sam->header.size);
1763 if (size <= sizeof (struct AttributeStoreMessage))
1766 return GNUNET_SYSERR;
1774 * Handler for store message
1777 * @param client who sent the message
1778 * @param message the message
1781 handle_attribute_store_message (void *cls,
1782 const struct AttributeStoreMessage *sam)
1784 struct AttributeStoreHandle *as_handle;
1785 struct IdpClient *idp = cls;
1787 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1788 "Received ATTRIBUTE_STORE message\n");
1790 data_len = ntohs (sam->attr_len);
1792 as_handle = GNUNET_new (struct AttributeStoreHandle);
1793 as_handle->attribute = attribute_deserialize ((char*)&sam[1],
1796 as_handle->r_id = ntohl (sam->id);
1797 as_handle->identity = sam->identity;
1798 GNUNET_CRYPTO_ecdsa_key_get_public (&sam->identity,
1799 &as_handle->identity_pkey);
1801 GNUNET_SERVICE_client_continue (idp->client);
1802 as_handle->client = idp;
1803 bootstrap_abe (&as_handle->identity, &store_after_abe_bootstrap, as_handle, GNUNET_NO);
1807 cleanup_iter_handle (struct AttributeIterator *ai)
1809 if (NULL != ai->abe_key)
1810 GNUNET_free (ai->abe_key);
1811 GNUNET_CONTAINER_DLL_remove (ai->client->op_head,
1812 ai->client->op_tail,
1818 attr_iter_error (void *cls)
1820 //struct AttributeIterator *ai = cls;
1822 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1823 "Failed to iterate over attributes\n");
1824 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1828 attr_iter_finished (void *cls)
1830 struct AttributeIterator *ai = cls;
1831 struct GNUNET_MQ_Envelope *env;
1832 struct AttributeResultMessage *arm;
1834 env = GNUNET_MQ_msg (arm,
1835 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_RESULT);
1836 arm->id = htonl (ai->request_id);
1837 arm->attr_len = htons (0);
1838 GNUNET_MQ_send (ai->client->mq, env);
1839 cleanup_iter_handle (ai);
1843 attr_iter_cb (void *cls,
1844 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
1846 unsigned int rd_count,
1847 const struct GNUNET_GNSRECORD_Data *rd)
1849 struct AttributeIterator *ai = cls;
1850 struct AttributeResultMessage *arm;
1851 struct GNUNET_CRYPTO_AbeKey *key;
1852 struct GNUNET_MQ_Envelope *env;
1853 ssize_t msg_extra_len;
1860 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it);
1864 if (GNUNET_GNSRECORD_TYPE_ID_ATTR != rd->record_type) {
1865 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it);
1868 attrs[0] = (char*)label;
1870 key = GNUNET_CRYPTO_cpabe_create_key (ai->abe_key,
1872 msg_extra_len = GNUNET_CRYPTO_cpabe_decrypt (rd->data,
1876 GNUNET_CRYPTO_cpabe_delete_key (key);
1877 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1878 "Found attribute: %s\n", label);
1879 env = GNUNET_MQ_msg_extra (arm,
1881 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_RESULT);
1882 arm->id = htonl (ai->request_id);
1883 arm->attr_len = htons (msg_extra_len);
1884 GNUNET_CRYPTO_ecdsa_key_get_public (zone,
1886 data_tmp = (char *) &arm[1];
1887 GNUNET_memcpy (data_tmp,
1890 GNUNET_MQ_send (ai->client->mq, env);
1891 GNUNET_free (attr_ser);
1896 iterate_after_abe_bootstrap (void *cls,
1897 struct GNUNET_CRYPTO_AbeMasterKey *abe_key)
1899 struct AttributeIterator *ai = cls;
1900 ai->abe_key = abe_key;
1901 ai->ns_it = GNUNET_NAMESTORE_zone_iteration_start (ns_handle,
1907 &attr_iter_finished,
1913 * Handles a #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ITERATION_START message
1915 * @param cls the client sending the message
1916 * @param zis_msg message from the client
1919 handle_iteration_start (void *cls,
1920 const struct AttributeIterationStartMessage *ais_msg)
1922 struct IdpClient *idp = cls;
1923 struct AttributeIterator *ai;
1925 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1926 "Received ATTRIBUTE_ITERATION_START message\n");
1927 ai = GNUNET_new (struct AttributeIterator);
1928 ai->request_id = ntohl (ais_msg->id);
1930 ai->identity = ais_msg->identity;
1932 GNUNET_CONTAINER_DLL_insert (idp->op_head,
1935 bootstrap_abe (&ai->identity, &iterate_after_abe_bootstrap, ai, GNUNET_NO);
1936 GNUNET_SERVICE_client_continue (idp->client);
1941 * Handles a #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ITERATION_STOP message
1943 * @param cls the client sending the message
1944 * @param ais_msg message from the client
1947 handle_iteration_stop (void *cls,
1948 const struct AttributeIterationStopMessage *ais_msg)
1950 struct IdpClient *idp = cls;
1951 struct AttributeIterator *ai;
1954 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1955 "Received `%s' message\n",
1956 "ATTRIBUTE_ITERATION_STOP");
1957 rid = ntohl (ais_msg->id);
1958 for (ai = idp->op_head; NULL != ai; ai = ai->next)
1959 if (ai->request_id == rid)
1964 GNUNET_SERVICE_client_drop (idp->client);
1967 GNUNET_CONTAINER_DLL_remove (idp->op_head,
1971 GNUNET_SERVICE_client_continue (idp->client);
1976 * Handles a #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_NEXT message
1978 * @param cls the client sending the message
1979 * @param message message from the client
1982 handle_iteration_next (void *cls,
1983 const struct AttributeIterationNextMessage *ais_msg)
1985 struct IdpClient *idp = cls;
1986 struct AttributeIterator *ai;
1989 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1990 "Received ATTRIBUTE_ITERATION_NEXT message\n");
1991 rid = ntohl (ais_msg->id);
1992 for (ai = idp->op_head; NULL != ai; ai = ai->next)
1993 if (ai->request_id == rid)
1998 GNUNET_SERVICE_client_drop (idp->client);
2001 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it);
2002 GNUNET_SERVICE_client_continue (idp->client);
2006 * Ticket iteration processor result
2008 enum ZoneIterationResult
2017 * Continue to iterate with next iteration_next call
2019 IT_SUCCESS_MORE_AVAILABLE = 1,
2022 * Iteration complete
2024 IT_SUCCESS_NOT_MORE_RESULTS_AVAILABLE = 2
2029 * Context for ticket iteration
2031 struct TicketIterationProcResult
2034 * The ticket iteration handle
2036 struct TicketIteration *ti;
2039 * Iteration result: iteration done?
2040 * #IT_SUCCESS_MORE_AVAILABLE: if there may be more results overall but
2041 * we got one for now and have sent it to the client
2042 * #IT_SUCCESS_NOT_MORE_RESULTS_AVAILABLE: if there are no further results,
2043 * #IT_START: if we are still trying to find a result.
2045 int res_iteration_finished;
2052 * Process ticket from database
2054 * @param cls struct TicketIterationProcResult
2055 * @param ticket the ticket
2056 * @param attrs the attributes
2059 ticket_iterate_proc (void *cls,
2060 const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket,
2061 const struct GNUNET_IDENTITY_PROVIDER_AttributeList *attrs)
2063 struct TicketIterationProcResult *proc = cls;
2067 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2068 "Iteration done\n");
2069 proc->res_iteration_finished = IT_SUCCESS_NOT_MORE_RESULTS_AVAILABLE;
2072 proc->res_iteration_finished = IT_SUCCESS_MORE_AVAILABLE;
2073 send_ticket_result (proc->ti->client,
2081 * Perform ticket iteration step
2083 * @param ti ticket iterator to process
2086 run_ticket_iteration_round (struct TicketIteration *ti)
2088 struct TicketIterationProcResult proc;
2089 struct GNUNET_MQ_Envelope *env;
2090 struct TicketResultMessage *trm;
2093 memset (&proc, 0, sizeof (proc));
2095 proc.res_iteration_finished = IT_START;
2096 while (IT_START == proc.res_iteration_finished)
2098 if (GNUNET_SYSERR ==
2099 (ret = TKT_database->iterate_tickets (TKT_database->cls,
2103 &ticket_iterate_proc,
2109 if (GNUNET_NO == ret)
2110 proc.res_iteration_finished = IT_SUCCESS_NOT_MORE_RESULTS_AVAILABLE;
2113 if (IT_SUCCESS_MORE_AVAILABLE == proc.res_iteration_finished)
2115 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2116 "More results available\n");
2117 return; /* more later */
2119 /* send empty response to indicate end of list */
2120 env = GNUNET_MQ_msg (trm,
2121 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_RESULT);
2122 trm->id = htonl (ti->r_id);
2123 GNUNET_MQ_send (ti->client->mq,
2125 GNUNET_CONTAINER_DLL_remove (ti->client->ticket_iter_head,
2126 ti->client->ticket_iter_tail,
2132 * Handles a #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_START message
2134 * @param cls the client sending the message
2135 * @param tis_msg message from the client
2138 handle_ticket_iteration_start (void *cls,
2139 const struct TicketIterationStartMessage *tis_msg)
2141 struct IdpClient *client = cls;
2142 struct TicketIteration *ti;
2144 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2145 "Received TICKET_ITERATION_START message\n");
2146 ti = GNUNET_new (struct TicketIteration);
2147 ti->r_id = ntohl (tis_msg->id);
2149 ti->client = client;
2150 ti->identity = tis_msg->identity;
2151 ti->is_audience = ntohl (tis_msg->is_audience);
2153 GNUNET_CONTAINER_DLL_insert (client->ticket_iter_head,
2154 client->ticket_iter_tail,
2156 run_ticket_iteration_round (ti);
2157 GNUNET_SERVICE_client_continue (client->client);
2162 * Handles a #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_STOP message
2164 * @param cls the client sending the message
2165 * @param tis_msg message from the client
2168 handle_ticket_iteration_stop (void *cls,
2169 const struct TicketIterationStopMessage *tis_msg)
2171 struct IdpClient *client = cls;
2172 struct TicketIteration *ti;
2175 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2176 "Received `%s' message\n",
2177 "TICKET_ITERATION_STOP");
2178 rid = ntohl (tis_msg->id);
2179 for (ti = client->ticket_iter_head; NULL != ti; ti = ti->next)
2180 if (ti->r_id == rid)
2185 GNUNET_SERVICE_client_drop (client->client);
2188 GNUNET_CONTAINER_DLL_remove (client->ticket_iter_head,
2189 client->ticket_iter_tail,
2192 GNUNET_SERVICE_client_continue (client->client);
2197 * Handles a #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_NEXT message
2199 * @param cls the client sending the message
2200 * @param message message from the client
2203 handle_ticket_iteration_next (void *cls,
2204 const struct TicketIterationNextMessage *tis_msg)
2206 struct IdpClient *client = cls;
2207 struct TicketIteration *ti;
2210 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2211 "Received TICKET_ITERATION_NEXT message\n");
2212 rid = ntohl (tis_msg->id);
2213 for (ti = client->ticket_iter_head; NULL != ti; ti = ti->next)
2214 if (ti->r_id == rid)
2219 GNUNET_SERVICE_client_drop (client->client);
2222 run_ticket_iteration_round (ti);
2223 GNUNET_SERVICE_client_continue (client->client);
2230 * Main function that will be run
2232 * @param cls closure
2233 * @param args remaining command-line arguments
2234 * @param cfgfile name of the configuration file used (for saving, can be NULL)
2235 * @param c configuration
2239 const struct GNUNET_CONFIGURATION_Handle *c,
2240 struct GNUNET_SERVICE_Handle *server)
2245 stats = GNUNET_STATISTICS_create ("identity-provider", cfg);
2247 //Connect to identity and namestore services
2248 ns_handle = GNUNET_NAMESTORE_connect (cfg);
2249 if (NULL == ns_handle)
2251 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "error connecting to namestore");
2254 gns_handle = GNUNET_GNS_connect (cfg);
2255 if (NULL == gns_handle)
2257 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "error connecting to gns");
2259 credential_handle = GNUNET_CREDENTIAL_connect (cfg);
2260 if (NULL == credential_handle)
2262 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "error connecting to credential");
2264 identity_handle = GNUNET_IDENTITY_connect (cfg,
2268 /* Loading DB plugin */
2270 GNUNET_CONFIGURATION_get_value_string (cfg,
2271 "identity-provider",
2274 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2275 "No database backend configured\n");
2276 GNUNET_asprintf (&db_lib_name,
2277 "libgnunet_plugin_identity_provider_%s",
2279 TKT_database = GNUNET_PLUGIN_load (db_lib_name,
2281 GNUNET_free (database);
2282 if (NULL == TKT_database)
2284 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2285 "Could not load database backend `%s'\n",
2287 GNUNET_SCHEDULER_shutdown ();
2292 GNUNET_CONFIGURATION_get_value_time (cfg,
2293 "identity-provider",
2294 "TOKEN_EXPIRATION_INTERVAL",
2295 &token_expiration_interval))
2297 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2298 "Time window for zone iteration: %s\n",
2299 GNUNET_STRINGS_relative_time_to_string (token_expiration_interval,
2302 token_expiration_interval = DEFAULT_TOKEN_EXPIRATION_INTERVAL;
2305 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL);
2309 * Called whenever a client is disconnected.
2311 * @param cls closure
2312 * @param client identification of the client
2313 * @param app_ctx @a client
2316 client_disconnect_cb (void *cls,
2317 struct GNUNET_SERVICE_Client *client,
2320 struct IdpClient *idp = app_ctx;
2321 struct AttributeIterator *ai;
2323 //TODO other operations
2325 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2326 "Client %p disconnected\n",
2329 while (NULL != (ai = idp->op_head))
2331 GNUNET_CONTAINER_DLL_remove (idp->op_head,
2341 * Add a client to our list of active clients.
2344 * @param client client to add
2345 * @param mq message queue for @a client
2346 * @return internal namestore client structure for this client
2349 client_connect_cb (void *cls,
2350 struct GNUNET_SERVICE_Client *client,
2351 struct GNUNET_MQ_Handle *mq)
2353 struct IdpClient *idp;
2354 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2355 "Client %p connected\n",
2357 idp = GNUNET_new (struct IdpClient);
2358 idp->client = client;
2366 * Define "main" method using service macro.
2369 ("identity-provider",
2370 GNUNET_SERVICE_OPTION_NONE,
2373 &client_disconnect_cb,
2375 GNUNET_MQ_hd_var_size (attribute_store_message,
2376 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_STORE,
2377 struct AttributeStoreMessage,
2379 GNUNET_MQ_hd_fixed_size (iteration_start,
2380 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_START,
2381 struct AttributeIterationStartMessage,
2383 GNUNET_MQ_hd_fixed_size (iteration_next,
2384 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_NEXT,
2385 struct AttributeIterationNextMessage,
2387 GNUNET_MQ_hd_fixed_size (iteration_stop,
2388 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_STOP,
2389 struct AttributeIterationStopMessage,
2391 GNUNET_MQ_hd_var_size (issue_ticket_message,
2392 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ISSUE_TICKET,
2393 struct IssueTicketMessage,
2395 GNUNET_MQ_hd_var_size (consume_ticket_message,
2396 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_CONSUME_TICKET,
2397 struct ConsumeTicketMessage,
2399 GNUNET_MQ_hd_fixed_size (ticket_iteration_start,
2400 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_START,
2401 struct TicketIterationStartMessage,
2403 GNUNET_MQ_hd_fixed_size (ticket_iteration_next,
2404 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_NEXT,
2405 struct TicketIterationNextMessage,
2407 GNUNET_MQ_hd_fixed_size (ticket_iteration_stop,
2408 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_STOP,
2409 struct TicketIterationStopMessage,
2411 GNUNET_MQ_hd_var_size (revoke_ticket_message,
2412 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_REVOKE_TICKET,
2413 struct RevokeTicketMessage,
2415 GNUNET_MQ_handler_end());
2416 /* end of gnunet-service-identity-provider.c */