summaryrefslogtreecommitdiff
path: root/src/include/anastasis.h
blob: d2538684df8280dce65dc3b70de6e0c3ea84dd18 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
/*
  This file is part of Anastasis
  Copyright (C) 2020, 2021 Taler Systems SA

  Anastasis is free software; you can redistribute it and/or modify it under the
  terms of the GNU Lesser General Public License as published by the Free Software
  Foundation; either version 3, or (at your option) any later version.

  Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY
  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  A PARTICULAR PURPOSE.  See the GNU General Public License for more details.

  You should have received a copy of the GNU General Public License along with
  Anastasis; see the file COPYING.GPL.  If not, see <http://www.gnu.org/licenses/>
*/
/**
 * @file include/anastasis.h
 * @brief anastasis high-level client api
 * @author Christian Grothoff
 * @author Dominik Meister
 * @author Dennis Neufeld
 */
#ifndef ANASTASIS_H
#define ANASTASIS_H

#include "anastasis_service.h"
#include <taler/taler_json_lib.h>
#include <gnunet/gnunet_util_lib.h>
#include <stdbool.h>


/* ********************* Recovery api *********************** */

/**
 * Defines the instructions for a challenge, what does the user have
 * to do to fulfill the challenge.  Also defines the method and other
 * information for the challenge like a link for the video indent or a
 * information to which address an e-mail was sent.
 */
struct ANASTASIS_Challenge;


/**
 * Defines the instructions for a challenge, what does the user have
 * to do to fulfill the challenge.  Also defines the method and other
 * information for the challenge like a link for the video indent or a
 * information to which address an e-mail was sent.
 */
struct ANASTASIS_ChallengeDetails
{

  /**
   * UUID which identifies this challenge
   */
  struct ANASTASIS_CRYPTO_TruthUUIDP uuid;

  /**
   * Which type is this challenge (E-Mail, Security Question, SMS...)
   */
  const char *type;

  /**
   * Defines the base URL of the Anastasis provider used for the challenge.
   */
  const char *provider_url;

  /**
   * Instructions for solving the challenge (generic, set client-side
   * when challenge was established).
   */
  const char *instructions;

  /**
   * true if challenged was already solved, else false.
   */
  bool solved;

};


/**
 * Return public details about a challenge.
 *
 * @param challenge the challenge to inspect
 * @return public details about the challenge
 */
const struct ANASTASIS_ChallengeDetails *
ANASTASIS_challenge_get_details (struct ANASTASIS_Challenge *challenge);


/**
 * Possible outcomes of trying to start a challenge operation.
 */
enum ANASTASIS_ChallengeStatus
{

  /**
   * The challenge has been solved.
   */
  ANASTASIS_CHALLENGE_STATUS_SOLVED,

  /**
   * Instructions for how to solve the challenge are provided.  Also
   * used if the answer we provided was wrong (or if no answer was
   * provided, but one is needed).
   */
  ANASTASIS_CHALLENGE_STATUS_INSTRUCTIONS,

  /**
   * A redirection URL needed to solve the challenge is provided.  Also
   * used if the answer we provided was wrong (or if no answer was
   * provided, but one is needed).
   */
  ANASTASIS_CHALLENGE_STATUS_REDIRECT_FOR_AUTHENTICATION,

  /**
   * Payment is required before the challenge can be answered.
   */
  ANASTASIS_CHALLENGE_STATUS_PAYMENT_REQUIRED,

  /**
   * We encountered an error talking to the Anastasis service.
   */
  ANASTASIS_CHALLENGE_STATUS_SERVER_FAILURE,

  /**
   * The server does not know this truth.
   */
  ANASTASIS_CHALLENGE_STATUS_TRUTH_UNKNOWN,

  /**
   * The rate limit for solving the challenge was exceeded.
   */
  ANASTASIS_CHALLENGE_STATUS_RATE_LIMIT_EXCEEDED

};


/**
 * Response from an #ANASTASIS_challenge_start() operation.
 */
