gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-anastasis] branch master updated: work on ANASTASIS_truth_upload


From: gnunet
Subject: [taler-anastasis] branch master updated: work on ANASTASIS_truth_upload API, not finsihed
Date: Fri, 05 Feb 2021 12:50:57 +0100

This is an automated email from the git hooks/post-receive script.

grothoff pushed a commit to branch master
in repository anastasis.

The following commit(s) were added to refs/heads/master by this push:
     new 939cb27  work on ANASTASIS_truth_upload API, not finsihed
939cb27 is described below

commit 939cb27b140f5490e31bf2a7e16de856c6e8c23b
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Fri Feb 5 12:50:55 2021 +0100

    work on ANASTASIS_truth_upload API, not finsihed
---
 src/include/anastasis.h                  |  281 +++++---
 src/lib/anastasis_backup.c               | 1159 ++++++++++++++++++++++++++++++
 src/reducer/anastasis_api_backup_redux.c |  110 ++-
 src/testing/testing_cmd_truth_upload.c   |   41 +-
 4 files changed, 1373 insertions(+), 218 deletions(-)

diff --git a/src/include/anastasis.h b/src/include/anastasis.h
index 0875b89..d18b2ce 100644
--- a/src/include/anastasis.h
+++ b/src/include/anastasis.h
@@ -1,6 +1,6 @@
 /*
   This file is part of Anastasis
-  Copyright (C) 2020 Taler Systems SA
+  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
@@ -20,6 +20,9 @@
  * @author Dominik Meister
  * @author Dennis Neufeld
  */
+#ifndef ANASTASIS_H
+#define ANASTASIS_H
+
 #include <gnunet/platform.h>
 #include <taler/taler_json_lib.h>
 #include <gnunet/gnunet_util_lib.h>
@@ -44,7 +47,8 @@ struct ANASTASIS_PaymentDetails
 };
 
 
-/*Download api*/
+/* ********************* Recovery api *********************** */
+
 
 /**
  * Defines a Decryption Policy with multiple escrow methods
@@ -79,17 +83,25 @@ struct ANASTASIS_DecryptionPolicy
  */
 struct ANASTASIS_RecoveryInformation
 {
-  struct ANASTASIS_DecryptionPolicy *dps;
+  // FIXME: document
+  struct ANASTASIS_CRYPTO_SaltP salt;
 
-  unsigned int dps_len;
+  // FIXME: document
+  struct ANASTASIS_DecryptionPolicy *dps;
 
+  // FIXME: document
   struct ANASTASIS_Challenge **cs;
 
-  unsigned int cs_len;
+  // FIXME: document
+  unsigned int dps_len;
 
-  struct ANASTASIS_CRYPTO_SaltP salt;
+  // FIXME: document
+  unsigned int cs_len;
 
-  unsigned int version;     // actual version obtained
+  /**
+   * Actual version obtained. FIXME: of what?
+   */
+  unsigned int version;
 };
 
 
@@ -135,8 +147,8 @@ struct ANASTASIS_ChallengeAnswerOperation;
  * @param pso the challenge answer operation to cancel
  */
 void
-ANASTASIS_challenge_answer_cancel (struct
-                                   ANASTASIS_ChallengeAnswerOperation *cao);
+ANASTASIS_challenge_answer_cancel (
+  struct ANASTASIS_ChallengeAnswerOperation *cao);
 
 
 /**
@@ -159,33 +171,53 @@ ANASTASIS_challenge_answer (struct GNUNET_CURL_Context 
*ctx,
 
 
 /**
- * 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.
- *
- * @param method which method is this challenge (E-Mail, Security Question, 
SMS...)
- * @param url can be NULL defines the url or mail address used for the 
challenge
- * @param instructions defines which steps need to be done e.g. ( please look 
for the pin for recovery #1234)
- * @param cost Cost to solve this challenge
- * @param solved 1 if solved, else 0
- * @param truth_public_key Identifier of the challenge
- * @param currency Currency of the cost
- * @param cb_cls callback closure
+ * 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_ChallengeInformation
 {
+  /**
+   * Which method is this challenge (E-Mail, Security Question, SMS...)
+   */
   const char *method;
+
+  /**
+   * Defines the url or mail address used for the challenge. Can be NULL.
+   */
   const char *url;
-  const char *instructions;
-  struct TALER_Amount *cost;
-  unsigned int solved;
-  const struct ANASTASIS_CRYPTO_TruthPublicKeyP *truth_public_key;
-  const struct ANASTASIS_CRYPTO_NonceP *nonce;
-  char *currency;
+
+  /**
+   * Describes which steps need to be done e.g. "Please look for the
+   * pin for recovery #1234".
+   */
+  const char *instructions; // FIXME: i18n?
+
+  /**
+   * Cost to solve this challenge
+   */
+  struct TALER_Amount *cost; // FIXME: why pointer!?
+
+  /**
+   * Identifier of the challenge
+   */
+  const struct ANASTASIS_CRYPTO_TruthPublicKeyP *truth_public_key; // FIXME: 
why pointer?
+
+  const struct ANASTASIS_CRYPTO_NonceP *nonce; // FIXME: why pointer?
+
+  // FIXME: document!
   struct ANASTASIS_Challenge *challenge;
-  void *cb_cls;
+  void *cb_cls; // ???
+
+  /**
+   * 1 if solved, else 0
+   */
+  unsigned int solved; // FIXME: use 'bool'!
+
 };
 
+
 /**
  * Defines a Challenge Callback which is initially sent with the challenge 
run. It gives back the previously
  * defined Challenge Information and a Status Code, like "payment missing".
@@ -335,58 +367,59 @@ ANASTASIS_recovery_abort (struct ANASTASIS_Recovery *r);
 void
 ANASTASIS_recovery_free (struct ANASTASIS_Recovery *r);
 
-/* Upload api
------------------------------------------------------------------ */
+
+/* ************************* Backup API ***************************** */
+
 
 /**
-* Truth Upload struct
-*/
+ * Handle for the operation to establish a truth object by sharing
+ * an encrypted key share with an Anastasis provider.
+ */
 struct ANASTASIS_TruthUpload;
 
+
 /**
-* provider_url + truth public key
-*/
+ * 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;
 
