gnunet-svn
[Top][All Lists]
Advanced

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

[taler-anastasis] branch master updated: unify code to always upload has


From: gnunet
Subject: [taler-anastasis] branch master updated: unify code to always upload hashed answers to server, even for PINs
Date: Sat, 06 Feb 2021 17:58:24 +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 16f8c7e  unify code to always upload hashed answers to server, even 
for PINs
16f8c7e is described below

commit 16f8c7e18af167a14f0f2068d3453aa994095af8
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Sat Feb 6 17:58:22 2021 +0100

    unify code to always upload hashed answers to server, even for PINs
---
 src/backend/anastasis-httpd_truth.c            |  57 +---
 src/include/anastasis.h                        | 198 ++++++++------
 src/include/anastasis_crypto_lib.h             |  13 +
 src/include/anastasis_database_plugin.h        |   7 +-
 src/include/anastasis_service.h                |   5 +-
 src/lib/anastasis_recovery.c                   | 357 ++++++++-----------------
 src/reducer/anastasis_api_recovery_redux.c     |  48 ++--
 src/reducer/anastasis_api_redux.c              |  18 +-
 src/restclient/anastasis_api_keyshare_lookup.c |  16 +-
 src/stasis/plugin_anastasis_postgres.c         |  57 ++--
 src/testing/testing_api_cmd_keyshare_lookup.c  |  24 +-
 src/testing/testing_cmd_challenge_answer.c     |   3 +-
 src/testing/testing_cmd_challenge_start.c      | 162 +++++------
 src/util/anastasis_crypto.c                    | 140 ++--------
 14 files changed, 436 insertions(+), 669 deletions(-)

diff --git a/src/backend/anastasis-httpd_truth.c 
b/src/backend/anastasis-httpd_truth.c
index 94d60bd..6169ab9 100644
--- a/src/backend/anastasis-httpd_truth.c
+++ b/src/backend/anastasis-httpd_truth.c
@@ -139,6 +139,7 @@ struct GetContext
 static struct GetContext *gc_head;
 static struct GetContext *gc_tail;
 
