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_signatures.h"
37 #include "identity_provider.h"
38 #include "identity_token.h"
39 #include "identity_attribute.h"
48 * Normal operation state
50 #define STATE_POST_INIT 1
53 * Minimum interval between updates
55 #define MIN_WAIT_TIME GNUNET_TIME_UNIT_MINUTES
58 * Standard token expiration time
60 #define DEFAULT_TOKEN_EXPIRATION_INTERVAL GNUNET_TIME_UNIT_HOURS
65 static struct GNUNET_IDENTITY_Handle *identity_handle;
68 * Token expiration interval
70 static struct GNUNET_TIME_Relative token_expiration_interval;
75 static struct GNUNET_NAMESTORE_Handle *ns_handle;
80 static struct GNUNET_GNS_Handle *gns_handle;
85 static struct GNUNET_CREDENTIAL_Handle *credential_handle;
90 static struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
95 static struct GNUNET_NAMESTORE_ZoneIterator *ns_it;
100 static struct GNUNET_SCHEDULER_Task *timeout_task;
105 static struct GNUNET_SCHEDULER_Task *update_task;
109 * Currently processed token
111 static struct IdentityToken *token;
114 * Label for currently processed token
119 * Scopes for processed token
124 * Handle to the statistics service.
126 static struct GNUNET_STATISTICS_Handle *stats;
131 static const struct GNUNET_CONFIGURATION_Handle *cfg;
139 * Callback after an ABE bootstrap
142 * @param abe_key the ABE key that exists or was created
145 (*AbeBootstrapResult) (void *cls,
146 struct GNUNET_CRYPTO_AbeMasterKey *abe_key);
149 struct AbeBootstrapHandle
152 * Function to call when finished
154 AbeBootstrapResult proc;
162 * Key of the zone we are iterating over.
164 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
167 * Namestore Queue Entry
169 struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
172 * The issuer egos ABE master key
174 struct GNUNET_CRYPTO_AbeMasterKey *abe_key;
178 * An attribute iteration operation.
180 struct AttributeIterator
183 * Next element in the DLL
185 struct AttributeIterator *next;
188 * Previous element in the DLL
190 struct AttributeIterator *prev;
193 * IDP client which intiated this zone iteration
195 struct IdpClient *client;
198 * Key of the zone we are iterating over.
200 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
203 * The issuer egos ABE master key
205 struct GNUNET_CRYPTO_AbeMasterKey *abe_key;
210 struct GNUNET_NAMESTORE_ZoneIterator *ns_it;
213 * The operation id fot the zone iteration in the response for the client
230 struct GNUNET_SERVICE_Client *client;
233 * Message queue for transmission to @e client
235 struct GNUNET_MQ_Handle *mq;
239 * Attribute iteration operations in
240 * progress initiated by this client
242 struct AttributeIterator *op_head;
246 * Attribute iteration operations
247 * in progress initiated by this client
249 struct AttributeIterator *op_tail;
254 struct AttributeStoreHandle
260 struct IdpClient *client;
265 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
270 struct GNUNET_CRYPTO_EcdsaPublicKey identity_pkey;
273 * The issuer egos ABE master key
275 struct GNUNET_CRYPTO_AbeMasterKey *abe_key;
280 struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
283 * The attribute to store
285 struct GNUNET_IDENTITY_PROVIDER_Attribute *attribute;
295 struct VerifiedAttributeEntry
300 struct VerifiedAttributeEntry *prev;
305 struct VerifiedAttributeEntry *next;
313 struct ParallelLookups;
315 struct ExchangeHandle
321 struct IdpClient *client;
326 struct TokenTicket *ticket;
331 struct IdentityToken *token;
336 struct GNUNET_GNS_LookupRequest *lookup_request;
341 struct GNUNET_CRYPTO_EcdsaPrivateKey aud_privkey;
344 * ParallelLookups DLL
346 struct ParallelLookup *parallel_lookups_head;
347 struct ParallelLookup *parallel_lookups_tail;
349 struct GNUNET_SCHEDULER_Task *kill_task;
350 struct GNUNET_CRYPTO_AbeKey *key;
363 struct ParallelLookup
365 struct ParallelLookup *next;
367 struct ParallelLookup *prev;
369 struct GNUNET_GNS_LookupRequest *lookup_request;
371 struct ExchangeHandle *handle;
382 struct IdpClient *client;
387 struct GNUNET_CRYPTO_EcdsaPrivateKey iss_key;
392 struct GNUNET_CRYPTO_EcdsaPublicKey iss_pkey;
397 struct GNUNET_CRYPTO_EcdsaPublicKey aud_key;
400 * The issuer egos ABE master key
402 struct GNUNET_CRYPTO_AbeMasterKey *abe_key;
407 struct GNUNET_TIME_Absolute expiration;
417 struct VerifiedAttributeEntry *v_attr_head;
422 struct VerifiedAttributeEntry *v_attr_tail;
432 struct GNUNET_NAMESTORE_ZoneIterator *ns_it;
437 struct GNUNET_CREDENTIAL_Request *credential_request;
442 struct GNUNET_CONTAINER_MultiHashMap *attr_map;
447 struct IdentityToken *token;
452 struct TokenTicket *ticket;
457 struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
460 * The label the token is stored under
471 * DLL for ego handles to egos containing the ID_ATTRS in a map in json_t format
479 struct EgoEntry *next;
484 struct EgoEntry *prev;
489 struct GNUNET_IDENTITY_Ego *ego;
492 * Attribute map. Contains the attributes as json_t
494 struct GNUNET_CONTAINER_MultiHashMap *attr_map;
504 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
508 GNUNET_STATISTICS_destroy (stats, GNUNET_NO);
512 if (NULL != timeout_task)
513 GNUNET_SCHEDULER_cancel (timeout_task);
514 if (NULL != update_task)
515 GNUNET_SCHEDULER_cancel (update_task);
516 if (NULL != identity_handle)
517 GNUNET_IDENTITY_disconnect (identity_handle);
518 if (NULL != gns_handle)
519 GNUNET_GNS_disconnect (gns_handle);
520 if (NULL != credential_handle)
521 GNUNET_CREDENTIAL_disconnect (credential_handle);
523 GNUNET_NAMESTORE_zone_iteration_stop (ns_it);
525 GNUNET_NAMESTORE_cancel (ns_qe);
526 if (NULL != ns_handle)
527 GNUNET_NAMESTORE_disconnect (ns_handle);
539 * @param tc task context
542 do_shutdown (void *cls)
544 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
545 "Shutting down...\n");
550 static struct GNUNET_MQ_Envelope*
551 create_exchange_result_message (const char* token,
553 uint64_t ticket_nonce,
556 struct GNUNET_MQ_Envelope *env;
557 struct ExchangeResultMessage *erm;
558 uint16_t token_len = strlen (token) + 1;
560 env = GNUNET_MQ_msg_extra (erm,
562 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_EXCHANGE_RESULT);
563 erm->ticket_nonce = htonl (ticket_nonce);
565 GNUNET_memcpy (&erm[1], token, token_len);
570 static struct GNUNET_MQ_Envelope*
571 create_issue_result_message (const char* label,
576 struct GNUNET_MQ_Envelope *env;
577 struct IssueResultMessage *irm;
581 GNUNET_asprintf (&tmp_str, "%s,%s,%s", label, ticket, token);
582 len = strlen (tmp_str) + 1;
583 env = GNUNET_MQ_msg_extra (irm,
585 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ISSUE_RESULT);
587 GNUNET_memcpy (&irm[1], tmp_str, strlen (tmp_str) + 1);
588 GNUNET_free (tmp_str);
593 cleanup_issue_handle (struct IssueHandle *handle)
595 if (NULL != handle->attr_map)
596 GNUNET_CONTAINER_multihashmap_destroy (handle->attr_map);
597 if (NULL != handle->scopes)
598 GNUNET_free (handle->scopes);
599 if (NULL != handle->token)
600 token_destroy (handle->token);
601 if (NULL != handle->ticket)
602 ticket_destroy (handle->ticket);
603 if (NULL != handle->label)
604 GNUNET_free (handle->label);
605 if (NULL != handle->ns_it)
606 GNUNET_NAMESTORE_zone_iteration_stop (handle->ns_it);
607 if (NULL != handle->credential_request)
608 GNUNET_CREDENTIAL_request_cancel (handle->credential_request);
609 GNUNET_free (handle);
613 store_record_issue_cont (void *cls,
617 struct IssueHandle *handle = cls;
618 struct GNUNET_MQ_Envelope *env;
622 handle->ns_qe = NULL;
623 if (GNUNET_SYSERR == success)
625 cleanup_issue_handle (handle);
626 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n",
628 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
631 if (GNUNET_OK != ticket_serialize (handle->ticket,
635 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n",
636 "Error serializing ticket\n");
637 cleanup_issue_handle (handle);
638 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
641 if (GNUNET_OK != token_to_string (handle->token,
645 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n",
646 "Error serializing token\n");
647 GNUNET_free (ticket_str);
648 cleanup_issue_handle (handle);
649 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
652 env = create_issue_result_message (handle->label,
656 GNUNET_MQ_send (handle->client->mq,
658 cleanup_issue_handle (handle);
659 GNUNET_free (ticket_str);
660 GNUNET_free (token_str);
664 create_sym_key_from_ecdh(const struct GNUNET_HashCode *new_key_hash,
665 struct GNUNET_CRYPTO_SymmetricSessionKey *skey,
666 struct GNUNET_CRYPTO_SymmetricInitializationVector *iv)
668 struct GNUNET_CRYPTO_HashAsciiEncoded new_key_hash_str;
670 GNUNET_CRYPTO_hash_to_enc (new_key_hash,
672 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating symmetric rsa key from %s\n", (char*)&new_key_hash_str);
673 static const char ctx_key[] = "gnuid-aes-ctx-key";
674 GNUNET_CRYPTO_kdf (skey, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
675 new_key_hash, sizeof (struct GNUNET_HashCode),
676 ctx_key, strlen (ctx_key),
678 static const char ctx_iv[] = "gnuid-aes-ctx-iv";
679 GNUNET_CRYPTO_kdf (iv, sizeof (struct GNUNET_CRYPTO_SymmetricInitializationVector),
680 new_key_hash, sizeof (struct GNUNET_HashCode),
681 ctx_iv, strlen (ctx_iv),
687 serialize_abe_keyinfo (const struct IssueHandle *handle,
688 const struct GNUNET_CRYPTO_AbeKey *rp_key,
689 struct GNUNET_CRYPTO_EcdhePrivateKey **ecdh_privkey,
693 char *serialized_key;
695 struct GNUNET_CRYPTO_EcdhePublicKey ecdh_pubkey;
698 struct GNUNET_CRYPTO_SymmetricSessionKey skey;
699 struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
700 struct GNUNET_HashCode new_key_hash;
703 size = GNUNET_CRYPTO_cpabe_serialize_key (rp_key,
704 (void**)&serialized_key);
705 buf = GNUNET_malloc (strlen (handle->scopes) + 1 + size);
708 strlen (handle->scopes) + 1);
709 GNUNET_memcpy (buf + strlen (handle->scopes) + 1,
712 // ECDH keypair E = eG
713 *ecdh_privkey = GNUNET_CRYPTO_ecdhe_key_create();
714 GNUNET_CRYPTO_ecdhe_key_get_public (*ecdh_privkey,
716 enc_keyinfo = GNUNET_malloc (size + strlen (handle->scopes) + 1);
717 // Derived key K = H(eB)
718 GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecdh_ecdsa (*ecdh_privkey,
721 create_sym_key_from_ecdh(&new_key_hash, &skey, &iv);
722 enc_size = GNUNET_CRYPTO_symmetric_encrypt (buf,
723 size + strlen (handle->scopes) + 1,
726 *result = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)+
728 GNUNET_memcpy (*result,
730 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
731 GNUNET_memcpy (*result + sizeof (struct GNUNET_CRYPTO_EcdhePublicKey),
734 GNUNET_free (enc_keyinfo);
735 return sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)+enc_size;
739 cleanup_exchange_handle (struct ExchangeHandle *handle)
741 if (NULL != handle->ticket)
742 ticket_destroy (handle->ticket);
743 if (NULL != handle->token)
744 token_destroy (handle->token);
745 GNUNET_free (handle);
750 * Build a token and store it
752 * @param cls the IssueHandle
755 sign_and_return_token (void *cls)
757 struct ExchangeHandle *handle = cls;
758 struct GNUNET_MQ_Envelope *env;
763 time = GNUNET_TIME_absolute_get().abs_value_us;
764 exp_time = time + token_expiration_interval.rel_value_us;
766 token_add_attr_int (handle->token, "nbf", time);
767 token_add_attr_int (handle->token, "iat", time);
768 token_add_attr_int (handle->token, "exp", exp_time);
771 GNUNET_assert (GNUNET_OK == token_to_string (handle->token,
772 &handle->aud_privkey,
775 env = create_exchange_result_message (token_str,
777 handle->ticket->payload->nonce,
779 GNUNET_MQ_send (handle->client->mq,
781 cleanup_exchange_handle (handle);
782 GNUNET_free (token_str);
787 * Build an ABE key and store it
789 * @param cls the IssueHandle
792 issue_ticket (void *cls)
794 struct GNUNET_CRYPTO_EcdsaPublicKey pub_key;
795 struct GNUNET_CRYPTO_EcdhePrivateKey *ecdhe_privkey;
796 struct IssueHandle *handle = cls;
797 struct GNUNET_GNSRECORD_Data code_record[1];
798 struct GNUNET_CRYPTO_AbeKey *rp_key;
800 char *code_record_data;
808 size_t code_record_len;
812 GNUNET_asprintf (&nonce_str, "%lu", handle->nonce);
813 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Request nonce: %s\n", nonce_str);
815 GNUNET_CRYPTO_ecdsa_key_get_public (&handle->iss_key,
817 handle->ticket = ticket_create (handle->nonce,
822 time = GNUNET_TIME_absolute_get().abs_value_us;
823 exp_time = time + token_expiration_interval.rel_value_us;
825 token_add_attr_int (handle->token, "nbf", time);
826 token_add_attr_int (handle->token, "iat", time);
827 token_add_attr_int (handle->token, "exp", exp_time);
828 token_add_attr (handle->token, "nonce", nonce_str);
830 //Create new ABE key for RP
831 attrs_len = (GNUNET_CONTAINER_multihashmap_size (handle->attr_map) + 1) * sizeof (char*);
832 attrs = GNUNET_malloc (attrs_len);
834 scopes_tmp = GNUNET_strdup (handle->scopes);
835 for (scope = strtok (scopes_tmp, ","); NULL != scope; scope = strtok (NULL, ",")) {
839 rp_key = GNUNET_CRYPTO_cpabe_create_key (handle->abe_key,
841 code_record_len = serialize_abe_keyinfo (handle,
845 code_record[0].data = code_record_data;
846 code_record[0].data_size = code_record_len;
847 code_record[0].expiration_time = exp_time;
848 code_record[0].record_type = GNUNET_GNSRECORD_TYPE_ABE_KEY;
849 code_record[0].flags = GNUNET_GNSRECORD_RF_NONE;
853 handle->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
858 &store_record_issue_cont,
860 GNUNET_free (ecdhe_privkey);
861 GNUNET_free (nonce_str);
862 GNUNET_free (code_record_data);
867 * @param cred the credential
868 * @return the resulting json, NULL if failed
871 credential_to_json (struct GNUNET_CREDENTIAL_Credential *cred)
876 char attribute[cred->issuer_attribute_len + 1];
879 issuer = GNUNET_CRYPTO_ecdsa_public_key_to_string (&cred->issuer_key);
882 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
883 "Issuer in credential malformed\n");
886 subject = GNUNET_CRYPTO_ecdsa_public_key_to_string (&cred->subject_key);
889 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
890 "Subject in credential malformed\n");
891 GNUNET_free (issuer);
894 GNUNET_STRINGS_base64_encode ((char*)&cred->signature,
895 sizeof (struct GNUNET_CRYPTO_EcdsaSignature),
898 cred->issuer_attribute,
899 cred->issuer_attribute_len);
900 attribute[cred->issuer_attribute_len] = '\0';
901 cred_obj = json_object ();
902 json_object_set_new (cred_obj, "issuer", json_string (issuer));
903 json_object_set_new (cred_obj, "subject", json_string (subject));
904 json_object_set_new (cred_obj, "attribute", json_string (attribute));
905 json_object_set_new (cred_obj, "signature", json_string (signature));
906 json_object_set_new (cred_obj, "expiration", json_integer (cred->expiration.abs_value_us));
907 GNUNET_free (issuer);
908 GNUNET_free (subject);
909 GNUNET_free (signature);
915 handle_vattr_collection (void* cls,
916 unsigned int d_count,
917 struct GNUNET_CREDENTIAL_Delegation *dc,
918 unsigned int c_count,
919 struct GNUNET_CREDENTIAL_Credential *cred)
921 struct IssueHandle *handle = cls;
922 struct VerifiedAttributeEntry *vattr;
926 handle->credential_request = NULL;
930 GNUNET_SCHEDULER_add_now (&issue_ticket, handle);
933 cred_array = json_array();
934 for (i=0;i<c_count;i++)
936 cred_json = credential_to_json (cred);
937 if (NULL == cred_json)
939 json_array_append (cred_array, cred_json);
940 token_add_attr_json (handle->token,
941 handle->v_attr_head->name,
944 json_decref (cred_array);
945 vattr = handle->v_attr_head;
947 GNUNET_CONTAINER_DLL_remove (handle->v_attr_head,
950 GNUNET_free (vattr->name);
953 if (NULL == handle->v_attr_head)
955 GNUNET_SCHEDULER_add_now (&issue_ticket, handle);
958 handle->credential_request = GNUNET_CREDENTIAL_collect (credential_handle,
960 handle->v_attr_head->name,
962 &handle_vattr_collection,
969 attr_collect_error (void *cls)
971 struct IssueHandle *handle = cls;
973 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Adding attribute Error!\n");
974 handle->ns_it = NULL;
975 GNUNET_SCHEDULER_add_now (&issue_ticket, handle);
980 attr_collect_finished (void *cls)
982 struct IssueHandle *handle = cls;
984 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding attribute END: \n");
985 handle->ns_it = NULL;
987 if (NULL == handle->v_attr_head)
989 GNUNET_SCHEDULER_add_now (&issue_ticket, handle);
992 handle->credential_request = GNUNET_CREDENTIAL_collect (credential_handle,
994 handle->v_attr_head->name,
996 &handle_vattr_collection,
1000 * Collect attributes for token
1003 attr_collect (void *cls,
1004 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
1006 unsigned int rd_count,
1007 const struct GNUNET_GNSRECORD_Data *rd)
1009 struct IssueHandle *handle = cls;
1012 struct GNUNET_HashCode key;
1014 GNUNET_CRYPTO_hash (label,
1018 if (0 == rd_count ||
1019 ( (NULL != handle->attr_map) &&
1020 (GNUNET_YES != GNUNET_CONTAINER_multihashmap_contains (handle->attr_map,
1025 GNUNET_NAMESTORE_zone_iterator_next (handle->ns_it);
1029 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding attribute: %s\n", label);
1033 if (rd->record_type == GNUNET_GNSRECORD_TYPE_ID_ATTR)
1035 data = GNUNET_GNSRECORD_value_to_string (rd->record_type,
1038 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding value: %s\n", data);
1039 token_add_attr (handle->token,
1044 GNUNET_NAMESTORE_zone_iterator_next (handle->ns_it);
1049 for (; i < rd_count; i++)
1051 if (rd->record_type == GNUNET_GNSRECORD_TYPE_ID_ATTR)
1053 data = GNUNET_GNSRECORD_value_to_string (rd[i].record_type,
1056 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding value: %s\n", data);
1057 token_add_attr (handle->token, label, data);
1062 GNUNET_NAMESTORE_zone_iterator_next (handle->ns_it);
1066 process_parallel_lookup (void *cls, uint32_t rd_count,
1067 const struct GNUNET_GNSRECORD_Data *rd)
1069 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
1070 "Parallel lookup finished (count=%u)\n", rd_count);
1071 struct ParallelLookup *parallel_lookup = cls;
1072 struct ExchangeHandle *handle = parallel_lookup->handle;
1076 GNUNET_CONTAINER_DLL_remove (handle->parallel_lookups_head,
1077 handle->parallel_lookups_tail,
1079 GNUNET_free (parallel_lookup);
1082 if (rd->record_type == GNUNET_GNSRECORD_TYPE_ID_ATTR)
1084 GNUNET_CRYPTO_cpabe_decrypt (rd->data,
1088 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, "Adding value: %s\n", data);
1089 token_add_attr (handle->token,
1090 parallel_lookup->label,
1096 for (; i < rd_count; i++)
1098 if (rd[i].record_type == GNUNET_GNSRECORD_TYPE_ID_ATTR)
1100 data = GNUNET_GNSRECORD_value_to_string (rd[i].record_type,
1103 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, "Adding value: %s\n", data);
1104 token_add_attr (handle->token, parallel_lookup->label, data);
1109 if (NULL != handle->parallel_lookups_head)
1110 return; //Wait for more
1112 GNUNET_SCHEDULER_cancel (handle->kill_task);
1113 GNUNET_SCHEDULER_add_now (&sign_and_return_token, handle);
1117 abort_parallel_lookups (void *cls)
1119 struct ExchangeHandle *handle = cls;
1120 struct ParallelLookup *lu;
1121 struct ParallelLookup *tmp;
1123 for (lu = handle->parallel_lookups_head;
1125 GNUNET_GNS_lookup_cancel (lu->lookup_request);
1126 GNUNET_free (lu->label);
1128 GNUNET_CONTAINER_DLL_remove (handle->parallel_lookups_head,
1129 handle->parallel_lookups_tail,
1134 GNUNET_SCHEDULER_add_now (&sign_and_return_token, handle);
1139 process_lookup_result (void *cls, uint32_t rd_count,
1140 const struct GNUNET_GNSRECORD_Data *rd)
1142 struct ExchangeHandle *handle = cls;
1143 struct GNUNET_HashCode new_key_hash;
1144 struct GNUNET_CRYPTO_SymmetricSessionKey enc_key;
1145 struct GNUNET_CRYPTO_SymmetricInitializationVector enc_iv;
1146 struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_key;
1147 struct ParallelLookup *parallel_lookup;
1153 handle->lookup_request = NULL;
1156 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1157 "Number of keys %d != 1.",
1159 cleanup_exchange_handle (handle);
1160 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1165 ecdh_key = (struct GNUNET_CRYPTO_EcdhePublicKey *)rd->data;
1167 buf = GNUNET_malloc (rd->data_size - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
1169 //Calculate symmetric key from ecdh parameters
1170 GNUNET_assert (GNUNET_OK ==
1171 GNUNET_CRYPTO_ecdsa_ecdh (&handle->aud_privkey,
1174 create_sym_key_from_ecdh (&new_key_hash,
1177 size = GNUNET_CRYPTO_symmetric_decrypt (rd->data + sizeof (struct GNUNET_CRYPTO_EcdhePublicKey),
1178 rd->data_size - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey),
1183 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1184 "Decrypted bytes: %zd Expected bytes: %zd\n",
1185 size, rd->data_size - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
1187 scopes = GNUNET_strdup (buf);
1188 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
1189 "Scopes %s\n", scopes);
1190 handle->key = GNUNET_CRYPTO_cpabe_deserialize_key ((void*)(buf + strlen (scopes) + 1),
1191 rd->data_size - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)
1192 - strlen (scopes) - 1);
1194 for (scope = strtok (scopes, ","); NULL != scope; scope = strtok (NULL, ","))
1196 GNUNET_asprintf (&lookup_query,
1199 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
1200 "Looking up %s\n", lookup_query);
1201 parallel_lookup = GNUNET_new (struct ParallelLookup);
1202 parallel_lookup->handle = handle;
1203 parallel_lookup->label = GNUNET_strdup (scope);
1204 parallel_lookup->lookup_request
1205 = GNUNET_GNS_lookup (gns_handle,
1207 &handle->ticket->payload->identity_key,
1208 GNUNET_GNSRECORD_TYPE_ID_ATTR,
1209 GNUNET_GNS_LO_LOCAL_MASTER,
1210 &process_parallel_lookup,
1212 GNUNET_CONTAINER_DLL_insert (handle->parallel_lookups_head,
1213 handle->parallel_lookups_tail,
1216 handle->kill_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES,3),
1217 &abort_parallel_lookups,
1222 * Checks a exchange message
1224 * @param cls client sending the message
1225 * @param xm message of type `struct ExchangeMessage`
1226 * @return #GNUNET_OK if @a xm is well-formed
1229 check_exchange_message (void *cls,
1230 const struct ExchangeMessage *xm)
1234 size = ntohs (xm->header.size);
1235 if (size <= sizeof (struct ExchangeMessage))
1238 return GNUNET_SYSERR;
1245 * Handler for exchange message
1248 * @param client who sent the message
1249 * @param message the message
1252 handle_exchange_message (void *cls,
1253 const struct ExchangeMessage *xm)
1255 struct ExchangeHandle *xchange_handle;
1256 struct IdpClient *idp = cls;
1260 ticket = (const char *) &xm[1];
1261 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1262 "Received EXCHANGE of `%s' from client\n",
1264 xchange_handle = GNUNET_malloc (sizeof (struct ExchangeHandle));
1265 xchange_handle->aud_privkey = xm->aud_privkey;
1266 xchange_handle->r_id = xm->id;
1267 if (GNUNET_SYSERR == ticket_parse (ticket,
1268 &xchange_handle->aud_privkey,
1269 &xchange_handle->ticket))
1271 GNUNET_free (xchange_handle);
1272 GNUNET_SERVICE_client_drop (idp->client);
1275 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Looking for ABE key under %s\n",
1276 xchange_handle->ticket->payload->label);
1277 GNUNET_asprintf (&lookup_query,
1279 xchange_handle->ticket->payload->label);
1280 GNUNET_SERVICE_client_continue (idp->client);
1281 xchange_handle->client = idp;
1282 xchange_handle->token = token_create (&xchange_handle->ticket->payload->identity_key,
1283 &xchange_handle->ticket->payload->identity_key);
1284 xchange_handle->lookup_request
1285 = GNUNET_GNS_lookup (gns_handle,
1287 &xchange_handle->ticket->payload->identity_key,
1288 GNUNET_GNSRECORD_TYPE_ABE_KEY,
1289 GNUNET_GNS_LO_LOCAL_MASTER,
1290 &process_lookup_result,
1292 GNUNET_free (lookup_query);
1297 * Checks an issue message
1299 * @param cls client sending the message
1300 * @param im message of type `struct IssueMessage`
1301 * @return #GNUNET_OK if @a im is well-formed
1304 check_issue_message(void *cls,
1305 const struct IssueMessage *im)
1309 size = ntohs (im->header.size);
1310 if (size <= sizeof (struct IssueMessage))
1313 return GNUNET_SYSERR;
1315 scopes = (char *) &im[1];
1316 if ('\0' != scopes[size - sizeof (struct IssueMessage) - 1])
1318 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1319 "Malformed scopes received!\n");
1321 return GNUNET_SYSERR;
1327 attr_collect_task (void *cls)
1329 struct IssueHandle *issue_handle = cls;
1331 issue_handle->ns_it = GNUNET_NAMESTORE_zone_iteration_start (ns_handle,
1332 &issue_handle->iss_key,
1333 &attr_collect_error,
1337 &attr_collect_finished,
1344 abe_key_lookup_error (void *cls)
1346 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1347 "Error looking for ABE master!\n");
1348 GNUNET_SCHEDULER_add_now (&do_shutdown, cls);
1352 abe_key_lookup_result (void *cls,
1353 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
1355 unsigned int rd_count,
1356 const struct GNUNET_GNSRECORD_Data *rd)
1358 struct IssueHandle *handle = cls;
1361 for (i=0;i<rd_count;i++) {
1362 if (GNUNET_GNSRECORD_TYPE_ABE_MASTER != rd[i].record_type)
1364 handle->abe_key = GNUNET_CRYPTO_cpabe_deserialize_master_key ((void**)rd[i].data,
1366 GNUNET_SCHEDULER_add_now (&attr_collect_task, handle);
1369 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1370 "No ABE master found!\n");
1371 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1377 * Handler for issue message
1380 * @param client who sent the message
1381 * @param message the message
1384 handle_issue_message (void *cls,
1385 const struct IssueMessage *im)
1391 struct GNUNET_HashCode key;
1392 struct IssueHandle *issue_handle;
1393 struct IdpClient *idp = cls;
1395 scopes = (const char *) &im[1];
1396 //v_attrs = (const char *) &im[1] + ntohl(im->scope_len);
1397 issue_handle = GNUNET_malloc (sizeof (struct IssueHandle));
1398 issue_handle->attr_map = GNUNET_CONTAINER_multihashmap_create (5,
1400 scopes_tmp = GNUNET_strdup (scopes);
1402 for (scope = strtok (scopes_tmp, ","); NULL != scope; scope = strtok (NULL, ","))
1404 GNUNET_CRYPTO_hash (scope,
1407 GNUNET_CONTAINER_multihashmap_put (issue_handle->attr_map,
1410 GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE);
1412 GNUNET_free (scopes_tmp);
1413 /*scopes_tmp = GNUNET_strdup (v_attrs);
1415 for (scope = strtok (scopes_tmp, ","); NULL != scope; scope = strtok (NULL, ","))
1417 vattr_entry = GNUNET_new (struct VerifiedAttributeEntry);
1418 vattr_entry->name = GNUNET_strdup (scope);
1419 GNUNET_CONTAINER_DLL_insert (issue_handle->v_attr_head,
1420 issue_handle->v_attr_tail,
1423 GNUNET_free (scopes_tmp);*/
1427 issue_handle->r_id = im->id;
1428 issue_handle->aud_key = im->aud_key;
1429 issue_handle->iss_key = im->iss_key;
1430 GNUNET_CRYPTO_ecdsa_key_get_public (&im->iss_key,
1431 &issue_handle->iss_pkey);
1432 issue_handle->expiration = GNUNET_TIME_absolute_ntoh (im->expiration);
1433 issue_handle->nonce = ntohl (im->nonce);
1434 GNUNET_SERVICE_client_continue (idp->client);
1435 issue_handle->client = idp;
1436 issue_handle->scopes = GNUNET_strdup (scopes);
1437 issue_handle->token = token_create (&issue_handle->iss_pkey,
1438 &issue_handle->aud_key);
1440 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG,
1442 GNUNET_STRINGS_base64_encode ((char*)&rnd_key,
1444 &issue_handle->label);
1445 issue_handle->ns_qe = GNUNET_NAMESTORE_records_lookup (ns_handle,
1446 &issue_handle->iss_key,
1448 &abe_key_lookup_error,
1450 &abe_key_lookup_result,
1455 cleanup_as_handle (struct AttributeStoreHandle *handle)
1457 if (NULL != handle->attribute)
1458 GNUNET_free (handle->attribute);
1459 if (NULL != handle->abe_key)
1460 GNUNET_free (handle->abe_key);
1461 GNUNET_free (handle);
1467 attr_store_cont (void *cls,
1471 struct AttributeStoreHandle *as_handle = cls;
1472 struct GNUNET_MQ_Envelope *env;
1473 struct AttributeStoreResponseMessage *acr_msg;
1475 if (GNUNET_SYSERR == success)
1477 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1478 "Failed to store attribute %s\n",
1480 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1484 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1485 "Sending ATTRIBUTE_STORE_RESPONSE message\n");
1486 env = GNUNET_MQ_msg (acr_msg,
1487 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_STORE_RESPONSE);
1488 acr_msg->id = htonl (as_handle->r_id);
1489 acr_msg->op_result = htonl (GNUNET_OK);
1490 GNUNET_MQ_send (as_handle->client->mq,
1492 cleanup_as_handle (as_handle);
1496 attr_store_task (void *cls)
1498 struct AttributeStoreHandle *as_handle = cls;
1499 struct GNUNET_GNSRECORD_Data rd[1];
1503 buf_size = attribute_serialize_get_size (as_handle->attribute);
1504 buf = GNUNET_malloc (buf_size);
1506 attribute_serialize (as_handle->attribute,
1510 * Encrypt the attribute value and store in namestore
1512 rd[0].data_size = GNUNET_CRYPTO_cpabe_encrypt (buf,
1514 as_handle->attribute->name, //Policy
1516 (void**)&rd[0].data);
1518 rd[0].record_type = GNUNET_GNSRECORD_TYPE_ID_ATTR;
1519 rd[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
1520 rd[0].expiration_time = GNUNET_TIME_UNIT_HOURS.rel_value_us; //TODO sane?
1521 as_handle->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
1522 &as_handle->identity,
1523 as_handle->attribute->name,
1528 GNUNET_free ((void*)rd[0].data);
1533 bootstrap_store_cont (void *cls,
1537 struct AbeBootstrapHandle *abh = cls;
1538 if (GNUNET_SYSERR == success)
1540 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1541 "Failed to bootstrap ABE master %s\n",
1543 abh->proc (abh->proc_cls, NULL);
1544 GNUNET_free (abh->abe_key);
1548 abh->proc (abh->proc_cls, abh->abe_key);
1553 bootstrap_store_task (void *cls)
1555 struct AbeBootstrapHandle *abh = cls;
1556 struct GNUNET_GNSRECORD_Data rd[1];
1558 rd[0].data_size = GNUNET_CRYPTO_cpabe_serialize_master_key (abh->abe_key,
1559 (void**)&rd[0].data);
1560 rd[0].record_type = GNUNET_GNSRECORD_TYPE_ABE_MASTER;
1561 rd[0].flags = GNUNET_GNSRECORD_RF_NONE | GNUNET_GNSRECORD_RF_PRIVATE;
1562 rd[0].expiration_time = GNUNET_TIME_UNIT_HOURS.rel_value_us; //TODO sane?
1563 abh->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
1568 &bootstrap_store_cont,
1573 bootstrap_abe_error (void *cls)
1575 struct AbeBootstrapHandle *abh = cls;
1577 abh->proc (abh->proc_cls, NULL);
1584 bootstrap_abe_result (void *cls,
1585 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
1587 unsigned int rd_count,
1588 const struct GNUNET_GNSRECORD_Data *rd)
1590 struct AbeBootstrapHandle *abh = cls;
1591 struct GNUNET_CRYPTO_AbeMasterKey *abe_key;
1594 for (i=0;i<rd_count;i++) {
1595 if (GNUNET_GNSRECORD_TYPE_ABE_MASTER != rd[i].record_type)
1597 abe_key = GNUNET_CRYPTO_cpabe_deserialize_master_key ((void**)rd[i].data,
1599 abh->proc (abh->proc_cls, abe_key);
1604 //No ABE master found, bootstrapping...
1605 abh->abe_key = GNUNET_CRYPTO_cpabe_create_master_key ();
1606 GNUNET_SCHEDULER_add_now (&bootstrap_store_task, abh);
1610 bootstrap_abe (const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
1611 AbeBootstrapResult proc,
1614 struct AbeBootstrapHandle *abh;
1616 abh = GNUNET_new (struct AbeBootstrapHandle);
1618 abh->proc_cls = cls;
1619 abh->identity = *identity;
1620 abh->ns_qe = GNUNET_NAMESTORE_records_lookup (ns_handle,
1623 &bootstrap_abe_error,
1625 &bootstrap_abe_result,
1631 store_after_abe_bootstrap (void *cls,
1632 struct GNUNET_CRYPTO_AbeMasterKey *abe_key)
1634 struct AttributeStoreHandle *ash = cls;
1635 ash->abe_key = abe_key;
1636 GNUNET_SCHEDULER_add_now (&attr_store_task, ash);
1640 * Checks a store message
1642 * @param cls client sending the message
1643 * @param sam message of type `struct AttributeStoreMessage`
1644 * @return #GNUNET_OK if @a im is well-formed
1647 check_attribute_store_message(void *cls,
1648 const struct AttributeStoreMessage *sam)
1652 size = ntohs (sam->header.size);
1653 if (size <= sizeof (struct AttributeStoreMessage))
1656 return GNUNET_SYSERR;
1664 * Handler for store message
1667 * @param client who sent the message
1668 * @param message the message
1671 handle_attribute_store_message (void *cls,
1672 const struct AttributeStoreMessage *sam)
1674 struct AttributeStoreHandle *as_handle;
1675 struct IdpClient *idp = cls;
1678 data_len = ntohs (sam->attr_len);
1680 as_handle = GNUNET_new (struct AttributeStoreHandle);
1681 as_handle->attribute = attribute_deserialize ((char*)&sam[1],
1684 as_handle->r_id = sam->id;
1685 as_handle->identity = sam->identity;
1686 GNUNET_CRYPTO_ecdsa_key_get_public (&sam->identity,
1687 &as_handle->identity_pkey);
1689 GNUNET_SERVICE_client_continue (idp->client);
1690 as_handle->client = idp;
1692 bootstrap_abe (&as_handle->identity, &store_after_abe_bootstrap, as_handle);
1696 cleanup_iter_handle (struct AttributeIterator *ai)
1698 if (NULL != ai->abe_key)
1699 GNUNET_free (ai->abe_key);
1704 attr_iter_error (void *cls)
1706 //struct AttributeIterator *ai = cls;
1708 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1709 "Failed to iterate over attributes\n");
1710 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1714 attr_iter_finished (void *cls)
1716 struct AttributeIterator *ai = cls;
1717 struct GNUNET_MQ_Envelope *env;
1718 struct AttributeResultMessage *arm;
1720 env = GNUNET_MQ_msg (arm,
1721 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_RESULT);
1722 arm->id = htonl (ai->request_id);
1723 arm->attr_len = htons (0);
1724 GNUNET_MQ_send (ai->client->mq, env);
1725 cleanup_iter_handle (ai);
1729 attr_iter_cb (void *cls,
1730 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
1732 unsigned int rd_count,
1733 const struct GNUNET_GNSRECORD_Data *rd)
1735 struct AttributeIterator *ai = cls;
1736 struct AttributeResultMessage *arm;
1737 struct GNUNET_CRYPTO_AbeKey *key;
1738 struct GNUNET_MQ_Envelope *env;
1739 ssize_t msg_extra_len;
1746 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it);
1750 if (GNUNET_GNSRECORD_TYPE_ID_ATTR != rd->record_type) {
1751 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it);
1754 attrs[0] = (char*)label;
1756 key = GNUNET_CRYPTO_cpabe_create_key (ai->abe_key,
1758 msg_extra_len = GNUNET_CRYPTO_cpabe_decrypt (rd->data,
1762 GNUNET_CRYPTO_cpabe_delete_key (key);
1763 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
1764 "Found attribute: %s\n", label);
1765 env = GNUNET_MQ_msg_extra (arm,
1767 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_RESULT);
1768 arm->id = htonl (ai->request_id);
1769 arm->attr_len = htons (msg_extra_len);
1770 arm->identity = *zone;
1771 data_tmp = (char *) &arm[1];
1772 GNUNET_memcpy (data_tmp,
1775 GNUNET_MQ_send (ai->client->mq, env);
1776 GNUNET_free (attr_ser);
1781 iterate_after_abe_bootstrap (void *cls,
1782 struct GNUNET_CRYPTO_AbeMasterKey *abe_key)
1784 struct AttributeIterator *ai = cls;
1785 ai->abe_key = abe_key;
1786 ai->ns_it = GNUNET_NAMESTORE_zone_iteration_start (ns_handle,
1792 &attr_iter_finished,
1798 * Handles a #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ITERATION_START message
1800 * @param cls the client sending the message
1801 * @param zis_msg message from the client
1804 handle_iteration_start (void *cls,
1805 const struct AttributeIterationStartMessage *ais_msg)
1807 struct IdpClient *idp = cls;
1808 struct AttributeIterator *ai;
1810 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1811 "Received ATTRIBUTE_ITERATION_START message\n");
1812 ai = GNUNET_new (struct AttributeIterator);
1813 ai->request_id = ntohl (ais_msg->id);
1815 ai->identity = ais_msg->identity;
1817 GNUNET_CONTAINER_DLL_insert (idp->op_head,
1820 bootstrap_abe (&ai->identity, &iterate_after_abe_bootstrap, ai);
1821 GNUNET_SERVICE_client_continue (idp->client);
1826 * Handles a #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ITERATION_STOP message
1828 * @param cls the client sending the message
1829 * @param ais_msg message from the client
1832 handle_iteration_stop (void *cls,
1833 const struct AttributeIterationStopMessage *ais_msg)
1835 struct IdpClient *idp = cls;
1836 struct AttributeIterator *ai;
1839 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1840 "Received `%s' message\n",
1841 "ATTRIBUTE_ITERATION_STOP");
1842 rid = ntohl (ais_msg->id);
1843 for (ai = idp->op_head; NULL != ai; ai = ai->next)
1844 if (ai->request_id == rid)
1849 GNUNET_SERVICE_client_drop (idp->client);
1852 GNUNET_CONTAINER_DLL_remove (idp->op_head,
1856 GNUNET_SERVICE_client_continue (idp->client);
1861 * Handles a #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_NEXT message
1863 * @param cls the client sending the message
1864 * @param message message from the client
1867 handle_iteration_next (void *cls,
1868 const struct AttributeIterationNextMessage *ais_msg)
1870 struct IdpClient *idp = cls;
1871 struct AttributeIterator *ai;
1874 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1875 "Received ATTRIBUTE_ITERATION_NEXT message\n");
1876 rid = ntohl (ais_msg->id);
1877 for (ai = idp->op_head; NULL != ai; ai = ai->next)
1878 if (ai->request_id == rid)
1883 GNUNET_SERVICE_client_drop (idp->client);
1886 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it);
1887 GNUNET_SERVICE_client_continue (idp->client);
1894 * Main function that will be run
1896 * @param cls closure
1897 * @param args remaining command-line arguments
1898 * @param cfgfile name of the configuration file used (for saving, can be NULL)
1899 * @param c configuration
1903 const struct GNUNET_CONFIGURATION_Handle *c,
1904 struct GNUNET_SERVICE_Handle *server)
1908 stats = GNUNET_STATISTICS_create ("identity-provider", cfg);
1910 //Connect to identity and namestore services
1911 ns_handle = GNUNET_NAMESTORE_connect (cfg);
1912 if (NULL == ns_handle)
1914 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "error connecting to namestore");
1917 gns_handle = GNUNET_GNS_connect (cfg);
1918 if (NULL == gns_handle)
1920 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "error connecting to gns");
1922 credential_handle = GNUNET_CREDENTIAL_connect (cfg);
1923 if (NULL == credential_handle)
1925 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "error connecting to credential");
1927 identity_handle = GNUNET_IDENTITY_connect (cfg,
1932 GNUNET_CONFIGURATION_get_value_time (cfg,
1933 "identity-provider",
1934 "TOKEN_EXPIRATION_INTERVAL",
1935 &token_expiration_interval))
1937 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1938 "Time window for zone iteration: %s\n",
1939 GNUNET_STRINGS_relative_time_to_string (token_expiration_interval,
1942 token_expiration_interval = DEFAULT_TOKEN_EXPIRATION_INTERVAL;
1945 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL);
1949 * Called whenever a client is disconnected.
1951 * @param cls closure
1952 * @param client identification of the client
1953 * @param app_ctx @a client
1956 client_disconnect_cb (void *cls,
1957 struct GNUNET_SERVICE_Client *client,
1960 struct IdpClient *idp = app_ctx;
1961 struct AttributeIterator *ai;
1963 //TODO other operations
1965 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1966 "Client %p disconnected\n",
1969 while (NULL != (ai = idp->op_head))
1971 GNUNET_CONTAINER_DLL_remove (idp->op_head,
1981 * Add a client to our list of active clients.
1984 * @param client client to add
1985 * @param mq message queue for @a client
1986 * @return internal namestore client structure for this client
1989 client_connect_cb (void *cls,
1990 struct GNUNET_SERVICE_Client *client,
1991 struct GNUNET_MQ_Handle *mq)
1993 struct IdpClient *idp;
1994 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1995 "Client %p connected\n",
1997 idp = GNUNET_new (struct IdpClient);
1998 idp->client = client;
2006 * Define "main" method using service macro.
2009 ("identity-provider",
2010 GNUNET_SERVICE_OPTION_NONE,
2013 &client_disconnect_cb,
2015 GNUNET_MQ_hd_var_size (issue_message,
2016 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ISSUE,
2017 struct IssueMessage,
2019 GNUNET_MQ_hd_var_size (exchange_message,
2020 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_EXCHANGE,
2021 struct ExchangeMessage,
2023 GNUNET_MQ_hd_var_size (attribute_store_message,
2024 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_STORE,
2025 struct AttributeStoreMessage,
2027 GNUNET_MQ_hd_fixed_size (iteration_start,
2028 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_START,
2029 struct AttributeIterationStartMessage,
2031 GNUNET_MQ_hd_fixed_size (iteration_next,
2032 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_NEXT,
2033 struct AttributeIterationNextMessage,
2035 GNUNET_MQ_hd_fixed_size (iteration_stop,
2036 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_STOP,
2037 struct AttributeIterationStopMessage,
2039 GNUNET_MQ_handler_end());
2040 /* end of gnunet-service-identity-provider.c */