struct ANASTASIS_ChallengeStartResponse
{
  /**
   * What is our status on satisfying this challenge. Determines @e details.
   */
  enum ANASTASIS_ChallengeStatus cs;

  /**
   * Which challenge is this about?
   */
  struct ANASTASIS_Challenge *challenge;

  /**
   * Details depending on @e cs
   */
  union
  {

    /**
     * Challenge details provided if
     * @e cs is #ANASTASIS_CHALLENGE_STATUS_INSTRUCTIONS.
     */
    struct
    {

      /**
       * Response with server-side instructions for the user.
       */
      const void *body;

      /**
       * Mime type of the data in @e body.
       */
      const char *content_type;

      /**
       * Number of bytes in @e body
       */
      size_t body_size;

      /**
       * HTTP status returned by the server.  #MHD_HTTP_ALREADY_REPORTED
       * if the server did already send the challenge to the user,
       * #MHD_HTTP_FORBIDDEN if the answer was wrong (or missing).
       */
      unsigned int http_status;
    } open_challenge;


    /**
     * Response with URL to redirect the user to, if
     * @e cs is #ANASTASIS_CHALLENGE_STATUS_REDIRECT_FOR_AUTHENTICATION.
     */
    const char *redirect_url;

    /**
     * Response with instructions for how to pay, if
     * @e cs is #ANASTASIS_CHALLENGE_STATUS_PAYMENT_REQUIRED.
     */
    struct
    {

      /**
       * "taler://pay" URI with details how to pay for the challenge.
       */
      const char *taler_pay_uri;

      /**
       * Payment secret from @e taler_pay_uri.
       */
      struct ANASTASIS_PaymentSecretP payment_secret;

    } payment_required;


    /**
     * Response with details about a server-side failure, if
     * @e cs is #ANASTASIS_CHALLENGE_STATUS_SERVER_FAILURE.
     */
    struct
    {

      /**
       * HTTP status returned by the server.
       */
      unsigned int http_status;

      /**
       * Taler-specific error code.
       */
      enum TALER_ErrorCode ec;

    } server_failure;

  } details;
};


/**
 * Defines a callback for the response status for a challenge start
 * operation.
 *
 * @param cls closure
 * @param csr response details
 */
typedef void
(*ANASTASIS_AnswerFeedback)(
  void *cls,
  const struct ANASTASIS_ChallengeStartResponse *csr);


/**
 * User starts a challenge which reponds out of bounds (E-Mail, SMS,
 * Postal..)  If the challenge is zero cost, the challenge
 * instructions will be sent to the client. If the challenge needs
 * payment a payment link is sent to the client. After payment the
 * challenge start method has to be called again.
 *
 * @param c reference to the escrow challenge which is started
 * @param psp payment secret, NULL if no payment was yet made
 * @param timeout how long to wait for payment
 * @param hashed_answer answer to the challenge, NULL if we have none yet
 * @param af reference to the answerfeedback which is passed back to the user
 * @param af_cls closure for @a af
 * @return #GNUNET_OK if the challenge was successfully started
 */
int
ANASTASIS_challenge_start (struct ANASTASIS_Challenge *c,
                           const struct ANASTASIS_PaymentSecretP *psp,
                           struct GNUNET_TIME_Relative timeout,
                           const struct GNUNET_HashCode *hashed_answer,
                           ANASTASIS_AnswerFeedback af,
                           void *af_cls);


/**
 * Challenge answer for a security question. Is referenced to
 * a challenge and sends back an AnswerFeedback.  Convenience
 * wrapper around #ANASTASIS_challenge_start that hashes @a answer
 * for security questions.
 *
 * @param c reference to the challenge which is answered
 * @param psp information about payment made for the recovery
 * @param timeout how long to wait for payment
 * @param answer user input instruction defines which input is needed
 * @param af reference to the answerfeedback which is passed back to the user
 * @param af_cls closure for @a af
 * @return #GNUNET_OK on success
 */
