aboutsummaryrefslogtreecommitdiff
path: root/src/escrow/plugin_escrow_gns.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/escrow/plugin_escrow_gns.c')
-rw-r--r--src/escrow/plugin_escrow_gns.c1449
1 files changed, 1449 insertions, 0 deletions
diff --git a/src/escrow/plugin_escrow_gns.c b/src/escrow/plugin_escrow_gns.c
new file mode 100644
index 000000000..4f9ce64a1
--- /dev/null
+++ b/src/escrow/plugin_escrow_gns.c
@@ -0,0 +1,1449 @@
1/*
2 This file is part of GNUnet
3 Copyright (C) 2020 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
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 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
21/**
22 * @file escrow/plugin_escrow_gns.c
23 * @brief escrow-plugin-gns escrow plugin for the escrow of the key
24 * using GNS and escrow identities
25 *
26 * @author Johannes Späth
27 */
28#include "platform.h"
29#include "gnunet_util_lib.h"
30#include "gnunet_escrow_plugin.h"
31#include "escrow_plugin_helper.h"
32#include "gnunet_namestore_service.h"
33#include "gnunet_gns_service.h"
34#include "gnunet_gnsrecord_lib.h"
35#include "../identity/identity.h"
36#include <sss.h>
37#include <inttypes.h>
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
53struct IdentityOperationEntry
54{
55 /**
56 * DLL
57 */
58 struct IdentityOperationEntry *prev;
59
60 /**
61 * DLL
62 */
63 struct IdentityOperationEntry *next;
64
65 /**
66 * Identity operation
67 */
68 struct GNUNET_IDENTITY_Operation *id_op;
69
70 /**
71 * Private key of the respective ego
72 */
73 const struct GNUNET_CRYPTO_EcdsaPrivateKey *pk;
74
75 /**
76 * Name of the respective ego
77 */
78 const char *name;
79
80 /**
81 * Index of the respective share
82 */
83 uint8_t i;
84
85 /**
86 * The plugin operation that started the identity operation
87 */
88 struct ESCROW_PluginOperationWrapper *plugin_op_wrap;
89};
90
91
92struct PkEntry
93{
94 /**
95 * DLL
96 */
97 struct PkEntry *prev;
98
99 /**
100 * DLL
101 */
102 struct PkEntry *next;
103
104 /**
105 * private key
106 */
107 const struct GNUNET_CRYPTO_EcdsaPrivateKey *pk;
108
109 /**
110 * index of the respective share
111 */
112 uint8_t i;
113};
114
115
116struct NamestoreQueueEntry
117{
118 /**
119 * DLL
120 */
121 struct NamestoreQueueEntry *prev;
122
123 /**
124 * DLL
125 */
126 struct NamestoreQueueEntry *next;
127
128 /**
129 * Namestore queue entry
130 */
131 struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
132
133 /**
134 * Plugin operation that called the namestore operation
135 */
136 struct ESCROW_PluginOperationWrapper *plugin_op_wrap;
137};
138
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
169struct ESCROW_GnsPluginOperation
170{
171 /**
172 * Handle for the escrow component
173 */
174 struct GNUNET_ESCROW_Handle *h;
175
176 /**
177 * Scheduler task the SCHEDULE operation returns (needed for cancellation)
178 */
179 struct GNUNET_SCHEDULER_Task *sched_task;
180
181 /**
182 * Namestore handle
183 */
184 struct GNUNET_NAMESTORE_Handle *ns_h;
185
186 /**
187 * GNS handle
188 */
189 struct GNUNET_GNS_Handle *gns_h;
190
191 /**
192 * Continuation for a plugin operation (e.g. used for restore, as this
193 * callback has to be called from the IDENTITY service after finishing)
194 */
195 ESCROW_Plugin_Continuation cont;
196
197 /**
198 * Ego continuation wrapper
199 */
200 struct ESCROW_Plugin_EgoContinuationWrapper *ego_wrap;
201
202 /**
203 * Anchor continuation wrapper
204 */
205 struct ESCROW_Plugin_AnchorContinuationWrapper *anchor_wrap;
206
207 /**
208 * Verify continuation wrapper
209 */
210 struct ESCROW_Plugin_VerifyContinuationWrapper *verify_wrap;
211
212 /**
213 * Counter for the created escrow identities
214 */
215 uint8_t escrow_id_counter;
216
217 /**
218 * Number of shares
219 */
220 uint8_t shares;
221
222 /**
223 * Share threshold
224 */
225 uint8_t share_threshold;
226
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 /**
248 * The ego
249 */
250 struct GNUNET_IDENTITY_Ego *ego;
251
252 /**
253 * The name of the ego
254 */
255 const char *egoName;
256
257 /**
258 * Private key of the ego
259 */
260 const struct GNUNET_CRYPTO_EcdsaPrivateKey *pk;
261
262 /**
263 * User secret string
264 */
265 char *userSecret;
266
267 /**
268 * DLL head for identity operations
269 */
270 struct IdentityOperationEntry *id_ops_head;
271
272 /**
273 * DLL tail for identity operations
274 */
275 struct IdentityOperationEntry *id_ops_tail;
276
277 /**
278 * DLL head for escrow private keys
279 */
280 struct PkEntry *escrow_pks_head;
281
282 /**
283 * DLL tail for escrow private keys
284 */
285 struct PkEntry *escrow_pks_tail;
286
287 /**
288 * DLL head for namestore queue entries
289 */
290 struct NamestoreQueueEntry *ns_qes_head;
291
292 /**
293 * DLL tail for namestore queue entries
294 */
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;
306};
307
308/**
309 * Identity handle
310 */
311static struct GNUNET_IDENTITY_Handle *identity_handle;
312
313/**
314 * Handle for the plugin instance
315 */
316struct ESCROW_PluginHandle ph;
317
318
319/**
320 * Clean up a plugin operation, i.e. remove it from the list and
321 * free the respective memory
322 */
323void
324cleanup_plugin_operation (struct ESCROW_PluginOperationWrapper *plugin_op_wrap)
325{
326 struct ESCROW_GnsPluginOperation *p_op;
327 struct IdentityOperationEntry *curr_id_op, *next_id_op;
328 struct PkEntry *curr_pk, *next_pk;
329 struct NamestoreQueueEntry *curr_ns_qe, *next_ns_qe;
330 struct GnsLookupRequestEntry *curr_gns_lr, *next_gns_lr;
331
332 p_op = (struct ESCROW_GnsPluginOperation*)plugin_op_wrap->plugin_op;
333
334 GNUNET_CONTAINER_DLL_remove (ph.plugin_op_head,
335 ph.plugin_op_tail,
336 plugin_op_wrap);
337 if (NULL != p_op->anchor_wrap)
338 GNUNET_free (p_op->anchor_wrap);
339 if (NULL != p_op->ego_wrap)
340 GNUNET_free (p_op->ego_wrap);
341 if (NULL != p_op->verify_wrap)
342 GNUNET_free (p_op->verify_wrap);
343 if (NULL != p_op->userSecret)
344 GNUNET_free (p_op->userSecret);
345 /* clean up identity operation list */
346 for (curr_id_op = p_op->id_ops_head; NULL != curr_id_op; curr_id_op = next_id_op)
347 {
348 next_id_op = curr_id_op->next;
349 GNUNET_CONTAINER_DLL_remove (p_op->id_ops_head,
350 p_op->id_ops_tail,
351 curr_id_op);
352 GNUNET_IDENTITY_cancel (curr_id_op->id_op);
353 GNUNET_free (curr_id_op);
354 }
355 /* clean up escrow pk list */
356 for (curr_pk = p_op->escrow_pks_head; NULL != curr_pk; curr_pk = next_pk)
357 {
358 next_pk = curr_pk->next;
359 GNUNET_CONTAINER_DLL_remove (p_op->escrow_pks_head,
360 p_op->escrow_pks_tail,
361 curr_pk);
362 GNUNET_free (curr_pk);
363 }
364 /* clean up namestore operation list */
365 for (curr_ns_qe = p_op->ns_qes_head; NULL != curr_ns_qe; curr_ns_qe = next_ns_qe)
366 {
367 next_ns_qe = curr_ns_qe->next;
368 GNUNET_CONTAINER_DLL_remove (p_op->ns_qes_head,
369 p_op->ns_qes_tail,
370 curr_ns_qe);
371 // also frees the curr_ns_qe->ns_qe
372 GNUNET_NAMESTORE_cancel (curr_ns_qe->ns_qe);
373 GNUNET_free (curr_ns_qe);
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);
388 /* disconnect from namestore service */
389 if (NULL != 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 */
395 if (NULL != 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);
400 GNUNET_free (p_op);
401 GNUNET_free (plugin_op_wrap);
402}
403
404
405void
406start_cont (void *cls)
407{
408 struct ESCROW_PluginOperationWrapper *plugin_op_wrap = cls;
409 struct ESCROW_GnsPluginOperation *p_op;
410
411 p_op = (struct ESCROW_GnsPluginOperation*)plugin_op_wrap->plugin_op;
412 p_op->cont (p_op->anchor_wrap);
413
414 cleanup_plugin_operation (plugin_op_wrap);
415}
416
417
418sss_Keyshare *
419split_private_key (struct ESCROW_GnsPluginOperation *p_op)
420{
421 sss_Keyshare *keyshares;
422
423 keyshares = GNUNET_malloc (sizeof (sss_Keyshare) * p_op->shares);
424 sss_create_keyshares (keyshares,
425 p_op->pk->d,
426 p_op->shares,
427 p_op->share_threshold);
428
429 return keyshares;
430}
431
432
433static void
434keyshare_distribution_finished (struct ESCROW_PluginOperationWrapper *plugin_op_wrap)
435{
436 struct ESCROW_GnsPluginOperation *p_op;
437 struct GNUNET_ESCROW_Anchor *anchor;
438 int anchorDataSize;
439
440 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "All keyshares distributed\n");
441
442 p_op = (struct ESCROW_GnsPluginOperation *)plugin_op_wrap->plugin_op;
443
444 anchorDataSize = strlen(p_op->userSecret) + 1;
445 anchor = GNUNET_malloc (sizeof (struct GNUNET_ESCROW_Anchor) + anchorDataSize);
446 anchor->method = GNUNET_ESCROW_KEY_GNS;
447 anchor->size = anchorDataSize;
448 GNUNET_memcpy (&anchor[1], p_op->userSecret, anchorDataSize);
449
450 p_op->anchor_wrap->escrowAnchor = anchor;
451
452 /* set the last escrow time */
453 ESCROW_update_escrow_status (p_op->h, p_op->ego, "gns");
454
455 /* call the continuation */
456 start_cont (plugin_op_wrap);
457}
458
459
460static void
461keyshare_distributed (void *cls,
462 int32_t success,
463 const char *emsg)
464{
465 struct NamestoreQueueEntry *ns_qe = cls;
466 struct ESCROW_PluginOperationWrapper *plugin_op_wrap;
467 struct ESCROW_GnsPluginOperation *p_op;
468
469 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Keyshare distributed\n");
470
471 plugin_op_wrap = ns_qe->plugin_op_wrap;
472 p_op = (struct ESCROW_GnsPluginOperation *)plugin_op_wrap->plugin_op;
473
474 if (GNUNET_SYSERR == success)
475 {
476 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
477 "Failed to store keyshare %s\n",
478 emsg);
479 p_op->anchor_wrap->escrowAnchor = NULL;
480 p_op->anchor_wrap->emsg = _ ("Keyshare distribution failed!\n");
481 p_op->cont (p_op->anchor_wrap);
482 // this also cancels all running namestore operations
483 cleanup_plugin_operation (plugin_op_wrap);
484 }
485
486 // remove qe from list, check if all namestore operations are finished
487 GNUNET_CONTAINER_DLL_remove (p_op->ns_qes_head,
488 p_op->ns_qes_tail,
489 ns_qe);
490 GNUNET_free (ns_qe);
491 if (NULL == p_op->ns_qes_head)
492 keyshare_distribution_finished (plugin_op_wrap);
493}
494
495
496static char *
497get_label (const char *userSecret)
498{
499 char *label;
500 struct GNUNET_HashCode hash;
501 struct GNUNET_CRYPTO_HashAsciiEncoded hashEnc;
502
503 // the label is the hash of the userSecret
504 GNUNET_CRYPTO_hash (userSecret, strlen (userSecret), &hash);
505 GNUNET_CRYPTO_hash_to_enc (&hash, &hashEnc);
506 label = GNUNET_strdup ((char *)hashEnc.encoding);
507
508 return label;
509}
510
511
512static int
513distribute_keyshares (struct ESCROW_PluginOperationWrapper *plugin_op_wrap,
514 sss_Keyshare *keyshares)
515{
516 struct ESCROW_GnsPluginOperation *p_op;
517 struct GNUNET_NAMESTORE_Handle *ns_h;
518 struct NamestoreQueueEntry *curr_ns_qe;
519 struct PkEntry *curr_pk;
520 char *curr_label;
521 struct GNUNET_GNSRECORD_Data curr_rd[1];
522
523 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Distributing keyshares\n");
524
525 p_op = (struct ESCROW_GnsPluginOperation *)plugin_op_wrap->plugin_op;
526
527 ns_h = GNUNET_NAMESTORE_connect (p_op->h->cfg);
528 p_op->ns_h = ns_h;
529
530 for (curr_pk = p_op->escrow_pks_head; NULL != curr_pk; curr_pk = curr_pk->next)
531 {
532 curr_label = get_label (p_op->userSecret);
533 curr_ns_qe = GNUNET_new (struct NamestoreQueueEntry);
534
535 curr_rd[0].data_size = sizeof (sss_Keyshare);
536 curr_rd[0].data = keyshares[curr_pk->i];
537 curr_rd[0].record_type = GNUNET_GNSRECORD_TYPE_ESCROW_KEYSHARE;
538 curr_rd[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
539 // TODO: config param?
540 curr_rd[0].expiration_time = 30 * 24 * GNUNET_TIME_relative_get_hour_().rel_value_us;
541
542 curr_ns_qe->plugin_op_wrap = plugin_op_wrap;
543 curr_ns_qe->ns_qe = GNUNET_NAMESTORE_records_store (ns_h,
544 curr_pk->pk,
545 curr_label,
546 1,
547 curr_rd,
548 &keyshare_distributed,
549 curr_ns_qe);
550 GNUNET_CONTAINER_DLL_insert_tail (p_op->ns_qes_head,
551 p_op->ns_qes_tail,
552 curr_ns_qe);
553 GNUNET_free (curr_label);
554 }
555
556 return GNUNET_OK;
557}
558
559
560void
561escrow_ids_finished (struct ESCROW_PluginOperationWrapper *plugin_op_wrap)
562{
563 struct ESCROW_GnsPluginOperation *p_op;
564 sss_Keyshare *keyshares;
565
566 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "All escrow identities created\n");
567
568 p_op = (struct ESCROW_GnsPluginOperation *)plugin_op_wrap->plugin_op;
569
570 /* split the private key (SSS) */
571 keyshares = split_private_key (p_op);
572 if (NULL == keyshares)
573 {
574 p_op->anchor_wrap->escrowAnchor = NULL;
575 p_op->anchor_wrap->emsg = _ ("Failed to split the key!\n");
576 start_cont (plugin_op_wrap);
577 return;
578 }
579
580 /* distribute the shares to the identities */
581 if (GNUNET_OK != distribute_keyshares (plugin_op_wrap, keyshares))
582 {
583 p_op->anchor_wrap->escrowAnchor = NULL;
584 p_op->anchor_wrap->emsg = _ ("Failed to distribute the keyshares!\n");
585 start_cont (plugin_op_wrap);
586 return;
587 }
588
589 /* operation continues in keyshare_distribution_finished
590 after all keyshares have been distributed */
591}
592
593
594void
595escrow_id_created (void *cls,
596 const struct GNUNET_CRYPTO_EcdsaPrivateKey *pk,
597 const char *emsg)
598{
599 struct IdentityOperationEntry *id_op = cls;
600 struct ESCROW_PluginOperationWrapper *plugin_op_wrap;
601 struct ESCROW_GnsPluginOperation *p_op;
602 struct PkEntry *pk_entry;
603
604 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Escrow identity %d created\n", id_op->i);
605
606 plugin_op_wrap = id_op->plugin_op_wrap;
607 p_op = (struct ESCROW_GnsPluginOperation *)plugin_op_wrap->plugin_op;
608
609 if (NULL == pk)
610 {
611 if (NULL != emsg)
612 {
613 fprintf (stderr,
614 "Identity create operation returned with error: %s\n",
615 emsg);
616 p_op->anchor_wrap->emsg = _ ("Identity create failed!\n");
617 }
618 else
619 p_op->anchor_wrap->emsg = _ ("Failed to create ego!\n");
620 p_op->anchor_wrap->escrowAnchor = NULL;
621 p_op->cont (p_op->anchor_wrap);
622 // this also cancels all running identity operations
623 cleanup_plugin_operation (plugin_op_wrap);
624 return;
625 }
626
627 /* escrow identity successfully created */
628 GNUNET_CONTAINER_DLL_remove (p_op->id_ops_head,
629 p_op->id_ops_tail,
630 id_op);
631
632 /* insert pk into our list */
633 pk_entry = GNUNET_new (struct PkEntry);
634 pk_entry->pk = pk;
635 pk_entry->i = id_op->i;
636 GNUNET_CONTAINER_DLL_insert_tail (p_op->escrow_pks_head,
637 p_op->escrow_pks_tail,
638 pk_entry);
639
640 GNUNET_free (id_op);
641
642 /* check if this was the last id_op */
643 p_op->escrow_id_counter++;
644 if (p_op->escrow_id_counter == p_op->shares)
645 {
646 escrow_ids_finished (plugin_op_wrap);
647 }
648}
649
650
651static uint8_t
652count_digits (uint8_t n)
653{
654 uint8_t i = 0;
655
656 do
657 {
658 i++;
659 n /= 10;
660 } while (n != 0);
661
662 return i;
663}
664
665
666static char *
667get_escrow_id_name (const char *name,
668 uint8_t i)
669{
670 char *str, *prefix, *number;
671 uint8_t j = 0;
672
673 prefix = "escrow-id_";
674 number = GNUNET_malloc (count_digits (i) + 1);
675 sprintf (number, "%d", i);
676
677 str = GNUNET_malloc (strlen (prefix)
678 + strlen (name)
679 + 1
680 + strlen (number)
681 + 1);
682
683 memcpy (str, prefix, strlen (prefix));
684 j += strlen (prefix);
685 memcpy (str + j, name, strlen (name));
686 j += strlen (name);
687 str[j++] = '_';
688 memcpy (str + j, number, strlen (number));
689 j += strlen (number);
690 str[j] = '\0';
691
692 GNUNET_free (number);
693
694 return str;
695}
696
697
698static int
699escrow_id_exists (const char *name,
700 const struct GNUNET_CRYPTO_EcdsaPrivateKey *pk)
701{
702 struct EgoEntry *curr;
703
704 for (curr = ph.ego_head; NULL != curr; curr = curr->next)
705 {
706 if (0 == strcmp (name, curr->identifier))
707 {
708 if (0 == memcmp (&curr->ego->pk,
709 pk,
710 sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey)))
711 return GNUNET_YES;
712 else // the escrow id's name exists for an ego, but the pk is wrong
713 return GNUNET_SYSERR;
714 }
715 }
716
717 return GNUNET_NO;
718}
719
720
721static struct GNUNET_CRYPTO_EcdsaPrivateKey *
722derive_private_key (const char *name,
723 const char *password,
724 uint8_t i)
725{
726 struct GNUNET_CRYPTO_EcdsaPrivateKey *pk;
727 static const char ctx[] = "gnunet-escrow-id-ctx";
728
729 pk = GNUNET_new (struct GNUNET_CRYPTO_EcdsaPrivateKey);
730 GNUNET_CRYPTO_kdf (pk,
731 sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey),
732 ctx, strlen (ctx),
733 password, strlen (password),
734 name, strlen (name),
735 &i, 1,
736 NULL);
737
738 pk->d[0] &= 248;
739 pk->d[31] &= 127;
740 pk->d[31] |= 64;
741
742 return pk;
743}
744
745
746static void
747handle_existing_wrong_ego_deletion (void *cls,
748 const char *emsg)
749{
750 struct IdentityOperationEntry *curr_id_op = cls;
751 struct ESCROW_PluginOperationWrapper *plugin_op_wrap;
752 struct ESCROW_GnsPluginOperation *p_op;
753
754 plugin_op_wrap = curr_id_op->plugin_op_wrap;
755 p_op = (struct ESCROW_GnsPluginOperation *)plugin_op_wrap->plugin_op;
756
757 if (NULL != emsg)
758 {
759 fprintf (stderr,
760 "Identity create operation returned with error: %s\n",
761 emsg);
762 p_op->anchor_wrap->emsg = _ ("Identity delete of wrong existing ego failed!\n");
763 p_op->anchor_wrap->escrowAnchor = NULL;
764 p_op->cont (p_op->anchor_wrap);
765 // this also cancels all running identity operations
766 cleanup_plugin_operation (plugin_op_wrap);
767 return;
768 }
769
770 /* no error occured, so create the new identity */
771 // the IdentityOperationEntry is reused, so only the id_op is updated
772 curr_id_op->id_op = GNUNET_IDENTITY_create (identity_handle,
773 curr_id_op->name,
774 curr_id_op->pk,
775 &escrow_id_created,
776 curr_id_op);
777}
778
779
780static void
781create_escrow_identities (struct ESCROW_PluginOperationWrapper *plugin_op_wrap,
782 const char *name)
783{
784 struct ESCROW_GnsPluginOperation *p_op;
785 struct GNUNET_CRYPTO_EcdsaPrivateKey *curr_pk;
786 char *curr_name;
787 struct IdentityOperationEntry *curr_id_op;
788 struct PkEntry *curr_pk_entry;
789 int exists_ret;
790
791 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating escrow identities\n");
792
793 p_op = (struct ESCROW_GnsPluginOperation *)plugin_op_wrap->plugin_op;
794
795 for (uint8_t i = 0; i < p_op->shares; i++)
796 {
797 curr_pk = derive_private_key (name, p_op->userSecret, i);
798 curr_name = get_escrow_id_name (name, i);
799
800 // check if the escrow identity already exists
801 exists_ret = escrow_id_exists (curr_name, curr_pk);
802 if (GNUNET_SYSERR == exists_ret)
803 {
804 /* an ego with identifier name but the wrong pk exists, delete it first */
805 curr_id_op = GNUNET_new (struct IdentityOperationEntry);
806 curr_id_op->pk = curr_pk;
807 curr_id_op->name = curr_name;
808 curr_id_op->i = i;
809 curr_id_op->plugin_op_wrap = plugin_op_wrap;
810 curr_id_op->id_op = GNUNET_IDENTITY_delete (identity_handle,
811 curr_name,
812 &handle_existing_wrong_ego_deletion,
813 curr_id_op);
814 GNUNET_CONTAINER_DLL_insert (p_op->id_ops_head,
815 p_op->id_ops_tail,
816 curr_id_op);
817 }
818 else if (GNUNET_YES == exists_ret)
819 {
820 // the escrow id already exists, so insert the pk into our list
821 curr_pk_entry = GNUNET_new (struct PkEntry);
822 curr_pk_entry->pk = curr_pk;
823 curr_pk_entry->i = i;
824 GNUNET_CONTAINER_DLL_insert (p_op->escrow_pks_head,
825 p_op->escrow_pks_tail,
826 curr_pk_entry);
827
828 p_op->escrow_id_counter++;
829 if (p_op->escrow_id_counter == p_op->shares)
830 {
831 escrow_ids_finished (plugin_op_wrap);
832 }
833 }
834 else // GNUNET_NO
835 {
836 /* store the identity operation in our list */
837 curr_id_op = GNUNET_new (struct IdentityOperationEntry);
838 curr_id_op->pk = curr_pk;
839 curr_id_op->name = curr_name;
840 curr_id_op->i = i;
841 curr_id_op->plugin_op_wrap = plugin_op_wrap;
842 curr_id_op->id_op = GNUNET_IDENTITY_create (identity_handle,
843 curr_name,
844 curr_pk,
845 &escrow_id_created,
846 curr_id_op);
847 GNUNET_CONTAINER_DLL_insert (p_op->id_ops_head,
848 p_op->id_ops_tail,
849 curr_id_op);
850 }
851 }
852}
853
854
855void
856continue_start (void *cls)
857{
858 struct ESCROW_PluginOperationWrapper *plugin_op_wrap = cls;
859 struct ESCROW_GnsPluginOperation *p_op;
860 unsigned long long shares, share_threshold;
861 struct GNUNET_TIME_Relative delay;
862
863 p_op = (struct ESCROW_GnsPluginOperation *)plugin_op_wrap->plugin_op;
864
865 if (ESCROW_PLUGIN_STATE_POST_INIT != ph.state)
866 {
867 delay.rel_value_us = 200 * GNUNET_TIME_relative_get_millisecond_().rel_value_us;
868 GNUNET_SCHEDULER_add_delayed (delay, &continue_start, plugin_op_wrap);
869 return;
870 }
871
872 // get config
873 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (p_op->h->cfg,
874 "escrow",
875 "gns_shares",
876 &shares))
877 {
878 fprintf (stderr, "Number of shares not specified in config!");
879 p_op->anchor_wrap->escrowAnchor = NULL;
880 p_op->sched_task = GNUNET_SCHEDULER_add_now (&start_cont, plugin_op_wrap);
881 return;
882 }
883 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (p_op->h->cfg,
884 "escrow",
885 "gns_share_threshold",
886 &share_threshold))
887 {
888 fprintf (stderr, "Share threshold not specified in config");
889 p_op->anchor_wrap->escrowAnchor = NULL;
890 p_op->sched_task = GNUNET_SCHEDULER_add_now (&start_cont, plugin_op_wrap);
891 return;
892 }
893 p_op->shares = (uint8_t)shares;
894 p_op->share_threshold = (uint8_t)share_threshold;
895
896 /* create the escrow identities */
897 create_escrow_identities (plugin_op_wrap, p_op->ego->name);
898
899 /* operation continues in escrow_ids_finished
900 after all escrow identities are created */
901}
902
903
904/**
905 * Start the GNS escrow of the key
906 *
907 * @param h the handle for the escrow component
908 * @param ego the identity ego containing the private key
909 * @param userSecret the user secret (e.g. for derivation of escrow identities)
910 * @param cb the function called upon completion
911 * @param op_id unique ID of the respective ESCROW_Operation
912 *
913 * @return plugin operation wrapper
914 */
915struct ESCROW_PluginOperationWrapper *
916start_gns_key_escrow (struct GNUNET_ESCROW_Handle *h,
917 struct GNUNET_IDENTITY_Ego *ego,
918 const char *userSecret,
919 GNUNET_SCHEDULER_TaskCallback cb,
920 uint32_t op_id)
921{
922 struct ESCROW_PluginOperationWrapper *plugin_op_wrap;
923 struct ESCROW_GnsPluginOperation *p_op;
924 struct ESCROW_Plugin_AnchorContinuationWrapper *w;
925 struct GNUNET_TIME_Relative delay;
926
927 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting GNS escrow\n");
928
929 // create a new GNS plugin operation (in a wrapper) and insert it into the DLL
930 plugin_op_wrap = GNUNET_new (struct ESCROW_PluginOperationWrapper);
931 plugin_op_wrap->plugin_op = GNUNET_new (struct ESCROW_GnsPluginOperation);
932 GNUNET_CONTAINER_DLL_insert_tail (ph.plugin_op_head,
933 ph.plugin_op_tail,
934 plugin_op_wrap);
935
936 p_op = (struct ESCROW_GnsPluginOperation *)plugin_op_wrap->plugin_op;
937 p_op->h = h;
938 p_op->cont = cb;
939 p_op->ego = ego;
940
941 w = GNUNET_new (struct ESCROW_Plugin_AnchorContinuationWrapper);
942 w->h = h;
943 w->op_id = op_id;
944 p_op->anchor_wrap = w;
945
946 if (NULL == ego || NULL == userSecret)
947 {
948 w->escrowAnchor = NULL;
949 if (NULL == ego)
950 w->emsg = _ ("ESCROW_put was called with ego == NULL\n");
951 else if (NULL == userSecret)
952 w->emsg = _ ("GNS escrow needs a user secret!\n");
953 p_op->sched_task = GNUNET_SCHEDULER_add_now (&start_cont, plugin_op_wrap);
954 return plugin_op_wrap;
955 }
956 p_op->pk = GNUNET_IDENTITY_ego_get_private_key (ego);
957 p_op->userSecret = GNUNET_strdup (userSecret);
958
959 if (ESCROW_PLUGIN_STATE_POST_INIT == ph.state)
960 {
961 continue_start (plugin_op_wrap);
962 }
963 else
964 {
965 delay.rel_value_us = 200 * GNUNET_TIME_relative_get_millisecond_().rel_value_us;
966 GNUNET_SCHEDULER_add_delayed (delay, &continue_start, plugin_op_wrap);
967 }
968
969 return plugin_op_wrap;
970}
971
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
1052void
1053verify_cont (void *cls)
1054{
1055 struct ESCROW_PluginOperationWrapper *plugin_op_wrap = cls;
1056 struct ESCROW_GnsPluginOperation *p_op;
1057
1058 p_op = (struct ESCROW_GnsPluginOperation*)plugin_op_wrap->plugin_op;
1059 p_op->cont (p_op->verify_wrap);
1060
1061 cleanup_plugin_operation (plugin_op_wrap);
1062}
1063
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
1089/**
1090 * Verify the GNS escrow of the key
1091 *
1092 * @param h the handle for the escrow component
1093 * @param ego the identity ego containing the private key
1094 * @param escrowAnchor the escrow anchor needed to restore the key
1095 * @param cb the function called upon completion
1096 * @param op_id unique ID of the respective ESCROW_Operation
1097 *
1098 * @return plugin operation wrapper
1099 */
1100struct ESCROW_PluginOperationWrapper *
1101verify_gns_key_escrow (struct GNUNET_ESCROW_Handle *h,
1102 struct GNUNET_IDENTITY_Ego *ego,
1103 struct GNUNET_ESCROW_Anchor *escrowAnchor,
1104 GNUNET_SCHEDULER_TaskCallback cb,
1105 uint32_t op_id)
1106{
1107 struct ESCROW_PluginOperationWrapper *plugin_op_wrap;
1108 struct ESCROW_GnsPluginOperation *p_op;
1109 struct ESCROW_Plugin_VerifyContinuationWrapper *w;
1110
1111 // create a new GNS plugin operation (in a wrapper) and insert it into the DLL
1112 plugin_op_wrap = GNUNET_new (struct ESCROW_PluginOperationWrapper);
1113 plugin_op_wrap->plugin_op = GNUNET_new (struct ESCROW_GnsPluginOperation);
1114 GNUNET_CONTAINER_DLL_insert_tail (ph.plugin_op_head,
1115 ph.plugin_op_tail,
1116 plugin_op_wrap);
1117
1118 p_op = (struct ESCROW_GnsPluginOperation *)plugin_op_wrap->plugin_op;
1119 p_op->h = h;
1120 p_op->cont = cb;
1121 p_op->ego = ego;
1122 p_op->userSecret = gns_anchor_data_to_string (h, escrowAnchor);
1123
1124 w = GNUNET_new (struct ESCROW_Plugin_VerifyContinuationWrapper);
1125 w->h = h;
1126 w->op_id = op_id;
1127 p_op->verify_wrap = w;
1128
1129 if (NULL == ego)
1130 {
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
1142 return plugin_op_wrap;
1143}
1144
1145
1146void
1147ego_created (const struct GNUNET_IDENTITY_Ego *ego)
1148{
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);
1237}
1238
1239
1240/**
1241 * Restore the key from GNS escrow
1242 *
1243 * @param h the handle for the escrow component
1244 * @param escrowAnchor the escrow anchor needed to restore the key
1245 * @param egoName the name of the ego to restore
1246 * @param cb the function called upon completion
1247 * @param op_id unique ID of the respective ESCROW_Operation
1248 *
1249 * @return plugin operation wrapper
1250 */
1251struct ESCROW_PluginOperationWrapper *
1252restore_gns_key_escrow (struct GNUNET_ESCROW_Handle *h,
1253 struct GNUNET_ESCROW_Anchor *escrowAnchor,
1254 const char *egoName,
1255 GNUNET_SCHEDULER_TaskCallback cb,
1256 uint32_t op_id)
1257{
1258 struct ESCROW_PluginOperationWrapper *plugin_op_wrap;
1259 struct ESCROW_GnsPluginOperation *p_op;
1260 struct ESCROW_Plugin_EgoContinuationWrapper *w;
1261
1262 // create a new GNS plugin operation (in a wrapper) and insert it into the DLL
1263 plugin_op_wrap = GNUNET_new (struct ESCROW_PluginOperationWrapper);
1264 plugin_op_wrap->plugin_op = GNUNET_new (struct ESCROW_GnsPluginOperation);
1265 GNUNET_CONTAINER_DLL_insert_tail (ph.plugin_op_head,
1266 ph.plugin_op_tail,
1267 plugin_op_wrap);
1268
1269 p_op = (struct ESCROW_GnsPluginOperation *)plugin_op_wrap->plugin_op;
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);
1275
1276 w = GNUNET_new (struct ESCROW_Plugin_EgoContinuationWrapper);
1277 w->h = h;
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);
1294
1295 return plugin_op_wrap;
1296}
1297
1298
1299/**
1300 * Get the status of a GNS escrow
1301 *
1302 * @param h the handle for the escrow component
1303 * @param ego the identity ego of which the status has to be obtained
1304 *
1305 * @return the status of the escrow packed into a GNUNET_ESCROW_Status struct
1306 */
1307struct GNUNET_ESCROW_Status *
1308gns_get_status (struct GNUNET_ESCROW_Handle *h,
1309 struct GNUNET_IDENTITY_Ego *ego)
1310{
1311 return ESCROW_get_escrow_status (h, ego);
1312}
1313
1314
1315/**
1316 * Deserialize an escrow anchor string into a GNUNET_ESCROW_Anchor struct
1317 *
1318 * @param anchorString the encoded escrow anchor string
1319 *
1320 * @return the deserialized data packed into a GNUNET_ESCROW_Anchor struct
1321 */
1322struct GNUNET_ESCROW_Anchor *
1323gns_anchor_string_to_data (struct GNUNET_ESCROW_Handle *h,
1324 char *anchorString)
1325{
1326 struct GNUNET_ESCROW_Anchor *anchor;
1327 uint32_t data_size;
1328
1329 data_size = strlen (anchorString) + 1;
1330
1331 anchor = GNUNET_malloc (sizeof (struct GNUNET_ESCROW_Anchor) + data_size);
1332 anchor->size = data_size;
1333 // TODO: deserialize?
1334 GNUNET_memcpy (&anchor[1], anchorString, data_size);
1335
1336 return anchor;
1337}
1338
1339
1340/**
1341 * Serialize an escrow anchor struct into a string
1342 *
1343 * @param h the handle for the escrow component
1344 * @param escrowAnchor the escrow anchor struct
1345 *
1346 * @return the encoded escrow anchor string
1347 */
1348char *
1349gns_anchor_data_to_string (struct GNUNET_ESCROW_Handle *h,
1350 struct GNUNET_ESCROW_Anchor *escrowAnchor)
1351{
1352 char *anchorString;
1353
1354 anchorString = GNUNET_malloc (escrowAnchor->size);
1355 GNUNET_memcpy (anchorString, &escrowAnchor[1], escrowAnchor->size);
1356
1357 return anchorString;
1358}
1359
1360
1361/**
1362 * Cancel a GNS plugin operation.
1363 *
1364 * @param plugin_op_wrap the plugin operation wrapper containing the operation
1365 */
1366void
1367cancel_gns_operation (struct ESCROW_PluginOperationWrapper *plugin_op_wrap)
1368{
1369 struct ESCROW_PluginOperationWrapper *curr;
1370
1371 for (curr = ph.plugin_op_head; NULL != curr; curr = curr->next)
1372 {
1373 if (curr == plugin_op_wrap)
1374 {
1375 GNUNET_CONTAINER_DLL_remove (ph.plugin_op_head,
1376 ph.plugin_op_tail,
1377 curr);
1378 cleanup_plugin_operation (curr);
1379 return;
1380 }
1381 }
1382}
1383
1384
1385/**
1386 * IdentityInitContinuation for the GNS plugin
1387 */
1388void
1389gns_cont_init ()
1390{
1391 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "GNS plugin initialized");
1392}
1393
1394
1395/**
1396 * Entry point for the plugin.
1397 *
1398 * @param cls Config info
1399 *
1400 * @return the exported block API
1401 */
1402void *
1403libgnunet_plugin_escrow_gns_init (void *cls)
1404{
1405 struct GNUNET_ESCROW_KeyPluginFunctions *api;
1406 struct GNUNET_CONFIGURATION_Handle *cfg = cls;
1407
1408 api = GNUNET_new (struct GNUNET_ESCROW_KeyPluginFunctions);
1409 api->start_key_escrow = &start_gns_key_escrow;
1410 api->verify_key_escrow = &verify_gns_key_escrow;
1411 api->restore_key = &restore_gns_key_escrow;
1412 api->get_status = &gns_get_status;
1413 api->anchor_string_to_data = &gns_anchor_string_to_data;
1414 api->anchor_data_to_string = &gns_anchor_data_to_string;
1415 api->cancel_plugin_operation = &cancel_gns_operation;
1416
1417 ph.state = ESCROW_PLUGIN_STATE_INIT;
1418 ph.id_init_cont = &gns_cont_init;
1419
1420 ph.ego_create_cont = &ego_created;
1421 identity_handle = GNUNET_IDENTITY_connect (cfg,
1422 &ESCROW_list_ego,
1423 &ph);
1424
1425 return api;
1426}
1427
1428
1429/**
1430 * Exit point from the plugin.
1431 *
1432 * @param cls the return value from #libgnunet_plugin_block_test_init()
1433 *
1434 * @return NULL
1435 */
1436void *
1437libgnunet_plugin_escrow_gns_done (void *cls)
1438{
1439 struct GNUNET_RECLAIM_EscrowKeyPluginFunctions *api = cls;
1440
1441 GNUNET_free (api);
1442 GNUNET_IDENTITY_disconnect (identity_handle);
1443 ESCROW_cleanup_ego_list (&ph);
1444
1445 return NULL;
1446}
1447
1448
1449/* end of plugin_escrow_gns.c */