aboutsummaryrefslogtreecommitdiff
path: root/src/escrow/plugin_escrow_gns.c
diff options
context:
space:
mode:
authorjospaeth <spaethj@in.tum.de>2020-08-15 16:23:46 +0200
committerjospaeth <spaethj@in.tum.de>2020-08-15 16:23:46 +0200
commit91d9d4251d3b1d0fab1780da73b6969581d22ffe (patch)
tree112ff43d6b844b6497588b617ceb3b93017e3260 /src/escrow/plugin_escrow_gns.c
parent006a0802a8d4e89f58146c3bd1f16bb95eb5eee9 (diff)
downloadgnunet-91d9d4251d3b1d0fab1780da73b6969581d22ffe.tar.gz
gnunet-91d9d4251d3b1d0fab1780da73b6969581d22ffe.zip
begin implementation of gns verify and restore
Diffstat (limited to 'src/escrow/plugin_escrow_gns.c')
-rw-r--r--src/escrow/plugin_escrow_gns.c345
1 files changed, 335 insertions, 10 deletions
diff --git a/src/escrow/plugin_escrow_gns.c b/src/escrow/plugin_escrow_gns.c
index 3e2025b08..4f9ce64a1 100644
--- a/src/escrow/plugin_escrow_gns.c
+++ b/src/escrow/plugin_escrow_gns.c
@@ -30,12 +30,26 @@
30#include "gnunet_escrow_plugin.h" 30#include "gnunet_escrow_plugin.h"
31#include "escrow_plugin_helper.h" 31#include "escrow_plugin_helper.h"
32#include "gnunet_namestore_service.h" 32#include "gnunet_namestore_service.h"
33#include "gnunet_gns_service.h"
33#include "gnunet_gnsrecord_lib.h" 34#include "gnunet_gnsrecord_lib.h"
34#include "../identity/identity.h" 35#include "../identity/identity.h"
35#include <sss.h> 36#include <sss.h>
36#include <inttypes.h> 37#include <inttypes.h>
37 38
38 39
40/* declare this function here, as it is used by other functions above the definition */
41char *
42gns_anchor_data_to_string (struct GNUNET_ESCROW_Handle *h,
43 struct GNUNET_ESCROW_Anchor *escrowAnchor);
44
45
46/**
47 * Continuation with a private key (used for restore_private_key)
48 */
49typedef void (*PkContinuation) (void *cls,
50 const struct GNUNET_CRYPTO_EcdsaPrivateKey *pk);
51
52
39struct IdentityOperationEntry 53struct IdentityOperationEntry
40{ 54{
41 /** 55 /**
@@ -123,6 +137,35 @@ struct NamestoreQueueEntry
123}; 137};
124 138
125 139
140struct GnsLookupRequestEntry
141{
142 /**
143 * DLL
144 */
145 struct GnsLookupRequestEntry *prev;
146
147 /**
148 * DLL
149 */
150 struct GnsLookupRequestEntry *next;
151
152 /**
153 * GNS lookup request
154 */
155 struct GNUNET_GNS_LookupRequest *lr;
156
157 /**
158 * Plugin operation that started the lookup
159 */
160 struct ESCROW_PluginOperationWrapper *plugin_op_wrap;
161
162 /**
163 * index of the respective share
164 */
165 uint8_t i;
166};
167
168
126struct ESCROW_GnsPluginOperation 169struct ESCROW_GnsPluginOperation
127{ 170{
128 /** 171 /**
@@ -141,6 +184,11 @@ struct ESCROW_GnsPluginOperation
141 struct GNUNET_NAMESTORE_Handle *ns_h; 184 struct GNUNET_NAMESTORE_Handle *ns_h;
142 185
143 /** 186 /**
187 * GNS handle
188 */
189 struct GNUNET_GNS_Handle *gns_h;
190
191 /**
144 * Continuation for a plugin operation (e.g. used for restore, as this 192 * Continuation for a plugin operation (e.g. used for restore, as this
145 * callback has to be called from the IDENTITY service after finishing) 193 * callback has to be called from the IDENTITY service after finishing)
146 */ 194 */
@@ -177,11 +225,36 @@ struct ESCROW_GnsPluginOperation
177 uint8_t share_threshold; 225 uint8_t share_threshold;
178 226
179 /** 227 /**
228 * Continuation to be called with the restored private key
229 */
230 PkContinuation restore_pk_cont;
231
232 /**
233 * Closure for @a cont
234 */
235 void *restore_pk_cont_cls;
236
237 /**
238 * Array for the restored keyshares
239 */
240 sss_Keyshare *restored_keyshares;
241
242 /**
243 * Identity operation for the create of the restored ego
244 */
245 struct GNUNET_IDENTITY_Operation *id_op;
246
247 /**
180 * The ego 248 * The ego
181 */ 249 */
182 struct GNUNET_IDENTITY_Ego *ego; 250 struct GNUNET_IDENTITY_Ego *ego;
183 251
184 /** 252 /**
253 * The name of the ego
254 */
255 const char *egoName;
256
257 /**
185 * Private key of the ego 258 * Private key of the ego
186 */ 259 */
187 const struct GNUNET_CRYPTO_EcdsaPrivateKey *pk; 260 const struct GNUNET_CRYPTO_EcdsaPrivateKey *pk;
@@ -189,7 +262,7 @@ struct ESCROW_GnsPluginOperation
189 /** 262 /**
190 * User secret string 263 * User secret string
191 */ 264 */
192 const char *userSecret; 265 char *userSecret;
193 266
194 /** 267 /**
195 * DLL head for identity operations 268 * DLL head for identity operations
@@ -220,6 +293,16 @@ struct ESCROW_GnsPluginOperation
220 * DLL tail for namestore queue entries 293 * DLL tail for namestore queue entries
221 */ 294 */
222 struct NamestoreQueueEntry *ns_qes_tail; 295 struct NamestoreQueueEntry *ns_qes_tail;
296
297 /**
298 * DLL head for GNS lookup requests
299 */
300 struct GnsLookupRequestEntry *gns_lrs_head;
301
302 /**
303 * DLL tail for GNS lookup requests
304 */
305 struct GnsLookupRequestEntry *gns_lrs_tail;
223}; 306};
224 307
225/** 308/**
@@ -244,6 +327,7 @@ cleanup_plugin_operation (struct ESCROW_PluginOperationWrapper *plugin_op_wrap)
244 struct IdentityOperationEntry *curr_id_op, *next_id_op; 327 struct IdentityOperationEntry *curr_id_op, *next_id_op;
245 struct PkEntry *curr_pk, *next_pk; 328 struct PkEntry *curr_pk, *next_pk;
246 struct NamestoreQueueEntry *curr_ns_qe, *next_ns_qe; 329 struct NamestoreQueueEntry *curr_ns_qe, *next_ns_qe;
330 struct GnsLookupRequestEntry *curr_gns_lr, *next_gns_lr;
247 331
248 p_op = (struct ESCROW_GnsPluginOperation*)plugin_op_wrap->plugin_op; 332 p_op = (struct ESCROW_GnsPluginOperation*)plugin_op_wrap->plugin_op;
249 333
@@ -256,6 +340,8 @@ cleanup_plugin_operation (struct ESCROW_PluginOperationWrapper *plugin_op_wrap)
256 GNUNET_free (p_op->ego_wrap); 340 GNUNET_free (p_op->ego_wrap);
257 if (NULL != p_op->verify_wrap) 341 if (NULL != p_op->verify_wrap)
258 GNUNET_free (p_op->verify_wrap); 342 GNUNET_free (p_op->verify_wrap);
343 if (NULL != p_op->userSecret)
344 GNUNET_free (p_op->userSecret);
259 /* clean up identity operation list */ 345 /* clean up identity operation list */
260 for (curr_id_op = p_op->id_ops_head; NULL != curr_id_op; curr_id_op = next_id_op) 346 for (curr_id_op = p_op->id_ops_head; NULL != curr_id_op; curr_id_op = next_id_op)
261 { 347 {
@@ -286,11 +372,31 @@ cleanup_plugin_operation (struct ESCROW_PluginOperationWrapper *plugin_op_wrap)
286 GNUNET_NAMESTORE_cancel (curr_ns_qe->ns_qe); 372 GNUNET_NAMESTORE_cancel (curr_ns_qe->ns_qe);
287 GNUNET_free (curr_ns_qe); 373 GNUNET_free (curr_ns_qe);
288 } 374 }
375 /* clean up GNS lookup request list */
376 for (curr_gns_lr = p_op->gns_lrs_head; NULL != curr_gns_lr; curr_gns_lr = next_gns_lr)
377 {
378 next_gns_lr = curr_gns_lr->next;
379 GNUNET_CONTAINER_DLL_remove (p_op->gns_lrs_head,
380 p_op->gns_lrs_tail,
381 curr_gns_lr);
382 GNUNET_GNS_lookup_cancel (curr_gns_lr->lr);
383 GNUNET_free (curr_gns_lr);
384 }
385 /* free the keyshares array */
386 if (NULL != p_op->restored_keyshares)
387 GNUNET_free (p_op->restored_keyshares);
289 /* disconnect from namestore service */ 388 /* disconnect from namestore service */
290 if (NULL != p_op->ns_h) 389 if (NULL != p_op->ns_h)
291 GNUNET_NAMESTORE_disconnect (p_op->ns_h); 390 GNUNET_NAMESTORE_disconnect (p_op->ns_h);
391 /* disconnect from GNS service */
392 if (NULL != p_op->gns_h)
393 GNUNET_GNS_disconnect (p_op->gns_h);
394 /* cancel scheduled task */
292 if (NULL != p_op->sched_task) 395 if (NULL != p_op->sched_task)
293 GNUNET_SCHEDULER_cancel (p_op->sched_task); 396 GNUNET_SCHEDULER_cancel (p_op->sched_task);
397 /* cancel identity operation */
398 if (NULL != p_op->id_op)
399 GNUNET_IDENTITY_cancel (p_op->id_op);
294 GNUNET_free (p_op); 400 GNUNET_free (p_op);
295 GNUNET_free (plugin_op_wrap); 401 GNUNET_free (plugin_op_wrap);
296} 402}
@@ -848,7 +954,7 @@ start_gns_key_escrow (struct GNUNET_ESCROW_Handle *h,
848 return plugin_op_wrap; 954 return plugin_op_wrap;
849 } 955 }
850 p_op->pk = GNUNET_IDENTITY_ego_get_private_key (ego); 956 p_op->pk = GNUNET_IDENTITY_ego_get_private_key (ego);
851 p_op->userSecret = userSecret; 957 p_op->userSecret = GNUNET_strdup (userSecret);
852 958
853 if (ESCROW_PLUGIN_STATE_POST_INIT == ph.state) 959 if (ESCROW_PLUGIN_STATE_POST_INIT == ph.state)
854 { 960 {
@@ -864,6 +970,85 @@ start_gns_key_escrow (struct GNUNET_ESCROW_Handle *h,
864} 970}
865 971
866 972
973static void
974process_keyshares (struct ESCROW_PluginOperationWrapper *plugin_op_wrap)
975{
976 struct ESCROW_GnsPluginOperation *p_op;
977 struct GNUNET_CRYPTO_EcdsaPrivateKey *pk;
978
979 p_op = (struct ESCROW_GnsPluginOperation*)plugin_op_wrap->plugin_op;
980
981 // TODO: check if enough keyshares have been restored, combine them
982
983 p_op->restore_pk_cont (p_op->restore_pk_cont_cls, pk);
984}
985
986
987static void
988process_gns_lookup_result (void *cls,
989 uint32_t rd_count,
990 const struct GNUNET_GNSRECORD_Data *rd)
991{
992 struct GnsLookupRequestEntry *gns_lr = cls;
993 struct ESCROW_PluginOperationWrapper *plugin_op_wrap;
994 struct ESCROW_GnsPluginOperation *p_op;
995 sss_Keyshare keyshare;
996
997 plugin_op_wrap = gns_lr->plugin_op_wrap;
998 p_op = (struct ESCROW_GnsPluginOperation*)plugin_op_wrap->plugin_op;
999
1000 // TODO: handle result, store keyshare, check if this was the last keyshare
1001 GNUNET_memcpy (p_op->restored_keyshares[gns_lr->i],
1002 keyshare,
1003 sizeof (sss_Keyshare));
1004
1005 if (1) // TODO: last keyshare?
1006 process_keyshares(plugin_op_wrap);
1007}
1008
1009
1010static void
1011restore_private_key (struct ESCROW_PluginOperationWrapper *plugin_op_wrap,
1012 struct GNUNET_ESCROW_Anchor *escrowAnchor,
1013 PkContinuation cont,
1014 void *cont_cls)
1015{
1016 struct ESCROW_GnsPluginOperation *p_op;
1017 struct GNUNET_CRYPTO_EcdsaPrivateKey *curr_escrow_pk, *ego_pk;
1018 struct GNUNET_CRYPTO_EcdsaPublicKey curr_escrow_pub;
1019 char *curr_escrow_name;
1020 struct GnsLookupRequestEntry *curr_gns_lr;
1021
1022 p_op = (struct ESCROW_GnsPluginOperation*)plugin_op_wrap->plugin_op;
1023
1024 p_op->gns_h = GNUNET_GNS_connect (p_op->h->cfg);
1025 p_op->restore_pk_cont = cont;
1026 p_op->restore_pk_cont_cls = cont_cls;
1027 p_op->restored_keyshares = GNUNET_malloc (sizeof (sss_Keyshare) * p_op->shares);
1028
1029 for (uint8_t i = 0; i < p_op->shares; i++)
1030 {
1031 curr_escrow_pk = derive_private_key (p_op->ego->name, p_op->userSecret, i);
1032 curr_escrow_name = get_escrow_id_name (p_op->ego->name, i);
1033
1034 curr_gns_lr = GNUNET_new (struct GnsLookupRequestEntry);
1035 curr_gns_lr->plugin_op_wrap = plugin_op_wrap;
1036 curr_gns_lr->i = i;
1037 GNUNET_CRYPTO_ecdsa_key_get_public (curr_escrow_pk, &curr_escrow_pub);
1038 curr_gns_lr->lr = GNUNET_GNS_lookup (p_op->gns_h,
1039 NULL, // TODO: name
1040 &curr_escrow_pub,
1041 GNUNET_GNSRECORD_TYPE_ESCROW_KEYSHARE,
1042 GNUNET_GNS_LO_DEFAULT,
1043 &process_gns_lookup_result,
1044 curr_gns_lr);
1045 GNUNET_CONTAINER_DLL_insert_tail (p_op->gns_lrs_head,
1046 p_op->gns_lrs_tail,
1047 curr_gns_lr);
1048 }
1049}
1050
1051
867void 1052void
868verify_cont (void *cls) 1053verify_cont (void *cls)
869{ 1054{
@@ -877,6 +1062,30 @@ verify_cont (void *cls)
877} 1062}
878 1063
879 1064
1065static void
1066verify_restored_pk (void *cls,
1067 const struct GNUNET_CRYPTO_EcdsaPrivateKey *pk)
1068{
1069 struct ESCROW_PluginOperationWrapper *plugin_op_wrap = cls;
1070 struct ESCROW_GnsPluginOperation *p_op;
1071 const struct GNUNET_CRYPTO_EcdsaPrivateKey *ego_pk;
1072 char *ego_pk_string;
1073 int verificationResult;
1074
1075 p_op = (struct ESCROW_GnsPluginOperation *)plugin_op_wrap->plugin_op;
1076
1077 ego_pk = GNUNET_IDENTITY_ego_get_private_key (p_op->ego);
1078 ego_pk_string = GNUNET_CRYPTO_ecdsa_private_key_to_string (ego_pk);
1079 verificationResult = memcmp (pk,
1080 ego_pk,
1081 sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey))
1082 == 0 ? GNUNET_ESCROW_VALID : GNUNET_ESCROW_INVALID;
1083
1084 p_op->verify_wrap->verificationResult = verificationResult;
1085 verify_cont (plugin_op_wrap);
1086}
1087
1088
880/** 1089/**
881 * Verify the GNS escrow of the key 1090 * Verify the GNS escrow of the key
882 * 1091 *
@@ -890,7 +1099,7 @@ verify_cont (void *cls)
890 */ 1099 */
891struct ESCROW_PluginOperationWrapper * 1100struct ESCROW_PluginOperationWrapper *
892verify_gns_key_escrow (struct GNUNET_ESCROW_Handle *h, 1101verify_gns_key_escrow (struct GNUNET_ESCROW_Handle *h,
893 const struct GNUNET_IDENTITY_Ego *ego, 1102 struct GNUNET_IDENTITY_Ego *ego,
894 struct GNUNET_ESCROW_Anchor *escrowAnchor, 1103 struct GNUNET_ESCROW_Anchor *escrowAnchor,
895 GNUNET_SCHEDULER_TaskCallback cb, 1104 GNUNET_SCHEDULER_TaskCallback cb,
896 uint32_t op_id) 1105 uint32_t op_id)
@@ -909,22 +1118,122 @@ verify_gns_key_escrow (struct GNUNET_ESCROW_Handle *h,
909 p_op = (struct ESCROW_GnsPluginOperation *)plugin_op_wrap->plugin_op; 1118 p_op = (struct ESCROW_GnsPluginOperation *)plugin_op_wrap->plugin_op;
910 p_op->h = h; 1119 p_op->h = h;
911 p_op->cont = cb; 1120 p_op->cont = cb;
1121 p_op->ego = ego;
1122 p_op->userSecret = gns_anchor_data_to_string (h, escrowAnchor);
912 1123
913 w = GNUNET_new (struct ESCROW_Plugin_VerifyContinuationWrapper); 1124 w = GNUNET_new (struct ESCROW_Plugin_VerifyContinuationWrapper);
914 w->h = h; 1125 w->h = h;
915 w->op_id = op_id; 1126 w->op_id = op_id;
916 p_op->verify_wrap = w; 1127 p_op->verify_wrap = w;
917 1128
918 // TODO: implement 1129 if (NULL == ego)
919 w->verificationResult = GNUNET_ESCROW_INVALID; 1130 {
920 p_op->sched_task = GNUNET_SCHEDULER_add_now (&verify_cont, plugin_op_wrap); 1131 w->verificationResult = GNUNET_ESCROW_INVALID;
1132 w->emsg = _ ("ESCROW_verify was called with ego == NULL!\n");
1133 p_op->sched_task = GNUNET_SCHEDULER_add_now (&verify_cont, plugin_op_wrap);
1134 return plugin_op_wrap;
1135 }
1136
1137 restore_private_key (plugin_op_wrap,
1138 escrowAnchor,
1139 &verify_restored_pk,
1140 plugin_op_wrap);
1141
921 return plugin_op_wrap; 1142 return plugin_op_wrap;
922} 1143}
923 1144
1145
924void 1146void
925ego_created (const struct GNUNET_IDENTITY_Ego *ego) 1147ego_created (const struct GNUNET_IDENTITY_Ego *ego)
926{ 1148{
927 return; 1149 struct ESCROW_PluginOperationWrapper *curr;
1150 struct ESCROW_GnsPluginOperation *curr_p_op;
1151 char *ego_pk_string, *curr_pk_string;
1152
1153 ego_pk_string = GNUNET_CRYPTO_ecdsa_private_key_to_string (&ego->pk);
1154
1155 for (curr = ph.plugin_op_head; NULL != curr; curr = curr->next)
1156 {
1157 curr_p_op = (struct ESCROW_GnsPluginOperation *)curr->plugin_op;
1158 curr_pk_string = GNUNET_CRYPTO_ecdsa_private_key_to_string (curr_p_op->pk);
1159 // compare the strings of the private keys
1160 if (0 == strcmp (ego_pk_string, curr_pk_string))
1161 {
1162 // the ego was created due to a restore operation that is not yet finished
1163 curr_p_op->ego_wrap->ego = ego;
1164 curr_p_op->cont (curr_p_op->ego_wrap);
1165
1166 cleanup_plugin_operation (curr);
1167
1168 GNUNET_free (curr_pk_string);
1169 GNUNET_free (ego_pk_string);
1170 return;
1171 }
1172 GNUNET_free (curr_pk_string);
1173 }
1174 GNUNET_free (ego_pk_string);
1175}
1176
1177
1178static void
1179handle_restore_error (void *cls)
1180{
1181 struct ESCROW_PluginOperationWrapper *plugin_op_wrap = cls;
1182 struct ESCROW_GnsPluginOperation *p_op;
1183
1184 p_op = (struct ESCROW_GnsPluginOperation*)plugin_op_wrap->plugin_op;
1185 p_op->cont (p_op->ego_wrap);
1186
1187 cleanup_plugin_operation (plugin_op_wrap);
1188}
1189
1190
1191static void
1192id_create_finished (void *cls,
1193 const struct GNUNET_CRYPTO_EcdsaPrivateKey *pk,
1194 const char *emsg)
1195{
1196 struct ESCROW_PluginOperationWrapper *plugin_op_wrap = cls;
1197 struct ESCROW_GnsPluginOperation *p_op;
1198
1199 p_op = (struct ESCROW_GnsPluginOperation*)plugin_op_wrap->plugin_op;
1200
1201 if (NULL == pk)
1202 {
1203 if (NULL != emsg)
1204 {
1205 fprintf (stderr,
1206 "Identity create operation returned with error: %s\n",
1207 emsg);
1208 p_op->ego_wrap->emsg = _ ("Identity create failed!\n");
1209 }
1210 else
1211 p_op->ego_wrap->emsg = _ ("Failed to create ego!\n");
1212 p_op->ego_wrap->ego = NULL;
1213 p_op->cont (p_op->ego_wrap);
1214 return;
1215 }
1216
1217 /* no error occurred, p_op->restore_cont will be called in ego_created, which
1218 is called from ESCROW_list_ego after adding the new ego to our list */
1219 p_op->pk = pk;
1220}
1221
1222
1223static void
1224restore_ego_from_pk (void *cls,
1225 const struct GNUNET_CRYPTO_EcdsaPrivateKey *pk)
1226{
1227 struct ESCROW_PluginOperationWrapper *plugin_op_wrap = cls;
1228 struct ESCROW_GnsPluginOperation *p_op;
1229
1230 p_op = (struct ESCROW_GnsPluginOperation*)plugin_op_wrap->plugin_op;
1231
1232 p_op->id_op = GNUNET_IDENTITY_create (identity_handle,
1233 p_op->egoName,
1234 pk,
1235 &id_create_finished,
1236 plugin_op_wrap);
928} 1237}
929 1238
930 1239
@@ -959,14 +1268,30 @@ restore_gns_key_escrow (struct GNUNET_ESCROW_Handle *h,
959 1268
960 p_op = (struct ESCROW_GnsPluginOperation *)plugin_op_wrap->plugin_op; 1269 p_op = (struct ESCROW_GnsPluginOperation *)plugin_op_wrap->plugin_op;
961 p_op->h = h; 1270 p_op->h = h;
1271 // set cont here (has to be scheduled from the IDENTITY service when it finished)
1272 p_op->cont = cb;
1273 p_op->egoName = egoName;
1274 p_op->userSecret = gns_anchor_data_to_string (h, escrowAnchor);
962 1275
963 w = GNUNET_new (struct ESCROW_Plugin_EgoContinuationWrapper); 1276 w = GNUNET_new (struct ESCROW_Plugin_EgoContinuationWrapper);
964 w->h = h; 1277 w->h = h;
965 w->op_id = op_id; 1278 w->op_id = op_id;
1279 p_op->ego_wrap = w;
1280
1281 if (NULL == escrowAnchor)
1282 {
1283 w->ego = NULL;
1284 w->emsg = _ ("ESCROW_get was called with escrowAnchor == NULL!\n");
1285 // schedule handle_restore_error, which calls the callback and cleans up
1286 p_op->sched_task = GNUNET_SCHEDULER_add_now (&handle_restore_error, plugin_op_wrap);
1287 return plugin_op_wrap;
1288 }
1289
1290 restore_private_key (plugin_op_wrap,
1291 escrowAnchor,
1292 &restore_ego_from_pk,
1293 plugin_op_wrap);
966 1294
967 // TODO: implement
968 w->ego = NULL;
969 p_op->sched_task = GNUNET_SCHEDULER_add_now (cb, w);
970 return plugin_op_wrap; 1295 return plugin_op_wrap;
971} 1296}
972 1297