int
ANASTASIS_challenge_answer (struct ANASTASIS_Challenge *c,
                            const struct ANASTASIS_PaymentSecretP *psp,
                            struct GNUNET_TIME_Relative timeout,
                            const char *answer,
                            ANASTASIS_AnswerFeedback af,
                            void *af_cls);


/**
 * Challenge answer from the user like input SMS TAN or e-mail wpin. Is
 * referenced to a challenge and sends back an AnswerFeedback.
 * Convenience wrapper around #ANASTASIS_challenge_start that hashes
 * numeric (unsalted) @a answer.  Variant for numeric answers.
 *
 * @param c reference to the challenge which is answered
 * @param psp information about payment made for the recovery
 * @param timeout how long to wait for payment
 * @param answer user input instruction defines which input is needed
 * @param af reference to the answerfeedback which is passed back to the user
 * @param af_cls closure for @a af
 * @return #GNUNET_OK on success
 */
int
ANASTASIS_challenge_answer2 (struct ANASTASIS_Challenge *c,
                             const struct ANASTASIS_PaymentSecretP *psp,
                             struct GNUNET_TIME_Relative timeout,
                             uint64_t answer,
                             ANASTASIS_AnswerFeedback af,
                             void *af_cls);


/**
 * Abort answering challenge.
 *
 * @param c reference to the escrow challenge which was started
 */
void
ANASTASIS_challenge_abort (struct ANASTASIS_Challenge *c);


/**
 * Defines a Decryption Policy with multiple escrow methods
 */
struct ANASTASIS_DecryptionPolicy
{
  /**
   * Array of challenges needed to solve for this decryption policy.
   */
  struct ANASTASIS_Challenge **challenges;

  /**
   * Length of the @a challenges in this policy.
   */
  unsigned int challenges_length;

};


/**
 * Defines the recovery information (possible policies and version of the recovery document)
 */
struct ANASTASIS_RecoveryInformation
{

  /**
   * Array of @e dps_len policies that would allow recovery of the core secret.
   */
  struct ANASTASIS_DecryptionPolicy **dps;

  /**
   * Array of all @e cs_len challenges to be solved (for any of the policies).
   */
  struct ANASTASIS_Challenge **cs;

  /**
   * Name of the secret being recovered, possibly NULL.
   */
  const char *secret_name;

  /**
   * Length of the @e dps array.
   */
  unsigned int dps_len;

  /**
   * Length of the @e cs array.
   */
  unsigned int cs_len;

  /**
   * Actual recovery document version obtained.
   */
  unsigned int version;
};


/**
 * Callback which passes back the recovery document and its possible
 * policies. Also passes back the version of the document for the user
 * to check.
 *
 * @param cls closure for the callback
 * @param ri recovery information struct which contains the policies
 */
typedef void
(*ANASTASIS_PolicyCallback)(void *cls,
                            const struct ANASTASIS_RecoveryInformation *ri);


/**
 * Possible outcomes of a recovery process.
 */
enum ANASTASIS_RecoveryStatus
{

  /**
   * Recovery succeeded.
   */
  ANASTASIS_RS_SUCCESS = 0,

  /**
   * The HTTP download of the policy failed.
   */
  ANASTASIS_RS_POLICY_DOWNLOAD_FAILED,

  /**
   * We did not get a valid policy document.
   */
  ANASTASIS_RS_POLICY_DOWNLOAD_NO_POLICY,

  /**
   * The decompressed policy document was too big for available memory.
   */
  ANASTASIS_RS_POLICY_DOWNLOAD_TOO_BIG,

  /**
   * The decrypted policy document was not compressed.
   */
  ANASTASIS_RS_POLICY_DOWNLOAD_INVALID_COMPRESSION,

  /**
   * The decompressed policy document was not in JSON.
   */
  ANASTASIS_RS_POLICY_DOWNLOAD_NO_JSON,

  /**
   * The decompressed policy document was in malformed JSON.
   */
  ANASTASIS_RS_POLICY_MALFORMED_JSON,

  /**
   * The Anastasis server reported a transient error.
   */
  ANASTASIS_RS_POLICY_SERVER_ERROR,

