aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/identity-provider/gnunet-service-identity-provider.c345
-rw-r--r--src/include/gnunet_gnsrecord_lib.h5
2 files changed, 300 insertions, 50 deletions
diff --git a/src/identity-provider/gnunet-service-identity-provider.c b/src/identity-provider/gnunet-service-identity-provider.c
index 4194aabc4..0aaee93e5 100644
--- a/src/identity-provider/gnunet-service-identity-provider.c
+++ b/src/identity-provider/gnunet-service-identity-provider.c
@@ -147,6 +147,8 @@ struct VerifiedAttributeEntry
147 char* name; 147 char* name;
148}; 148};
149 149
150struct ParallelLookups;
151
150struct ExchangeHandle 152struct ExchangeHandle
151{ 153{
152 154
@@ -174,6 +176,15 @@ struct ExchangeHandle
174 * Audience Key 176 * Audience Key
175 */ 177 */
176 struct GNUNET_CRYPTO_EcdsaPrivateKey aud_privkey; 178 struct GNUNET_CRYPTO_EcdsaPrivateKey aud_privkey;
179
180 /**
181 * ParallelLookups DLL
182 */
183 struct ParallelLookup *parallel_lookups_head;
184 struct ParallelLookup *parallel_lookups_tail;
185
186 struct GNUNET_SCHEDULER_Task *kill_task;
187 struct GNUNET_CRYPTO_AbeKey *key;
177 188
178 /** 189 /**
179 * Label to return 190 * Label to return
@@ -186,6 +197,17 @@ struct ExchangeHandle
186 uint32_t r_id; 197 uint32_t r_id;
187}; 198};
188 199
200struct ParallelLookup
201{
202 struct ParallelLookup *next;
203
204 struct ParallelLookup *prev;
205
206 struct GNUNET_GNS_LookupRequest *lookup_request;
207
208 struct ExchangeHandle *handle;
209};
210
189struct IssueHandle 211struct IssueHandle
190{ 212{
191 213
@@ -549,6 +571,15 @@ serialize_abe_keyinfo (const struct IssueHandle *handle,
549 return GNUNET_OK; 571 return GNUNET_OK;
550} 572}
551 573
574static void
575cleanup_exchange_handle (struct ExchangeHandle *handle)
576{
577 if (NULL != handle->ticket)
578 ticket_destroy (handle->ticket);
579 if (NULL != handle->token)
580 token_destroy (handle->token);
581 GNUNET_free (handle);
582}
552 583
553 584
554/** 585/**
@@ -559,6 +590,43 @@ serialize_abe_keyinfo (const struct IssueHandle *handle,
559static void 590static void
560sign_and_return_token (void *cls) 591sign_and_return_token (void *cls)
561{ 592{
593 struct ExchangeHandle *handle = cls;
594 struct GNUNET_MQ_Envelope *env;
595 char *token_str;
596 uint64_t time;
597 uint64_t exp_time;
598
599 time = GNUNET_TIME_absolute_get().abs_value_us;
600 exp_time = time + token_expiration_interval.rel_value_us;
601
602 token_add_attr_int (handle->token, "nbf", time);
603 token_add_attr_int (handle->token, "iat", time);
604 token_add_attr_int (handle->token, "exp", exp_time);
605
606 //Readable
607 GNUNET_assert (GNUNET_OK == token_to_string (handle->token,
608 &handle->aud_privkey,
609 &token_str));
610
611 env = create_exchange_result_message (token_str,
612 handle->label,
613 handle->ticket->payload->nonce,
614 handle->r_id);
615 GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq(handle->client),
616 env);
617 cleanup_exchange_handle (handle);
618 GNUNET_free (token_str);
619
620}
621
622/**
623 * Build an ABE key and store it
624 *
625 * @param cls the IssueHandle
626 */
627static void
628issue_ticket (void *cls)
629{
562 struct GNUNET_CRYPTO_EcdsaPublicKey pub_key; 630 struct GNUNET_CRYPTO_EcdsaPublicKey pub_key;
563 struct GNUNET_CRYPTO_EcdhePrivateKey *ecdhe_privkey; 631 struct GNUNET_CRYPTO_EcdhePrivateKey *ecdhe_privkey;
564 struct IssueHandle *handle = cls; 632 struct IssueHandle *handle = cls;
@@ -695,7 +763,7 @@ handle_vattr_collection (void* cls,
695 763
696 if (NULL == cred) 764 if (NULL == cred)
697 { 765 {
698 GNUNET_SCHEDULER_add_now (&sign_and_return_token, handle); 766 GNUNET_SCHEDULER_add_now (&issue_ticket, handle);
699 return; 767 return;
700 } 768 }
701 cred_array = json_array(); 769 cred_array = json_array();
@@ -706,8 +774,8 @@ handle_vattr_collection (void* cls,
706 continue; 774 continue;
707 json_array_append (cred_array, cred_json); 775 json_array_append (cred_array, cred_json);
708 token_add_attr_json (handle->token, 776 token_add_attr_json (handle->token,
709 handle->v_attr_head->name, 777 handle->v_attr_head->name,
710 cred_array); 778 cred_array);
711 } 779 }
712 json_decref (cred_array); 780 json_decref (cred_array);
713 vattr = handle->v_attr_head; 781 vattr = handle->v_attr_head;
@@ -717,10 +785,10 @@ handle_vattr_collection (void* cls,
717 vattr); 785 vattr);
718 GNUNET_free (vattr->name); 786 GNUNET_free (vattr->name);
719 GNUNET_free (vattr); 787 GNUNET_free (vattr);
720 788
721 if (NULL == handle->v_attr_head) 789 if (NULL == handle->v_attr_head)
722 { 790 {
723 GNUNET_SCHEDULER_add_now (&sign_and_return_token, handle); 791 GNUNET_SCHEDULER_add_now (&issue_ticket, handle);
724 return; 792 return;
725 } 793 }
726 handle->credential_request = GNUNET_CREDENTIAL_collect (credential_handle, 794 handle->credential_request = GNUNET_CREDENTIAL_collect (credential_handle,
@@ -740,7 +808,7 @@ attr_collect_error (void *cls)
740 808
741 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Adding attribute Error!\n"); 809 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Adding attribute Error!\n");
742 handle->ns_it = NULL; 810 handle->ns_it = NULL;
743 GNUNET_SCHEDULER_add_now (&sign_and_return_token, handle); 811 GNUNET_SCHEDULER_add_now (&issue_ticket, handle);
744} 812}
745 813
746 814
@@ -754,7 +822,7 @@ attr_collect_finished (void *cls)
754 822
755 if (NULL == handle->v_attr_head) 823 if (NULL == handle->v_attr_head)
756 { 824 {
757 GNUNET_SCHEDULER_add_now (&sign_and_return_token, handle); 825 GNUNET_SCHEDULER_add_now (&issue_ticket, handle);
758 return; 826 return;
759 } 827 }
760 handle->credential_request = GNUNET_CREDENTIAL_collect (credential_handle, 828 handle->credential_request = GNUNET_CREDENTIAL_collect (credential_handle,
@@ -831,13 +899,75 @@ attr_collect (void *cls,
831} 899}
832 900
833static void 901static void
834cleanup_exchange_handle (struct ExchangeHandle *handle) 902process_parallel_lookup (void *cls, uint32_t rd_count,
903 const struct GNUNET_GNSRECORD_Data *rd)
835{ 904{
836 if (NULL != handle->ticket) 905 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
837 ticket_destroy (handle->ticket); 906 "Parallel lookup finished\n");
838 if (NULL != handle->token) 907 struct ParallelLookup *parallel_lookup = cls;
839 token_destroy (handle->token); 908 struct ExchangeHandle *handle = parallel_lookup->handle;
840 GNUNET_free (handle); 909 char *data;
910 int i;
911
912 GNUNET_CONTAINER_DLL_remove (handle->parallel_lookups_head,
913 handle->parallel_lookups_tail,
914 parallel_lookup);
915 GNUNET_free (parallel_lookup);
916 if (1 == rd_count)
917 {
918 if (rd->record_type == GNUNET_GNSRECORD_TYPE_ID_ATTR)
919 {
920 GNUNET_CRYPTO_cpabe_decrypt (rd->data,
921 rd->data_size,
922 handle->key,
923 (void**)&data);
924 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding value: %s\n", data);
925 token_add_attr (handle->token,
926 label,
927 data);
928 GNUNET_free (data);
929 }
930 } else {
931 i = 0;
932 for (; i < rd_count; i++)
933 {
934 if (rd->record_type == GNUNET_GNSRECORD_TYPE_ID_ATTR)
935 {
936 data = GNUNET_GNSRECORD_value_to_string (rd[i].record_type,
937 rd[i].data,
938 rd[i].data_size);
939 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding value: %s\n", data);
940 token_add_attr (handle->token, label, data);
941 GNUNET_free (data);
942 }
943 }
944 }
945 if (NULL != handle->parallel_lookups_head)
946 return; //Wait for more
947 //Else we are done
948 GNUNET_SCHEDULER_cancel (handle->kill_task);
949 GNUNET_SCHEDULER_add_now (&sign_and_return_token, handle);
950}
951
952void
953abort_parallel_lookups (void *cls)
954{
955 struct ExchangeHandle *handle = cls;
956 struct ParallelLookup *lu;
957 struct ParallelLookup *tmp;
958
959 for (lu = handle->parallel_lookups_head;
960 NULL != lu;) {
961 GNUNET_GNS_lookup_cancel (lu->lookup_request);
962 tmp = lu->next;
963 GNUNET_CONTAINER_DLL_remove (handle->parallel_lookups_head,
964 handle->parallel_lookups_tail,
965 lu);
966 GNUNET_free (lu);
967 lu = tmp;
968 }
969 GNUNET_SCHEDULER_add_now (&sign_and_return_token, handle);
970
841} 971}
842 972
843static void 973static void
@@ -845,45 +975,79 @@ process_lookup_result (void *cls, uint32_t rd_count,
845 const struct GNUNET_GNSRECORD_Data *rd) 975 const struct GNUNET_GNSRECORD_Data *rd)
846{ 976{
847 struct ExchangeHandle *handle = cls; 977 struct ExchangeHandle *handle = cls;
848 struct GNUNET_MQ_Envelope *env; 978 struct GNUNET_HashCode new_key_hash;
849 char* token_str; 979 struct GNUNET_CRYPTO_SymmetricSessionKey enc_key;
850 char* record_str; 980 struct GNUNET_CRYPTO_SymmetricInitializationVector enc_iv;
981 struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_key;
982 struct ParallelLookup *parallel_lookup;
983 size_t size;
984 char *buf;
985 char *scope;
986 char *lookup_query;
851 987
852 handle->lookup_request = NULL; 988 handle->lookup_request = NULL;
853 if (2 != rd_count) 989 if (1 != rd_count)
854 { 990 {
855 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 991 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
856 "Number of tokens %d != 2.", 992 "Number of keys %d != 1.",
857 rd_count); 993 rd_count);
858 cleanup_exchange_handle (handle); 994 cleanup_exchange_handle (handle);
859 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); 995 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
860 return; 996 return;
861 } 997 }
862 998
863 record_str = 999 //Decrypt
864 GNUNET_GNSRECORD_value_to_string (GNUNET_GNSRECORD_TYPE_ID_TOKEN, 1000 ecdh_key = (struct GNUNET_CRYPTO_EcdhePublicKey *)rd->data;
865 rd->data, 1001
866 rd->data_size); 1002 buf = GNUNET_malloc (rd->data_size - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
1003
1004 //Calculate symmetric key from ecdh parameters
1005 GNUNET_assert (GNUNET_OK ==
1006 GNUNET_CRYPTO_ecdsa_ecdh (&handle->aud_privkey,
1007 ecdh_key,
1008 &new_key_hash));
1009 create_sym_key_from_ecdh (&new_key_hash,
1010 &enc_key,
1011 &enc_iv);
1012 size = GNUNET_CRYPTO_symmetric_decrypt (rd->data + sizeof (struct GNUNET_CRYPTO_EcdhePublicKey),
1013 rd->data_size - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey),
1014 &enc_key,
1015 &enc_iv,
1016 buf);
867 1017
868 //Decrypt and parse 1018 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
869 GNUNET_assert (GNUNET_OK == token_parse (record_str, 1019 "Decrypted bytes: %zd Expected bytes: %zd\n",
870 &handle->aud_privkey, 1020 size, rd->data_size - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
871 &handle->token));
872 1021
873 //Readable 1022 scopes = GNUNET_strdup (buf);
874 GNUNET_assert (GNUNET_OK == token_to_string (handle->token,
875 &handle->aud_privkey,
876 &token_str));
877 1023
878 env = create_exchange_result_message (token_str, 1024 handle->key = GNUNET_CRYPTO_cpabe_deserialize_key ((void*)(buf + strlen (scopes) + 1),
879 handle->label, 1025 rd->data_size - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)
880 handle->ticket->payload->nonce, 1026 - strlen (scopes) - 1);
881 handle->r_id); 1027
882 GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq(handle->client), 1028 for (scope = strtok (scopes, ","); NULL != scope; scope = strtok (NULL, ","))
883 env); 1029 {
884 cleanup_exchange_handle (handle); 1030 GNUNET_asprintf (&lookup_query,
885 GNUNET_free (record_str); 1031 "%s.%s.gnu",
886 GNUNET_free (token_str); 1032 scope,
1033 GNUNET_CRYPTO_ecdsa_public_key_to_string (&handle->ticket->payload->identity_key));
1034 parallel_lookup = GNUNET_new (struct ParallelLookup);
1035 parallel_lookup->handle = handle;
1036 parallel_lookup->lookup_request
1037 = GNUNET_GNS_lookup (gns_handle,
1038 lookup_query,
1039 &handle->ticket->aud_key,
1040 GNUNET_GNSRECORD_TYPE_ID_ATTR,
1041 GNUNET_GNS_LO_LOCAL_MASTER,
1042 &process_parallel_lookup,
1043 parallel_lookup);
1044 GNUNET_CONTAINER_DLL_insert (handle->parallel_lookups_head,
1045 handle->parallel_lookups_tail,
1046 parallel_lookup);
1047 }
1048 handle->kill_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES,3),
1049 &abort_parallel_lookups,
1050 handle);
887} 1051}
888 1052
889/** 1053/**
@@ -940,18 +1104,20 @@ handle_exchange_message (void *cls,
940 GNUNET_SERVICE_client_drop (client); 1104 GNUNET_SERVICE_client_drop (client);
941 return; 1105 return;
942 } 1106 }
943 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Looking for token under %s\n", 1107 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Looking for ABE key under %s\n",
944 xchange_handle->ticket->payload->label); 1108 xchange_handle->ticket->payload->label);
945 GNUNET_asprintf (&lookup_query, 1109 GNUNET_asprintf (&lookup_query,
946 "%s.gnu", 1110 "%s.gnu",
947 xchange_handle->ticket->payload->label); 1111 xchange_handle->ticket->payload->label);
948 GNUNET_SERVICE_client_continue (client); 1112 GNUNET_SERVICE_client_continue (client);
949 xchange_handle->client = client; 1113 xchange_handle->client = client;
1114 xchange_handle->token = token_create (&xchange_handle->ticket->payload->identity_key,
1115 &xchange_handle->ticket->payload->identity_key);
950 xchange_handle->lookup_request 1116 xchange_handle->lookup_request
951 = GNUNET_GNS_lookup (gns_handle, 1117 = GNUNET_GNS_lookup (gns_handle,
952 lookup_query, 1118 lookup_query,
953 &xchange_handle->ticket->payload->identity_key, 1119 &xchange_handle->ticket->payload->identity_key,
954 GNUNET_GNSRECORD_TYPE_ID_TOKEN, 1120 GNUNET_GNSRECORD_TYPE_ABE_KEY,
955 GNUNET_GNS_LO_LOCAL_MASTER, 1121 GNUNET_GNS_LO_LOCAL_MASTER,
956 &process_lookup_result, 1122 &process_lookup_result,
957 xchange_handle); 1123 xchange_handle);
@@ -989,6 +1155,87 @@ check_issue_message(void *cls,
989 return GNUNET_OK; 1155 return GNUNET_OK;
990} 1156}
991 1157
1158void
1159attr_collect_task (void *cls)
1160{
1161 struct IssueHandle *issue_handle = cls;
1162
1163 issue_handle->ns_it = GNUNET_NAMESTORE_zone_iteration_start (ns_handle,
1164 &issue_handle->iss_key,
1165 &attr_collect_error,
1166 issue_handle,
1167 &attr_collect,
1168 issue_handle,
1169 &attr_collect_finished,
1170 issue_handle);
1171}
1172
1173void
1174store_bootstrap_cont (void *cls,
1175 int32_t success,
1176 const char *emsg)
1177{
1178 if (GNUNET_SYSERR == success)
1179 {
1180 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1181 "Failed to bootstrap ABE master %s\n",
1182 emsg);
1183 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1184 return;
1185 }
1186 GNUNET_SCHEDULER_add_now (&attr_collect_task, cls);
1187}
1188
1189void
1190store_bootstrap_task (void *cls)
1191{
1192 struct IssueHandle *issue_handle = cls;
1193 struct GNUNET_GNSRECORD_Data rd[1];
1194
1195 rd[0].data_size = GNUNET_CRYPTO_cpabe_serialize_master_key (issue_handle->abe_key,
1196 (void**)&rd[0].data);
1197 rd[0].record_type = GNUNET_GNSRECORD_TYPE_ABE_MASTER;
1198 rd[0].flags = GNUNET_GNSRECORD_RF_NONE | GNUNET_GNSRECORD_RF_PRIVATE;
1199 rd[0].expiration_time = GNUNET_TIME_UNIT_HOURS.rel_value_us; //TODO sane?
1200 issue_handle->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
1201 &issue_handle->iss_key,
1202 "+",
1203 1,
1204 rd,
1205 &store_bootstrap_cont,
1206 issue_handle);
1207}
1208
1209void
1210abe_key_lookup_error (void *cls)
1211{
1212 GNUNET_SCHEDULER_add_now (&do_shutdown, cls);
1213}
1214
1215void
1216abe_key_lookup_result (void *cls,
1217 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
1218 const char *label,
1219 unsigned int rd_count,
1220 const struct GNUNET_GNSRECORD_Data *rd)
1221{
1222 struct IssueHandle *handle = cls;
1223 int i;
1224
1225 for (i=0;i<rd_count;i++) {
1226 if (GNUNET_GNSRECORD_TYPE_ABE_MASTER != rd[i].record_type)
1227 continue;
1228 handle->abe_key = GNUNET_CRYPTO_cpabe_deserialize_master_key ((void**)rd[i].data,
1229 rd[i].data_size);
1230 GNUNET_SCHEDULER_add_now (&attr_collect_task, handle);
1231 return;
1232 }
1233
1234 //No ABE master found, bootstrapping...
1235 handle->abe_key = GNUNET_CRYPTO_cpabe_create_master_key ();
1236 GNUNET_SCHEDULER_add_now (&store_bootstrap_task, handle);
1237}
1238
992/** 1239/**
993 * 1240 *
994 * Handler for issue message 1241 * Handler for issue message
@@ -1061,15 +1308,13 @@ handle_issue_message (void *cls,
1061 GNUNET_STRINGS_base64_encode ((char*)&rnd_key, 1308 GNUNET_STRINGS_base64_encode ((char*)&rnd_key,
1062 sizeof (uint64_t), 1309 sizeof (uint64_t),
1063 &issue_handle->label); 1310 &issue_handle->label);
1064 1311 issue_handle->ns_qe = GNUNET_NAMESTORE_records_lookup (ns_handle,
1065 issue_handle->ns_it = GNUNET_NAMESTORE_zone_iteration_start (ns_handle, 1312 &issue_handle->iss_key,
1066 &issue_handle->iss_key, 1313 "+",
1067 &attr_collect_error, 1314 &abe_key_lookup_error,
1068 issue_handle, 1315 issue_handle,
1069 &attr_collect, 1316 &abe_key_lookup_result,
1070 issue_handle, 1317 issue_handle);
1071 &attr_collect_finished,
1072 issue_handle);
1073} 1318}
1074 1319
1075 1320
diff --git a/src/include/gnunet_gnsrecord_lib.h b/src/include/gnunet_gnsrecord_lib.h
index aa0c6721f..d03b4db3b 100644
--- a/src/include/gnunet_gnsrecord_lib.h
+++ b/src/include/gnunet_gnsrecord_lib.h
@@ -129,6 +129,11 @@ extern "C"
129#define GNUNET_GNSRECORD_TYPE_ABE_KEY 65550 129#define GNUNET_GNSRECORD_TYPE_ABE_KEY 65550
130 130
131/** 131/**
132 * Record type for ABE master keys
133 */
134#define GNUNET_GNSRECORD_TYPE_ABE_MASTER 65551
135
136/**
132 * Flags that can be set for a record. 137 * Flags that can be set for a record.
133 */ 138 */
134enum GNUNET_GNSRECORD_Flags 139enum GNUNET_GNSRECORD_Flags