-/**
-* Initiates a callback for the payment of the truth upload
-*
-* @param cls closure for callback
-* @param taler_pay_url payment link for the transaction (taler://pay/Foo)
-* @param ec status code of the request
-*/
-typedef void
-(*ANASTASIS_TruthPaymentCallback)(void *cls,
-                                  const char *taler_pay_url,
-                                  enum TALER_ErrorCode ec);
 
 /**
-* Upload information
-* caller MUST free 't' using ANASTASIS_truth_free()
-*
-* @param cls closure for callback
-* @param t Truth object (contains provider url and truth public key)
-*/
+ * 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 ec status code of the request (success, failure, payment required)
+ * @param t truth object to create policies, NULL on failure
+ * @param taler_pay_url URL to make a payment, NULL if no payment is required
+ */
 typedef void
 (*ANASTASIS_TruthCallback)(void *cls,
-                           struct ANASTASIS_Truth *t);
+                           enum ANASTASIS_ErrorCode ec,
+                           struct ANASTASIS_Truth *t,
+                           const char *taler_pay_url);
+
 
 /**
-* Uploads a truth object onto a escrow provider
-*
-* @param ctx the CURL context used to connect to the backend
-* @param user_id user identifier derived from user data and backend salt
-* @param method defines the method of the challenge (secure question, sms, 
email)
-* @param instructions depending on method! usually only for security 
question/answer!
-* @param mime_type format of the challenge
-* @param salt the server salt
-* @param truth_data contains the truth for this challenge i.e. phone number, 
email address
-* @param truth_data_size size of the data
-* @param tpc opens a truth payment callback to pay the upload
-* @param tpc_cls closure for the payment callback
-* @param tc opens the truth callback which contains the status of the upload
-* @param tc_cls closure for the callback
-*/
+ * 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 method defines the method of the challenge (secure question, sms, 
email)
+ * @param instructions depending on method! usually only for security 
question/answer!
+ * @param mime_type format of the challenge
+ * @param salt the server salt
+ * @param truth_data contains the truth for this challenge i.e. phone number, 
email address
+ * @param truth_data_size size of the data
+ * @param tc opens the truth callback which contains the status of the upload
+ * @param tc_cls closure for the callback
+ */
 struct ANASTASIS_TruthUpload *
 ANASTASIS_truth_upload (struct GNUNET_CURL_Context *ctx,
                         const struct ANASTASIS_CRYPTO_UserIdentifierP *user_id,
@@ -397,22 +430,23 @@ ANASTASIS_truth_upload (struct GNUNET_CURL_Context *ctx,
                         const struct ANASTASIS_CRYPTO_PowSalt *salt,
                         const void *truth_data,
                         size_t truth_data_size,
-                        ANASTASIS_TruthPaymentCallback tpc,
-                        void *tpc_cls,
                         ANASTASIS_TruthCallback tc,
                         void *tc_cls);
 
 /**
-* Cancels a upload process
-* @param tu handle for the upload
-*/
+ * 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 allocated
-* @param t object to clean up
-*/
+ * 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);
 
@@ -438,34 +472,42 @@ ANASTASIS_truth_from_json (const json_t *json);
 json_t *
 ANASTASIS_truth_to_json (const struct ANASTASIS_Truth *t);
 
+
 /**
-* Policy object to upload
-*/
+ * 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 truths and 
encrypts the escrow master key.
-* @param truths array of truths which are stored on different providers
-* @param truths_len amount of truths in this 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
-*/
+ * Destroys a policy object.
+ *
+ * @param p handle for the policy to destroy
+ */
 void
 ANASTASIS_policy_destroy (struct ANASTASIS_Policy *p);
 
+
 /**
  * Function called with the results of a #secret_share().
  *
  * @param cls closure
- * @param @param current_etag sends back the etag of the upload (used to 
prevent redundant uploads)
- * @param server_url url of the server to pay for
+ * @param current_etag sends back the etag of the upload (used to prevent 
redundant uploads)
+ * @param server_url url of the server that provided the @a ec response
  * @param ec status code of the request
  * @param http_status http status code
  */
@@ -476,14 +518,15 @@ typedef void
                                  const enum TALER_ErrorCode ec,
                                  unsigned int http_status);
 