  /**
   * The Anastasis server no longer has a policy (likely expired).
   */
  ANASTASIS_RS_POLICY_GONE,

  /**
   * The Anastasis server reported that the account is unknown.
   */
  ANASTASIS_RS_POLICY_UNKNOWN
};


/**
 * This function is called whenever the recovery process ends.
 * On success, the secret is returned in @a secret.
 *
 * @param cls closure
 * @param ec error code
 * @param secret contains the core secret which is passed to the user
 * @param secret_size defines the size of the core secret
 */
typedef void
(*ANASTASIS_CoreSecretCallback)(void *cls,
                                enum ANASTASIS_RecoveryStatus rc,
                                const void *secret,
                                size_t secret_size);


/**
 * stores provider URIs, identity key material, decrypted recovery document (internally!)
 */
struct ANASTASIS_Recovery;


/**
 * Starts the recovery process by opening callbacks for the coresecret and a policy callback. A list of
 * providers is checked for policies and passed back to the client.
 *
 * @param ctx context for making HTTP requests
 * @param id_data contains the users identity, (user account on providers)
 * @param version defines the version which will be downloaded NULL for latest version
 * @param anastasis_provider_url NULL terminated list of possible provider urls
 * @param provider_salt the server salt
 * @param pc opens the policy call back which holds the downloaded version and the policies
 * @param pc_cls closure for callback
 * @param csc core secret callback is opened, with this the core secert is passed to the client after the authentication
 * @param csc_cls handle for the callback
 * @return recovery operation handle
 */
struct ANASTASIS_Recovery *
ANASTASIS_recovery_begin (
  struct GNUNET_CURL_Context *ctx,
  const json_t *id_data,
  unsigned int version,
  const char *anastasis_provider_url,
  const struct ANASTASIS_CRYPTO_ProviderSaltP *provider_salt,
  ANASTASIS_PolicyCallback pc,
  void *pc_cls,
  ANASTASIS_CoreSecretCallback csc,
  void *csc_cls);


/**
 * Serialize recovery operation state and returning it.
 * The recovery MAY still continue, applications should call
 * #ANASTASIS_recovery_abort() to truly end the recovery.
 *
 * @param r recovery operation to suspend.
 * @return JSON serialized state of @a r
 */
json_t *
ANASTASIS_recovery_serialize (const struct ANASTASIS_Recovery *r);


/**
 * Deserialize recovery operation.
 *
 * @param ctx context for making HTTP requests
 * @param input result from #ANASTASIS_recovery_serialize()
 * @param pc opens the policy call back which holds the downloaded version and the policies
 * @param pc_cls closure for callback
 * @param csc core secret callback is opened, with this the core secert is passed to the client after the authentication
 * @param csc_cls handle for the callback
 * @return recovery operation handle
 */
struct ANASTASIS_Recovery *
ANASTASIS_recovery_deserialize (struct GNUNET_CURL_Context *ctx,
                                const json_t *input,
                                ANASTASIS_PolicyCallback pc,
                                void *pc_cls,
                                ANASTASIS_CoreSecretCallback csc,
                                void *csc_cls);


/**
 * Cancels the recovery process
 *
 * @param r handle to the recovery struct
 */
void
ANASTASIS_recovery_abort (struct ANASTASIS_Recovery *r);


/* ************************* Backup API ***************************** */


/**
 * Represents a truth object, which is a key share and the respective
 * challenge to be solved with an Anastasis provider to recover the
 * key share.
 */
struct ANASTASIS_Truth;


/**
 * Extracts truth data from JSON.
 *
 * @param json JSON encoding to decode; truth returned ONLY valid as long
 *             as the JSON remains valid (do not decref until the truth
 *             is truly finished)
 * @return decoded truth object, NULL on error
 */
struct ANASTASIS_Truth *
ANASTASIS_truth_from_json (const json_t *json);


