aboutsummaryrefslogtreecommitdiff
path: root/src/escrow/plugin_escrow_gns.c
diff options
context:
space:
mode:
authorjospaeth <spaethj@in.tum.de>2020-08-08 17:11:05 +0200
committerjospaeth <spaethj@in.tum.de>2020-08-08 17:11:05 +0200
commit7dc7d65cd35ac00c7495d81da4456b73c1928b11 (patch)
treea8d6ebd7562abe31827c60442399d9e83d67da1a /src/escrow/plugin_escrow_gns.c
parent41cfd97254ab205c8405f21900d26a6c2ab88127 (diff)
downloadgnunet-7dc7d65cd35ac00c7495d81da4456b73c1928b11.tar.gz
gnunet-7dc7d65cd35ac00c7495d81da4456b73c1928b11.zip
begin implementation of the GNS escrow
Diffstat (limited to 'src/escrow/plugin_escrow_gns.c')
-rw-r--r--src/escrow/plugin_escrow_gns.c462
1 files changed, 437 insertions, 25 deletions
diff --git a/src/escrow/plugin_escrow_gns.c b/src/escrow/plugin_escrow_gns.c
index b296f081a..8a3d4e033 100644
--- a/src/escrow/plugin_escrow_gns.c
+++ b/src/escrow/plugin_escrow_gns.c
@@ -29,10 +29,55 @@
29#include "gnunet_util_lib.h" 29#include "gnunet_util_lib.h"
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"
33#include "../identity/identity.h"
32#include <sss.h> 34#include <sss.h>
33#include <inttypes.h> 35#include <inttypes.h>
34 36
35 37
38struct IdentityOperationEntry
39{
40 /**
41 * DLL
42 */
43 struct IdentityOperationEntry *prev;
44
45 /**
46 * DLL
47 */
48 struct IdentityOperationEntry *next;
49
50 /**
51 * Identity operation
52 */
53 struct GNUNET_IDENTITY_Operation *id_op;
54
55 /**
56 * Private key of the respective ego
57 */
58 const struct GNUNET_CRYPTO_EcdsaPrivateKey *pk;
59};
60
61
62struct PkEntry
63{
64 /**
65 * DLL
66 */
67 struct PkEntry *prev;
68
69 /**
70 * DLL
71 */
72 struct PkEntry *next;
73
74 /**
75 * private key
76 */
77 const struct GNUNET_CRYPTO_EcdsaPrivateKey *pk;
78};
79
80
36struct ESCROW_GnsPluginOperation 81struct ESCROW_GnsPluginOperation
37{ 82{
38 /** 83 /**
@@ -44,6 +89,72 @@ struct ESCROW_GnsPluginOperation
44 * Scheduler task the SCHEDULE operation returns (needed for cancellation) 89 * Scheduler task the SCHEDULE operation returns (needed for cancellation)
45 */ 90 */
46 struct GNUNET_SCHEDULER_Task *sched_task; 91 struct GNUNET_SCHEDULER_Task *sched_task;
92
93 /**
94 * Namestore handle
95 */
96 struct GNUNET_NAMESTORE_Handle *ns_h;
97
98 /**
99 * Continuation for a plugin operation (e.g. used for restore, as this
100 * callback has to be called from the IDENTITY service after finishing)
101 */
102 ESCROW_Plugin_Continuation cont;
103
104 /**
105 * Ego continuation wrapper
106 */
107 struct ESCROW_Plugin_EgoContinuationWrapper *ego_wrap;
108
109 /**
110 * Anchor continuation wrapper
111 */
112 struct ESCROW_Plugin_AnchorContinuationWrapper *anchor_wrap;
113
114 /**
115 * Verify continuation wrapper
116 */
117 struct ESCROW_Plugin_VerifyContinuationWrapper *verify_wrap;
118
119 /**
120 * Counter for the created escrow identities
121 */
122 uint8_t escrow_id_counter;
123
124 /**
125 * Number of shares
126 */
127 uint8_t shares;
128
129 /**
130 * Share threshold
131 */
132 uint8_t share_threshold;
133
134 /**
135 * Private key of the ego
136 */
137 const struct GNUNET_CRYPTO_EcdsaPrivateKey *pk;
138
139 /**
140 * DLL head for identity operations
141 */
142 struct IdentityOperationEntry *id_ops_head;
143
144 /**
145 * DLL tail for identity operations
146 */
147 struct IdentityOperationEntry *id_ops_tail;
148
149 /**
150 * DLL head for escrow private keys
151 */
152 struct PkEntry *escrow_pks_head;
153
154 /**
155 * DLL tail for escrow private keys
156 */
157 struct PkEntry *escrow_pks_tail;
47}; 158};
48 159
49/** 160/**
@@ -58,6 +169,258 @@ struct ESCROW_PluginHandle ph;
58 169
59 170
60/** 171/**
172 * Clean up a plugin operation, i.e. remove it from the list and
173 * free the respective memory
174 */
175void
176cleanup_plugin_operation (struct ESCROW_PluginOperationWrapper *plugin_op_wrap)
177{
178 struct ESCROW_GnsPluginOperation *p_op;
179 struct IdentityOperationEntry *curr_id_op;
180 struct PkEntry *curr_pk;
181
182 p_op = (struct ESCROW_GnsPluginOperation*)plugin_op_wrap->plugin_op;
183
184 GNUNET_CONTAINER_DLL_remove (ph.plugin_op_head,
185 ph.plugin_op_tail,
186 plugin_op_wrap);
187 if (NULL != p_op->anchor_wrap)
188 GNUNET_free (p_op->anchor_wrap);
189 if (NULL != p_op->ego_wrap)
190 GNUNET_free (p_op->ego_wrap);
191 if (NULL != p_op->verify_wrap)
192 GNUNET_free (p_op->verify_wrap);
193 /* clean up identity operation list */
194 for (curr_id_op = p_op->id_ops_head; NULL != curr_id_op; curr_id_op = curr_id_op->next)
195 {
196 GNUNET_CONTAINER_DLL_remove (p_op->id_ops_head,
197 p_op->id_ops_tail,
198 curr_id_op);
199 GNUNET_free (curr_id_op->id_op);
200 GNUNET_free (curr_id_op);
201 }
202 /* clean up escrow pk list */
203 for (curr_pk = p_op->escrow_pks_head; NULL != curr_pk; curr_pk = curr_pk->next)
204 {
205 GNUNET_CONTAINER_DLL_remove (p_op->escrow_pks_head,
206 p_op->escrow_pks_tail,
207 curr_pk);
208 GNUNET_free (curr_pk);
209 }
210 /* disconnect from namestore service */
211 GNUNET_NAMESTORE_disconnect (p_op->ns_h);
212 GNUNET_free (p_op);
213 GNUNET_free (plugin_op_wrap);
214}
215
216
217void
218start_cont (void *cls)
219{
220 struct ESCROW_PluginOperationWrapper *plugin_op_wrap = cls;
221 struct ESCROW_GnsPluginOperation *p_op;
222
223 p_op = (struct ESCROW_GnsPluginOperation*)plugin_op_wrap->plugin_op;
224 p_op->cont (p_op->anchor_wrap);
225
226 cleanup_plugin_operation (plugin_op_wrap);
227}
228
229
230sss_Keyshare *
231split_private_key (struct ESCROW_GnsPluginOperation *p_op)
232{
233 sss_Keyshare *keyshares;
234
235 keyshares = GNUNET_malloc (sizeof (sss_Keyshare) * p_op->shares);
236 sss_create_keyshares (keyshares,
237 p_op->pk->d,
238 p_op->shares,
239 p_op->share_threshold);
240
241 return keyshares;
242}
243
244
245void
246distribute_keyshares (struct ESCROW_GnsPluginOperation *p_op,
247 sss_Keyshare *keyshares)
248{
249 struct GNUNET_NAMESTORE_Handle *ns_h;
250 struct PkEntry *curr_pk;
251 char *curr_label;
252
253 ns_h = GNUNET_NAMESTORE_connect (p_op->h->cfg);
254 p_op->ns_h = ns_h;
255
256 for (curr_pk = p_op->escrow_pks_head; NULL != curr_pk; curr_pk = curr_pk->next)
257 {
258 // TODO: implement
259 curr_label = NULL;
260 GNUNET_NAMESTORE_records_store (ns_h,
261 curr_pk->pk,
262 curr_label,
263 0,
264 NULL,
265 NULL,
266 NULL);
267 }
268}
269
270
271void
272escrow_ids_finished (struct ESCROW_GnsPluginOperation *p_op)
273{
274 sss_Keyshare *keyshares;
275 struct GNUNET_ESCROW_Anchor *anchor;
276 int anchorDataSize;
277
278 /* split the private key (SSS) */
279 keyshares = split_private_key (p_op);
280 if (NULL == keyshares)
281 {
282 p_op->anchor_wrap->escrowAnchor = NULL;
283 p_op->sched_task = GNUNET_SCHEDULER_add_now (&start_cont, p_op);
284 return;
285 }
286
287 /* distribute the shares to the identities */
288 distribute_keyshares (p_op, keyshares);
289
290 // TODO: implement
291 anchorDataSize = 0; // TODO!
292 anchor = GNUNET_malloc (sizeof (struct GNUNET_ESCROW_Anchor) + anchorDataSize);
293
294 p_op->anchor_wrap->escrowAnchor = anchor;
295
296 /* call the continuation */
297 p_op->cont (p_op->anchor_wrap);
298}
299
300
301void
302escrow_id_created (void *cls,
303 const struct GNUNET_CRYPTO_EcdsaPrivateKey *pk,
304 const char *emsg)
305{
306 struct ESCROW_GnsPluginOperation *p_op = cls;
307 struct IdentityOperationEntry *curr_id_op;
308 struct PkEntry *pk_entry;
309
310 if (NULL == pk)
311 {
312 if (NULL != emsg)
313 fprintf (stderr,
314 "Identity create operation returned with error: %s\n",
315 emsg);
316 else
317 fprintf (stderr, "Failed to create ego!");
318 p_op->anchor_wrap->escrowAnchor = NULL;
319 p_op->cont (p_op->anchor_wrap);
320 return;
321 }
322
323 /* escrow identity successfully created */
324 for (curr_id_op = p_op->id_ops_head; NULL != curr_id_op; curr_id_op = curr_id_op->next)
325 {
326 if (pk == curr_id_op->pk)
327 {
328 GNUNET_CONTAINER_DLL_remove (p_op->id_ops_head,
329 p_op->id_ops_tail,
330 curr_id_op);
331 GNUNET_free (curr_id_op);
332 break;
333 }
334 }
335
336 /* insert pk into our list */
337 pk_entry = GNUNET_new (struct PkEntry);
338 GNUNET_CONTAINER_DLL_insert_tail (p_op->escrow_pks_head,
339 p_op->escrow_pks_tail,
340 pk_entry);
341
342 p_op->escrow_id_counter++;
343 if (p_op->escrow_id_counter == p_op->shares)
344 {
345 escrow_ids_finished (p_op);
346 }
347}
348
349
350static uint8_t
351count_digits (uint8_t n)
352{
353 uint8_t i = 0;
354 while (n != 0)
355 {
356 i++;
357 n /= 10;
358 }
359 return i;
360}
361
362
363static char *
364get_escrow_id_name (const char *name,
365 uint8_t i)
366{
367 char *str, *prefix, *number;
368 uint8_t j = 0;
369
370 prefix = "escrow-id_";
371 number = GNUNET_malloc (count_digits (i) + 1);
372 sprintf (number, "%d", i);
373
374 str = GNUNET_malloc (strlen (prefix)
375 + strlen (name)
376 + 1
377 + strlen (number)
378 + 1);
379
380 memcpy (str, prefix, strlen (prefix));
381 j += strlen (prefix);
382 memcpy (str + j, name, strlen (name));
383 j += strlen (name);
384 str[j++] = '_';
385 memcpy (str + j, number, strlen (number));
386 j += strlen (number);
387 str[j] = '\0';
388
389 GNUNET_free (number);
390
391 return str;
392}
393
394
395static void
396create_escrow_identities (struct ESCROW_GnsPluginOperation *p_op,
397 const char *name)
398{
399 struct GNUNET_CRYPTO_EcdsaPrivateKey *curr_pk;
400 char *curr_name;
401 struct IdentityOperationEntry *curr_id_op;
402
403 for (uint8_t i = 0; i < p_op->shares; i++)
404 {
405 curr_pk = NULL; // TODO: derive key
406 curr_name = get_escrow_id_name (name, i);
407
408 /* store the identity operation in our list */
409 curr_id_op = GNUNET_new (struct IdentityOperationEntry);
410 curr_id_op->pk = curr_pk;
411 curr_id_op->id_op = GNUNET_IDENTITY_create (identity_handle,
412 curr_name,
413 curr_pk,
414 &escrow_id_created,
415 p_op);
416 GNUNET_CONTAINER_DLL_insert (p_op->id_ops_head,
417 p_op->id_ops_tail,
418 curr_id_op);
419 }
420}
421
422
423/**
61 * Start the GNS escrow of the key 424 * Start the GNS escrow of the key
62 * 425 *
63 * @param h the handle for the escrow component 426 * @param h the handle for the escrow component
@@ -73,10 +436,6 @@ start_gns_key_escrow (struct GNUNET_ESCROW_Handle *h,
73 GNUNET_SCHEDULER_TaskCallback cb, 436 GNUNET_SCHEDULER_TaskCallback cb,
74 uint32_t op_id) 437 uint32_t op_id)
75{ 438{
76 const struct GNUNET_CRYPTO_EcdsaPrivateKey *pk;
77 sss_Keyshare keyshares;
78 struct GNUNET_ESCROW_Anchor *anchor;
79 int anchorDataSize;
80 struct ESCROW_PluginOperationWrapper *plugin_op_wrap; 439 struct ESCROW_PluginOperationWrapper *plugin_op_wrap;
81 struct ESCROW_GnsPluginOperation *p_op; 440 struct ESCROW_GnsPluginOperation *p_op;
82 struct ESCROW_Plugin_AnchorContinuationWrapper *w; 441 struct ESCROW_Plugin_AnchorContinuationWrapper *w;
@@ -91,20 +450,22 @@ start_gns_key_escrow (struct GNUNET_ESCROW_Handle *h,
91 450
92 p_op = (struct ESCROW_GnsPluginOperation *)plugin_op_wrap->plugin_op; 451 p_op = (struct ESCROW_GnsPluginOperation *)plugin_op_wrap->plugin_op;
93 p_op->h = h; 452 p_op->h = h;
453 p_op->cont = cb;
94 454
95 w = GNUNET_new (struct ESCROW_Plugin_AnchorContinuationWrapper); 455 w = GNUNET_new (struct ESCROW_Plugin_AnchorContinuationWrapper);
96 w->h = h; 456 w->h = h;
97 w->op_id = op_id; 457 w->op_id = op_id;
458 p_op->anchor_wrap = w;
98 459
99 if (NULL == ego) 460 if (NULL == ego)
100 { 461 {
101 w->escrowAnchor = NULL; 462 w->escrowAnchor = NULL;
102 p_op->sched_task = GNUNET_SCHEDULER_add_now (cb, w); 463 p_op->sched_task = GNUNET_SCHEDULER_add_now (&start_cont, plugin_op_wrap);
103 return plugin_op_wrap; 464 return plugin_op_wrap;
104 } 465 }
105 pk = GNUNET_IDENTITY_ego_get_private_key (ego); 466 p_op->pk = GNUNET_IDENTITY_ego_get_private_key (ego);
106 467
107 // split the private key (SSS) 468 // get config
108 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (h->cfg, 469 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (h->cfg,
109 "escrow", 470 "escrow",
110 "gns_shares", 471 "gns_shares",
@@ -112,7 +473,7 @@ start_gns_key_escrow (struct GNUNET_ESCROW_Handle *h,
112 { 473 {
113 fprintf (stderr, "Number of shares not specified in config!"); 474 fprintf (stderr, "Number of shares not specified in config!");
114 w->escrowAnchor = NULL; 475 w->escrowAnchor = NULL;
115 p_op->sched_task = GNUNET_SCHEDULER_add_now (cb, w); 476 p_op->sched_task = GNUNET_SCHEDULER_add_now (&start_cont, plugin_op_wrap);
116 return plugin_op_wrap; 477 return plugin_op_wrap;
117 } 478 }
118 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (h->cfg, 479 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (h->cfg,
@@ -122,27 +483,32 @@ start_gns_key_escrow (struct GNUNET_ESCROW_Handle *h,
122 { 483 {
123 fprintf (stderr, "Share threshold not specified in config"); 484 fprintf (stderr, "Share threshold not specified in config");
124 w->escrowAnchor = NULL; 485 w->escrowAnchor = NULL;
125 p_op->sched_task = GNUNET_SCHEDULER_add_now (cb, w); 486 p_op->sched_task = GNUNET_SCHEDULER_add_now (&start_cont, plugin_op_wrap);
126 return plugin_op_wrap; 487 return plugin_op_wrap;
127 } 488 }
128 sss_create_keyshares (&keyshares, 489 p_op->shares = (uint8_t)shares;
129 pk->d, 490 p_op->share_threshold = (uint8_t)share_threshold;
130 (uint8_t)shares,
131 (uint8_t)share_threshold);
132 491
133 // create the escrow identities 492 /* create the escrow identities */
493 create_escrow_identities (p_op, ego->name);
134 494
135 // distribute the shares to the identities 495 /* operation continues in escrow_ids_finished
496 after all escrow identities are created */
136 497
498 return plugin_op_wrap;
499}
137 500
138 // TODO: implement 501
139 anchorDataSize = 0; // TODO! 502void
140 anchor = GNUNET_malloc (sizeof (struct GNUNET_ESCROW_Anchor) + anchorDataSize); 503verify_cont (void *cls)
504{
505 struct ESCROW_PluginOperationWrapper *plugin_op_wrap = cls;
506 struct ESCROW_GnsPluginOperation *p_op;
141 507
142 w->escrowAnchor = anchor; 508 p_op = (struct ESCROW_GnsPluginOperation*)plugin_op_wrap->plugin_op;
509 p_op->cont (p_op->verify_wrap);
143 510
144 p_op->sched_task = GNUNET_SCHEDULER_add_now (cb, w); 511 cleanup_plugin_operation (plugin_op_wrap);
145 return plugin_op_wrap;
146} 512}
147 513
148 514
@@ -177,14 +543,16 @@ verify_gns_key_escrow (struct GNUNET_ESCROW_Handle *h,
177 543
178 p_op = (struct ESCROW_GnsPluginOperation *)plugin_op_wrap->plugin_op; 544 p_op = (struct ESCROW_GnsPluginOperation *)plugin_op_wrap->plugin_op;
179 p_op->h = h; 545 p_op->h = h;
546 p_op->cont = cb;
180 547
181 w = GNUNET_new (struct ESCROW_Plugin_VerifyContinuationWrapper); 548 w = GNUNET_new (struct ESCROW_Plugin_VerifyContinuationWrapper);
182 w->h = h; 549 w->h = h;
183 w->op_id = op_id; 550 w->op_id = op_id;
551 p_op->verify_wrap = w;
184 552
185 // TODO: implement 553 // TODO: implement
186 w->verificationResult = GNUNET_ESCROW_INVALID; 554 w->verificationResult = GNUNET_ESCROW_INVALID;
187 p_op->sched_task = GNUNET_SCHEDULER_add_now (cb, w); 555 p_op->sched_task = GNUNET_SCHEDULER_add_now (&verify_cont, plugin_op_wrap);
188 return plugin_op_wrap; 556 return plugin_op_wrap;
189} 557}
190 558
@@ -203,7 +571,7 @@ verify_gns_key_escrow (struct GNUNET_ESCROW_Handle *h,
203struct ESCROW_PluginOperationWrapper * 571struct ESCROW_PluginOperationWrapper *
204restore_gns_key_escrow (struct GNUNET_ESCROW_Handle *h, 572restore_gns_key_escrow (struct GNUNET_ESCROW_Handle *h,
205 struct GNUNET_ESCROW_Anchor *escrowAnchor, 573 struct GNUNET_ESCROW_Anchor *escrowAnchor,
206 char *egoName, 574 const char *egoName,
207 GNUNET_SCHEDULER_TaskCallback cb, 575 GNUNET_SCHEDULER_TaskCallback cb,
208 uint32_t op_id) 576 uint32_t op_id)
209{ 577{
@@ -308,8 +676,52 @@ gns_anchor_data_to_string (struct GNUNET_ESCROW_Handle *h,
308void 676void
309cancel_gns_operation (struct ESCROW_PluginOperationWrapper *plugin_op_wrap) 677cancel_gns_operation (struct ESCROW_PluginOperationWrapper *plugin_op_wrap)
310{ 678{
311 // TODO: implement 679 struct ESCROW_PluginOperationWrapper *curr;
312 return; 680 struct ESCROW_GnsPluginOperation *p_op;
681 struct IdentityOperationEntry *curr_id_op;
682 struct PkEntry *curr_pk;
683
684 for (curr = ph.plugin_op_head; NULL != curr; curr = curr->next)
685 {
686 if (curr == plugin_op_wrap)
687 {
688 GNUNET_CONTAINER_DLL_remove (ph.plugin_op_head,
689 ph.plugin_op_tail,
690 curr);
691 p_op = (struct ESCROW_GnsPluginOperation *)curr->plugin_op;
692
693 /* clean up the identity operation list */
694 for (curr_id_op = p_op->id_ops_head; NULL != curr_id_op; curr_id_op = curr_id_op->next)
695 {
696 GNUNET_CONTAINER_DLL_remove (p_op->id_ops_head,
697 p_op->id_ops_tail,
698 curr_id_op);
699 GNUNET_IDENTITY_cancel (curr_id_op->id_op);
700 GNUNET_free (curr_id_op);
701 }
702
703 /* clean up the escrow pk list */
704 for (curr_pk = p_op->escrow_pks_head; NULL != curr_pk; curr_pk = curr_pk->next)
705 {
706 GNUNET_CONTAINER_DLL_remove (p_op->escrow_pks_head,
707 p_op->escrow_pks_tail,
708 curr_pk);
709 GNUNET_free (curr_pk);
710 }
711
712 if (NULL != p_op->ns_h)
713 {
714 GNUNET_NAMESTORE_disconnect (p_op->ns_h);
715 p_op->ns_h = NULL;
716 }
717
718 if (NULL != p_op->sched_task)
719 GNUNET_SCHEDULER_cancel (p_op->sched_task);
720 GNUNET_free (p_op);
721 GNUNET_free (curr);
722 return;
723 }
724 }
313} 725}
314 726
315 727