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_token.h"
40 #include "identity_attribute.h"
49 * Normal operation state
51 #define STATE_POST_INIT 1
54 * Minimum interval between updates
56 #define MIN_WAIT_TIME GNUNET_TIME_UNIT_MINUTES
59 * Standard token expiration time
61 #define DEFAULT_TOKEN_EXPIRATION_INTERVAL GNUNET_TIME_UNIT_HOURS
66 static struct GNUNET_IDENTITY_Handle *identity_handle;
71 static struct GNUNET_IDENTITY_PROVIDER_PluginFunctions *TKT_database;
76 static char *db_lib_name;
79 * Token expiration interval
81 static struct GNUNET_TIME_Relative token_expiration_interval;
86 static struct GNUNET_NAMESTORE_Handle *ns_handle;
91 static struct GNUNET_GNS_Handle *gns_handle;
96 static struct GNUNET_CREDENTIAL_Handle *credential_handle;
101 static struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
106 static struct GNUNET_NAMESTORE_ZoneIterator *ns_it;
111 static struct GNUNET_SCHEDULER_Task *timeout_task;
116 static struct GNUNET_SCHEDULER_Task *update_task;
120 * Currently processed token
122 static struct IdentityToken *token;
125 * Label for currently processed token
130 * Scopes for processed token
135 * Handle to the statistics service.
137 static struct GNUNET_STATISTICS_Handle *stats;
142 static const struct GNUNET_CONFIGURATION_Handle *cfg;
150 * A ticket iteration operation.
152 struct TicketIteration
157 struct TicketIteration *next;
162 struct TicketIteration *prev;
165 * Client which intiated this zone iteration
167 struct IdpClient *client;
170 * Key of the identity we are iterating over.
172 struct GNUNET_CRYPTO_EcdsaPublicKey identity;
175 * Identity is audience
177 uint32_t is_audience;
180 * The operation id fot the iteration in the response for the client
185 * Offset of the iteration used to address next result of the
186 * iteration in the store
188 * Initialy set to 0 in handle_iteration_start
189 * Incremented with by every call to handle_iteration_next
198 * Callback after an ABE bootstrap
201 * @param abe_key the ABE key that exists or was created
204 (*AbeBootstrapResult) (void *cls,
205 struct GNUNET_CRYPTO_AbeMasterKey *abe_key);
208 struct AbeBootstrapHandle
211 * Function to call when finished
213 AbeBootstrapResult proc;
221 * Key of the zone we are iterating over.
223 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
226 * Namestore Queue Entry
228 struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
231 * The issuer egos ABE master key
233 struct GNUNET_CRYPTO_AbeMasterKey *abe_key;
237 * An attribute iteration operation.
239 struct AttributeIterator
242 * Next element in the DLL
244 struct AttributeIterator *next;
247 * Previous element in the DLL
249 struct AttributeIterator *prev;
252 * IDP client which intiated this zone iteration
254 struct IdpClient *client;
257 * Key of the zone we are iterating over.
259 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
262 * The issuer egos ABE master key
264 struct GNUNET_CRYPTO_AbeMasterKey *abe_key;
269 struct GNUNET_NAMESTORE_ZoneIterator *ns_it;
272 * The operation id fot the zone iteration in the response for the client
289 struct GNUNET_SERVICE_Client *client;
292 * Message queue for transmission to @e client
294 struct GNUNET_MQ_Handle *mq;
298 * Attribute iteration operations in
299 * progress initiated by this client
301 struct AttributeIterator *op_head;
305 * Attribute iteration operations
306 * in progress initiated by this client
308 struct AttributeIterator *op_tail;
311 * Head of DLL of ticket iteration ops
313 struct TicketIteration *ticket_iter_head;
316 * Tail of DLL of ticket iteration ops
318 struct TicketIteration *ticket_iter_tail;
323 struct AttributeStoreHandle
329 struct IdpClient *client;
334 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
339 struct GNUNET_CRYPTO_EcdsaPublicKey identity_pkey;
342 * The issuer egos ABE master key
344 struct GNUNET_CRYPTO_AbeMasterKey *abe_key;
349 struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
352 * The attribute to store
354 struct GNUNET_IDENTITY_PROVIDER_Attribute *attribute;
364 struct VerifiedAttributeEntry
369 struct VerifiedAttributeEntry *prev;
374 struct VerifiedAttributeEntry *next;
382 struct ParallelLookup;
383 struct ParallelLookup2;
385 struct ConsumeTicketHandle
391 struct IdpClient *client;
396 struct GNUNET_IDENTITY_PROVIDER_Ticket2 ticket;
401 struct GNUNET_GNS_LookupRequest *lookup_request;
406 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
411 struct GNUNET_CRYPTO_EcdsaPublicKey identity_pub;
416 struct ParallelLookup2 *parallel_lookups_head;
421 struct ParallelLookup2 *parallel_lookups_tail;
426 struct GNUNET_SCHEDULER_Task *kill_task;
431 struct GNUNET_CRYPTO_AbeKey *key;
436 struct GNUNET_IDENTITY_PROVIDER_AttributeList *attrs;
444 struct ParallelLookup2
446 struct ParallelLookup2 *next;
448 struct ParallelLookup2 *prev;
450 struct GNUNET_GNS_LookupRequest *lookup_request;
452 struct ConsumeTicketHandle *handle;
458 struct ExchangeHandle
464 struct IdpClient *client;
469 struct TokenTicket *ticket;
474 struct IdentityToken *token;
479 struct GNUNET_GNS_LookupRequest *lookup_request;
484 struct GNUNET_CRYPTO_EcdsaPrivateKey aud_privkey;
487 * ParallelLookups DLL
489 struct ParallelLookup *parallel_lookups_head;
490 struct ParallelLookup *parallel_lookups_tail;
492 struct GNUNET_SCHEDULER_Task *kill_task;
493 struct GNUNET_CRYPTO_AbeKey *key;
506 struct ParallelLookup
508 struct ParallelLookup *next;
510 struct ParallelLookup *prev;
512 struct GNUNET_GNS_LookupRequest *lookup_request;
514 struct ExchangeHandle *handle;
520 struct TicketIssueHandle
526 struct IdpClient *client;
529 * Attributes to issue
531 struct GNUNET_IDENTITY_PROVIDER_AttributeList *attrs;
536 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
541 struct GNUNET_IDENTITY_PROVIDER_Ticket2 ticket;
546 struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
564 struct IdpClient *client;
569 struct GNUNET_CRYPTO_EcdsaPrivateKey iss_key;
574 struct GNUNET_CRYPTO_EcdsaPublicKey iss_pkey;
579 struct GNUNET_CRYPTO_EcdsaPublicKey aud_key;
582 * The issuer egos ABE master key
584 struct GNUNET_CRYPTO_AbeMasterKey *abe_key;
589 struct GNUNET_TIME_Absolute expiration;
599 struct VerifiedAttributeEntry *v_attr_head;
604 struct VerifiedAttributeEntry *v_attr_tail;
614 struct GNUNET_NAMESTORE_ZoneIterator *ns_it;
619 struct GNUNET_CREDENTIAL_Request *credential_request;
624 struct GNUNET_CONTAINER_MultiHashMap *attr_map;
629 struct IdentityToken *token;
634 struct TokenTicket *ticket;
639 struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
642 * The label the token is stored under
653 * DLL for ego handles to egos containing the ID_ATTRS in a map in json_t format
661 struct EgoEntry *next;
666 struct EgoEntry *prev;
671 struct GNUNET_IDENTITY_Ego *ego;
674 * Attribute map. Contains the attributes as json_t
676 struct GNUNET_CONTAINER_MultiHashMap *attr_map;
686 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
690 GNUNET_STATISTICS_destroy (stats, GNUNET_NO);
693 GNUNET_break (NULL == GNUNET_PLUGIN_unload (db_lib_name,
695 GNUNET_free (db_lib_name);
697 if (NULL != timeout_task)
698 GNUNET_SCHEDULER_cancel (timeout_task);
699 if (NULL != update_task)
700 GNUNET_SCHEDULER_cancel (update_task);
701 if (NULL != identity_handle)
702 GNUNET_IDENTITY_disconnect (identity_handle);
703 if (NULL != gns_handle)
704 GNUNET_GNS_disconnect (gns_handle);
705 if (NULL != credential_handle)
706 GNUNET_CREDENTIAL_disconnect (credential_handle);
708 GNUNET_NAMESTORE_zone_iteration_stop (ns_it);
710 GNUNET_NAMESTORE_cancel (ns_qe);
711 if (NULL != ns_handle)
712 GNUNET_NAMESTORE_disconnect (ns_handle);
724 * @param tc task context
727 do_shutdown (void *cls)
729 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
730 "Shutting down...\n");
735 * Finished storing newly bootstrapped ABE key
738 bootstrap_store_cont (void *cls,
742 struct AbeBootstrapHandle *abh = cls;
743 if (GNUNET_SYSERR == success)
745 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
746 "Failed to bootstrap ABE master %s\n",
748 abh->proc (abh->proc_cls, NULL);
749 GNUNET_free (abh->abe_key);
753 abh->proc (abh->proc_cls, abh->abe_key);
758 * Generates and stores a new ABE key
761 bootstrap_store_task (void *cls)
763 struct AbeBootstrapHandle *abh = cls;
764 struct GNUNET_GNSRECORD_Data rd[1];
766 rd[0].data_size = GNUNET_CRYPTO_cpabe_serialize_master_key (abh->abe_key,
767 (void**)&rd[0].data);
768 rd[0].record_type = GNUNET_GNSRECORD_TYPE_ABE_MASTER;
769 rd[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION | GNUNET_GNSRECORD_RF_PRIVATE;
770 rd[0].expiration_time = GNUNET_TIME_UNIT_HOURS.rel_value_us; //TODO sane?
771 abh->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
776 &bootstrap_store_cont,
781 * Error checking for ABE master
784 bootstrap_abe_error (void *cls)
786 struct AbeBootstrapHandle *abh = cls;
788 abh->proc (abh->proc_cls, NULL);
794 * Handle ABE lookup in namestore
797 bootstrap_abe_result (void *cls,
798 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
800 unsigned int rd_count,
801 const struct GNUNET_GNSRECORD_Data *rd)
803 struct AbeBootstrapHandle *abh = cls;
804 struct GNUNET_CRYPTO_AbeMasterKey *abe_key;
807 for (i=0;i<rd_count;i++) {
808 if (GNUNET_GNSRECORD_TYPE_ABE_MASTER != rd[i].record_type)
810 abe_key = GNUNET_CRYPTO_cpabe_deserialize_master_key ((void**)rd[i].data,
812 abh->proc (abh->proc_cls, abe_key);
817 //No ABE master found, bootstrapping...
818 abh->abe_key = GNUNET_CRYPTO_cpabe_create_master_key ();
819 GNUNET_SCHEDULER_add_now (&bootstrap_store_task, abh);
823 * Bootstrap ABE master if it does not yet exists.
824 * Will call the AbeBootstrapResult processor when done.
827 bootstrap_abe (const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
828 AbeBootstrapResult proc,
831 struct AbeBootstrapHandle *abh;
833 abh = GNUNET_new (struct AbeBootstrapHandle);
836 abh->identity = *identity;
837 abh->ns_qe = GNUNET_NAMESTORE_records_lookup (ns_handle,
840 &bootstrap_abe_error,
842 &bootstrap_abe_result,
849 static struct GNUNET_MQ_Envelope*
850 create_exchange_result_message (const char* token,
852 uint64_t ticket_nonce,
855 struct GNUNET_MQ_Envelope *env;
856 struct ExchangeResultMessage *erm;
857 uint16_t token_len = strlen (token) + 1;
859 env = GNUNET_MQ_msg_extra (erm,
861 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_EXCHANGE_RESULT);
862 erm->ticket_nonce = htonl (ticket_nonce);
864 GNUNET_memcpy (&erm[1], token, token_len);
869 static struct GNUNET_MQ_Envelope*
870 create_issue_result_message (const char* label,
875 struct GNUNET_MQ_Envelope *env;
876 struct IssueResultMessage *irm;
880 GNUNET_asprintf (&tmp_str, "%s,%s,%s", label, ticket, token);
881 len = strlen (tmp_str) + 1;
882 env = GNUNET_MQ_msg_extra (irm,
884 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ISSUE_RESULT);
886 GNUNET_memcpy (&irm[1], tmp_str, strlen (tmp_str) + 1);
887 GNUNET_free (tmp_str);
892 cleanup_issue_handle (struct IssueHandle *handle)
894 if (NULL != handle->attr_map)
895 GNUNET_CONTAINER_multihashmap_destroy (handle->attr_map);
896 if (NULL != handle->scopes)
897 GNUNET_free (handle->scopes);
898 if (NULL != handle->token)
899 token_destroy (handle->token);
900 if (NULL != handle->ticket)
901 ticket_destroy (handle->ticket);
902 if (NULL != handle->label)
903 GNUNET_free (handle->label);
904 if (NULL != handle->ns_it)
905 GNUNET_NAMESTORE_zone_iteration_stop (handle->ns_it);
906 if (NULL != handle->credential_request)
907 GNUNET_CREDENTIAL_request_cancel (handle->credential_request);
908 GNUNET_free (handle);
912 store_record_issue_cont (void *cls,
916 struct IssueHandle *handle = cls;
917 struct GNUNET_MQ_Envelope *env;
921 handle->ns_qe = NULL;
922 if (GNUNET_SYSERR == success)
924 cleanup_issue_handle (handle);
925 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n",
927 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
930 if (GNUNET_OK != ticket_serialize (handle->ticket,
934 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n",
935 "Error serializing ticket\n");
936 cleanup_issue_handle (handle);
937 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
940 if (GNUNET_OK != token_to_string (handle->token,
944 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n",
945 "Error serializing token\n");
946 GNUNET_free (ticket_str);
947 cleanup_issue_handle (handle);
948 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
951 env = create_issue_result_message (handle->label,
955 GNUNET_MQ_send (handle->client->mq,
957 cleanup_issue_handle (handle);
958 GNUNET_free (ticket_str);
959 GNUNET_free (token_str);
963 create_sym_key_from_ecdh(const struct GNUNET_HashCode *new_key_hash,
964 struct GNUNET_CRYPTO_SymmetricSessionKey *skey,
965 struct GNUNET_CRYPTO_SymmetricInitializationVector *iv)
967 struct GNUNET_CRYPTO_HashAsciiEncoded new_key_hash_str;
969 GNUNET_CRYPTO_hash_to_enc (new_key_hash,
971 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating symmetric rsa key from %s\n", (char*)&new_key_hash_str);
972 static const char ctx_key[] = "gnuid-aes-ctx-key";
973 GNUNET_CRYPTO_kdf (skey, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
974 new_key_hash, sizeof (struct GNUNET_HashCode),
975 ctx_key, strlen (ctx_key),
977 static const char ctx_iv[] = "gnuid-aes-ctx-iv";
978 GNUNET_CRYPTO_kdf (iv, sizeof (struct GNUNET_CRYPTO_SymmetricInitializationVector),
979 new_key_hash, sizeof (struct GNUNET_HashCode),
980 ctx_iv, strlen (ctx_iv),
986 serialize_abe_keyinfo (const struct IssueHandle *handle,
987 const struct GNUNET_CRYPTO_AbeKey *rp_key,
988 struct GNUNET_CRYPTO_EcdhePrivateKey **ecdh_privkey,
992 char *serialized_key;
994 struct GNUNET_CRYPTO_EcdhePublicKey ecdh_pubkey;
997 struct GNUNET_CRYPTO_SymmetricSessionKey skey;
998 struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
999 struct GNUNET_HashCode new_key_hash;
1002 size = GNUNET_CRYPTO_cpabe_serialize_key (rp_key,
1003 (void**)&serialized_key);
1004 buf = GNUNET_malloc (strlen (handle->scopes) + 1 + size);
1007 strlen (handle->scopes) + 1);
1008 GNUNET_memcpy (buf + strlen (handle->scopes) + 1,
1011 // ECDH keypair E = eG
1012 *ecdh_privkey = GNUNET_CRYPTO_ecdhe_key_create();
1013 GNUNET_CRYPTO_ecdhe_key_get_public (*ecdh_privkey,
1015 enc_keyinfo = GNUNET_malloc (size + strlen (handle->scopes) + 1);
1016 // Derived key K = H(eB)
1017 GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecdh_ecdsa (*ecdh_privkey,
1020 create_sym_key_from_ecdh(&new_key_hash, &skey, &iv);
1021 enc_size = GNUNET_CRYPTO_symmetric_encrypt (buf,
1022 size + strlen (handle->scopes) + 1,
1025 *result = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)+
1027 GNUNET_memcpy (*result,
1029 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
1030 GNUNET_memcpy (*result + sizeof (struct GNUNET_CRYPTO_EcdhePublicKey),
1033 GNUNET_free (enc_keyinfo);
1034 return sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)+enc_size;
1038 cleanup_exchange_handle (struct ExchangeHandle *handle)
1040 if (NULL != handle->ticket)
1041 ticket_destroy (handle->ticket);
1042 if (NULL != handle->token)
1043 token_destroy (handle->token);
1044 GNUNET_free (handle);
1049 * Build a token and store it
1051 * @param cls the IssueHandle
1054 sign_and_return_token (void *cls)
1056 struct ExchangeHandle *handle = cls;
1057 struct GNUNET_MQ_Envelope *env;
1062 time = GNUNET_TIME_absolute_get().abs_value_us;
1063 exp_time = time + token_expiration_interval.rel_value_us;
1065 token_add_attr_int (handle->token, "nbf", time);
1066 token_add_attr_int (handle->token, "iat", time);
1067 token_add_attr_int (handle->token, "exp", exp_time);
1070 GNUNET_assert (GNUNET_OK == token_to_string (handle->token,
1071 &handle->aud_privkey,
1074 env = create_exchange_result_message (token_str,
1076 handle->ticket->payload->nonce,
1078 GNUNET_MQ_send (handle->client->mq,
1080 cleanup_exchange_handle (handle);
1081 GNUNET_free (token_str);
1086 * Build an ABE key and store it
1088 * @param cls the IssueHandle
1091 issue_ticket (void *cls)
1093 struct GNUNET_CRYPTO_EcdsaPublicKey pub_key;
1094 struct GNUNET_CRYPTO_EcdhePrivateKey *ecdhe_privkey;
1095 struct IssueHandle *handle = cls;
1096 struct GNUNET_GNSRECORD_Data code_record[1];
1097 struct GNUNET_CRYPTO_AbeKey *rp_key;
1099 char *code_record_data;
1107 size_t code_record_len;
1111 GNUNET_asprintf (&nonce_str, "%lu", handle->nonce);
1112 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Request nonce: %s\n", nonce_str);
1114 GNUNET_CRYPTO_ecdsa_key_get_public (&handle->iss_key,
1116 handle->ticket = ticket_create (handle->nonce,
1121 time = GNUNET_TIME_absolute_get().abs_value_us;
1122 exp_time = time + token_expiration_interval.rel_value_us;
1124 token_add_attr_int (handle->token, "nbf", time);
1125 token_add_attr_int (handle->token, "iat", time);
1126 token_add_attr_int (handle->token, "exp", exp_time);
1127 token_add_attr (handle->token, "nonce", nonce_str);
1129 //Create new ABE key for RP
1130 attrs_len = (GNUNET_CONTAINER_multihashmap_size (handle->attr_map) + 1) * sizeof (char*);
1131 attrs = GNUNET_malloc (attrs_len);
1133 scopes_tmp = GNUNET_strdup (handle->scopes);
1134 for (scope = strtok (scopes_tmp, ","); NULL != scope; scope = strtok (NULL, ",")) {
1138 rp_key = GNUNET_CRYPTO_cpabe_create_key (handle->abe_key,
1140 code_record_len = serialize_abe_keyinfo (handle,
1144 code_record[0].data = code_record_data;
1145 code_record[0].data_size = code_record_len;
1146 code_record[0].expiration_time = exp_time;
1147 code_record[0].record_type = GNUNET_GNSRECORD_TYPE_ABE_KEY;
1148 code_record[0].flags = GNUNET_GNSRECORD_RF_NONE;
1152 handle->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
1157 &store_record_issue_cont,
1159 GNUNET_free (ecdhe_privkey);
1160 GNUNET_free (nonce_str);
1161 GNUNET_free (code_record_data);
1165 * Credential to JSON
1166 * @param cred the credential
1167 * @return the resulting json, NULL if failed
1170 credential_to_json (struct GNUNET_CREDENTIAL_Credential *cred)
1175 char attribute[cred->issuer_attribute_len + 1];
1178 issuer = GNUNET_CRYPTO_ecdsa_public_key_to_string (&cred->issuer_key);
1181 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1182 "Issuer in credential malformed\n");
1185 subject = GNUNET_CRYPTO_ecdsa_public_key_to_string (&cred->subject_key);
1186 if (NULL == subject)
1188 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1189 "Subject in credential malformed\n");
1190 GNUNET_free (issuer);
1193 GNUNET_STRINGS_base64_encode ((char*)&cred->signature,
1194 sizeof (struct GNUNET_CRYPTO_EcdsaSignature),
1197 cred->issuer_attribute,
1198 cred->issuer_attribute_len);
1199 attribute[cred->issuer_attribute_len] = '\0';
1200 cred_obj = json_object ();
1201 json_object_set_new (cred_obj, "issuer", json_string (issuer));
1202 json_object_set_new (cred_obj, "subject", json_string (subject));
1203 json_object_set_new (cred_obj, "attribute", json_string (attribute));
1204 json_object_set_new (cred_obj, "signature", json_string (signature));
1205 json_object_set_new (cred_obj, "expiration", json_integer (cred->expiration.abs_value_us));
1206 GNUNET_free (issuer);
1207 GNUNET_free (subject);
1208 GNUNET_free (signature);
1214 handle_vattr_collection (void* cls,
1215 unsigned int d_count,
1216 struct GNUNET_CREDENTIAL_Delegation *dc,
1217 unsigned int c_count,
1218 struct GNUNET_CREDENTIAL_Credential *cred)
1220 struct IssueHandle *handle = cls;
1221 struct VerifiedAttributeEntry *vattr;
1225 handle->credential_request = NULL;
1229 GNUNET_SCHEDULER_add_now (&issue_ticket, handle);
1232 cred_array = json_array();
1233 for (i=0;i<c_count;i++)
1235 cred_json = credential_to_json (cred);
1236 if (NULL == cred_json)
1238 json_array_append (cred_array, cred_json);
1239 token_add_attr_json (handle->token,
1240 handle->v_attr_head->name,
1243 json_decref (cred_array);
1244 vattr = handle->v_attr_head;
1246 GNUNET_CONTAINER_DLL_remove (handle->v_attr_head,
1247 handle->v_attr_tail,
1249 GNUNET_free (vattr->name);
1250 GNUNET_free (vattr);
1252 if (NULL == handle->v_attr_head)
1254 GNUNET_SCHEDULER_add_now (&issue_ticket, handle);
1257 handle->credential_request = GNUNET_CREDENTIAL_collect (credential_handle,
1259 handle->v_attr_head->name,
1261 &handle_vattr_collection,
1268 attr_collect_error (void *cls)
1270 struct IssueHandle *handle = cls;
1272 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Adding attribute Error!\n");
1273 handle->ns_it = NULL;
1274 GNUNET_SCHEDULER_add_now (&issue_ticket, handle);
1279 attr_collect_finished (void *cls)
1281 struct IssueHandle *handle = cls;
1283 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding attribute END: \n");
1284 handle->ns_it = NULL;
1286 if (NULL == handle->v_attr_head)
1288 GNUNET_SCHEDULER_add_now (&issue_ticket, handle);
1291 handle->credential_request = GNUNET_CREDENTIAL_collect (credential_handle,
1293 handle->v_attr_head->name,
1295 &handle_vattr_collection,
1300 * Collect attributes for token
1303 attr_collect (void *cls,
1304 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
1306 unsigned int rd_count,
1307 const struct GNUNET_GNSRECORD_Data *rd)
1309 struct IssueHandle *handle = cls;
1312 struct GNUNET_HashCode key;
1314 GNUNET_CRYPTO_hash (label,
1318 if (0 == rd_count ||
1319 ( (NULL != handle->attr_map) &&
1320 (GNUNET_YES != GNUNET_CONTAINER_multihashmap_contains (handle->attr_map,
1325 GNUNET_NAMESTORE_zone_iterator_next (handle->ns_it);
1329 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding attribute: %s\n", label);
1333 if (rd->record_type == GNUNET_GNSRECORD_TYPE_ID_ATTR)
1335 data = GNUNET_GNSRECORD_value_to_string (rd->record_type,
1338 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding value: %s\n", data);
1339 token_add_attr (handle->token,
1344 GNUNET_NAMESTORE_zone_iterator_next (handle->ns_it);
1349 for (; i < rd_count; i++)
1351 if (rd->record_type == GNUNET_GNSRECORD_TYPE_ID_ATTR)
1353 data = GNUNET_GNSRECORD_value_to_string (rd[i].record_type,
1356 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding value: %s\n", data);
1357 token_add_attr (handle->token, label, data);
1362 GNUNET_NAMESTORE_zone_iterator_next (handle->ns_it);
1366 process_parallel_lookup (void *cls, uint32_t rd_count,
1367 const struct GNUNET_GNSRECORD_Data *rd)
1369 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1370 "Parallel lookup finished (count=%u)\n", rd_count);
1371 struct ParallelLookup *parallel_lookup = cls;
1372 struct ExchangeHandle *handle = parallel_lookup->handle;
1376 GNUNET_CONTAINER_DLL_remove (handle->parallel_lookups_head,
1377 handle->parallel_lookups_tail,
1379 GNUNET_free (parallel_lookup);
1382 if (rd->record_type == GNUNET_GNSRECORD_TYPE_ID_ATTR)
1384 GNUNET_CRYPTO_cpabe_decrypt (rd->data,
1388 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding value: %s\n", data);
1389 token_add_attr (handle->token,
1390 parallel_lookup->label,
1396 for (; i < rd_count; i++)
1398 if (rd[i].record_type == GNUNET_GNSRECORD_TYPE_ID_ATTR)
1400 data = GNUNET_GNSRECORD_value_to_string (rd[i].record_type,
1403 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding value: %s\n", data);
1404 token_add_attr (handle->token, parallel_lookup->label, data);
1409 if (NULL != handle->parallel_lookups_head)
1410 return; //Wait for more
1412 GNUNET_SCHEDULER_cancel (handle->kill_task);
1413 GNUNET_SCHEDULER_add_now (&sign_and_return_token, handle);
1417 abort_parallel_lookups (void *cls)
1419 struct ExchangeHandle *handle = cls;
1420 struct ParallelLookup *lu;
1421 struct ParallelLookup *tmp;
1423 for (lu = handle->parallel_lookups_head;
1425 GNUNET_GNS_lookup_cancel (lu->lookup_request);
1426 GNUNET_free (lu->label);
1428 GNUNET_CONTAINER_DLL_remove (handle->parallel_lookups_head,
1429 handle->parallel_lookups_tail,
1434 GNUNET_SCHEDULER_add_now (&sign_and_return_token, handle);
1439 process_lookup_result (void *cls, uint32_t rd_count,
1440 const struct GNUNET_GNSRECORD_Data *rd)
1442 struct ExchangeHandle *handle = cls;
1443 struct GNUNET_HashCode new_key_hash;
1444 struct GNUNET_CRYPTO_SymmetricSessionKey enc_key;
1445 struct GNUNET_CRYPTO_SymmetricInitializationVector enc_iv;
1446 struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_key;
1447 struct ParallelLookup *parallel_lookup;
1453 handle->lookup_request = NULL;
1456 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1457 "Number of keys %d != 1.",
1459 cleanup_exchange_handle (handle);
1460 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1465 ecdh_key = (struct GNUNET_CRYPTO_EcdhePublicKey *)rd->data;
1467 buf = GNUNET_malloc (rd->data_size - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
1469 //Calculate symmetric key from ecdh parameters
1470 GNUNET_assert (GNUNET_OK ==
1471 GNUNET_CRYPTO_ecdsa_ecdh (&handle->aud_privkey,
1474 create_sym_key_from_ecdh (&new_key_hash,
1477 size = GNUNET_CRYPTO_symmetric_decrypt (rd->data + sizeof (struct GNUNET_CRYPTO_EcdhePublicKey),
1478 rd->data_size - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey),
1483 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1484 "Decrypted bytes: %zd Expected bytes: %zd\n",
1485 size, rd->data_size - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
1487 scopes = GNUNET_strdup (buf);
1488 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1489 "Scopes %s\n", scopes);
1490 handle->key = GNUNET_CRYPTO_cpabe_deserialize_key ((void*)(buf + strlen (scopes) + 1),
1491 rd->data_size - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)
1492 - strlen (scopes) - 1);
1494 for (scope = strtok (scopes, ","); NULL != scope; scope = strtok (NULL, ","))
1496 GNUNET_asprintf (&lookup_query,
1499 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1500 "Looking up %s\n", lookup_query);
1501 parallel_lookup = GNUNET_new (struct ParallelLookup);
1502 parallel_lookup->handle = handle;
1503 parallel_lookup->label = GNUNET_strdup (scope);
1504 parallel_lookup->lookup_request
1505 = GNUNET_GNS_lookup (gns_handle,
1507 &handle->ticket->payload->identity_key,
1508 GNUNET_GNSRECORD_TYPE_ID_ATTR,
1509 GNUNET_GNS_LO_LOCAL_MASTER,
1510 &process_parallel_lookup,
1512 GNUNET_CONTAINER_DLL_insert (handle->parallel_lookups_head,
1513 handle->parallel_lookups_tail,
1516 handle->kill_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES,3),
1517 &abort_parallel_lookups,
1522 * Checks a exchange message
1524 * @param cls client sending the message
1525 * @param xm message of type `struct ExchangeMessage`
1526 * @return #GNUNET_OK if @a xm is well-formed
1529 check_exchange_message (void *cls,
1530 const struct ExchangeMessage *xm)
1534 size = ntohs (xm->header.size);
1535 if (size <= sizeof (struct ExchangeMessage))
1538 return GNUNET_SYSERR;
1545 * Handler for exchange message
1548 * @param client who sent the message
1549 * @param message the message
1552 handle_exchange_message (void *cls,
1553 const struct ExchangeMessage *xm)
1555 struct ExchangeHandle *xchange_handle;
1556 struct IdpClient *idp = cls;
1560 ticket = (const char *) &xm[1];
1561 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1562 "Received EXCHANGE of `%s' from client\n",
1564 xchange_handle = GNUNET_malloc (sizeof (struct ExchangeHandle));
1565 xchange_handle->aud_privkey = xm->aud_privkey;
1566 xchange_handle->r_id = xm->id;
1567 if (GNUNET_SYSERR == ticket_parse (ticket,
1568 &xchange_handle->aud_privkey,
1569 &xchange_handle->ticket))
1571 GNUNET_free (xchange_handle);
1572 GNUNET_SERVICE_client_drop (idp->client);
1575 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Looking for ABE key under %s\n",
1576 xchange_handle->ticket->payload->label);
1577 GNUNET_asprintf (&lookup_query,
1579 xchange_handle->ticket->payload->label);
1580 GNUNET_SERVICE_client_continue (idp->client);
1581 xchange_handle->client = idp;
1582 xchange_handle->token = token_create (&xchange_handle->ticket->payload->identity_key,
1583 &xchange_handle->ticket->payload->identity_key);
1584 xchange_handle->lookup_request
1585 = GNUNET_GNS_lookup (gns_handle,
1587 &xchange_handle->ticket->payload->identity_key,
1588 GNUNET_GNSRECORD_TYPE_ABE_KEY,
1589 GNUNET_GNS_LO_LOCAL_MASTER,
1590 &process_lookup_result,
1592 GNUNET_free (lookup_query);
1597 attr_collect_task (void *cls)
1599 struct IssueHandle *issue_handle = cls;
1601 issue_handle->ns_it = GNUNET_NAMESTORE_zone_iteration_start (ns_handle,
1602 &issue_handle->iss_key,
1603 &attr_collect_error,
1607 &attr_collect_finished,
1612 abe_key_lookup_error (void *cls)
1614 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1615 "Error looking for ABE master!\n");
1616 GNUNET_SCHEDULER_add_now (&do_shutdown, cls);
1620 abe_key_lookup_result (void *cls,
1621 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
1623 unsigned int rd_count,
1624 const struct GNUNET_GNSRECORD_Data *rd)
1626 struct IssueHandle *handle = cls;
1629 for (i=0;i<rd_count;i++) {
1630 if (GNUNET_GNSRECORD_TYPE_ABE_MASTER != rd[i].record_type)
1632 handle->abe_key = GNUNET_CRYPTO_cpabe_deserialize_master_key ((void**)rd[i].data,
1634 GNUNET_SCHEDULER_add_now (&attr_collect_task, handle);
1637 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1638 "No ABE master found!\n");
1639 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1645 * Checks an issue message
1647 * @param cls client sending the message
1648 * @param im message of type `struct IssueMessage`
1649 * @return #GNUNET_OK if @a im is well-formed
1652 check_issue_message(void *cls,
1653 const struct IssueMessage *im)
1657 size = ntohs (im->header.size);
1658 if (size <= sizeof (struct IssueMessage))
1661 return GNUNET_SYSERR;
1663 scopes = (char *) &im[1];
1664 if ('\0' != scopes[size - sizeof (struct IssueMessage) - 1])
1666 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1667 "Malformed scopes received!\n");
1669 return GNUNET_SYSERR;
1677 * Handler for issue message
1680 * @param client who sent the message
1681 * @param message the message
1684 handle_issue_message (void *cls,
1685 const struct IssueMessage *im)
1691 struct GNUNET_HashCode key;
1692 struct IssueHandle *issue_handle;
1693 struct IdpClient *idp = cls;
1695 scopes = (const char *) &im[1];
1696 //v_attrs = (const char *) &im[1] + ntohl(im->scope_len);
1697 issue_handle = GNUNET_malloc (sizeof (struct IssueHandle));
1698 issue_handle->attr_map = GNUNET_CONTAINER_multihashmap_create (5,
1700 scopes_tmp = GNUNET_strdup (scopes);
1702 for (scope = strtok (scopes_tmp, ","); NULL != scope; scope = strtok (NULL, ","))
1704 GNUNET_CRYPTO_hash (scope,
1707 GNUNET_CONTAINER_multihashmap_put (issue_handle->attr_map,
1710 GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE);
1712 GNUNET_free (scopes_tmp);
1713 /*scopes_tmp = GNUNET_strdup (v_attrs);
1715 for (scope = strtok (scopes_tmp, ","); NULL != scope; scope = strtok (NULL, ","))
1717 vattr_entry = GNUNET_new (struct VerifiedAttributeEntry);
1718 vattr_entry->name = GNUNET_strdup (scope);
1719 GNUNET_CONTAINER_DLL_insert (issue_handle->v_attr_head,
1720 issue_handle->v_attr_tail,
1723 GNUNET_free (scopes_tmp);*/
1727 issue_handle->r_id = im->id;
1728 issue_handle->aud_key = im->aud_key;
1729 issue_handle->iss_key = im->iss_key;
1730 GNUNET_CRYPTO_ecdsa_key_get_public (&im->iss_key,
1731 &issue_handle->iss_pkey);
1732 issue_handle->expiration = GNUNET_TIME_absolute_ntoh (im->expiration);
1733 issue_handle->nonce = ntohl (im->nonce);
1734 GNUNET_SERVICE_client_continue (idp->client);
1735 issue_handle->client = idp;
1736 issue_handle->scopes = GNUNET_strdup (scopes);
1737 issue_handle->token = token_create (&issue_handle->iss_pkey,
1738 &issue_handle->aud_key);
1740 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG,
1742 GNUNET_STRINGS_base64_encode ((char*)&rnd_key,
1744 &issue_handle->label);
1745 issue_handle->ns_qe = GNUNET_NAMESTORE_records_lookup (ns_handle,
1746 &issue_handle->iss_key,
1748 &abe_key_lookup_error,
1750 &abe_key_lookup_result,
1755 cleanup_ticket_issue_handle (struct TicketIssueHandle *handle)
1757 if (NULL != handle->attrs)
1758 attribute_list_destroy (handle->attrs);
1759 if (NULL != handle->ns_qe)
1760 GNUNET_NAMESTORE_cancel (handle->ns_qe);
1761 GNUNET_free (handle);
1766 send_ticket_result (struct IdpClient *client,
1768 const struct GNUNET_IDENTITY_PROVIDER_Ticket2 *ticket,
1769 const struct GNUNET_IDENTITY_PROVIDER_AttributeList *attrs)
1771 struct TicketResultMessage *irm;
1772 struct GNUNET_MQ_Envelope *env;
1774 struct GNUNET_IDENTITY_PROVIDER_Ticket2 *ticket_buf;
1777 attrs_size = attribute_list_serialize_get_size (attrs);
1779 /* store ticket in DB */
1780 if (GNUNET_OK != TKT_database->store_ticket (TKT_database->cls,
1784 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1785 "Unable to store ticket after issue\n");
1789 env = GNUNET_MQ_msg_extra (irm,
1790 sizeof (struct GNUNET_IDENTITY_PROVIDER_Ticket2) + attrs_size,
1791 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_RESULT);
1792 ticket_buf = (struct GNUNET_IDENTITY_PROVIDER_Ticket2 *)&irm[1];
1793 *ticket_buf = *ticket;
1794 attrs_buf = (char*)&ticket_buf[1];
1795 attribute_list_serialize (attrs,
1797 irm->id = htonl (r_id);
1799 GNUNET_MQ_send (client->mq,
1804 store_ticket_issue_cont (void *cls,
1808 struct TicketIssueHandle *handle = cls;
1810 handle->ns_qe = NULL;
1811 if (GNUNET_SYSERR == success)
1813 cleanup_ticket_issue_handle (handle);
1814 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n",
1816 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1819 send_ticket_result (handle->client,
1823 cleanup_ticket_issue_handle (handle);
1829 serialize_abe_keyinfo2 (const struct TicketIssueHandle *handle,
1830 const struct GNUNET_CRYPTO_AbeKey *rp_key,
1831 struct GNUNET_CRYPTO_EcdhePrivateKey **ecdh_privkey,
1834 struct GNUNET_CRYPTO_EcdhePublicKey ecdh_pubkey;
1835 struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry *le;
1837 char *serialized_key;
1843 struct GNUNET_CRYPTO_SymmetricSessionKey skey;
1844 struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
1845 struct GNUNET_HashCode new_key_hash;
1848 size = GNUNET_CRYPTO_cpabe_serialize_key (rp_key,
1849 (void**)&serialized_key);
1851 for (le = handle->attrs->list_head; NULL != le; le = le->next) {
1852 attrs_str_len += strlen (le->attribute->name) + 1;
1854 buf = GNUNET_malloc (attrs_str_len + size);
1856 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1857 "Writing attributes\n");
1858 for (le = handle->attrs->list_head; NULL != le; le = le->next) {
1859 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1860 "%s\n", le->attribute->name);
1863 GNUNET_memcpy (write_ptr,
1864 le->attribute->name,
1865 strlen (le->attribute->name));
1866 write_ptr[strlen (le->attribute->name)] = ',';
1867 write_ptr += strlen (le->attribute->name) + 1;
1870 write_ptr[0] = '\0'; //replace last , with a 0-terminator
1872 GNUNET_memcpy (write_ptr,
1875 // ECDH keypair E = eG
1876 *ecdh_privkey = GNUNET_CRYPTO_ecdhe_key_create();
1877 GNUNET_CRYPTO_ecdhe_key_get_public (*ecdh_privkey,
1879 enc_keyinfo = GNUNET_malloc (size + attrs_str_len);
1880 // Derived key K = H(eB)
1881 GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecdh_ecdsa (*ecdh_privkey,
1882 &handle->ticket.audience,
1884 create_sym_key_from_ecdh(&new_key_hash, &skey, &iv);
1885 enc_size = GNUNET_CRYPTO_symmetric_encrypt (buf,
1886 size + attrs_str_len,
1889 *result = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)+
1891 GNUNET_memcpy (*result,
1893 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
1894 GNUNET_memcpy (*result + sizeof (struct GNUNET_CRYPTO_EcdhePublicKey),
1897 GNUNET_free (enc_keyinfo);
1898 return sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)+enc_size;
1904 issue_ticket_after_abe_bootstrap (void *cls,
1905 struct GNUNET_CRYPTO_AbeMasterKey *abe_key)
1907 struct TicketIssueHandle *ih = cls;
1908 struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry *le;
1909 struct GNUNET_CRYPTO_EcdhePrivateKey *ecdhe_privkey;
1910 struct GNUNET_GNSRECORD_Data code_record[1];
1911 struct GNUNET_CRYPTO_AbeKey *rp_key;
1912 char *code_record_data;
1917 size_t code_record_len;
1919 //Create new ABE key for RP
1921 for (le = ih->attrs->list_head; NULL != le; le = le->next)
1923 attrs = GNUNET_malloc ((attrs_len + 1)*sizeof (char*));
1925 for (le = ih->attrs->list_head; NULL != le; le = le->next) {
1926 attrs[i] = (char*) le->attribute->name;
1930 rp_key = GNUNET_CRYPTO_cpabe_create_key (abe_key,
1933 //TODO review this wireformat
1934 code_record_len = serialize_abe_keyinfo2 (ih,
1938 code_record[0].data = code_record_data;
1939 code_record[0].data_size = code_record_len;
1940 code_record[0].expiration_time = GNUNET_TIME_UNIT_DAYS.rel_value_us;
1941 code_record[0].record_type = GNUNET_GNSRECORD_TYPE_ABE_KEY;
1942 code_record[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
1944 label = GNUNET_STRINGS_data_to_string_alloc (&ih->ticket.rnd,
1947 ih->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
1952 &store_ticket_issue_cont,
1954 GNUNET_free (ecdhe_privkey);
1955 GNUNET_free (label);
1956 GNUNET_free (attrs);
1957 GNUNET_free (code_record_data);
1962 * Checks a ticket issue message
1964 * @param cls client sending the message
1965 * @param im message of type `struct TicketIssueMessage`
1966 * @return #GNUNET_OK if @a im is well-formed
1969 check_ticket_issue_message(void *cls,
1970 const struct TicketIssueMessage *im)
1974 size = ntohs (im->header.size);
1975 if (size <= sizeof (struct TicketIssueMessage))
1978 return GNUNET_SYSERR;
1986 * Handler for ticket issue message
1989 * @param client who sent the message
1990 * @param message the message
1993 handle_ticket_issue_message (void *cls,
1994 const struct TicketIssueMessage *im)
1996 struct TicketIssueHandle *ih;
1997 struct IdpClient *idp = cls;
2000 ih = GNUNET_new (struct TicketIssueHandle);
2001 attrs_len = ntohs (im->attr_len);
2002 ih->attrs = attribute_list_deserialize ((char*)&im[1], attrs_len);
2003 ih->r_id = ntohl (im->id);
2005 ih->identity = im->identity;
2006 GNUNET_CRYPTO_ecdsa_key_get_public (&ih->identity,
2007 &ih->ticket.identity);
2008 ih->ticket.audience = im->rp;
2010 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG,
2012 bootstrap_abe (&ih->identity, &issue_ticket_after_abe_bootstrap, ih);
2013 GNUNET_SERVICE_client_continue (idp->client);
2020 cleanup_as_handle (struct AttributeStoreHandle *handle)
2022 if (NULL != handle->attribute)
2023 GNUNET_free (handle->attribute);
2024 if (NULL != handle->abe_key)
2025 GNUNET_free (handle->abe_key);
2026 GNUNET_free (handle);
2030 * Checks a ticket consume message
2032 * @param cls client sending the message
2033 * @param im message of type `struct ConsumeTicketMessage`
2034 * @return #GNUNET_OK if @a im is well-formed
2037 check_consume_ticket_message(void *cls,
2038 const struct ConsumeTicketMessage *cm)
2042 size = ntohs (cm->header.size);
2043 if (size <= sizeof (struct ConsumeTicketMessage))
2046 return GNUNET_SYSERR;
2052 process_parallel_lookup2 (void *cls, uint32_t rd_count,
2053 const struct GNUNET_GNSRECORD_Data *rd)
2055 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2056 "Parallel lookup finished (count=%u)\n", rd_count);
2057 struct ParallelLookup2 *parallel_lookup = cls;
2058 struct ConsumeTicketHandle *handle = parallel_lookup->handle;
2059 struct ConsumeTicketResultMessage *crm;
2060 struct GNUNET_MQ_Envelope *env;
2061 struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry *attr_le;
2067 GNUNET_CONTAINER_DLL_remove (handle->parallel_lookups_head,
2068 handle->parallel_lookups_tail,
2070 GNUNET_free (parallel_lookup->label);
2071 GNUNET_free (parallel_lookup);
2073 GNUNET_break(0);//TODO
2074 if (rd->record_type == GNUNET_GNSRECORD_TYPE_ID_ATTR)
2076 attr_len = GNUNET_CRYPTO_cpabe_decrypt (rd->data,
2080 attr_le = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry);
2081 attr_le->attribute = attribute_deserialize (data,
2083 GNUNET_CONTAINER_DLL_insert (handle->attrs->list_head,
2084 handle->attrs->list_tail,
2088 if (NULL != handle->parallel_lookups_head)
2089 return; //Wait for more
2090 /* Else we are done */
2092 /* Store ticket in DB */
2093 if (GNUNET_OK != TKT_database->store_ticket (TKT_database->cls,
2097 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2098 "Unable to store ticket after consume\n");
2102 GNUNET_SCHEDULER_cancel (handle->kill_task);
2103 attrs_len = attribute_list_serialize_get_size (handle->attrs);
2104 env = GNUNET_MQ_msg_extra (crm,
2106 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_CONSUME_TICKET_RESULT);
2107 crm->id = htonl (handle->r_id);
2108 crm->attrs_len = htons (attrs_len);
2109 crm->identity = handle->ticket.identity;
2110 data_tmp = (char *) &crm[1];
2111 attribute_list_serialize (handle->attrs,
2113 GNUNET_MQ_send (handle->client->mq, env);
2117 abort_parallel_lookups2 (void *cls)
2119 struct ConsumeTicketHandle *handle = cls;
2120 struct ParallelLookup2 *lu;
2121 struct ParallelLookup2 *tmp;
2122 struct AttributeResultMessage *arm;
2123 struct GNUNET_MQ_Envelope *env;
2125 for (lu = handle->parallel_lookups_head;
2127 GNUNET_GNS_lookup_cancel (lu->lookup_request);
2128 GNUNET_free (lu->label);
2130 GNUNET_CONTAINER_DLL_remove (handle->parallel_lookups_head,
2131 handle->parallel_lookups_tail,
2136 env = GNUNET_MQ_msg (arm,
2137 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_RESULT);
2138 arm->id = htonl (handle->r_id);
2139 arm->attr_len = htons (0);
2140 GNUNET_MQ_send (handle->client->mq, env);
2145 cleanup_consume_ticket_handle (struct ConsumeTicketHandle *handle)
2147 if (NULL != handle->key)
2148 GNUNET_free (handle->key);
2149 GNUNET_free (handle);
2154 process_consume_abe_key (void *cls, uint32_t rd_count,
2155 const struct GNUNET_GNSRECORD_Data *rd)
2157 struct ConsumeTicketHandle *handle = cls;
2158 struct GNUNET_HashCode new_key_hash;
2159 struct GNUNET_CRYPTO_SymmetricSessionKey enc_key;
2160 struct GNUNET_CRYPTO_SymmetricInitializationVector enc_iv;
2161 struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_key;
2162 struct ParallelLookup2 *parallel_lookup;
2168 handle->lookup_request = NULL;
2171 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2172 "Number of keys %d != 1.",
2174 cleanup_consume_ticket_handle (handle);
2175 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
2180 ecdh_key = (struct GNUNET_CRYPTO_EcdhePublicKey *)rd->data;
2182 buf = GNUNET_malloc (rd->data_size - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
2184 //Calculate symmetric key from ecdh parameters
2185 GNUNET_assert (GNUNET_OK ==
2186 GNUNET_CRYPTO_ecdsa_ecdh (&handle->identity,
2189 create_sym_key_from_ecdh (&new_key_hash,
2192 size = GNUNET_CRYPTO_symmetric_decrypt (rd->data + sizeof (struct GNUNET_CRYPTO_EcdhePublicKey),
2193 rd->data_size - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey),
2198 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2199 "Decrypted bytes: %zd Expected bytes: %zd\n",
2200 size, rd->data_size - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
2202 scopes = GNUNET_strdup (buf);
2203 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2204 "Scopes %s\n", scopes);
2205 handle->key = GNUNET_CRYPTO_cpabe_deserialize_key ((void*)(buf + strlen (scopes) + 1),
2206 rd->data_size - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)
2207 - strlen (scopes) - 1);
2209 for (scope = strtok (scopes, ","); NULL != scope; scope = strtok (NULL, ","))
2211 GNUNET_asprintf (&lookup_query,
2214 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2215 "Looking up %s\n", lookup_query);
2216 parallel_lookup = GNUNET_new (struct ParallelLookup2);
2217 parallel_lookup->handle = handle;
2218 parallel_lookup->label = GNUNET_strdup (scope);
2219 parallel_lookup->lookup_request
2220 = GNUNET_GNS_lookup (gns_handle,
2222 &handle->ticket.identity,
2223 GNUNET_GNSRECORD_TYPE_ID_ATTR,
2224 GNUNET_GNS_LO_LOCAL_MASTER,
2225 &process_parallel_lookup2,
2227 GNUNET_CONTAINER_DLL_insert (handle->parallel_lookups_head,
2228 handle->parallel_lookups_tail,
2230 GNUNET_free (lookup_query);
2232 handle->kill_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES,3),
2233 &abort_parallel_lookups2,
2240 * Handler for ticket issue message
2243 * @param client who sent the message
2244 * @param message the message
2247 handle_consume_ticket_message (void *cls,
2248 const struct ConsumeTicketMessage *cm)
2250 struct ConsumeTicketHandle *ch;
2251 struct IdpClient *idp = cls;
2255 ch = GNUNET_new (struct ConsumeTicketHandle);
2256 ch->r_id = ntohl (cm->id);
2258 ch->identity = cm->identity;
2259 ch->attrs = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_AttributeList);
2260 GNUNET_CRYPTO_ecdsa_key_get_public (&ch->identity,
2262 ch->ticket = *((struct GNUNET_IDENTITY_PROVIDER_Ticket2*)&cm[1]);
2263 rnd_label = GNUNET_STRINGS_data_to_string_alloc (&ch->ticket.rnd,
2265 GNUNET_asprintf (&lookup_query,
2268 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2269 "Looking for ABE key under %s\n", lookup_query);
2272 = GNUNET_GNS_lookup (gns_handle,
2274 &ch->ticket.identity,
2275 GNUNET_GNSRECORD_TYPE_ABE_KEY,
2276 GNUNET_GNS_LO_LOCAL_MASTER,
2277 &process_consume_abe_key,
2279 GNUNET_free (rnd_label);
2280 GNUNET_free (lookup_query);
2281 GNUNET_SERVICE_client_continue (idp->client);
2285 attr_store_cont (void *cls,
2289 struct AttributeStoreHandle *as_handle = cls;
2290 struct GNUNET_MQ_Envelope *env;
2291 struct AttributeStoreResponseMessage *acr_msg;
2293 if (GNUNET_SYSERR == success)
2295 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2296 "Failed to store attribute %s\n",
2298 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
2302 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2303 "Sending ATTRIBUTE_STORE_RESPONSE message\n");
2304 env = GNUNET_MQ_msg (acr_msg,
2305 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_STORE_RESPONSE);
2306 acr_msg->id = htonl (as_handle->r_id);
2307 acr_msg->op_result = htonl (GNUNET_OK);
2308 GNUNET_MQ_send (as_handle->client->mq,
2310 cleanup_as_handle (as_handle);
2314 attr_store_task (void *cls)
2316 struct AttributeStoreHandle *as_handle = cls;
2317 struct GNUNET_GNSRECORD_Data rd[1];
2321 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2322 "Storing attribute\n");
2323 buf_size = attribute_serialize_get_size (as_handle->attribute);
2324 buf = GNUNET_malloc (buf_size);
2326 attribute_serialize (as_handle->attribute,
2330 * Encrypt the attribute value and store in namestore
2332 rd[0].data_size = GNUNET_CRYPTO_cpabe_encrypt (buf,
2334 as_handle->attribute->name, //Policy
2336 (void**)&rd[0].data);
2338 rd[0].record_type = GNUNET_GNSRECORD_TYPE_ID_ATTR;
2339 rd[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
2340 rd[0].expiration_time = GNUNET_TIME_UNIT_HOURS.rel_value_us; //TODO sane?
2341 as_handle->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
2342 &as_handle->identity,
2343 as_handle->attribute->name,
2348 GNUNET_free ((void*)rd[0].data);
2354 store_after_abe_bootstrap (void *cls,
2355 struct GNUNET_CRYPTO_AbeMasterKey *abe_key)
2357 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2358 "Finished ABE bootstrap\n");
2359 struct AttributeStoreHandle *ash = cls;
2360 ash->abe_key = abe_key;
2361 GNUNET_SCHEDULER_add_now (&attr_store_task, ash);
2365 * Checks a store message
2367 * @param cls client sending the message
2368 * @param sam message of type `struct AttributeStoreMessage`
2369 * @return #GNUNET_OK if @a im is well-formed
2372 check_attribute_store_message(void *cls,
2373 const struct AttributeStoreMessage *sam)
2377 size = ntohs (sam->header.size);
2378 if (size <= sizeof (struct AttributeStoreMessage))
2381 return GNUNET_SYSERR;
2389 * Handler for store message
2392 * @param client who sent the message
2393 * @param message the message
2396 handle_attribute_store_message (void *cls,
2397 const struct AttributeStoreMessage *sam)
2399 struct AttributeStoreHandle *as_handle;
2400 struct IdpClient *idp = cls;
2402 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2403 "Received ATTRIBUTE_STORE message\n");
2405 data_len = ntohs (sam->attr_len);
2407 as_handle = GNUNET_new (struct AttributeStoreHandle);
2408 as_handle->attribute = attribute_deserialize ((char*)&sam[1],
2411 as_handle->r_id = ntohl (sam->id);
2412 as_handle->identity = sam->identity;
2413 GNUNET_CRYPTO_ecdsa_key_get_public (&sam->identity,
2414 &as_handle->identity_pkey);
2416 GNUNET_SERVICE_client_continue (idp->client);
2417 as_handle->client = idp;
2418 bootstrap_abe (&as_handle->identity, &store_after_abe_bootstrap, as_handle);
2422 cleanup_iter_handle (struct AttributeIterator *ai)
2424 if (NULL != ai->abe_key)
2425 GNUNET_free (ai->abe_key);
2426 GNUNET_CONTAINER_DLL_remove (ai->client->op_head,
2427 ai->client->op_tail,
2433 attr_iter_error (void *cls)
2435 //struct AttributeIterator *ai = cls;
2437 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2438 "Failed to iterate over attributes\n");
2439 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
2443 attr_iter_finished (void *cls)
2445 struct AttributeIterator *ai = cls;
2446 struct GNUNET_MQ_Envelope *env;
2447 struct AttributeResultMessage *arm;
2449 env = GNUNET_MQ_msg (arm,
2450 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_RESULT);
2451 arm->id = htonl (ai->request_id);
2452 arm->attr_len = htons (0);
2453 GNUNET_MQ_send (ai->client->mq, env);
2454 cleanup_iter_handle (ai);
2458 attr_iter_cb (void *cls,
2459 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
2461 unsigned int rd_count,
2462 const struct GNUNET_GNSRECORD_Data *rd)
2464 struct AttributeIterator *ai = cls;
2465 struct AttributeResultMessage *arm;
2466 struct GNUNET_CRYPTO_AbeKey *key;
2467 struct GNUNET_MQ_Envelope *env;
2468 ssize_t msg_extra_len;
2475 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it);
2479 if (GNUNET_GNSRECORD_TYPE_ID_ATTR != rd->record_type) {
2480 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it);
2483 attrs[0] = (char*)label;
2485 key = GNUNET_CRYPTO_cpabe_create_key (ai->abe_key,
2487 msg_extra_len = GNUNET_CRYPTO_cpabe_decrypt (rd->data,
2491 GNUNET_CRYPTO_cpabe_delete_key (key);
2492 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2493 "Found attribute: %s\n", label);
2494 env = GNUNET_MQ_msg_extra (arm,
2496 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_RESULT);
2497 arm->id = htonl (ai->request_id);
2498 arm->attr_len = htons (msg_extra_len);
2499 GNUNET_CRYPTO_ecdsa_key_get_public (zone,
2501 data_tmp = (char *) &arm[1];
2502 GNUNET_memcpy (data_tmp,
2505 GNUNET_MQ_send (ai->client->mq, env);
2506 GNUNET_free (attr_ser);
2511 iterate_after_abe_bootstrap (void *cls,
2512 struct GNUNET_CRYPTO_AbeMasterKey *abe_key)
2514 struct AttributeIterator *ai = cls;
2515 ai->abe_key = abe_key;
2516 ai->ns_it = GNUNET_NAMESTORE_zone_iteration_start (ns_handle,
2522 &attr_iter_finished,
2528 * Handles a #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ITERATION_START message
2530 * @param cls the client sending the message
2531 * @param zis_msg message from the client
2534 handle_iteration_start (void *cls,
2535 const struct AttributeIterationStartMessage *ais_msg)
2537 struct IdpClient *idp = cls;
2538 struct AttributeIterator *ai;
2540 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2541 "Received ATTRIBUTE_ITERATION_START message\n");
2542 ai = GNUNET_new (struct AttributeIterator);
2543 ai->request_id = ntohl (ais_msg->id);
2545 ai->identity = ais_msg->identity;
2547 GNUNET_CONTAINER_DLL_insert (idp->op_head,
2550 bootstrap_abe (&ai->identity, &iterate_after_abe_bootstrap, ai);
2551 GNUNET_SERVICE_client_continue (idp->client);
2556 * Handles a #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ITERATION_STOP message
2558 * @param cls the client sending the message
2559 * @param ais_msg message from the client
2562 handle_iteration_stop (void *cls,
2563 const struct AttributeIterationStopMessage *ais_msg)
2565 struct IdpClient *idp = cls;
2566 struct AttributeIterator *ai;
2569 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2570 "Received `%s' message\n",
2571 "ATTRIBUTE_ITERATION_STOP");
2572 rid = ntohl (ais_msg->id);
2573 for (ai = idp->op_head; NULL != ai; ai = ai->next)
2574 if (ai->request_id == rid)
2579 GNUNET_SERVICE_client_drop (idp->client);
2582 GNUNET_CONTAINER_DLL_remove (idp->op_head,
2586 GNUNET_SERVICE_client_continue (idp->client);
2591 * Handles a #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_NEXT message
2593 * @param cls the client sending the message
2594 * @param message message from the client
2597 handle_iteration_next (void *cls,
2598 const struct AttributeIterationNextMessage *ais_msg)
2600 struct IdpClient *idp = cls;
2601 struct AttributeIterator *ai;
2604 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2605 "Received ATTRIBUTE_ITERATION_NEXT message\n");
2606 rid = ntohl (ais_msg->id);
2607 for (ai = idp->op_head; NULL != ai; ai = ai->next)
2608 if (ai->request_id == rid)
2613 GNUNET_SERVICE_client_drop (idp->client);
2616 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it);
2617 GNUNET_SERVICE_client_continue (idp->client);
2621 * Ticket iteration processor result
2623 enum ZoneIterationResult
2632 * Continue to iterate with next iteration_next call
2634 IT_SUCCESS_MORE_AVAILABLE = 1,
2637 * Iteration complete
2639 IT_SUCCESS_NOT_MORE_RESULTS_AVAILABLE = 2
2644 * Context for ticket iteration
2646 struct TicketIterationProcResult
2649 * The ticket iteration handle
2651 struct TicketIteration *ti;
2654 * Iteration result: iteration done?
2655 * #IT_SUCCESS_MORE_AVAILABLE: if there may be more results overall but
2656 * we got one for now and have sent it to the client
2657 * #IT_SUCCESS_NOT_MORE_RESULTS_AVAILABLE: if there are no further results,
2658 * #IT_START: if we are still trying to find a result.
2660 int res_iteration_finished;
2667 * Process ticket from database
2669 * @param cls struct TicketIterationProcResult
2670 * @param ticket the ticket
2671 * @param attrs the attributes
2674 ticket_iterate_proc (void *cls,
2675 const struct GNUNET_IDENTITY_PROVIDER_Ticket2 *ticket,
2676 const struct GNUNET_IDENTITY_PROVIDER_AttributeList *attrs)
2678 struct TicketIterationProcResult *proc = cls;
2682 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2683 "Iteration done\n");
2684 proc->res_iteration_finished = IT_SUCCESS_NOT_MORE_RESULTS_AVAILABLE;
2687 if ((NULL == ticket) || (NULL == attrs))
2690 proc->res_iteration_finished = IT_START;
2694 proc->res_iteration_finished = IT_SUCCESS_MORE_AVAILABLE;
2695 send_ticket_result (proc->ti->client,
2703 * Perform ticket iteration step
2705 * @param ti ticket iterator to process
2708 run_ticket_iteration_round (struct TicketIteration *ti)
2710 struct TicketIterationProcResult proc;
2711 struct GNUNET_MQ_Envelope *env;
2712 struct TicketResultMessage *trm;
2715 memset (&proc, 0, sizeof (proc));
2717 proc.res_iteration_finished = IT_START;
2718 while (IT_START == proc.res_iteration_finished)
2720 if (GNUNET_SYSERR ==
2721 (ret = TKT_database->iterate_tickets (TKT_database->cls,
2725 &ticket_iterate_proc,
2731 if (GNUNET_NO == ret)
2732 proc.res_iteration_finished = IT_SUCCESS_NOT_MORE_RESULTS_AVAILABLE;
2735 if (IT_SUCCESS_MORE_AVAILABLE == proc.res_iteration_finished)
2737 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2738 "More results available\n");
2739 return; /* more later */
2741 /* send empty response to indicate end of list */
2742 env = GNUNET_MQ_msg (trm,
2743 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_RESULT);
2744 trm->id = htonl (ti->r_id);
2745 GNUNET_MQ_send (ti->client->mq,
2747 GNUNET_CONTAINER_DLL_remove (ti->client->ticket_iter_head,
2748 ti->client->ticket_iter_tail,
2754 * Handles a #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_START message
2756 * @param cls the client sending the message
2757 * @param tis_msg message from the client
2760 handle_ticket_iteration_start (void *cls,
2761 const struct TicketIterationStartMessage *tis_msg)
2763 struct IdpClient *client = cls;
2764 struct TicketIteration *ti;
2766 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2767 "Received TICKET_ITERATION_START message\n");
2768 ti = GNUNET_new (struct TicketIteration);
2769 ti->r_id = ntohl (tis_msg->id);
2771 ti->client = client;
2772 ti->identity = tis_msg->identity;
2773 ti->is_audience = ntohl (tis_msg->is_audience);
2775 GNUNET_CONTAINER_DLL_insert (client->ticket_iter_head,
2776 client->ticket_iter_tail,
2778 run_ticket_iteration_round (ti);
2779 GNUNET_SERVICE_client_continue (client->client);
2784 * Handles a #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_STOP message
2786 * @param cls the client sending the message
2787 * @param tis_msg message from the client
2790 handle_ticket_iteration_stop (void *cls,
2791 const struct TicketIterationStopMessage *tis_msg)
2793 struct IdpClient *client = cls;
2794 struct TicketIteration *ti;
2797 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2798 "Received `%s' message\n",
2799 "TICKET_ITERATION_STOP");
2800 rid = ntohl (tis_msg->id);
2801 for (ti = client->ticket_iter_head; NULL != ti; ti = ti->next)
2802 if (ti->r_id == rid)
2807 GNUNET_SERVICE_client_drop (client->client);
2810 GNUNET_CONTAINER_DLL_remove (client->ticket_iter_head,
2811 client->ticket_iter_tail,
2814 GNUNET_SERVICE_client_continue (client->client);
2819 * Handles a #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_NEXT message
2821 * @param cls the client sending the message
2822 * @param message message from the client
2825 handle_ticket_iteration_next (void *cls,
2826 const struct TicketIterationNextMessage *tis_msg)
2828 struct IdpClient *client = cls;
2829 struct TicketIteration *ti;
2832 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2833 "Received TICKET_ITERATION_NEXT message\n");
2834 rid = ntohl (tis_msg->id);
2835 for (ti = client->ticket_iter_head; NULL != ti; ti = ti->next)
2836 if (ti->r_id == rid)
2841 GNUNET_SERVICE_client_drop (client->client);
2844 run_ticket_iteration_round (ti);
2845 GNUNET_SERVICE_client_continue (client->client);
2852 * Main function that will be run
2854 * @param cls closure
2855 * @param args remaining command-line arguments
2856 * @param cfgfile name of the configuration file used (for saving, can be NULL)
2857 * @param c configuration
2861 const struct GNUNET_CONFIGURATION_Handle *c,
2862 struct GNUNET_SERVICE_Handle *server)
2867 stats = GNUNET_STATISTICS_create ("identity-provider", cfg);
2869 //Connect to identity and namestore services
2870 ns_handle = GNUNET_NAMESTORE_connect (cfg);
2871 if (NULL == ns_handle)
2873 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "error connecting to namestore");
2876 gns_handle = GNUNET_GNS_connect (cfg);
2877 if (NULL == gns_handle)
2879 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "error connecting to gns");
2881 credential_handle = GNUNET_CREDENTIAL_connect (cfg);
2882 if (NULL == credential_handle)
2884 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "error connecting to credential");
2886 identity_handle = GNUNET_IDENTITY_connect (cfg,
2890 /* Loading DB plugin */
2892 GNUNET_CONFIGURATION_get_value_string (cfg,
2893 "identity-provider",
2896 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2897 "No database backend configured\n");
2898 GNUNET_asprintf (&db_lib_name,
2899 "libgnunet_plugin_identity_provider_%s",
2901 TKT_database = GNUNET_PLUGIN_load (db_lib_name,
2903 GNUNET_free (database);
2904 if (NULL == TKT_database)
2906 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2907 "Could not load database backend `%s'\n",
2909 GNUNET_SCHEDULER_shutdown ();
2914 GNUNET_CONFIGURATION_get_value_time (cfg,
2915 "identity-provider",
2916 "TOKEN_EXPIRATION_INTERVAL",
2917 &token_expiration_interval))
2919 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2920 "Time window for zone iteration: %s\n",
2921 GNUNET_STRINGS_relative_time_to_string (token_expiration_interval,
2924 token_expiration_interval = DEFAULT_TOKEN_EXPIRATION_INTERVAL;
2927 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL);
2931 * Called whenever a client is disconnected.
2933 * @param cls closure
2934 * @param client identification of the client
2935 * @param app_ctx @a client
2938 client_disconnect_cb (void *cls,
2939 struct GNUNET_SERVICE_Client *client,
2942 struct IdpClient *idp = app_ctx;
2943 struct AttributeIterator *ai;
2945 //TODO other operations
2947 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2948 "Client %p disconnected\n",
2951 while (NULL != (ai = idp->op_head))
2953 GNUNET_CONTAINER_DLL_remove (idp->op_head,
2963 * Add a client to our list of active clients.
2966 * @param client client to add
2967 * @param mq message queue for @a client
2968 * @return internal namestore client structure for this client
2971 client_connect_cb (void *cls,
2972 struct GNUNET_SERVICE_Client *client,
2973 struct GNUNET_MQ_Handle *mq)
2975 struct IdpClient *idp;
2976 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2977 "Client %p connected\n",
2979 idp = GNUNET_new (struct IdpClient);
2980 idp->client = client;
2988 * Define "main" method using service macro.
2991 ("identity-provider",
2992 GNUNET_SERVICE_OPTION_NONE,
2995 &client_disconnect_cb,
2997 GNUNET_MQ_hd_var_size (issue_message,
2998 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ISSUE,
2999 struct IssueMessage,
3001 GNUNET_MQ_hd_var_size (exchange_message,
3002 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_EXCHANGE,
3003 struct ExchangeMessage,
3005 GNUNET_MQ_hd_var_size (attribute_store_message,
3006 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_STORE,
3007 struct AttributeStoreMessage,
3009 GNUNET_MQ_hd_fixed_size (iteration_start,
3010 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_START,
3011 struct AttributeIterationStartMessage,
3013 GNUNET_MQ_hd_fixed_size (iteration_next,
3014 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_NEXT,
3015 struct AttributeIterationNextMessage,
3017 GNUNET_MQ_hd_fixed_size (iteration_stop,
3018 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_STOP,
3019 struct AttributeIterationStopMessage,
3021 GNUNET_MQ_hd_var_size (ticket_issue_message,
3022 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ISSUE,
3023 struct TicketIssueMessage,
3025 GNUNET_MQ_hd_var_size (consume_ticket_message,
3026 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_CONSUME_TICKET,
3027 struct ConsumeTicketMessage,
3029 GNUNET_MQ_hd_fixed_size (ticket_iteration_start,
3030 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_START,
3031 struct TicketIterationStartMessage,
3033 GNUNET_MQ_hd_fixed_size (ticket_iteration_next,
3034 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_NEXT,
3035 struct TicketIterationNextMessage,
3037 GNUNET_MQ_hd_fixed_size (ticket_iteration_stop,
3038 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_STOP,
3039 struct TicketIterationStopMessage,
3042 GNUNET_MQ_handler_end());
3043 /* end of gnunet-service-identity-provider.c */