/**
 * Returns JSON-encoded truth data.
 * Creates a policy with a set of truth's.  Creates the policy key
 * with the different key shares from the @a truths. The policy key
 * will then be used to encrypt/decrypt the escrow master key.
 *
 * @param t object to return JSON encoding for
 * @return JSON encoding of @a t
 */
json_t *
ANASTASIS_truth_to_json (const struct ANASTASIS_Truth *t);


/**
 * Handle for the operation to establish a truth object by sharing
 * an encrypted key share with an Anastasis provider.
 */
struct ANASTASIS_TruthUpload;


/**
 * Upload result information.  The resulting truth object can be used
 * to create policies.  If payment is required, the @a taler_pay_url
 * is returned and the operation must be retried after payment.
 * Callee MUST free @a t using ANASTASIS_truth_free().
 *
 * @param cls closure for callback
 * @param t truth object to create policies, NULL on failure
 * @param ud upload details, useful to continue in case of errors, NULL on success
 */
typedef void
(*ANASTASIS_TruthCallback)(void *cls,
                           struct ANASTASIS_Truth *t,
                           const struct ANASTASIS_UploadDetails *ud);


/**
 * Uploads truth data to an escrow provider. The resulting truth object
 * is returned via the @a tc function. If payment is required, it is
 * requested via the @a tcp callback.
 *
 * @param ctx the CURL context used to connect to the backend
 * @param user_id user identifier derived from user data and backend salt
 * @param provider_url base URL of the provider to upload to
 * @param type defines the type of the challenge (secure question, sms, email)
 * @param instructions depending on @a type! usually only for security question/answer!
 * @param mime_type format of the challenge
 * @param provider_salt the providers salt
 * @param truth_data contains the truth for this challenge i.e. phone number, email address
 * @param truth_data_size size of the @a truth_data
 * @param payment_years_requested for how many years would the client like the service to store the truth?
 * @param pay_timeout how long to wait for payment
 * @param tc opens the truth callback which contains the status of the upload
 * @param tc_cls closure for the @a tc callback
 */
struct ANASTASIS_TruthUpload *
ANASTASIS_truth_upload (
  struct GNUNET_CURL_Context *ctx,
  const struct ANASTASIS_CRYPTO_UserIdentifierP *user_id,
  const char *provider_url,
  const char *type,
  const char *instructions,
  const char *mime_type,
  const struct ANASTASIS_CRYPTO_ProviderSaltP *provider_salt,
  const void *truth_data,
  size_t truth_data_size,
  uint32_t payment_years_requested,
  struct GNUNET_TIME_Relative pay_timeout,
  ANASTASIS_TruthCallback tc,
  void *tc_cls);


/**
 * Retries upload of truth data to an escrow provider. The resulting
 * truth object is returned via the @a tc function. If payment is
 * required, it is requested via the @a tcp callback.
 *
 * @param ctx the CURL context used to connect to the backend
 * @param user_id user identifier derived from user data and backend salt
 * @param provider_url base URL of the provider to upload to
 * @param type defines the type of the challenge (secure question, sms, email)
 * @param instructions depending on @a type! usually only for security question/answer!
 * @param mime_type format of the challenge
 * @param provider_salt the providers salt
 * @param truth_data contains the truth for this challenge i.e. phone number, email address
 * @param truth_data_size size of the @a truth_data
 * @param payment_years_requested for how many years would the client like the service to store the truth?
 * @param pay_timeout how long to wait for payment
 * @param nonce nonce to use for symmetric encryption
 * @param uuid truth UUID to use
 * @param salt salt to use to hash security questions
 * @param truth_key symmetric encryption key to use to encrypt @a truth_data
 * @param key_share share of the overall key to store in this truth object
 * @param tc opens the truth callback which contains the status of the upload
 * @param tc_cls closure for the @a tc callback
 */