+
 /**
-* Callback for a payment process for uploading a policy
-*
-* @param cls closure for the callback
-* @param taler_pay_url url for the payment (taler://pay/Foo)
-* @param server_url url of the server to pay for
-* @param ec status of the request
-*/
+ * Callback for a payment process for uploading a policy
+ *
+ * @param cls closure for the callback
+ * @param taler_pay_url url for the payment (taler://pay/Foo)
+ * @param server_url url of the server to pay for
+ * @param ec status of the request
+ */
 typedef void
 (*ANASTASIS_SharePaymentCallback)(void *cls,
                                   const char *taler_pay_url,
@@ -491,27 +534,30 @@ typedef void
                                   enum TALER_ErrorCode ec);
 
 /**
-* Defines a recovery document upload process (recovery document consists of 
multiple policies)
-*/
+ * Defines a recovery document upload process (recovery document
+ * consists of multiple policies)
+ */
 struct ANASTASIS_SecretShare;
 
+
 /**
-* Creates a recovery document with the created policies.
-*
-* @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 last_etag NULL on 'first' use, otherwise 'current_etag' from previous 
ShareResultCallback
-* @param policies list of policies which are included in this recovery document
-* @param policies_length amount of policies in the document
-* @param pds contains details of past payments
-* @param pds_len length of @a pds array
-* @param spc payment callback is opened to pay the upload
-* @param spc_cls closure for the payment callback
-* @param src callback for the upload process
-* @param src_cls closure for the upload callback
-* @param core_secret input of the user which is secured by anastasis e.g. 
(wallet private key)
-* @param core_secret_size size of the core secret
-*/
+ * Creates a recovery document with the created policies and uploads it to
+ * all servers.  FIXME: how do we know the upload(s) are completed?
+ *
+ * @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 last_etag NULL on 'first' use, otherwise 'current_etag' from 
previous ShareResultCallback
+ * @param policies list of policies which are included in this recovery 
document
+ * @param policies_length amount of policies in the document
+ * @param pds contains details of past payments
+ * @param pds_len length of @a pds array
+ * @param spc payment callback is opened to pay the upload
+ * @param spc_cls closure for the payment callback
+ * @param src callback for the upload process
+ * @param src_cls closure for the upload callback
+ * @param core_secret input of the user which is secured by anastasis e.g. 
(wallet private key)
+ * @param core_secret_size size of the core secret
+ */
 struct ANASTASIS_SecretShare *
 ANASTASIS_secret_share (struct GNUNET_CURL_Context *ctx,
                         const json_t *id_data,
@@ -527,9 +573,14 @@ ANASTASIS_secret_share (struct GNUNET_CURL_Context *ctx,
                         const void *core_secret,
                         size_t core_secret_size);
 
+
 /**
-* Cancels a secret share request
-* @param ss handle to the request
-*/
+ * Cancels a secret share request.
+ *
+ * @param ss handle to the request
+ */
 void
 ANASTASIS_secret_share_cancel (struct ANASTASIS_SecretShare *ss);
+
+
+#endif
diff --git a/src/lib/anastasis_backup.c b/src/lib/anastasis_backup.c
new file mode 100644
index 0000000..24ac098
--- /dev/null
+++ b/src/lib/anastasis_backup.c
@@ -0,0 +1,1159 @@
+/*
+  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/>
+*/
+/**
+ * @brief anastasis client api
+ * @author Christian Grothoff
+ * @author Dominik Meister
+ * @author Dennis Neufeld
+ */
+
+#include "anastasis.h"
+#include <taler/taler_json_lib.h>
+#include <gnunet/gnunet_util_lib.h>
+#include <taler/taler_merchant_service.h>
+
+
+struct ANASTASIS_Truth
+{
+  /**
+   * Identification of the truth
+   */
+  struct ANASTASIS_CRYPTO_NonceP nonce;
+
+  /**
+   * Keyshare of this truth, used to generate policy keys
+   */
+  struct ANASTASIS_CRYPTO_KeyShareP key_share;
+
+  /**
+   * Key used to encrypt this truth
+   */
+  struct ANASTASIS_CRYPTO_TruthKeyP truth_key;
+
+  /**
+   * Server salt used to derive user identifier
+   */
+  struct ANASTASIS_CRYPTO_PowSalt salt;
+
+  /**
+   * Url of the server
+   */
+  char *url;
+
+  /**
+   * Method used for this truth
+   */
+  char *method;
+
+  /**
+   * Instructions for the user to recover this truth.
+   */
+  char *instructions;
+
+  /**
+   * Mime type of the truth.
+   */
+  char *mime_type;
+
+};
+
+
+struct ANASTASIS_TruthUpload
+{
+
+  /**
+   * User identifier used for the keyshare encryption
+   */
+  struct ANASTASIS_CRYPTO_UserIdentifierP id;
+
+  /**
+   * CURL Context for the Post Request
+   */
+  struct GNUNET_CURL_Context *ctx;
+
+  /**
+   * Callback which sends back the generated truth object later used to build 
the policy
+   */
+  ANASTASIS_TruthCallback tc;
+
+  /**
+   * Closure for the Callback
+   */
+  void *tc_cls;
+
+  /**
+   * Reference to the Truthstore Operation
+   */
+  struct ANASTASIS_TruthStoreOperation *tso;
+
+  /**
+   * The truth we are uploading.
+   */
+  struct ANASTASIS_Truth *t;
+
+};
+
+
+/**
+ * Function called with the result of trying to upload truth.
+ *
+ * @param cls our `struct ANASTASIS_TruthUpload`
+ * @param ec error code
+ * @param http_status HTTP status code (unused)
+ * @param ud details about the upload result
+ */
+static void
+truth_store_callback (void *cls,
+                      enum ANASTASIS_ErrorCode ec,
+                      unsigned int http_status,
+                      const struct ANASTASIS_UploadDetails *ud)
+{
+  struct ANASTASIS_TruthUpload *tu = cls;
+
+  (void) http_status;
+  tu->tso = NULL;
+  if (NULL == ud)
+  {
+    tu->tc (tu->tc_cls,
+            ANASTASIS_US_CLIENT_ERROR,
+            NULL,
+            NULL);
+    ANASTASIS_truth_upload_cancel (tu);
+    return;
+  }
+  switch (ud->us)
+  {
+  case ANASTASIS_US_SUCCESS:
+    tu->tc (tu->tc_cls,
+            ANASTASIS_US_SUCCESS,
+            tu->t,
+            NULL);
+    tu->t = NULL;
+    break;
+  case ANASTASIS_US_PAYMENT_REQUIRED:
+    {
+      struct TALER_MERCHANT_PayUriData pd;
+
+      if (GNUNET_OK !=
+          TALER_MERCHANT_parse_pay_uri (ud->details.payment_request,
+                                        &pd))
+      {
+        GNUNET_break_op (0);
+        tu->tc (tu->tc_cls,
+                ANASTASIS_US_SERVER_ERROR,
+                NULL,
+                pd.order_id);
+      }
+      else
+      {
+        GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                    "At truth upload order ID from Anastasis service is %s\n",
+                    pd.order_id);
+        tu->tc (tu->tc_cls,
+                ANASTASIS_US_PAYMENT_REQUIRED,
+                NULL,
+                pd.order_id);
+        TALER_MERCHANT_parse_pay_uri_free (&pd);
+      }
+    }
+    break;
+  case ANASTASIS_US_CONFLICTING_TRUTH:
+    tu->tc (tu->tc_cls,
+            ANASTASIS_US_CONFLICTING_TRUTH,
+            NULL,
+            NULL);
+    GNUNET_break (0);
+    break;
+  case ANASTASIS_US_HTTP_ERROR:
+    tu->tc (tu->tc_cls,
+            ANASTASIS_US_HTTP_ERROR,
+            NULL,
+            NULL);
+    break;
+  case ANASTASIS_US_CLIENT_ERROR:
+    GNUNET_break (0);
+    tu->tc (tu->tc_cls,
+            ANASTASIS_US_CLIENT_ERROR,
+            NULL,
+            NULL);
+    break;
+  case ANASTASIS_US_SERVER_ERROR:
+    tu->tc (tu->tc_cls,
+            ANASTASIS_US_SERVER_ERROR,
+            NULL,
+            NULL);
+    break;
+  default:
+    GNUNET_break (0);
+    tu->tc (tu->tc_cls,
+            ANASTASIS_US_CLIENT_ERROR,
+            NULL,
+            NULL);
+    break;
+  }
+  ANASTASIS_truth_upload_cancel (tu);
+}
+
+
+struct ANASTASIS_TruthUpload *
+ANASTASIS_truth_upload (struct GNUNET_CURL_Context *ctx,
+                        const struct ANASTASIS_CRYPTO_UserIdentifierP *user_id,
+                        const char *provider_url,
+                        const char *method,
+                        const char *instructions,
+                        const char *mime_type,
+                        const struct ANASTASIS_CRYPTO_PowSalt *salt,
+                        const void *truth_data,
+                        size_t truth_data_size,
+                        ANASTASIS_TruthCallback tc,
+                        void *tc_cls)
+{
+  struct ANASTASIS_TruthUpload *tu;
+  struct ANASTASIS_Truth *t;
+  struct ANASTASIS_CRYPTO_EncryptedKeyShareP *encrypted_key_share;
+  struct ANASTASIS_CRYPTO_TruthPublicKeyP pub_key;
+  void *encrypted_truth;
+  size_t encrypted_truth_size;
+  json_t *truth;
+
+  tu = GNUNET_new (struct ANASTASIS_TruthUpload);
+  tu->tc = tc;
+  tu->tc_cls = tc_cls;
+  tu->ctx = ctx;
+  tu->id = *user_id;
+  tu->tc = tc;
+  tu->tc_cls = tc_cls;
+  t = GNUNET_new (struct ANASTASIS_Truth);
+  t->url = GNUNET_strdup (provider_url);
+  t->method = GNUNET_strdup (method);
+  t->instructions = (NULL != instructions)
+    ? GNUNET_strdup (instructions)
+    : NULL;
+  t->mime_type = (NULL != mime_type)
+    ? GNUNET_strdup (mime_type)
+    : NULL;
+  t->salt = *salt;
+  tu->t = t;
+  GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
+                              &t->nonce,
+                              sizeof (struct ANASTASIS_CRYPTO_NonceP));
+  ANASTASIS_CRYPTO_keyshare_create (&t->key_share);
+  ANASTASIS_CRYPTO_keyshare_encrypt (&t->key_share,
+                                     &tu->id,
+                                     &encrypted_key_share);
+  GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_STRONG,
+                              &t->truth_key,
+                              sizeof (struct ANASTASIS_CRYPTO_TruthKeyP));
+  // FIXME: this seems VERY wrong, may be motivated from secure question???
+  {
+    struct GNUNET_HashCode hashed_answer;
+
+    GNUNET_CRYPTO_hash (truth_data,
+                        truth_data_size,
+                        &hashed_answer);
+    ANASTASIS_CRYPTO_truth_encrypt (&t->truth_key,
+                                    &hashed_answer,
+                                    sizeof(hashed_answer),
+                                    &encrypted_truth,
+                                    &encrypted_truth_size);
+  }
+  truth = json_pack ("{s:o," /* encrypted KeyShare */
+                     " s:s," /* method */
+                     " s:o," /* nonce */
+                     " s:s}", /* truth_mime */
+                     "keyshare_data", GNUNET_JSON_from_data_auto (
+                       encrypted_key_share),
+                     "method", method,
+                     "encrypted_truth", GNUNET_JSON_from_data (
+                       encrypted_truth, encrypted_truth_size),
+                     "truth_mime", mime_type);
+  GNUNET_free (encrypted_key_share);
+  GNUNET_free (encrypted_truth);
+  if (NULL == truth)
+  {
+    GNUNET_break (0);
+    return NULL;
+  }
+  ANASTASIS_CRYPTO_truth_public_key_derive (&t->nonce,
+                                            &pub_key);
+  tu->tso = ANASTASIS_truth_store (tu->ctx,
+                                   t->url,
+                                   &pub_key,
+                                   truth,
+                                   GNUNET_NO, // FIXME: tu->payment_requested,
+                                   NULL, // FIXME: tu->paid_order_id,
+                                   &truth_store_callback,
+                                   tu);
+  if (NULL == tu->tso)
+  {
+    GNUNET_break (0);
+    ANASTASIS_truth_free (t);
+    ANASTASIS_truth_upload_cancel (tu);
+    return NULL;
+  }
+  return tu;
+}
+
+
+void
+ANASTASIS_truth_upload_cancel (struct ANASTASIS_TruthUpload *tu)
+{
+  if (NULL != tu->tso)
+  {
+    ANASTASIS_truth_store_cancel (tu->tso);
+    tu->tso = NULL;
+  }
+  if (NULL != tu->t)
+  {
+    ANASTASIS_truth_free (tu->t);
+    tu->t = NULL;
+  }
+  GNUNET_free (tu);
+}
+
+
+void
+ANASTASIS_truth_free (struct ANASTASIS_Truth *t)
+{
+  GNUNET_free (t->url);
+  GNUNET_free (t->method);
+  GNUNET_free (t->instructions);
+  GNUNET_free (t->mime_type);
+  GNUNET_free (t);
+}
+
+
+json_t *
+ANASTASIS_truth_to_json (const struct ANASTASIS_Truth *t)
+{
+  return json_pack ("{s:s, s:o, s:s, s:s, s:s"
+                    ",s:o, s:o, s:o}",
+                    "url",
+                    t->url,
+                    "nonce",
+                    GNUNET_JSON_from_data_auto (&t->nonce),
+                    "method",
+                    t->method,
+                    "instructions",
+                    t->instructions,
+                    "mime-type",
+                    t->mime_type,
+                    "key-share",
+                    GNUNET_JSON_from_data_auto (&t->key_share),
+                    "truth-key",
+                    GNUNET_JSON_from_data_auto (&t->truth_key),
+                    "salt",
+                    GNUNET_JSON_from_data_auto (&t->salt));
+}
+
+
+struct ANASTASIS_Truth *
+ANASTASIS_truth_from_json (const json_t *json)
+{
+  struct ANASTASIS_Truth *t = GNUNET_new (struct ANASTASIS_Truth);
+  const char *url;
+  const char *method;
+  const char *instructions;
+  const char *mime_type;
+  struct GNUNET_JSON_Specification spec[] = {
+    GNUNET_JSON_spec_string ("url",
+                             &url),
+    GNUNET_JSON_spec_fixed_auto ("nonce",
+                                 &t->nonce),
+    GNUNET_JSON_spec_string ("method",
+                             &method),
+    GNUNET_JSON_spec_string ("instructions",
+                             &instructions),
+    GNUNET_JSON_spec_string ("mime-type",
+                             &mime_type),
+    GNUNET_JSON_spec_fixed_auto ("key-share",
+                                 &t->key_share),
+    GNUNET_JSON_spec_fixed_auto ("truth-key",
+                                 &t->truth_key),
+    GNUNET_JSON_spec_fixed_auto ("salt",
+                                 &t->salt),
+    GNUNET_JSON_spec_end ()
+  };
+  const char *err_name;
+  unsigned int err_line;
+
+  if (GNUNET_OK !=
+      GNUNET_JSON_parse (json,
+                         spec,
+                         &err_name,
+                         &err_line))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Failed to parse truth in line %u (%s)\n",
+                err_line,
+                err_name);
+    return NULL;
+  }
+  t->method = GNUNET_strdup (method);
+  t->instructions = GNUNET_strdup (instructions);
+  t->mime_type = GNUNET_strdup (mime_type);
+  t->url = GNUNET_strdup (url);
+  return t;
+}
+
+
+struct ANASTASIS_Policy
+{
+  /**
+   * Encrypted policy master key
+   */
+  struct ANASTASIS_CRYPTO_PolicyKeyP policy_key;
+
+  /**
+   * Salt used to encrypt the master key
+   */
+  struct ANASTASIS_CRYPTO_SaltP salt;
+
+  /**
+   * Array of truths
+   */
+  struct ANASTASIS_Truth **truths;
+
+  /**
+   * Length of @ truths array.
+   */
+  uint32_t truths_length;
+
+};
+
+
+/**
+ * Duplicate truth object.
+ *
+ * @param t object to duplicate
+ * @return copy of @a t
+ */
+static struct ANASTASIS_Truth *
+truth_dup (const struct ANASTASIS_Truth *t)
+{
+  struct ANASTASIS_Truth *d = GNUNET_new (struct ANASTASIS_Truth);
+
+  *d = *t;
+  d->url = GNUNET_strdup (t->url);
+  d->method = GNUNET_strdup (t->method);
+  d->instructions = GNUNET_strdup (t->instructions);
+  d->mime_type = GNUNET_strdup (t->mime_type);
+  return d;
+}
+
+
+struct ANASTASIS_Policy *
+ANASTASIS_policy_create (const struct ANASTASIS_Truth *truths[],
+                         unsigned int truths_len)
+{
+  struct ANASTASIS_Policy *p;
+
+  p = GNUNET_new (struct ANASTASIS_Policy);
+  GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
+                              &p->salt,
+                              sizeof (struct ANASTASIS_CRYPTO_SaltP));
+  {
+    struct ANASTASIS_CRYPTO_KeyShareP key_shares[truths_len];
+
+    for (unsigned int i = 0; i < truths_len; i++)
+      key_shares[i] = truths[i]->key_share;
+    ANASTASIS_CRYPTO_policy_key_derive (key_shares,
+                                        truths_len,
+                                        &p->salt,
+                                        &p->policy_key);
+  }
+  p->truths = GNUNET_new_array (truths_len,
+                                struct ANASTASIS_Truth *);
+  for (unsigned int i = 0; i<truths_len; i++)
+    p->truths[i] = truth_dup (truths[i]);
+  p->truths_length = truths_len;
+  return p;
+}
+
+
+void
+ANASTASIS_policy_destroy (struct ANASTASIS_Policy *p)
+{
+  for (unsigned int i = 0; i<p->truths_length; i++)
+    ANASTASIS_truth_free (p->truths[i]);
+  GNUNET_free (p->truths);
+  GNUNET_free (p);
+}
+
+
+struct ANASTASIS_SecretShare;
+
+/**
+ * State for a "policy store" CMD.
+ */
+struct PolicyStoreState
+{
+  /**
+   * User identifier used as entropy source for the account public key
+   */
+  struct ANASTASIS_CRYPTO_UserIdentifierP id;
+
+  /**
+   * Eddsa Publickey.
+   */
+  struct ANASTASIS_CRYPTO_AccountPublicKeyP anastasis_pub;
+
+  /**
+   * Eddsa Privatekey.
+   */
+  struct ANASTASIS_CRYPTO_AccountPrivateKeyP anastasis_priv;
+
+  /**
+   * Hash of the previous upload (maybe bogus if
+   * #ANASTASIS_TESTING_UO_PREV_HASH_WRONG is set in @e uo).
+   * Maybe all zeros if there was no previous upload.
+   */
+  struct GNUNET_HashCode prev_hash;
+
+  /**
+   * Hash of the current upload.
+   */
+  struct GNUNET_HashCode curr_hash;
+
+  /**
+   * Payment identifier.
+   */
+  struct ANASTASIS_PaymentSecretP payment_secret;
+
+  /**
+   * Struct to obtain the salt from the server
+   */
+  struct SaltState *st;
+
+  /**
+   * Server salt
+   */
+  const struct ANASTASIS_CRYPTO_PowSalt *server_salt;
+
+  /**
+   * The policy data.
+   */
+  void *recovery_data;
+
+  /**
+   * The /policy POST operation handle.
+   */
+  struct ANASTASIS_PolicyStoreOperation *pso;
+
+  /**
+   * URL of the anastasis backend.
+   */
+  const char *anastasis_url;
+
+  /**
+   * Payment order ID we got back, if any. Otherwise NULL.
+   */
+  char *payment_order_id;
+
+  /**
+   * Payment order ID we are to provide in the request, may be NULL.
+   */
+  const char *payment_order_req;
+
+  /**
+   * Previous upload, or NULL for none. Used to calculate what THIS
+   * upload is based on.
+   */
+  const char *prev_upload;
+
+  /**
+   * reference to SecretShare
+   */
+  struct ANASTASIS_SecretShare *ss;
+
+  /**
+   * Callback which gives back the payment details
+   */
+  ANASTASIS_SharePaymentCallback spc;
+
+  /**
+   * Closure for the payment callback
+   */
+  void *spc_cls;
+
+  /**
+   * Callback which gives back the result of the POST Request
+   */
+  ANASTASIS_ShareResultCallback src;
+
+  /**
+   * Closure for the Result Callback
+   */
+  void *src_cls;
+
+  /**
+   * Number of bytes in @e recovery_data
+   */
+  size_t recovery_data_size;
+
+  /**
+   * Expected status code.
+   */
+  unsigned int http_status;
+
+  int payment_requested;
+
+  /**
+   * Status of the transaction
+   */
+  enum ANASTASIS_ErrorCode ec;
+
+};
+
+/**
+* Defines a recovery document upload process (recovery document consists of 
multiple policies)
+*/
+struct ANASTASIS_SecretShare
+{
+  /**
+   * Closure for the Result Callback
+   */
+  struct GNUNET_CURL_Context *ctx;
+
+  /**
+   * References for the upload states and operations (size of truths passed)
+   */
+  struct PolicyStoreState **pss;
+
+  /**
+   * Closure for the Result Callback
+   */
+  unsigned int pss_length;
+};
+
+
+/**
+ * Free the state of a "policy store" CMD, and possibly
+ * cancel it if it did not complete.
+ *
+ * @param cls closure.
+ */
+static void
+policy_store_cleanup (void *cls)
+{
+  struct PolicyStoreState *pss = cls;
+
+  if (NULL != pss->pso)
+  {
+    ANASTASIS_policy_store_cancel (pss->pso);
+    pss->pso = NULL;
+  }
+  GNUNET_free (pss->recovery_data);
+  GNUNET_free (pss->payment_order_id);
+  GNUNET_free (pss);
+}
+
+
+static void
+policy_store_cb (void *cls,
+                 enum ANASTASIS_ErrorCode ec,
+                 unsigned int http_status,
+                 const struct ANASTASIS_UploadDetails *ud)
+{
+  struct PolicyStoreState *pss = cls;
+
+  pss->pso = NULL;
+  pss->ec = ec;
+  if ((http_status != pss->http_status) &&
+      (http_status != MHD_HTTP_PAYMENT_REQUIRED))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Unexpected response code %u/%d in %s:%u\n",
+                http_status,
+                (int) ec,
+                __FILE__,
+                __LINE__);
+
+    if (NULL != pss->src)
+    {
+      pss->src (pss->src_cls,
+                &pss->curr_hash,
+                pss->anastasis_url,
+                ec,
+                http_status);
+      pss->src = NULL;
+    }
+    return;
+  }
+  if (NULL != ud)
+  {
+    switch (ud->us)
+    {
+    case ANASTASIS_US_SUCCESS:
+      if (0 != GNUNET_memcmp (&pss->curr_hash,
+                              ud->details.curr_backup_hash))
+      {
+        GNUNET_break (0);
+        return;
+      }
+      break;
+    case ANASTASIS_US_PAYMENT_REQUIRED:
+      {
+        struct TALER_MERCHANT_PayUriData pd;
+
+        if (GNUNET_OK !=
+            TALER_MERCHANT_parse_pay_uri (ud->details.payment_request,
+                                          &pd))
+        {
+          GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                      "Did not find `%s' in `%s'\n",
+                      "/-/-/",
+                      ud->details.payment_request);
+          GNUNET_break (0);
+          return;
+        }
+        pss->payment_order_id = GNUNET_strdup (pd.order_id);
+        TALER_MERCHANT_parse_pay_uri_free (&pd);
+        GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                    "At %s:%d Order ID from Anastasis service is %s\n",
+                    __FILE__, __LINE__,
+                    pss->payment_order_id);
+        memset (&pss->curr_hash,
+                0,
+                sizeof (struct GNUNET_HashCode));
+        if (NULL != pss->spc)
+        {
+          pss->spc (pss->spc_cls,
+                    ud->details.payment_request,
+                    pss->anastasis_url,
+                    ec);
+          pss->spc = NULL;
+          return;
+        }
+      }
+    case ANASTASIS_US_CONFLICTING_POLICY:
+      GNUNET_break (0);
+      return;
+    case ANASTASIS_US_HTTP_ERROR:
+      break;
+    case ANASTASIS_US_CLIENT_ERROR:
+      GNUNET_break (0);
+      return;
+    case ANASTASIS_US_SERVER_ERROR:
+      GNUNET_break (0);
+      return;
+    default:
+      GNUNET_break (0);
+      return;
+    }
+    if (NULL != pss->src)
+    {
+      pss->src (pss->src_cls,
+                &pss->curr_hash,
+                pss->anastasis_url,
+                ec,
+                http_status);
+      pss->src = NULL;
+      return;
+    }
+  }
+  GNUNET_break (0);
+}
+
+
+/**
+ * Counts the number of different providers
+ *
+ * @param policies Array of policies
+ * @param policies_len Length of array
+ * @return number of different providers
+ */
+static unsigned int
+ANASTASIS_get_num_urls (const struct ANASTASIS_Policy *policies[],
+                        unsigned int policies_len)
+{
+  unsigned int len = 0;
+  unsigned int unique_urls_len = 0;
+
+  for (unsigned int i = 0; i < policies_len; i++)
+    len += policies[i]->truths_length;
+
+  {
+    char *provider[len];
+
+    for (unsigned int l = 0; l < policies_len; l++)
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                  "At %s:%d policy is %s-%llu b\n", __FILE__, __LINE__,
+                  TALER_B2S (policies[l]),
+                  (unsigned long long) sizeof (struct ANASTASIS_Policy));
+
+      for (unsigned int j = 0; j < policies[l]->truths_length; j++)
+      {
+        GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                    "At %s:%d truth is %s-%llu b\n", __FILE__, __LINE__,
+                    TALER_B2S (policies[l]->truths[j]),
+                    (unsigned long long) sizeof (struct ANASTASIS_Truth));
+
+        int contains_url = 0;
+        if (0 < unique_urls_len)
+        {
+          for (unsigned int k = 0; k < unique_urls_len; k++)
+          {
+            GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                        "At %s:%d provider url from truth is %s\n", __FILE__,
+                        __LINE__,
+                        policies[l]->truths[j]->url);
+
+            if (NULL != provider[k])
+            {
+              if (0 ==
+                  strcmp (policies[l]->truths[j]->url, provider[k]))
+              {
+                contains_url = 1;
+                break;
+              }
+            }
+          }
+        }
+
+        if (0 == contains_url)
+        {
+          provider[unique_urls_len]
+            = GNUNET_strdup (policies[l]->truths[j]->url);
+          GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                      "At %s:%d unique provider url is %s\n",
+                      __FILE__, __LINE__,
+                      provider[unique_urls_len]);
+          unique_urls_len++;
+        }
+      }
+    }
+    for (unsigned int i = 0; i < unique_urls_len; i++)
+    {
+      GNUNET_free (provider[i]);
+    }
+  }
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "At %s:%d unique_urls_len is %d\n", __FILE__, __LINE__,
+              unique_urls_len);
+
+  return unique_urls_len;
+}
+
+
+struct ANASTASIS_SecretShare *
+ANASTASIS_secret_share (struct GNUNET_CURL_Context *ctx,
+                        const json_t *id_data,
+                        const struct GNUNET_HashCode *last_etag,
+                        const struct ANASTASIS_Policy *policies[],
+                        unsigned int policies_len,
+                        const struct ANASTASIS_PaymentDetails *pds,
+                        unsigned int pds_len,
+                        ANASTASIS_SharePaymentCallback spc,
+                        void *spc_cls,
+                        ANASTASIS_ShareResultCallback src,
+                        void *src_cls,
+                        const void *core_secret,
+                        size_t core_secret_size)
+{
+  struct ANASTASIS_SecretShare *ss;
+
+  GNUNET_assert (policies_len > 0);
+  unsigned int pss_length = ANASTASIS_get_num_urls (policies,
+                                                    policies_len);
+  struct PolicyStoreState *pss[pss_length];
+  struct ANASTASIS_CRYPTO_EncryptedMasterKeyP
+    encrypted_master_keys[policies_len];
+  struct ANASTASIS_CRYPTO_PolicyKeyP policy_keys[policies_len];
+  void *encrypted_core_secret;
+  // Recovery document contains the array decryption policies and the array 
escrow methods
+  json_t *recovery_document;
+  size_t recovery_document_size;
+  char *recovery_document_str;
+  // json array
+  json_t *dec_policies;
+  // json array
+  json_t *esc_methods;
+
+  if (0 == pss_length)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "At %s:%d pss_length is %d!\n", __FILE__, __LINE__,
+                pss_length);
+    GNUNET_break (0);
+    return NULL;
+  }
+
+  ss = GNUNET_new (struct ANASTASIS_SecretShare);
+  for (unsigned int i = 0; i < pss_length; i++)
+  {
+    pss[i] = GNUNET_new (struct PolicyStoreState);
+    pss[i]->ss = ss;
+  }
+  ss->pss = pss;
+  ss->pss_length = pss_length;
+  ss->ctx = ctx;
+
+  for (unsigned int i = 0; i < policies_len; i++)
+    policy_keys[i] = policies[i]->policy_key;
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "At %s:%d core secret is %s-%llu b\n", __FILE__, __LINE__,
+              TALER_b2s (core_secret,
+                         core_secret_size),
+              (unsigned long long) core_secret_size);
+
+  ANASTASIS_CRYPTO_core_secret_encrypt (policy_keys,
+                                        policies_len,
+                                        core_secret,
+                                        core_secret_size,
+                                        &encrypted_core_secret,
+                                        encrypted_master_keys);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "At %s:%d encrypted core secret is %s-%llu b\n", __FILE__,
+              __LINE__,
+              TALER_b2s (encrypted_core_secret,
+                         core_secret_size),
+              (unsigned long long) core_secret_size);
+
+  dec_policies = json_array ();
+  esc_methods = json_array ();
+  int index_pss = 0;
+  for (unsigned int k = 0; k < policies_len; k++)
+  {
+    const struct ANASTASIS_Policy *policy = policies[k];
+
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "At %s:%d policy is %s\n",
+                __FILE__,
+                __LINE__,
+                TALER_B2S (&policy->policy_key));
+
+    json_t *nonces = json_array ();
+    for (unsigned int b = 0; b < policy->truths_length; b++)
+    {
+      json_array_append (nonces,
+                         GNUNET_JSON_from_data_auto (
+                           &policy->truths[b]->nonce));
+    }
+
+    if (0 !=
+        json_array_append_new (
+          dec_policies,
+          json_pack ("{s:o,"   /* encrypted master key */
+                     " s:o,"   /* policy nonces  */
+                     " s:o,"   /* policy salt  */
+                     " s:i}",  /* policy nonces length */
+                     "master_key",
+                     GNUNET_JSON_from_data_auto (
+                       &encrypted_master_keys[k]),
+                     "nonces",
+                     nonces,
+                     "salt",
+                     GNUNET_JSON_from_data_auto (&policy->salt),
+                     "nonces_length",
+                     (int) policy->truths_length)))
+    {
+      GNUNET_break (0);
+      json_decref (dec_policies);
+      return NULL;
+    }
+
+    // FIXME CHALLENGE
+    for (unsigned int l = 0; l < policy->truths_length; l++)
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                  "At %s:%d truth is %s-%llu b\n", __FILE__, __LINE__,
+                  TALER_B2S (policy->truths[l]),
+                  (unsigned long long) sizeof (struct ANASTASIS_Truth));
+
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                  "At %s:%d keyshare is %s-%llu b\n", __FILE__, __LINE__,
+                  TALER_B2S (&policy->truths[l]->key_share),
+                  (unsigned long
+                   long) sizeof (policy->truths[l]->key_share));
+
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                  "At %s:%d truthkey is %s-%llu b\n", __FILE__, __LINE__,
+                  TALER_B2S (&policy->truths[l]->truth_key),
+                  (unsigned long
+                   long) sizeof (policy->truths[l]->truth_key));
+
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                  "At %s:%d nonce is %s-%llu b\n", __FILE__, __LINE__,
+                  TALER_B2S (&policy->truths[l]->nonce),
+                  (unsigned long long) sizeof (policy->truths[l]->nonce));
+
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                  "At %s:%d server salt is %s-%llu b\n", __FILE__, __LINE__,
+                  TALER_B2S (&policy->truths[l]->salt),
+                  (unsigned long long) sizeof (policy->truths[l]->salt));
+
+      // FIXME: JUST APPEND UNIQUE NONCES!!!
+      // creates a json array for saving
+      if (0 !=
+          json_array_append_new (
+            esc_methods,
+            json_pack ("{s:o," /* truth nonce */
+                       " s:s," /* provider url */
+                       " s:s," /* instructions */
+                       " s:o," /* truth key */
+                       " s:o," /* truth salt */
+                       " s:s}", /* escrow method */
+                       "nonce",
+                       GNUNET_JSON_from_data_auto (
+                         &policy->truths[l]->nonce),
+                       "url",
+                       policy->truths[l]->url,
+                       "instructions",
+                       policy->truths[l]->instructions,
+                       "truth_key", GNUNET_JSON_from_data_auto (
+                         &policy->truths[l]->truth_key),
+                       "salt", GNUNET_JSON_from_data_auto (
+                         &policy->truths[l]->salt),
+                       "escrow_method",
+                       policy->truths[l]->method)))
+      {
+        GNUNET_break (0);
+        json_decref (esc_methods);
+        return NULL;
+      }
+
+      // prepares policy store operation
+      bool contains_url = false;
+      for (unsigned int j = 0; j < ss->pss_length; j++)
+      {
+        if (NULL != ss->pss[j]->anastasis_url)
+        {
+          if (0 == strcmp (ss->pss[j]->anastasis_url,
+                           policy->truths[l]->url))
+          {
+            contains_url = true;
+            break;
+          }
+        }
+      }
+      if (! contains_url)
+      {
+        ss->pss[index_pss]->anastasis_url = policy->truths[l]->url;
+        GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                    "At %s:%d anastasis url is %s\n", __FILE__, __LINE__,
+                    ss->pss[index_pss]->anastasis_url);
+        if (NULL != last_etag)
+          ss->pss[index_pss]->prev_hash = *last_etag;
+        ss->pss[index_pss]->server_salt = &policy->truths[l]->salt;
+        if (pds_len > 0)
+        {
+          for (unsigned int m = 0; 0 < pds_len; m++)
+          {
+            if (NULL == pds[m].provider_url)
+              continue;
+            if (0 == strcmp (pds[m].provider_url,
+                             policy->truths[l]->url))
+            {
+              ss->pss[index_pss]->payment_secret
+                = pds[m].payment_secret;
+              GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                          "At %s:%d Payment-Identifier from PD is: %s\n",
+                          __FILE__,
+                          __LINE__,
+                          TALER_B2S (&pds[m].payment_secret));
+              break;
+            }
+          }
+        }
+        index_pss++;
+      }
+    }
+  }
+
+  recovery_document = json_pack (
+    "{s:o," /* decryption policies */
+    " s:o," /* escrow methods */
+    " s:o}", /* encrypted core secret */
+    "policies", dec_policies,
+    "escrow_methods", esc_methods,
+    "core_secret", GNUNET_JSON_from_data (encrypted_core_secret,
+                                          core_secret_size));
+  GNUNET_free (encrypted_core_secret);
+  GNUNET_assert (NULL != recovery_document);
+
+  // FIXME COMPRESSION
+  recovery_document_str = json_dumps (recovery_document,
+                                      JSON_COMPACT | JSON_SORT_KEYS);
+  recovery_document_size = strlen (recovery_document_str);
+  GNUNET_assert (NULL != recovery_document_str);
+  json_decref (recovery_document);
+
+  for (unsigned int l = 0; l < ss->pss_length; l++)
+  {
+    ss->pss[l]->http_status = MHD_HTTP_NO_CONTENT;
+
+    ss->pss[l]->spc = spc;
+    ss->pss[l]->spc_cls = spc_cls;
+    ss->pss[l]->src = src;
+    ss->pss[l]->src_cls = src_cls;
+
+    ANASTASIS_CRYPTO_user_identifier_derive (id_data,
+                                             ss->pss[l]->server_salt,
+                                             &ss->pss[l]->id);
+
+    ANASTASIS_CRYPTO_account_private_key_derive (&ss->pss[l]->id,
+                                                 &ss->pss[l]->anastasis_priv);
+
+    ANASTASIS_CRYPTO_recovery_document_encrypt (&ss->pss[l]->id,
+                                                recovery_document_str,
+                                                recovery_document_size,
+                                                &ss->pss[l]->recovery_data,
+                                                
&ss->pss[l]->recovery_data_size);
+    GNUNET_free (recovery_document_str);
+    // hash recovery data
+    GNUNET_CRYPTO_hash (ss->pss[l]->recovery_data,
+                        ss->pss[l]->recovery_data_size,
+                        &ss->pss[l]->curr_hash);
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "At %s:%d current hash is %s-%llu b\n", __FILE__, __LINE__,
+                TALER_B2S (&ss->pss[l]->curr_hash),
+                (unsigned long long) sizeof (struct GNUNET_HashCode));
+
+    ss->pss[l]->pso = ANASTASIS_policy_store (ss->ctx,
+                                              ss->pss[l]->anastasis_url,
+                                              &ss->pss[l]->anastasis_priv,
+                                              ( ( (NULL !=
+                                                   ss->pss[l]->prev_upload) &&
+                                                  (GNUNET_NO == GNUNET_is_zero 
(
+                                                     last_etag)) ))
+                                              ? last_etag
+                                              : NULL,
+                                              ss->pss[l]->recovery_data,
+                                              ss->pss[l]->recovery_data_size,
+                                              ss->pss[l]->payment_requested,
+                                              (pds_len > 0)
+                                              ? &ss->pss[l]->payment_secret
+                                              : NULL,
+                                              &policy_store_cb,
+                                              ss->pss[l]);
+    if (NULL == ss->pss[l]->pso)
+    {
+      GNUNET_break (0);
+      return NULL;
+    }
+  }
+  return ss;
+}
+
+
+void
+ANASTASIS_secret_share_cancel (struct ANASTASIS_SecretShare *ss)
+{
+  GNUNET_free (ss);
+}
diff --git a/src/reducer/anastasis_api_backup_redux.c 
b/src/reducer/anastasis_api_backup_redux.c
index 1fc1224..5263008 100644
--- a/src/reducer/anastasis_api_backup_redux.c
+++ b/src/reducer/anastasis_api_backup_redux.c
@@ -1719,7 +1719,9 @@ upload_rec_documents (json_t *state,
 */
 static void
 truth_upload_cb (void *cls,
-                 struct ANASTASIS_Truth *t)
+                 enum ANASTASIS_ErrorCode ec,
+                 struct ANASTASIS_Truth *t,
+                 const char *taler_pay_url)
 {
   struct TruthUploadState *tus = cls;
   json_t *p;
@@ -1729,10 +1731,45 @@ truth_upload_cb (void *cls,
   tus->tuo = NULL;
   if (NULL == t)
   {
-    ANASTASIS_redux_fail (tus->cb,
-                          tus->cb_cls,
-                          TALER_EC_ANASTASIS_REDUCER_ACTION_INVALID, // FIXME: 
Error Code
-                          "enter_secret or pay");
+    char buf[13];
+    json_t *truth_uploads;
+    json_t *p;
+
+    if (NULL == taler_pay_url)
+    {
+      ANASTASIS_redux_fail (tus->cb,
+                            tus->cb_cls,
+                            TALER_EC_ANASTASIS_REDUCER_ACTION_INVALID, // 
FIXME: Error Code
+                            "enter_secret or pay");
+      return;
+    }
+
+    truth_uploads = json_object_get (tus->state,
+                                     "truth_uploads");
+    p = json_pack ("{s:I,s:s}",
+                   "status",
+                   (json_int_t) MHD_HTTP_PAYMENT_REQUIRED,
+                   "pay_url",
+                   taler_pay_url);
+    GNUNET_assert (NULL != p);
+    {
+      GNUNET_snprintf (buf,
+                       sizeof (buf),
+                       "%u",
+                       tus->index);
+      GNUNET_assert (0 ==
+                     json_object_set (truth_uploads,
+                                      buf,
+                                      p));
+
+    }
+    set_state (tus->state,
+               ANASTASIS_backup_state_to_string (
+                 ANASTASIS_BACKUP_STATE_POLICIES_PAYING));
+    tus->cb (tus->cb_cls,
+             ANASTASIS_EC_NONE,
+             tus->state);
+    tus->cb = NULL;
     return;
   }
   tus->truth = t;
@@ -1774,63 +1811,6 @@ truth_upload_cb (void *cls,
 }
 
 
-/**
- * Initiates a callback for the payment of the truth upload
- *
- * @param cls closure
- * @param taler_pay_url payment link for the transaction (taler://pay/Foo)
- * @param ec status code of the request
- */
-static void
-truth_payment_cb (void *cls,
-                  const char *taler_pay_url,
-                  enum TALER_ErrorCode ec)
-{
-  struct TruthUploadState *tus = cls;
-  tus->tuo = NULL;
-
-  if (! ec)
-  {
-    char buf[13];
-    json_t *truth_uploads;
-    json_t *p;
-
-    truth_uploads = json_object_get (tus->state,
-                                     "truth_uploads");
-    p = json_pack ("{s:I,s:s}",
-                   "status",
-                   (json_int_t) MHD_HTTP_PAYMENT_REQUIRED,
-                   "pay_url",
-                   taler_pay_url);
-    GNUNET_assert (NULL != p);
-    {
-      GNUNET_snprintf (buf,
-                       sizeof (buf),
-                       "%u",
-                       tus->index);
-      GNUNET_assert (0 ==
-                     json_object_set (truth_uploads,
-                                      buf,
-                                      p));
-
-    }
-    set_state (tus->state,
-               ANASTASIS_backup_state_to_string (
-                 ANASTASIS_BACKUP_STATE_POLICIES_PAYING));
-    tus->cb (tus->cb_cls,
-             ANASTASIS_EC_NONE,
-             tus->state);
-    tus->cb = NULL;
-    return;
-  }
-  ANASTASIS_redux_fail (tus->cb,
-                        tus->cb_cls,
-                        ec,
-                        "enter_secret or pay");
-  // FIXME: Payment handling
-}
-
-
 /**
  * Function to upload truths.
  *
@@ -1883,8 +1863,6 @@ upload_truths (json_t *state,
               &tus_arr[i]->backend_salt,
               tus_arr[i]->truth_data,
               tus_arr[i]->truth_data_size,
-              &truth_payment_cb,
-              tus_arr[i],
               &truth_upload_cb,
               tus_arr[i]);
             if (NULL == tus_arr[i]->tuo)
@@ -1919,8 +1897,6 @@ upload_truths (json_t *state,
                                                     &tus_arr[i]->backend_salt,
                                                     tus_arr[i]->truth_data,
                                                     
tus_arr[i]->truth_data_size,
-                                                    &truth_payment_cb,
-                                                    tus_arr[i],
                                                     &truth_upload_cb,
                                                     tus_arr[i]);
           if (NULL == tus_arr[i]->tuo)
@@ -2005,8 +1981,6 @@ upload_truths (json_t *state,
                                          &tus->backend_salt,
                                          tus->truth_data,
                                          tus->truth_data_size,
-                                         &truth_payment_cb,
-                                         tus,
                                          &truth_upload_cb,
                                          tus);
       if (NULL == tus->tuo)
diff --git a/src/testing/testing_cmd_truth_upload.c 
b/src/testing/testing_cmd_truth_upload.c
index c5665c2..5625008 100644
--- a/src/testing/testing_cmd_truth_upload.c
+++ b/src/testing/testing_cmd_truth_upload.c
@@ -119,13 +119,16 @@ struct TruthUploadState
 */
 static void
 truth_upload_cb (void *cls,
-                 struct ANASTASIS_Truth *t)
+                 enum ANASTASIS_ErrorCode ec,
+                 struct ANASTASIS_Truth *t,
+                 const char *taler_pay_url)
 {
   struct TruthUploadState *tus = cls;
-  tus->tuo = NULL;
 
+  tus->tuo = NULL;
   if (NULL == t)
   {
+    // FIXME: handle payment!
     GNUNET_break (0);
     TALER_TESTING_interpreter_fail (tus->is);
     return;
@@ -135,36 +138,6 @@ truth_upload_cb (void *cls,
 }
 
 
-/**
- * Initiates a callback for the payment of the truth upload
- *
- * @param cls closure
- * @param taler_pay_url payment link for the transaction (taler://pay/Foo)
- * @param ec status code of the request
- */
-static void
-truth_payment_cb (void *cls,
-                  const char *taler_pay_url,
-                  enum TALER_ErrorCode ec)
-{
-  struct TruthUploadState *tus = cls;
-  tus->tuo = NULL;
-  // FIXME: Payment handling
-  if (NULL == taler_pay_url)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Errorcode /%d in command %s in %s:%u\n",
-                (int) ec,
-                tus->is->commands[tus->is->ip].label,
-                __FILE__,
-                __LINE__);
-    TALER_TESTING_interpreter_fail (tus->is);
-    return;
-  }
-  TALER_TESTING_interpreter_next (tus->is);
-}
-
-
 /**
  * Run a "truth upload" CMD.
  *
@@ -218,8 +191,6 @@ truth_upload_run (void *cls,
                                      salt,
                                      tus->truth_data,
                                      tus->truth_data_size,
-                                     &truth_payment_cb,
-                                     tus->tpc_cls,
                                      &truth_upload_cb,
                                      tus);
 
@@ -368,4 +339,4 @@ ANASTASIS_TESTING_cmd_truth_upload (const char *label,
 }
 
 
-/* end of testing_cmd_truth_upload.c */
\ No newline at end of file
+/* end of testing_cmd_truth_upload.c */

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]