+
 void
 AH_truth_shutdown (void)
 {
@@ -210,9 +211,8 @@ make_payment_request (const char *order_id)
   {
     char *hdr;
 
-    /* TODO: support instances? */
     GNUNET_asprintf (&hdr,
-                     "taler://pay/%s/-/-/%s",
+                     "taler://pay/%s/%s",
                      AH_backend_url,
                      order_id);
     GNUNET_break (MHD_YES ==
@@ -637,8 +637,6 @@ AH_handler_truth_get (struct MHD_Connection *connection,
   TALER_amount_get_zero (AH_currency, &zero_amount);
   bool zero_cost = false;
 
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Handling truth get\n");
   if (NULL != gc)
   {
     if (NULL != gc->resp)
@@ -661,9 +659,6 @@ AH_handler_truth_get (struct MHD_Connection *connection,
     {
       enum ANASTASIS_AUTHORIZATION_Result ret;
 
-      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                  "authorization process started \n");
-
       ret = gc->authorization->process (gc->as,
                                         connection);
       switch (ret)
@@ -812,6 +807,7 @@ AH_handler_truth_get (struct MHD_Connection *connection,
   }
 
   /* Check if the cost is zero to skip the payment */
+  // FIXME: lookup costs properly!
   if (0 == strcmp ("question",
                    method))
   {
@@ -881,36 +877,22 @@ AH_handler_truth_get (struct MHD_Connection *connection,
       // generate new payment identifier
       GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
                                   &gc->payment_identifier,
-                                  sizeof (
-                                    struct ANASTASIS_PaymentSecretP));
-      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                  "At %s:%d Payment-Identifier generated is: %s\n",
-                  __FILE__,
-                  __LINE__,
-                  TALER_B2S (&gc->payment_identifier));
-
-      GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-                  "At %s:%d Payment is required, starting payment process\n",
-                  __FILE__,
-                  __LINE__);
+                                  sizeof (struct ANASTASIS_PaymentSecretP));
       return begin_payment (gc,
                             GNUNET_YES);
     }
   }
-
+  if (NULL == challenge_response_s)
+  {
+    // FIXME: queue PROPER reply...
+    GNUNET_free (decrypted_truth);
+    return MHD_NO;
+  }
+  GNUNET_CRYPTO_hash_from_string (challenge_response_s,
+                                  &challenge_response);
   if (0 == strcmp ("question",
                    method))
   {
-    if (NULL == challenge_response_s)
-    {
-      // FIXME: queue PROPER reply...
-      GNUNET_free (decrypted_truth);
-      return MHD_NO;
-    }
-
-    GNUNET_CRYPTO_hash_from_string (challenge_response_s,
-                                    &challenge_response);
-
     if (0 != GNUNET_memcmp (&challenge_response,
                             decrypted_truth))
     {
@@ -932,23 +914,10 @@ AH_handler_truth_get (struct MHD_Connection *connection,
   if (NULL != challenge_response_s)
   {
     enum ANASTASIS_DB_QueryStatus qs;
-    unsigned long long code;
-    char dummy;
-
-    if (1 != sscanf (challenge_response_s,
-                     "%llu%c",
-                     &code,
-                     &dummy))
-    {
-      // FIXME: queue PROPER reply...
-      GNUNET_free (decrypted_truth);
-      return MHD_NO;
-    }
 
     qs = db->verify_challenge_code (db->cls,
                                     &truth_public_key,
-                                    code);
-
+                                    &challenge_response);
     switch (qs)
     {
     case ANASTASIS_DB_STATUS_HARD_ERROR:
diff --git a/src/include/anastasis.h b/src/include/anastasis.h
index 2ab95bb..04ff37c 100644
--- a/src/include/anastasis.h
+++ b/src/include/anastasis.h
@@ -184,7 +184,6 @@ ANASTASIS_challenge_answer_cancel (
  * Challenge answer from the user like input SMS pin. Is referenced to a 
challenge and
  * sends back an AnswerFeedback.
  *
- * @param ctx context for curl interaction
  * @param c reference to the challenge which is answered
  * @param answer user input instruction defines which input is needed
  * @param af reference to the answerfeedback which is passed back to the user
@@ -192,13 +191,24 @@ ANASTASIS_challenge_answer_cancel (
  * @return handle to an challenge answer operation
  */
 struct ANASTASIS_ChallengeAnswerOperation *
-ANASTASIS_challenge_answer (struct GNUNET_CURL_Context *ctx,
-                            struct ANASTASIS_Challenge *c,
+ANASTASIS_challenge_answer (struct ANASTASIS_Challenge *c,
                             const char *answer,
                             ANASTASIS_AnswerFeedback af,
                             void *af_cls);
 
 
+/**
+ * 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".
+ *
+ * @param cls handle for the callback
+ * @param ec enum which defines the different status codes
+ *
+*/
+typedef void
+(*ANASTASIS_ChallengeCallback)(void *cls,
+                               enum TALER_ErrorCode ec); // i.e. payment 
missing
+
 /**
  * Defines the instructions for a challenge, what does the user have
  * to do to fulfill the challenge.  Also defines the method and other
@@ -207,134 +217,168 @@ ANASTASIS_challenge_answer (struct GNUNET_CURL_Context 
*ctx,
  */
 struct ANASTASIS_ChallengeInformation
 {
+
   /**
-   * Which method is this challenge (E-Mail, Security Question, SMS...)
+   * nonce which uniquely identifies the challenge
    */
-  const char *method;
+  struct ANASTASIS_CRYPTO_NonceP nonce;
 
   /**
-   * Defines the url or mail address used for the challenge. Can be NULL.
+   * Cost to solve this challenge
    */
-  const char *url;
+  struct TALER_Amount cost;
 
   /**
-   * Describes which steps need to be done e.g. "Please look for the
-   * pin for recovery #1234".
+   * Which method is this challenge (E-Mail, Security Question, SMS...)
    */
-  const char *instructions; // FIXME: i18n?
+  char *method;
 
   /**
-   * Cost to solve this challenge
+   * Instructions for solving the challenge (generic, set client-side
+   * when challenge was established).
    */
-  struct TALER_Amount *cost; // FIXME: why pointer!?
+  char *instructions;
 
   /**
-   * Identifier of the challenge
+   * Defines the url or mail address used for the challenge. Can be NULL.
    */
-  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; // ???
+  char *url;
 
   /**
-   * 1 if solved, else 0
+   * true if solved, else false.
    */
-  unsigned int solved; // FIXME: use 'bool'!
+  bool solved;
 
 };
 
 
-/**
- * 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".
- *
- * @param cls handle for the callback
- * @param ec enum which defines the different status codes
- *
-*/
-typedef void
-(*ANASTASIS_ChallengeCallback)(void *cls,
-                               enum TALER_ErrorCode ec); // i.e. payment 
missing
-
 /**
  * Returns information of a challenge.
  *
  * @param challenge reference to the escrow challenge which is started
  * @return ANASTASIS_ChallengeInformation object
  */
-struct ANASTASIS_ChallengeInformation *
+const struct ANASTASIS_ChallengeInformation *
 ANASTASIS_get_challenge (struct ANASTASIS_Challenge *challenge);
 
 
 /**
- * Converts a json challenge to struct.
- *
- * @param challenge reference to json challenge to be converted
- * @return ANASTASIS_Challenge object
+ * Possible outcomes of trying to start a challenge operation.
  */
-struct ANASTASIS_Challenge *
-ANASTASIS_json_to_challenge (json_t *challenge);
+enum ANASTASIS_ChallengeStatus
+{
+  /**
+   * Instructions for how to solve the challenge are provided.
+   */
+  ANASTASIS_CHALLENGE_STATUS_INSTRUCTIONS,
+
+  /**
+   * 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
+};
 
 
 /**
- * Returns JSON-encoded challenge information.
- *
- * @param ci object to return JSON encoding for
- * @return JSON encoding of @a r
+ * Response from an #ANASTASIS_challenge_start() operation.
  */
-json_t *
-ANASTASIS_challenge_information_to_json (const struct
-                                         ANASTASIS_ChallengeInformation *ci);
+struct ANASTASIS_ChallengeStartResponse
+{
+  enum ANASTASIS_ChallengeStatus cs;
+
+  union
+  {
+    /**
+     * Response with server-side instructions for the user, if
+     * @e cs is ANASTASIS_CHALLENGE_STATUS_INSTRUCTIONS.
+     */
+    const char *instructions;
+
+    /**
+     * Response with instructions for how to pay, if
+     * @a cs is ANASTASIS_CHALLENGE_STATUS_PAYMENT_REQUIRED.
+     */
+    struct
+    {
+
+      /**
+       * "taler://pay" URL with details how to pay for the challenge.
+       */
+      const char *taler_pay_url;
+
+      /**
+       * Anastasis backend base URL requesting the payment.
+       */
+      const char *server_url;
+
+    } payment_required;
+
+    struct
+    {
+
+      /**
+       * Error message (or NULL).
+       */
+      const char *message;
+
+      /**
+       * HTTP status returned by the server.
+       */
+      unsigned int http_status;
+
+    } server_failure;
+
+  } details;
+};
+
 
 /**
- * Defines a Callback for the payment of an escrow challenge. Sends back a 
payment link
- * and a status code.
+ * Defines a callback for the response status for a challenge start
+ * operation.
  *
  * @param cls handle to the request
- * @param response_string response from the challenge start(instructions look 
at email etc..)
- * @param http_status Status code for the request
+ * @param csr response details
  */
 typedef void
 (*ANASTASIS_ChallengeStartCallback)(void *cls,
-                                    const char *response_string,
-                                    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
-*/
-typedef void
-(*ANASTASIS_ChallengePaymentCallback)(void *cls,
-                                      const char *taler_pay_url,
-                                      const char *server_url,
-                                      unsigned int http_status);
+                                    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 with the same challenge reference.
+ * 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 cc opens a ChallengePaymentCallback for the requested information
  * @param cc_cls handle for the request
+ * @return #GNUNET_OK if the challenge was successfully started
  */
-void
-ANASTASIS_challenge_start (struct GNUNET_CURL_Context *ctx,
-                           struct ANASTASIS_Challenge *c,
-                           ANASTASIS_ChallengePaymentCallback cpc,
-                           void *cpc_cls,
+int
+ANASTASIS_challenge_start (struct ANASTASIS_Challenge *c,
+                           const struct ANASTASIS_PaymentSecretP *psp,
                            ANASTASIS_ChallengeStartCallback csc,
                            void *csc_cls);
 
 
+/**
+ * Abort challenge.
+ *
+ * @param c reference to the escrow challenge which was started
+ */
+void
+ANASTASIS_challenge_abort (struct ANASTASIS_Challenge *c);
+
+
 /**
  * Callback which passes back the recovery document and its possible
  * policies. Also passes back the version of the document for the user
diff --git a/src/include/anastasis_crypto_lib.h 
b/src/include/anastasis_crypto_lib.h
index f645b67..072dc83 100644
--- a/src/include/anastasis_crypto_lib.h
+++ b/src/include/anastasis_crypto_lib.h
@@ -183,6 +183,19 @@ struct ANASTASIS_CRYPTO_UserIdentifierP
 GNUNET_NETWORK_STRUCT_END
 
 
+/**
+ * Hash a numerical answer to compute the hash value to be submitted
+ * to the server for verification. Useful for PINs and SMS-TANs and
+ * other numbers submitted for challenges.
+ *
+ * @param code the numeric value to hash
+ * @param hashed_code the resulting hash value to submit to the Anastasis 
server
+ */
+void
+ANASTASIS_hash_answer (uint64_t code,
+                       struct GNUNET_HashCode *hashed_code);
+
+
 /**
  * Creates the UserIdentifier, it is used as entropy source for the encryption 
keys and
  * for the public and private key for signing the data.
diff --git a/src/include/anastasis_database_plugin.h 
b/src/include/anastasis_database_plugin.h
index 1239646..cb4ec1c 100644
--- a/src/include/anastasis_database_plugin.h
+++ b/src/include/anastasis_database_plugin.h
@@ -397,6 +397,7 @@ struct ANASTASIS_DatabasePlugin
     const struct ANASTASIS_PaymentSecretP *payment_secret,
     const struct TALER_Amount *amount);
 
+
   /**
    * Verify the provided code with the code on the server.
    * If the code matches the function will return with success, if the code
@@ -404,15 +405,15 @@ struct ANASTASIS_DatabasePlugin
    *
    * @param cls closure
    * @param truth_pub identification of the challenge which the code 
corresponds to
-   * @param code code which the user provided and wants to verify
-     (already verified that this is a uint64_t no checks needed)
+   * @param hashed_code code which the user provided and wants to verify
    * @return transaction status
    */
   enum ANASTASIS_DB_QueryStatus
   (*verify_challenge_code)(void *cls,
                            const struct
                            ANASTASIS_CRYPTO_TruthPublicKeyP *truth_pub,
-                           uint64_t code);
+                           const struct GNUNET_HashCode *hashed_code);
+
   /**
    * Insert a new challenge code for a given challenge identified by the 
challenge
    * public key. The function will first check if there is already a valid code
diff --git a/src/include/anastasis_service.h b/src/include/anastasis_service.h
index 4f0de4d..ff3e077 100644
--- a/src/include/anastasis_service.h
+++ b/src/include/anastasis_service.h
@@ -522,8 +522,7 @@ typedef void
  * @param truth_public_key identification of the Truth
  * @param truth_key Key used to Decrypt the Truth on the Server
  * @param payment_secret secret from the previously done payment NULL to 
trigger payment
- * @param answer Answer for the different authentication methods(code, hash)
- * @param answer_length size of the answer
+ * @param hashed_answer hashed answer to the challenge
  * @param cb callback which will work the response gotten from the backend
  * @param cb_cls closure to pass to the callback
  * @return handle for this operation, NULL upon errors
@@ -535,7 +534,7 @@ ANASTASIS_keyshare_lookup (
   const struct ANASTASIS_CRYPTO_TruthPublicKeyP *truth_public_key,
   const struct ANASTASIS_CRYPTO_TruthKeyP *truth_key,
   const struct ANASTASIS_PaymentSecretP *payment_secret,
-  const char *answer,
+  const struct GNUNET_HashCode *hashed_answer,
   ANASTASIS_KeyShareLookupCallback cb,
   void *cb_cls);
 
diff --git a/src/lib/anastasis_recovery.c b/src/lib/anastasis_recovery.c
index 193d457..228170b 100644
--- a/src/lib/anastasis_recovery.c
+++ b/src/lib/anastasis_recovery.c
@@ -132,6 +132,12 @@ struct ANASTASIS_Recovery
  */
 struct ANASTASIS_Challenge
 {
+
+  /**
+   * Information exported to clients about this challenge.
+   */
+  struct ANASTASIS_ChallengeInformation ci;
+
   /**
    * Payment identifier.
    */
@@ -142,11 +148,6 @@ struct ANASTASIS_Challenge
    */
   struct ANASTASIS_CRYPTO_TruthPublicKeyP truth_public_key;
 
-  /**
-   * nonce which identifies the challenge
-   */
-  struct ANASTASIS_CRYPTO_NonceP nonce;
-
   /**
    * Key used to encrypt the truth passed to the server
    */
@@ -157,16 +158,6 @@ struct ANASTASIS_Challenge
    */
   struct ANASTASIS_CRYPTO_PowSalt truth_salt;
 
-  /**
-   * Cost for authentication
-   */
-  struct TALER_Amount cost;
-
-  /**
-   * 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.
    */
@@ -198,50 +189,20 @@ struct ANASTASIS_Challenge
   struct ANASTASIS_Recovery *recovery;
 
   /**
-   * url to the escrow provider for this challenge
-   */
-  char *url;
-
-  /**
-   * plaintext challenge which is sent to the client
+   * Plaintext challenge which is sent to the client???
    */
-  void *challenge;
-
-  /**
-   * method of the challenge
-   */
-  char *escrow_method;
+  // void *challenge;
 
   /**
    * keyshare lookup operation
    */
   struct ANASTASIS_KeyShareLookupOperation *kslo;
 
-  /**
-   * Curl context
-   */
-  struct GNUNET_CURL_Context *ctx;
-
   /**
    * Encrypted key share
    */
   struct ANASTASIS_CRYPTO_KeyShareP *key_share;
 
-  /**
-   * Challenge instructions
-   */
-  char *instructions;
-
-  /**
-   * Passes back the payment information for the current challenge
-   */
-  ANASTASIS_ChallengePaymentCallback cpc;
-
-  /**
-   * Closure for the payment callback
-   */
-  void *cpc_cls;
-
   /**
    * The /truth GET operation handle.
    */
@@ -258,19 +219,14 @@ struct ANASTASIS_Challenge
   void *csc_cls;
 
   /**
-   * size of the challenge
+   * size of the challenge???
    */
-  size_t challenge_size;
-
-  /**
-   * Status of the challenge 0 pending, 1 solved
-   */
-  unsigned int solved;
+  // size_t challenge_size;
 
   /**
    * Expected http status
    */
-  unsigned int http_status;
+  // unsigned int http_status;
 
 };
 
@@ -294,16 +250,9 @@ keyshare_lookup_cb (void *cls,
                     const struct ANASTASIS_KeyShareDownloadDetails *dd)
 {
   struct ANASTASIS_Challenge *c = cls;
+  struct ANASTASIS_CRYPTO_UserIdentifierP id;
 
   c->kslo = NULL;
-  if (http_status != c->http_status)
-  {
-    c->af (c->af_cls,
-           http_status,
-           TALER_EC_INVALID); // FIXME: Error Code
-    return;
-  }
-  struct ANASTASIS_CRYPTO_UserIdentifierP id;
   ANASTASIS_CRYPTO_user_identifier_derive (c->recovery->id_data,
                                            &c->truth_salt,
                                            &id);
@@ -333,7 +282,7 @@ keyshare_lookup_cb (void *cls,
       for (unsigned int k = 0; k < c->recovery->solved_challenge_pos; k++)
       {
         if (0 == memcmp (&c->recovery->ri.dps[i].nonces[j],
-                         &c->recovery->solved_challenges[k].nonce,
+                         &c->recovery->solved_challenges[k].ci.nonce,
                          sizeof(struct ANASTASIS_CRYPTO_NonceP)))
         {
           missing = false;
@@ -365,7 +314,7 @@ keyshare_lookup_cb (void *cls,
       for (unsigned int m = 0; m < c->recovery->solved_challenge_pos; m++)
       {
         if (0 == memcmp (&c->recovery->ri.dps[success].nonces[l],
-                         &c->recovery->solved_challenges[m].nonce,
+                         &c->recovery->solved_challenges[m].ci.nonce,
                          sizeof(struct ANASTASIS_CRYPTO_NonceP)))
         {
           key_shares[l] = *c->recovery->solved_challenges[m].key_share;
@@ -407,134 +356,42 @@ ANASTASIS_challenge_answer_cancel (
 
 
 struct ANASTASIS_ChallengeAnswerOperation *
-ANASTASIS_challenge_answer (struct GNUNET_CURL_Context *ctx,
-                            struct ANASTASIS_Challenge *c,
+ANASTASIS_challenge_answer (struct ANASTASIS_Challenge *c,
                             const char *answer_str,
                             ANASTASIS_AnswerFeedback af,
                             void *af_cls)
 {
   struct ANASTASIS_ChallengeAnswerOperation *cao;
+  struct GNUNET_HashCode hashed_answer;
 
   cao = GNUNET_new (struct ANASTASIS_ChallengeAnswerOperation);
   cao->c = c;
   c->af = af;
-  c->ctx = ctx;
   c->af_cls = af_cls;
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "At %s:%d challenge answer is %s\n", __FILE__, __LINE__,
-              answer_str);
-
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "At %s:%d challenge %s-%llu is solved with url %s \n", __FILE__,
-              __LINE__,
-              TALER_B2S (&c->truth_public_key),
-              (unsigned long long) sizeof (c->truth_public_key),
-              c->url);
-
-  c->http_status = MHD_HTTP_OK;
-  if (0 == strcmp (c->escrow_method,
-                   "question"))
-  {
-    struct GNUNET_HashCode hashed_answer;
-    char *str;
-
-    GNUNET_CRYPTO_hash (answer_str,
-                        strlen (answer_str),
-                        &hashed_answer);
-    str = GNUNET_STRINGS_data_to_string_alloc (&hashed_answer,
-                                               sizeof (hashed_answer));
-    c->kslo = ANASTASIS_keyshare_lookup (c->ctx,
-                                         c->url,
-                                         &c->truth_public_key,
-                                         &c->truth_key,
-                                         &c->payment_secret,
-                                         str,
-                                         &keyshare_lookup_cb,
-                                         c);
-    GNUNET_free (str);
-    if (NULL == c->kslo)
-    {
-      GNUNET_break (0);
-      return NULL;
-    }
-  }
-  else
+  GNUNET_CRYPTO_hash (answer_str,
+                      strlen (answer_str),
+                      &hashed_answer);
+  c->kslo = ANASTASIS_keyshare_lookup (c->recovery->ctx,
+                                       c->ci.url,
+                                       &c->truth_public_key,
+                                       &c->truth_key,
+                                       &c->payment_secret,
+                                       &hashed_answer,
+                                       &keyshare_lookup_cb,
+                                       c);
+  if (NULL == c->kslo)
   {
-    c->kslo = ANASTASIS_keyshare_lookup (c->ctx,
-                                         c->url,
-                                         &c->truth_public_key,
-                                         &c->truth_key,
-                                         &c->payment_secret,
-                                         answer_str,
-                                         &keyshare_lookup_cb,
-                                         c);
-    if (NULL == c->kslo)
-    {
-      GNUNET_break (0);
-      return NULL;
-    }
+    GNUNET_break (0);
+    return NULL;
   }
   return cao;
 }
 
 
-struct ANASTASIS_ChallengeInformation *
+const struct ANASTASIS_ChallengeInformation *
 ANASTASIS_get_challenge (struct ANASTASIS_Challenge *challenge)
 {
-  struct ANASTASIS_ChallengeInformation *ci;
-
-  ci = GNUNET_new (struct ANASTASIS_ChallengeInformation);
-  ci->truth_public_key = &challenge->truth_public_key;
-  ci->method = challenge->escrow_method;
-  ci->url = challenge->url;
-  ci->nonce = &challenge->nonce;
-  ci->instructions = challenge->instructions;
-  ci->solved = challenge->solved;
-  ci->challenge = challenge;
-  return ci;
-}
-
-
-struct ANASTASIS_Challenge *
-ANASTASIS_json_to_challenge (json_t *challenge)
-{
-  const char *challenge_str;
-  struct ANASTASIS_Challenge *c = NULL;
-
-  GNUNET_assert (json_is_object (challenge));
-  challenge_str =
-    json_string_value (
-      json_object_get (challenge,
-                       "challenge"));
-  GNUNET_assert (GNUNET_OK ==
-                 GNUNET_STRINGS_string_to_data (
-                   challenge_str,
-                   strlen (challenge_str),
-                   c,
-                   sizeof (struct ANASTASIS_Challenge)));
-  return c;
-}
-
-
-json_t *
-ANASTASIS_challenge_information_to_json (
-  const struct ANASTASIS_ChallengeInformation *ci)
-{
-  return json_pack ("{s:o,s:s,s:s,s:o,s:s:s:I,s:o}",
-                    "truth_public_key",
-                    GNUNET_JSON_from_data_auto (ci->truth_public_key),
-                    "method",
-                    ci->method,
-                    "url",
-                    ci->url,
-                    "nonce",
-                    GNUNET_JSON_from_data_auto (ci->nonce),
-                    "instructions",
-                    ci->instructions,
-                    "solved",
-                    (json_int_t) ci->solved,
-                    "challenge",
-                    GNUNET_JSON_from_data_auto (ci->challenge));
+  return &challenge->ci;
 }
 
 
@@ -553,93 +410,90 @@ challenge_run_cb (void *cls,
   struct ANASTASIS_Challenge *c = cls;
 
   c->cro = NULL;
-  if (http_status == MHD_HTTP_PAYMENT_REQUIRED)
+  switch (http_status)
   {
-    const char *m;
+  case MHD_HTTP_PAYMENT_REQUIRED:
+    {
+      struct ANASTASIS_ChallengeStartResponse csr = {
+        .cs = ANASTASIS_CHALLENGE_STATUS_PAYMENT_REQUIRED,
+        .details.payment_required.server_url = c->ci.url,
+        .details.payment_required.taler_pay_url = response_string
+      };
 
-    if (0 != strncmp (response_string,
-                      "taler://pay/http",
-                      strlen ("taler://pay/http")))
+      c->csc (c->csc_cls,
+              &csr);
+      break;
+    }
+  case MHD_HTTP_OK:
     {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  "Did not find `%s' in `%s'\n",
-                  "/-/-/",
-                  response_string);
-      /*FIXME ERROR*/
-      return;
+      struct ANASTASIS_ChallengeStartResponse csr = {
+        .cs = ANASTASIS_CHALLENGE_STATUS_INSTRUCTIONS,
+        .details.instructions = response_string
+      };
+
+      c->csc (c->csc_cls,
+              &csr);
+      break;
     }
-    m = strstr (response_string, "/-/-/");
-    if (NULL == m)
+  default:
     {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  "Did not find `%s' in `%s'\n",
-                  "/-/-/",
-                  response_string);
-      /*FIXME ERROR*/
-
-      /* NOTE: The above is a simplifying assumption for the
-         test-logic, hitting this code merely means that
-         the assumptions for the test (i.e. no instance) are
-         not satisfied, it is not inherently the case that
-         the above token must appear in the payment request!
-
-         So if you hit this, you might just want to modify
-         the code here to handle this better! */
-      return;
+      struct ANASTASIS_ChallengeStartResponse csr = {
+        .cs = ANASTASIS_CHALLENGE_STATUS_SERVER_FAILURE,
+        .details.server_failure.message = response_string,
+        .details.server_failure.http_status = http_status
+      };
+
+      c->csc (c->csc_cls,
+              &csr);
+      break;
     }
-    c->payment_order_id = GNUNET_strdup (&m[strlen ("/-/-/")]);
-    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-                "Order ID from Anastasis service is `%s'\n",
-                c->payment_order_id);
-    c->cpc (c->cpc_cls,
-            response_string,
-            c->url,
-            http_status);
-    return;
   }
-  c->csc (c->csc_cls,
-          response_string,
-          http_status);
+  c->csc = NULL;
+  c->csc_cls = NULL;
 }
 
 
-void
-ANASTASIS_challenge_start (struct GNUNET_CURL_Context *ctx,
-                           struct ANASTASIS_Challenge *c,
-                           ANASTASIS_ChallengePaymentCallback cpc,
-                           void *cpc_cls,
+int
+ANASTASIS_challenge_start (struct ANASTASIS_Challenge *c,
+                           const struct ANASTASIS_PaymentSecretP *psp,
                            ANASTASIS_ChallengeStartCallback csc,
                            void *csc_cls)
 {
-  c->ctx = ctx;
   c->csc = csc;
   c->csc_cls = csc_cls;
-  c->cpc = cpc;
-  c->cpc_cls = cpc_cls;
-
-  if (NULL != c->payment_order_id)
-  {
-    GNUNET_STRINGS_string_to_data (c->payment_order_id,
-                                   strlen (c->payment_order_id),
-                                   &c->payment_secret,
-                                   sizeof (struct
-                                           ANASTASIS_PaymentSecretP));
-  }
-
-  c->cro = ANASTASIS_challenge_run (c->ctx,
-                                    c->url,
+  c->cro = ANASTASIS_challenge_run (c->recovery->ctx,
+                                    c->ci.url,
                                     &c->truth_public_key,
                                     &c->truth_key,
-                                    GNUNET_is_zero (&c->payment_secret)
-                                    ? NULL
-                                    : &c->payment_secret,
+                                    psp,
                                     &challenge_run_cb,
                                     c);
   if (NULL == c->cro)
+  {
+    GNUNET_break (0);
+    return GNUNET_SYSERR;
+  }
+  return GNUNET_OK;
+}
+
+
+/**
+ * Abort challenge.
+ *
+ * @param c reference to the escrow challenge which was started
+ */
+void
+ANASTASIS_challenge_abort (struct ANASTASIS_Challenge *c)
+{
+  if (NULL == c->cro)
   {
     GNUNET_break (0);
     return;
   }
+  ANASTASIS_challenge_run_cancel (c->cro);
+  c->cro = NULL;
+  c->csc = NULL;
+  c->csc_cls = NULL;
 }
 
 
@@ -813,7 +667,7 @@ policy_lookup_cb (void *cls,
     const char *escrow_method;
     struct GNUNET_JSON_Specification spec[] = {
       GNUNET_JSON_spec_fixed_auto ("nonce",
-                                   &cs->nonce),
+                                   &cs->ci.nonce),
       GNUNET_JSON_spec_string ("url",
                                &url),
       GNUNET_JSON_spec_string ("instructions",
@@ -845,10 +699,10 @@ policy_lookup_cb (void *cls,
       ANASTASIS_recovery_abort (r);
       return;
     }
-    cs->url = GNUNET_strdup (url);
-    cs->instructions = GNUNET_strdup (instructions);
-    cs->escrow_method = GNUNET_strdup (escrow_method);
-    ANASTASIS_CRYPTO_truth_public_key_derive (&cs->nonce,
+    cs->ci.url = GNUNET_strdup (url);
+    cs->ci.method = GNUNET_strdup (escrow_method);
+    cs->ci.instructions = GNUNET_strdup (instructions);
+    ANASTASIS_CRYPTO_truth_public_key_derive (&cs->ci.nonce,
                                               &cs->truth_public_key);
   }
   json_decref (esc_methods);
@@ -897,11 +751,11 @@ policy_lookup_cb (void *cls,
 
       if ( (NULL == nonce_str) ||
            (GNUNET_OK !=
-            GNUNET_STRINGS_string_to_data (nonce_str,
-                                           strlen (nonce_str),
-                                           &dp->nonces[n_index],
-                                           sizeof (struct
-                                                   ANASTASIS_CRYPTO_NonceP))) )
+            GNUNET_STRINGS_string_to_data (
+              nonce_str,
+              strlen (nonce_str),
+              &dp->nonces[n_index],
+              sizeof (struct ANASTASIS_CRYPTO_NonceP))) )
       {
         GNUNET_break_op (0);
         json_decref (dec_policies);
@@ -917,7 +771,6 @@ policy_lookup_cb (void *cls,
     json_decref (nonces);
   }
   json_decref (dec_policies);
-  r->solved_challenge_pos = 0;
   r->pc (r->pc_cls,
          &r->ri);
 }
@@ -989,9 +842,9 @@ ANASTASIS_recovery_abort (struct ANASTASIS_Recovery *r)
   {
     struct ANASTASIS_Challenge *cs = r->ri.cs[i];
 
-    GNUNET_free (cs->url);
-    GNUNET_free (cs->instructions);
-    GNUNET_free (cs->escrow_method);
+    GNUNET_free (cs->ci.url);
+    GNUNET_free (cs->ci.method);
+    GNUNET_free (cs->ci.instructions);
     GNUNET_free (cs);
   }
   GNUNET_free (r->ri.cs);
diff --git a/src/reducer/anastasis_api_recovery_redux.c 
b/src/reducer/anastasis_api_recovery_redux.c
index 952ce41..2f3dee2 100644
--- a/src/reducer/anastasis_api_recovery_redux.c
+++ b/src/reducer/anastasis_api_recovery_redux.c
@@ -161,7 +161,8 @@ set_state (json_t *state,
 }
 
 
-static void
+// static
+void
 challenge_payment_cb (void *cls,
                       const char *taler_pay_url,
                       const char *server_url,
@@ -261,15 +262,15 @@ challenge_payment_cb (void *cls,
 }
 
 
-static void
+// static
+void
 challenge_start_cb (void *cls,
                     const char *response_string,
                     unsigned int http_status_code)
 {
   json_t *recovery_information;
   json_t *challenges;
-  json_t *challenge;
-  struct ANASTASIS_ChallengeInformation *ci;
+  const struct ANASTASIS_ChallengeInformation *ci;
   struct ChallengeState *cs = cls;
 
   if (http_status_code != MHD_HTTP_OK)
@@ -295,15 +296,19 @@ challenge_start_cb (void *cls,
   challenges = json_object_get (recovery_information,
                                 "challenges");
   GNUNET_assert (json_is_array (challenges));
+#if FIXME
+  // overwrite challenge -- but only what we need here for the UI + nonce!
+  json_t *challenge;
+  // WTF?
   challenge =
     json_array_get (challenges,
                     cs->challenge_index);
-  // overwrite challenge
   challenge = ANASTASIS_challenge_information_to_json (ci);
   GNUNET_free (ci);
   GNUNET_assert (0 == json_array_set_new (challenges,
                                           cs->challenge_index,
                                           challenge));
+#endif
   cs->cb (cs->cb_cls,
           ANASTASIS_EC_NONE,
           cs->state);
@@ -377,10 +382,7 @@ select_challenge (json_t *state,
     return NULL;
   }
   json_t *recovery_information;
-  json_t *challenge;
   json_t *challenges;
-  const char *method;
-  const struct ANASTASIS_Challenge *c;
   struct ChallengeState *cs = GNUNET_new (struct ChallengeState);
 
   cs->cb = cb;
@@ -396,9 +398,16 @@ select_challenge (json_t *state,
   challenges = json_object_get (recovery_information,
                                 "challenges");
   GNUNET_assert (json_is_array (challenges));
+#if 0
+  const char *method;
+  struct ANASTASIS_Challenge *c;
+  json_t *challenge;
+
   challenge =
     json_array_get (challenges,
                     cs->challenge_index);
+  // FIXME: c->recovery not initialized here! PROBLEM!
+  // FIXME: get challenge via recovery start!
   c = ANASTASIS_json_to_challenge (challenge);
 
   method = json_string_value (
@@ -418,13 +427,13 @@ select_challenge (json_t *state,
       json_object_get (arguments,
                        "code"));
   }
-
-  ANASTASIS_challenge_start (ctx,
-                             (struct ANASTASIS_Challenge *) c,
+  // CANNOT WORK: derefs c->recovery!
+  ANASTASIS_challenge_start (c,
                              &challenge_payment_cb,
                              cs,
                              &challenge_start_cb,
                              cs);
+#endif
   return NULL;
 }
 
@@ -500,7 +509,8 @@ check_policy_fulfilled (json_t *state)
 }
 
 
-static void
+// static
+void
 challenge_answer_cb (void *af_cls,
                      unsigned int http_status_code,
                      enum TALER_ErrorCode ec)
@@ -542,10 +552,7 @@ solve_challenge (json_t *state,
     return NULL;
   }
   json_t *recovery_information;
-  json_t *challenge;
   json_t *challenges;
-  const char *method;
-  const struct ANASTASIS_Challenge *c;
   struct ChallengeState *cs = GNUNET_new (struct ChallengeState);
 
   cs->cb = cb;
@@ -561,9 +568,16 @@ solve_challenge (json_t *state,
   challenges = json_object_get (recovery_information,
                                 "challenges");
   GNUNET_assert (json_is_array (challenges));
+#if 0
+  json_t *challenge;
+  const char *method;
+  struct ANASTASIS_Challenge *c;
+
+  // FIXME: get challenge from recovery operation; deduplicate with code above!
   challenge =
     json_array_get (challenges,
                     cs->challenge_index);
+  // FIXME: c->recovery not initialized, will be deref'ed later!
   c = ANASTASIS_json_to_challenge (challenge);
 
   method = json_string_value (
@@ -584,11 +598,11 @@ solve_challenge (json_t *state,
                        "code"));
   }
 
-  cs->cao = ANASTASIS_challenge_answer (ctx,
-                                        (struct ANASTASIS_Challenge *) c,
+  cs->cao = ANASTASIS_challenge_answer (c,
                                         cs->answer,
                                         &challenge_answer_cb,
                                         cs);
+#endif
   cb (cb_cls,
       ANASTASIS_EC_NONE,
       state);
diff --git a/src/reducer/anastasis_api_redux.c 
b/src/reducer/anastasis_api_redux.c
index 873bdd2..41f43d2 100644
--- a/src/reducer/anastasis_api_redux.c
+++ b/src/reducer/anastasis_api_redux.c
@@ -923,28 +923,32 @@ policy_lookup_cb (void *cls,
 
   for (unsigned int i = 0; i < rss->ri->cs_len; i++)
   {
-    struct ANASTASIS_ChallengeInformation *ci =
+    const struct ANASTASIS_ChallengeInformation *ci =
       ANASTASIS_get_challenge (rss->ri->cs[i]);
-    unsigned int contains = 0;
+    bool contains = false;
     for (unsigned int i = 0; i < rss->challenges_length; i++)
     {
-      if (0 == memcmp (rss->challenges[i].nonce,
-                       ci->nonce,
+      if (0 == memcmp (&rss->challenges[i].nonce,
+                       &ci->nonce,
                        sizeof(struct ANASTASIS_CRYPTO_NonceP)))
       {
-        contains = 1;
+        contains = true;
         break;
       }
     }
-    if (0 == contains)
+    if (! contains)
     {
       GNUNET_array_append (rss->challenges,
                            rss->challenges_length,
                            *ci);
+#if FIXME
+      /* should probably only serialize the nonce and
+         what the UI needs! */
       GNUNET_assert (
         0 == json_array_append_new (
           challenges,
           ANASTASIS_challenge_information_to_json (ci)));
+#endif
     }
   }
   for (unsigned int i = 0; i < ri->dps_len; i++)
@@ -956,7 +960,7 @@ policy_lookup_cb (void *cls,
       for (unsigned int k = 0; k < rss->challenges_length; k++)
       {
         if (0 == memcmp (&ri->dps[i].nonces[j],
-                         rss->challenges[k].nonce,
+                         &rss->challenges[k].nonce,
                          sizeof (struct ANASTASIS_CRYPTO_NonceP)))
           GNUNET_assert (
             0 == json_array_append_new (policy,
diff --git a/src/restclient/anastasis_api_keyshare_lookup.c 
b/src/restclient/anastasis_api_keyshare_lookup.c
index 23e5e1f..baac040 100644
--- a/src/restclient/anastasis_api_keyshare_lookup.c
+++ b/src/restclient/anastasis_api_keyshare_lookup.c
@@ -230,7 +230,7 @@ ANASTASIS_keyshare_lookup (
   const struct ANASTASIS_CRYPTO_TruthPublicKeyP *truth_public_key,
   const struct ANASTASIS_CRYPTO_TruthKeyP *truth_key,
   const struct ANASTASIS_PaymentSecretP *payment_secret,
-  const char *answer,
+  const struct GNUNET_HashCode *hashed_answer,
   ANASTASIS_KeyShareLookupCallback cb,
   void *cb_cls)
 {
@@ -238,6 +238,7 @@ ANASTASIS_keyshare_lookup (
   CURL *eh;
   struct curl_slist *job_headers;
   char *path;
+  char *answer_s;
 
   job_headers = NULL;
   {
@@ -295,24 +296,21 @@ ANASTASIS_keyshare_lookup (
 
     pub_key_str = GNUNET_STRINGS_data_to_string_alloc (truth_public_key,
                                                        sizeof 
(*truth_public_key));
-    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                "truth public key in keyshare lookup:  %s\n",
-                pub_key_str);
     GNUNET_asprintf (&path,
                      "truth/%s",
                      pub_key_str);
     GNUNET_free (pub_key_str);
   }
+  answer_s = GNUNET_STRINGS_data_to_string_alloc (hashed_answer,
+                                                  sizeof (*hashed_answer));
+
   kslo->url = TALER_url_join (backend_url,
                               path,
                               "response",
-                              answer,
+                              answer_s,
                               NULL);
+  GNUNET_free (answer_s);
   GNUNET_free (path);
-
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Url get request (keyshare lookup): %s\n",
-              kslo->url);
   eh = ANASTASIS_curl_easy_get_ (kslo->url);
   GNUNET_assert (CURLE_OK ==
                  curl_easy_setopt (eh,
diff --git a/src/stasis/plugin_anastasis_postgres.c 
b/src/stasis/plugin_anastasis_postgres.c
index 104c73f..61d5e78 100644
--- a/src/stasis/plugin_anastasis_postgres.c
+++ b/src/stasis/plugin_anastasis_postgres.c
@@ -272,12 +272,11 @@ postgres_gc (void *cls,
  * @return transaction status, NULL if codes are different
  */
 static enum ANASTASIS_DB_QueryStatus
-check_valid_code (struct PostgresClosure *pg,
-                  const struct
-                  ANASTASIS_CRYPTO_TruthPublicKeyP *
-                  truth_public_key,
-                  uint64_t code,
-                  struct GNUNET_TIME_Absolute creation_date)
+check_valid_code (
+  struct PostgresClosure *pg,
+  const struct ANASTASIS_CRYPTO_TruthPublicKeyP *truth_public_key,
+  const struct GNUNET_HashCode *hashed_code,
+  struct GNUNET_TIME_Absolute creation_date)
 {
   enum ANASTASIS_DB_QueryStatus qs;
   uint64_t server_code;
@@ -305,11 +304,18 @@ check_valid_code (struct PostgresClosure *pg,
   case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
     return ANASTASIS_DB_STATUS_NO_RESULTS;
   case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
-    if (server_code == code)
     {
-      return ANASTASIS_DB_STATUS_VALID_CODE_STORED;
+      struct GNUNET_HashCode shashed_code;
+
+      ANASTASIS_hash_answer (server_code,
+                             &shashed_code);
+      if (0 == GNUNET_memcmp (&shashed_code,
+                              hashed_code))
+      {
+        return ANASTASIS_DB_STATUS_VALID_CODE_STORED;
+      }
+      return ANASTASIS_DB_STATUS_CHALLENGE_CODE_MISSMATCH;
     }
-    return ANASTASIS_DB_STATUS_CHALLENGE_CODE_MISSMATCH;
   default:
     GNUNET_break (0);
     return ANASTASIS_DB_STATUS_HARD_ERROR;
@@ -1641,16 +1647,14 @@ postgres_get_recovery_document (void *cls,
  *
  * @param cls closure
  * @param truth_pub identification of the challenge which the code corresponds 
to
- * @param code code which the user provided and wants to verify
-  (already verified that this is a uint64_t no checks needed)
+ * @param hashed_code code which the user provided and wants to verify
  * @return transaction status
  */
 enum ANASTASIS_DB_QueryStatus
-postgres_verify_challenge_code (void *cls,
-                                const struct
-                                ANASTASIS_CRYPTO_TruthPublicKeyP *truth_pub,
-                                uint64_t code)
-
+postgres_verify_challenge_code (
+  void *cls,
+  const struct ANASTASIS_CRYPTO_TruthPublicKeyP *truth_pub,
+  const struct GNUNET_HashCode *hashed_code)
 {
   struct PostgresClosure *pg = cls;
   enum ANASTASIS_DB_QueryStatus qs;
@@ -1658,21 +1662,17 @@ postgres_verify_challenge_code (void *cls,
 
   check_connection (pg);
   GNUNET_TIME_round_abs (&time_now);
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "At %s:%d Public key used to query db is: %s\n",
-              __FILE__,
-              __LINE__,
-              TALER_B2S (truth_pub));
-  /*Check if there is already a valid code */
+  /* Check if there is already a valid code */
   qs = check_valid_code (pg,
                          truth_pub,
-                         code,
+                         hashed_code,
                          time_now);
   if (qs != ANASTASIS_DB_STATUS_CHALLENGE_CODE_MISSMATCH)
     return qs;
 
-  if (GNUNET_OK != begin_transaction (pg,
-                                      "update_challenge_retry"))
+  if (GNUNET_OK !=
+      begin_transaction (pg,
+                         "update_challenge_retry"))
   {
     GNUNET_break (0);
     return ANASTASIS_DB_STATUS_HARD_ERROR;
@@ -1853,7 +1853,6 @@ postgres_update_challenge_payment (void *cls,
  * @param retry_counter amount of retries allowed
  * @return transaction status
  */
-
 enum ANASTASIS_DB_QueryStatus
 postgres_store_challenge_code (void *cls,
                                const struct
@@ -1867,15 +1866,19 @@ postgres_store_challenge_code (void *cls,
   enum ANASTASIS_DB_QueryStatus qs;
   struct GNUNET_TIME_Absolute creation_date = GNUNET_TIME_absolute_get ();
   struct GNUNET_TIME_Absolute expiration_date;
+  struct GNUNET_HashCode hashed_code;
 
   check_connection (pg);
   GNUNET_TIME_round_abs (&creation_date);
   expiration_date = GNUNET_TIME_absolute_add (creation_date,
                                               expiration_time);
+
   /*Check if there is already a valid code */
+  ANASTASIS_hash_answer (code,
+                         &hashed_code);
   qs = check_valid_code (pg,
                          truth_public_key,
-                         code,
+                         &hashed_code,
                          creation_date);
   if (qs != ANASTASIS_DB_STATUS_NO_RESULTS)
     return qs;
diff --git a/src/testing/testing_api_cmd_keyshare_lookup.c 
b/src/testing/testing_api_cmd_keyshare_lookup.c
index 4c20bc1..49f5a61 100644
--- a/src/testing/testing_api_cmd_keyshare_lookup.c
+++ b/src/testing/testing_api_cmd_keyshare_lookup.c
@@ -220,14 +220,22 @@ keyshare_lookup_run (void *cls,
     }
   }
 
-  ksls->kslo = ANASTASIS_keyshare_lookup (is->ctx,
-                                          ksls->anastasis_url,
-                                          ksls->truth_public_key,
-                                          &ksls->truth_key,
-                                          &ksls->payment_secret,
-                                          ksls->answer,
-                                          &keyshare_lookup_cb,
-                                          ksls);
+  {
+    struct GNUNET_HashCode h_answer;
+
+    GNUNET_CRYPTO_hash (ksls->answer,
+                        strlen (ksls->answer),
+                        &h_answer);
+
+    ksls->kslo = ANASTASIS_keyshare_lookup (is->ctx,
+                                            ksls->anastasis_url,
+                                            ksls->truth_public_key,
+                                            &ksls->truth_key,
+                                            &ksls->payment_secret,
+                                            &h_answer,
+                                            &keyshare_lookup_cb,
+                                            ksls);
+  }
   if (NULL == ksls->kslo)
   {
     GNUNET_break (0);
diff --git a/src/testing/testing_cmd_challenge_answer.c 
b/src/testing/testing_cmd_challenge_answer.c
index 798cf6a..1764389 100644
--- a/src/testing/testing_cmd_challenge_answer.c
+++ b/src/testing/testing_cmd_challenge_answer.c
@@ -151,8 +151,7 @@ challenge_answer_run (void *cls,
     cs->answer = code;
   }
 
-  cs->cao = ANASTASIS_challenge_answer (is->ctx,
-                                        (struct ANASTASIS_Challenge *) c,
+  cs->cao = ANASTASIS_challenge_answer ((struct ANASTASIS_Challenge *) c,
                                         cs->answer,
                                         &challenge_answer_cb,
                                         cs);
diff --git a/src/testing/testing_cmd_challenge_start.c 
b/src/testing/testing_cmd_challenge_start.c
index 2831a02..7d6f2fa 100644
--- a/src/testing/testing_cmd_challenge_start.c
+++ b/src/testing/testing_cmd_challenge_start.c
@@ -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
@@ -72,9 +72,9 @@ struct ChallengeState
   const char *payment_ref;
 
   /**
-   * Payment order ID we got back, if any. Otherwise NULL.
+   * "taler://pay/" URL we got back, if any. Otherwise NULL.
    */
-  char *payment_order_id;
+  char *payment_url;
 
   /**
    * Payment order ID we are to provide in the request, may be NULL.
@@ -89,107 +89,72 @@ struct ChallengeState
   /**
    * code we read in the file generated by the plugin
    */
-  char *code;
+  char code[22];
 };
 
 
+/**
+ * Callback for the response status for a challenge start operation.
+ *
+ * @param cls handle to the request
+ * @param csr response details
+ */
 static void
 challenge_start_cb (void *cls,
-                    const char *response_string,
-                    unsigned int http_status)
+                    const struct ANASTASIS_ChallengeStartResponse *csr)
 {
   struct ChallengeState *cs = cls;
   FILE *file;
-  cs->code = malloc (sizeof(char) * 22);
-  file = fopen (response_string, "r");
 
-  if (file == NULL)
+  switch (csr->cs)
   {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "could not find file: %s to command %s in %s:%u\n",
-                response_string,
-                cs->is->commands[cs->is->ip].label,
-                __FILE__,
-                __LINE__);
-    TALER_TESTING_interpreter_fail (cs->is);
-    return;
-  }
-  if (0 == fscanf (file, "%s", cs->code))
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "could not read file: %s to command %s in %s:%u\n",
-                response_string,
-                cs->is->commands[cs->is->ip].label,
-                __FILE__,
-                __LINE__);
-    TALER_TESTING_interpreter_fail (cs->is);
-    return;
-  }
-  TALER_TESTING_interpreter_next (cs->is);
-}
-
-
-static void
-challenge_payment_cb (void *cls,
-                      const char *taler_pay_url,
-                      const char *server_url,
-                      unsigned int http_status)
-{
-  const char *m;
-  struct ChallengeState *cs = cls;
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-              "At %s:%d the taler pay url is %s\n",
-              __FILE__, __LINE__,
-              taler_pay_url);
-  if (cs->http_status != http_status)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Unexpected response code %u/%d to command %s in %s:%u\n",
-                cs->http_status,
-                http_status,
-                cs->is->commands[cs->is->ip].label,
-                __FILE__,
-                __LINE__);
-    TALER_TESTING_interpreter_fail (cs->is);
+  case ANASTASIS_CHALLENGE_STATUS_INSTRUCTIONS:
+    file = fopen (csr->details.instructions,
+                  "r");
+    if (NULL == file)
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                  "Could not find file: %s to command %s in %s:%u\n",
+                  csr->details.instructions,
+                  cs->is->commands[cs->is->ip].label,
+                  __FILE__,
+                  __LINE__);
+      TALER_TESTING_interpreter_fail (cs->is);
+      return;
+    }
+    if (0 == fscanf (file, "%21s", cs->code))
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                  "could not read file: %s to command %s in %s:%u\n",
+                  csr->details.instructions,
+                  cs->is->commands[cs->is->ip].label,
+                  __FILE__,
+                  __LINE__);
+      TALER_TESTING_interpreter_fail (cs->is);
+      fclose (file);
+      return;
+    }
+    TALER_TESTING_interpreter_next (cs->is);
+    fclose (file);
     return;
-  }
-
-  if (0 != strncmp (taler_pay_url,
-                    "taler://pay/http",
-                    strlen ("taler://pay/http")))
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Did not find `%s' in `%s'\n",
-                "/-/-/",
-                taler_pay_url);
-    TALER_TESTING_interpreter_fail (cs->is);
+  case ANASTASIS_CHALLENGE_STATUS_PAYMENT_REQUIRED:
+    if (0 != strncmp (csr->details.payment_required.taler_pay_url,
+                      "taler://pay/http",
+                      strlen ("taler://pay/http")))
+    {
+      GNUNET_break (0);
+      TALER_TESTING_interpreter_fail (cs->is);
+      return;
+    }
+    cs->payment_url = GNUNET_strdup (
+      csr->details.payment_required.taler_pay_url);
+    TALER_TESTING_interpreter_next (cs->is);
     return;
-  }
-  m = strstr (taler_pay_url, "/-/-/");
-  if (NULL == m)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Did not find `%s' in `%s'\n",
-                "/-/-/",
-                taler_pay_url);
+  case ANASTASIS_CHALLENGE_STATUS_SERVER_FAILURE:
+    GNUNET_break (0);
     TALER_TESTING_interpreter_fail (cs->is);
-    /* NOTE: The above is a simplifying assumption for the
-        test-logic, hitting this code merely means that
-        the assumptions for the test (i.e. no instance) are
-        not satisfied, it is not inherently the case that
-        the above token must appear in the payment request!
-
-        So if you hit this, you might just want to modify
-        the code here to handle this better! */
     return;
   }
-  cs->payment_order_id = GNUNET_strdup (&m[strlen ("/-/-/")]);
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-              "At %s:%d Order ID from Anastasis service is %s\n",
-              __FILE__, __LINE__,
-              cs->payment_order_id);
-
-  TALER_TESTING_interpreter_next (cs->is);
 }
 
 
@@ -212,8 +177,9 @@ challenge_start_create_traits (void *cls,
   struct TALER_TESTING_Trait traits[] = {
     ANASTASIS_TESTING_make_trait_code (0,
                                        cs->code),
+    // FIXME: missmatch, need to fix traits!
     TALER_TESTING_make_trait_order_id (0,
-                                       cs->payment_order_id),
+                                       cs->payment_url),
     TALER_TESTING_make_trait_claim_token (0,
                                           &cs->token),
 
@@ -265,12 +231,16 @@ challenge_start_run (void *cls,
       return;
     }
   }
-  ANASTASIS_challenge_start (is->ctx,
-                             (struct ANASTASIS_Challenge *) c,
-                             &challenge_payment_cb,
-                             cs,
-                             &challenge_start_cb,
-                             cs);
+  if (GNUNET_OK !=
+      ANASTASIS_challenge_start ((struct ANASTASIS_Challenge *) c,
+                                 NULL, /* FIXME: pass payment secret! */
+                                 &challenge_start_cb,
+                                 cs))
+  {
+    GNUNET_break (0);
+    TALER_TESTING_interpreter_fail (cs->is);
+    return;
+  }
 }
 
 
diff --git a/src/util/anastasis_crypto.c b/src/util/anastasis_crypto.c
index ccae283..a9fe777 100644
--- a/src/util/anastasis_crypto.c
+++ b/src/util/anastasis_crypto.c
@@ -36,6 +36,22 @@
 #endif
 
 
+void
+ANASTASIS_hash_answer (uint64_t code,
+                       struct GNUNET_HashCode *hashed_code)
+{
+  char cbuf[32];
+
+  GNUNET_snprintf (cbuf,
+                   sizeof (cbuf),
+                   "%llu",
+                   (unsigned long long) code);
+  GNUNET_CRYPTO_hash (cbuf,
+                      strlen (cbuf),
+                      hashed_code);
+}
+
+
 /**
  * Compute @a key and @a iv.
  *
@@ -309,13 +325,6 @@ anastasis_decrypt (const void *key,
 }
 
 
-/**
- * Creates the UserIdentifier, it is used as entropy source for the encryption 
keys and
- * for the public and private key for signing the data.
- * @param id_data JSON encoded data, which contains the raw user secret
- * @param server_salt salt from the server (escrow provider)
- * @param[out] id reference to the id which was created
- */
 void
 ANASTASIS_CRYPTO_user_identifier_derive (
   const json_t *id_data,
@@ -336,11 +345,6 @@ ANASTASIS_CRYPTO_user_identifier_derive (
 }
 
 
-/**
- * Generates the eddsa private key used to authorize operations on policy
- * @param id holds a hashed user secret which is used as entropy source for 
the public key generation
- * @param priv_key[out] handle for the generated private key
- */
 void
 ANASTASIS_CRYPTO_account_private_key_derive (
   const struct ANASTASIS_CRYPTO_UserIdentifierP *id,
@@ -368,11 +372,6 @@ ANASTASIS_CRYPTO_account_private_key_derive (
 }
 
 
-/**
- * Generates the eddsa public Key used as the account identifier on the 
providers
- * @param id holds a hashed user secret which is used as entropy source for 
the public key generation
- * @param pub_key[out] handle for the generated public key
- */
 void
 ANASTASIS_CRYPTO_account_public_key_derive (
   const struct ANASTASIS_CRYPTO_UserIdentifierP *id,
@@ -386,17 +385,6 @@ ANASTASIS_CRYPTO_account_public_key_derive (
 }
 
 
-/**
- * Encrypt and signs the recovery document with AES256, the recovery document 
is
- * encrypted with a derivation from the user identifier and the salt "erd".
- *
- * @param id Hashed User input, used for the generation of the encryption key
- * @param rec_doc contains the recovery document as raw data
- * @param rd_size defines the size of the recovery document inside data
- * @param enc_rec_doc[out] return from the result, which contains the 
encrypted recovery document
- *            and the nonce and iv used for the encryption as Additional Data
- * @param erd_size[out] size of the result
- */
 void
 ANASTASIS_CRYPTO_recovery_document_encrypt (
   const struct ANASTASIS_CRYPTO_UserIdentifierP *id,
@@ -416,18 +404,6 @@ ANASTASIS_CRYPTO_recovery_document_encrypt (
 }
 
 
-/**
- * Decrypts the recovery document with AES256, the decryption key is generated 
with
- * the user identifier provided by the user and the salt "erd". The nonce and 
IV used for the encryption
- * are the first 48Byte of the data.
- *
- * @param id Hashed User input, used for the generation of the encryption key
- * @param enc_rec_doc, contains the encrypted recovery document and the nonce 
and iv used for the encryption.
- * @param erd_size size of the data
- * @param rec_doc[out] return from the result, which contains the encrypted 
recovery document
- *            and the nonce and iv used for the encryption as Additional Data
- * @param rd_size[out] size of the result
- */
 void
 ANASTASIS_CRYPTO_recovery_document_decrypt (
   const struct ANASTASIS_CRYPTO_UserIdentifierP *id,
@@ -447,13 +423,6 @@ ANASTASIS_CRYPTO_recovery_document_decrypt (
 }
 
 
-/**
- * Encrypts a keyshare with a key generated with the user identification as 
entropy and the salt "eks".
- *
- * @param key_share the key share which is afterwards encrypted
- * @param id the user identification which is the entropy source for the key 
generation
- * @param enc_key_share[out] holds the encrypted share, the first 48 Bytes are 
the used nonce and tag
- */
 void
 ANASTASIS_CRYPTO_keyshare_encrypt (
   const struct ANASTASIS_CRYPTO_KeyShareP *key_share,
@@ -482,13 +451,6 @@ ANASTASIS_CRYPTO_keyshare_encrypt (
 }
 
 
-/**
- * Decrypts a keyshare with a key generated with the user identification as 
entropy and the salt "eks".
- *
- * @param enc_key_share holds the encrypted share, the first 48 Bytes are the 
used nonce and tag
- * @param id the user identification which is the entropy source for the key 
generation
- * @param key_share[out] the result of decryption
- */
 void
 ANASTASIS_CRYPTO_keyshare_decrypt (
   const struct ANASTASIS_CRYPTO_EncryptedKeyShareP *enc_key_share,
@@ -513,12 +475,6 @@ ANASTASIS_CRYPTO_keyshare_decrypt (
 }
 
 
-/**
- * Generates the eddsa public Key  which is the identfier of the truth object.
- * The private key is used to sign the upload.
- * @param nonce is the seed to create and recreate the private key
- * @param pub_key[out] handle for the generated pub key
- */
 void
 ANASTASIS_CRYPTO_truth_public_key_derive (
   const struct ANASTASIS_CRYPTO_NonceP *nonce,
@@ -550,18 +506,6 @@ ANASTASIS_CRYPTO_truth_public_key_derive (
 }
 
 
-/**
- * Encrypts the truth data which contains the hashed answer or the phone 
number..
- * It is encrypted with AES256, the key is generated with the user 
identification as
- * entropy source and the salt "ect".
- *
- * @param truth_enc_key master key used for encryption of the truth
- * @param truth truth which will be encrypted
- * @param truth_size size of the truth
- * @param enc_truth[out] return from the result, which contains the encrypted 
truth
- *            and the nonce and iv used for the encryption as Additional Data
- * @param ect_size[out] size of the result
- */
 void
 ANASTASIS_CRYPTO_truth_encrypt (
   const struct ANASTASIS_CRYPTO_TruthKeyP *truth_enc_key,
@@ -581,17 +525,6 @@ ANASTASIS_CRYPTO_truth_encrypt (
 }
 
 
-/**
- * Decrypts the truth data which contains the hashed answer or the phone 
number..
- * It is decrypted with AES256, the key is generated with the user 
identification as
- * entropy source and the salt "ect".
- *
- * @param truth_enc_key master key used for encryption of the truth
- * @param enc_truth truth holds the encrypted truth which will be decrypted
- * @param ect_size size of the truth data
- * @param truth[out] return from the result, which contains the truth
- * @param truth_size[out] size of the result
- */
 void
 ANASTASIS_CRYPTO_truth_decrypt (
   const struct ANASTASIS_CRYPTO_TruthKeyP *truth_enc_key,
@@ -611,12 +544,6 @@ ANASTASIS_CRYPTO_truth_decrypt (
 }
 
 
-/**
- * A key share is randomly generated, one key share is generated for every
- * truth a policy contains.
- *
- * @param key_share[out] reference to the created key share.
- */
 void
 ANASTASIS_CRYPTO_keyshare_create (
   struct ANASTASIS_CRYPTO_KeyShareP *key_share)
@@ -627,15 +554,6 @@ ANASTASIS_CRYPTO_keyshare_create (
 }
 
 
-/**
- * Once per policy a policy key is derived. The policy key consists of
- * multiple key shares which are combined and hashed.
- *
- * @param key_shares list of key shares which are combined
- * @param keyshare_length amount of key shares inside the array
- * @param salt salt value
- * @param policy_key[out] reference to the created key
- */
 void
 ANASTASIS_CRYPTO_policy_key_derive (
   const struct ANASTASIS_CRYPTO_KeyShareP *key_shares,
@@ -655,21 +573,6 @@ ANASTASIS_CRYPTO_policy_key_derive (
 }
 
 
-/**
- * The core secret is the user provided secret which will be saved
- * with Anastasis.  The secret will be encrypted with the master key,
- * the master key is a random key which will be generated. The master
- * key afterwards will be encrypted with the different policy keys.
- * Encryption is performed with AES256.
- *
- * @param policy_keys an array of policy keys which are used to encrypt the 
master key
- * @param policy_keys_length defines the amount of policy keys and also the 
amount of encrypted master keys
- * @param core_secret the user provided core secret which is secured by 
anastasis
- * @param core_secret_size the size of the core secret
- * @param enc_core_secret[out] the core secret is encrypted with the generated 
master key
- * @param encrypted_master_keys[out] array of encrypted master keys which will 
be safed inside the policies one encrypted
- *        master key is created for each policy key
- */
 void
 ANASTASIS_CRYPTO_core_secret_encrypt (
   const struct ANASTASIS_CRYPTO_PolicyKeyP *policy_keys,
@@ -715,17 +618,6 @@ ANASTASIS_CRYPTO_core_secret_encrypt (
 }
 
 
-/**
- * Decrypts the core secret with the master key. First the master key is 
decrypted with the provided policy key.
- * Afterwards the core secret is encrypted with the master key. The core 
secret is returned.
- *
- * @param encrypted_master_key master key for decrypting the core secret, is 
itself encrypted by the policy key
- * @param policy_key built policy key which will decrypt the master key
- * @param encrypted_core_secret the encrypted core secret from the user, will 
be encrypted with the policy key
- * @param encrypted_core_secret_size size of the encrypted core secret
- * @param core_secret[out] decrypted core secret will be returned
- * @param core_secret_size[out] size of core secret
- */
 void
 ANASTASIS_CRYPTO_core_secret_recover (
   const struct ANASTASIS_CRYPTO_EncryptedMasterKeyP *encrypted_master_key,

-- 
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]