struct ANASTASIS_TruthUpload *
ANASTASIS_truth_upload2 (
  struct GNUNET_CURL_Context *ctx,
  const struct ANASTASIS_CRYPTO_UserIdentifierP *user_id,
  const char *provider_url,
  const char *type,
  const char *instructions,
  const char *mime_type,
  const struct ANASTASIS_CRYPTO_ProviderSaltP *provider_salt,
  const void *truth_data,
  size_t truth_data_size,
  uint32_t payment_years_requested,
  struct GNUNET_TIME_Relative pay_timeout,
  const struct ANASTASIS_CRYPTO_NonceP *nonce,
  const struct ANASTASIS_CRYPTO_TruthUUIDP *uuid,
  const struct ANASTASIS_CRYPTO_QuestionSaltP *salt,
  const struct ANASTASIS_CRYPTO_TruthKeyP *truth_key,
  const struct ANASTASIS_CRYPTO_KeyShareP *key_share,
  ANASTASIS_TruthCallback tc,
  void *tc_cls);


/**
 * Retries upload of truth data to an escrow provider using an
 * existing truth object. If payment is required, it is requested via
 * the @a tc callback.
 *
 * @param ctx the CURL context used to connect to the backend
 * @param user_id user identifier derived from user data and backend salt
 * @param[in] t truth details, reference is consumed
 * @param truth_data contains the truth for this challenge i.e. phone number, email address
 * @param truth_data_size size of the @a truth_data
 * @param payment_years_requested for how many years would the client like the service to store the truth?
 * @param pay_timeout how long to wait for payment
 * @param tc opens the truth callback which contains the status of the upload
 * @param tc_cls closure for the @a tc callback
 */
struct ANASTASIS_TruthUpload *
ANASTASIS_truth_upload3 (struct GNUNET_CURL_Context *ctx,
                         const struct ANASTASIS_CRYPTO_UserIdentifierP *user_id,
                         struct ANASTASIS_Truth *t,
                         const void *truth_data,
                         size_t truth_data_size,
                         uint32_t payment_years_requested,
                         struct GNUNET_TIME_Relative pay_timeout,
                         ANASTASIS_TruthCallback tc,
                         void *tc_cls);


/**
 * Cancels a truth upload process.
 *
 * @param tu handle for the upload
 */
void
ANASTASIS_truth_upload_cancel (struct ANASTASIS_TruthUpload *tu);


/**
 * Free's the truth object which was returned to a #ANASTASIS_TruthCallback.
 *
 * @param t object to clean up
 */
void
ANASTASIS_truth_free (struct ANASTASIS_Truth *t);


/**
 * Policy object, representing a set of truths (and thus challenges
 * to satisfy) to recover a secret.
 */
struct ANASTASIS_Policy;


/**
 * Creates a policy with a set of truth's.  Creates the policy key
 * with the different key shares from the @a truths. The policy key
 * will then be used to encrypt/decrypt the escrow master key.
 *
 * @param truths array of truths which are stored on different providers
 * @param truths_len length of the @a truths array
 */
struct ANASTASIS_Policy *
ANASTASIS_policy_create (const struct ANASTASIS_Truth *truths[],
                         unsigned int truths_len);


/**
 * Destroys a policy object.
 *
 * @param p handle for the policy to destroy
 */
void
ANASTASIS_policy_destroy (struct ANASTASIS_Policy *p);


/**
 * Information about a provider requesting payment for storing a policy.
 */
struct ANASTASIS_SharePaymentRequest
{
  /**
   * Payment request URL.
   */
  const char *payment_request_url;

  /**
   * Base URL of the provider requesting payment.
   */
  const char *provider_url;

  /**
   * The payment secret (aka order ID) extracted from the @e payment_request_url.
   */
  struct ANASTASIS_PaymentSecretP payment_secret;
};


/**
 * Result of uploading share data.
 */
enum ANASTASIS_ShareStatus
{
  /**
   * Upload successful.
   */
  ANASTASIS_SHARE_STATUS_SUCCESS = 0,

  /**
   * Upload requires payment.
   */
  ANASTASIS_SHARE_STATUS_PAYMENT_REQUIRED,

  /**
   * Failure to upload secret share at the provider.
   */
  ANASTASIS_SHARE_STATUS_PROVIDER_FAILED
};


/**
 * Per-provider status upon successful backup.
 */
struct ANASTASIS_ProviderSuccessStatus
{
  /**
   * Base URL of the provider.
   */
  const char *provider_url;

  /**
   * When will the policy expire?
   */
  struct GNUNET_TIME_Absolute policy_expiration;

  /**
   * Version number of the policy at the provider.
   */
  unsigned long long policy_version;

};


/**
 * Complete result of a secret sharing operation.
 */
struct ANASTASIS_ShareResult
{
  /**
   * Status of the share secret operation.
   */
  enum ANASTASIS_ShareStatus ss;

  /**
   * Details about the result, depending on @e ss.
   */
  union
  {

    struct
    {

      /**
       * Array of status details for each provider.
       */
      const struct ANASTASIS_ProviderSuccessStatus *pss;

      /**
       * Length of the @e policy_version and @e provider_urls arrays.
       */
      unsigned int num_providers;

    } success;

    struct
    {
      /**
       * Array of URLs with requested payments.
       */
      struct ANASTASIS_SharePaymentRequest *payment_requests;

      /**
       * Length of the payment_requests array.
       */
      unsigned int payment_requests_length;
    } payment_required;

    struct
    {
      /**
       * Base URL of the failed provider.
       */
      const char *provider_url;

      /**
       * HTTP status returned by the provider.
       */
      unsigned int http_status;

      /**
       * Upload status of the provider.
       */
      enum ANASTASIS_UploadStatus ec;


    } provider_failure;

  } details;

};


/**
 * Function called with the results of a #ANASTASIS_secret_share().
 *
 * @param cls closure
 * @param sr share result
 */
typedef void
(*ANASTASIS_ShareResultCallback)(void *cls,
                                 const struct ANASTASIS_ShareResult *sr);


/**
 * Defines a recovery document upload process (recovery document
 * consists of multiple policies)
 */
struct ANASTASIS_SecretShare;


/**
 * Details of a past payment
 */
struct ANASTASIS_ProviderDetails
{
  /**
   * URL of the provider backend.
   */
  const char *provider_url;

  /**
   * Payment order ID / secret of a past payment.
   */
  struct ANASTASIS_PaymentSecretP payment_secret;

  /**
   * Server salt. Points into a truth object from which we got the
   * salt.
   */
  struct ANASTASIS_CRYPTO_ProviderSaltP provider_salt;
};


/**
 * Creates a recovery document with the created policies and uploads it to
 * all servers.
 *
 * @param ctx the CURL context used to connect to the backend
 * @param id_data used to create a account identifier on the escrow provider
 * @param providers array of providers with URLs to upload the policies to
 * @param pss_length length of the @a providers array
 * @param policies list of policies which are included in this recovery document
 * @param policies_len length of the @a policies array
 * @param payment_years_requested for how many years would the client like the service to store the truth?
 * @param pay_timeout how long to wait for payment
 * @param src callback for the upload process
 * @param src_cls closure for the @a src upload callback
 * @param secret_name name of the core secret
 * @param core_secret input of the user which is secured by anastasis e.g. (wallet private key)
 * @param core_secret_size size of the @a core_secret
 * @return NULL on error
 */
struct ANASTASIS_SecretShare *
ANASTASIS_secret_share (struct GNUNET_CURL_Context *ctx,
                        const json_t *id_data,
                        const struct ANASTASIS_ProviderDetails providers[],
                        unsigned int pss_length,
                        const struct ANASTASIS_Policy *policies[],
                        unsigned int policies_len,
                        uint32_t payment_years_requested,
                        struct GNUNET_TIME_Relative pay_timeout,
                        ANASTASIS_ShareResultCallback src,
                        void *src_cls,
                        const char *secret_name,
                        const void *core_secret,
                        size_t core_secret_size);


/**
 * Cancels a secret share request.
 *
 * @param ss handle to the request
 */
void
ANASTASIS_secret_share_cancel (struct ANASTASIS_SecretShare *ss);


#endif