gnunet-svn
[Top][All Lists]
Advanced

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

[taler-anastasis] 06/10: Worked on escrow challenge


From: gnunet
Subject: [taler-anastasis] 06/10: Worked on escrow challenge
Date: Wed, 15 Jan 2020 23:42:30 +0100

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

dennis-neufeld pushed a commit to branch master
in repository anastasis.

commit fc3ba36bf79e7a0ee07953bc6096cab0d46258ff
Author: Dennis Neufeld <address@hidden>
AuthorDate: Mon Jan 6 09:08:14 2020 +0000

    Worked on escrow challenge
---
 src/backend/anastasis-httpd_truth.c    |  73 +++---
 src/lib/anastasis_api_truth_store.c    | 431 +++++++++++++++++++++++++++++++++
 src/stasis/plugin_anastasis_postgres.c |   6 +-
 3 files changed, 466 insertions(+), 44 deletions(-)

diff --git a/src/backend/anastasis-httpd_truth.c 
b/src/backend/anastasis-httpd_truth.c
index 2574992..72bd840 100644
--- a/src/backend/anastasis-httpd_truth.c
+++ b/src/backend/anastasis-httpd_truth.c
@@ -42,6 +42,7 @@ AH_handler_truth_get (struct MHD_Connection *connection,
   uuid_t uuid;
   struct GNUNET_CRYPTO_SymmetricSessionKey decryption_key;
   struct GNUNET_HashCode challenge_response;
+  const char *challenge_response_s;
   void *encrypted_truth;
   void *decrypted_truth;
   void *encrypted_keyshare;
@@ -61,6 +62,10 @@ AH_handler_truth_get (struct MHD_Connection *connection,
 
     uuid_str = &url[strlen ("/truth/")];
     uuid_parse (uuid_str, uuid);
+
+    challenge_response_s = MHD_lookup_connection_value (connection,
+                                            MHD_GET_ARGUMENT_KIND,
+                                            "response");
   }
   {
     // check if header contains Truth-Decryption-Key
@@ -87,31 +92,6 @@ AH_handler_truth_get (struct MHD_Connection *connection,
     else
       return MHD_HTTP_PRECONDITION_FAILED;
   }
-  {
-    // check if header contains Challenge-Response
-    const char *cr;
-
-    cr = MHD_lookup_connection_value (connection,
-                                      MHD_HEADER_KIND,
-                                      "Challenge-Response");
-
-    if ( (NULL != cr) &&
-         (GNUNET_OK !=
-          GNUNET_STRINGS_string_to_data (cr,
-                                         strlen (cr),
-                                         &challenge_response,
-                                         sizeof (&challenge_response))))
-    {
-      GNUNET_break_op (0);
-      return TALER_MHD_reply_with_error (connection,
-                                         MHD_HTTP_BAD_REQUEST,
-                                         // FIXME: find error code
-                                         TALER_EC_SYNC_BAD_IF_MATCH,
-                                         "Challenge_Response does not include 
a base32-encoded challenge response");
-    }
-    else
-      return MHD_HTTP_PRECONDITION_FAILED;
-  }
   {
     // load encrypted truth from db
     enum ANASTASIS_DB_QueryStatus qs;
@@ -123,29 +103,35 @@ AH_handler_truth_get (struct MHD_Connection *connection,
                                    &aes_gcm_tag,
                                    &nonce,
                                    &truth_mime,
-                                   &method); 
-    if (qs != ANASTASIS_DB_STATUS_SUCCESS_ONE_RESULT) {
+                                   &method);
+    if (qs != ANASTASIS_DB_STATUS_SUCCESS_ONE_RESULT)
+    {
       return qs;
     }
+
+    if (NULL == challenge_response_s)
+    {
+      //FIXME: Return escrow challenge
+    }
   }
   {
     struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
-    
+
     GNUNET_CRYPTO_symmetric_derive_iv (&iv,
                                        &decryption_key,
                                        "ECT",
                                        strlen ("ECT"));
 
     decrypted_truth = GNUNET_malloc (GNUNET_CRYPTO_AES_KEY_LENGTH);
-    
-    //decrypt encrypted_truth
+
+    // decrypt encrypted_truth
     if (GNUNET_CRYPTO_AES_KEY_LENGTH !=
         GNUNET_CRYPTO_symmetric_decrypt (result,
                                          GNUNET_CRYPTO_AES_KEY_LENGTH,
                                          &decryption_key,
                                          &iv,
                                          decrypted_truth
-                                        ))
+                                         ))
     {
       printf ("Wrong return value from decrypt block.\n");
       ret = 1;
@@ -153,10 +139,14 @@ AH_handler_truth_get (struct MHD_Connection *connection,
     }
   }
   {
-    //validate challenge response
-    if (method == "Secure Question") {
-      if(0 != GNUNET_memcmp (&challenge_response,
-                             decrypted_truth))
+    // validate challenge response
+    if (method == "Secure Question")
+    {
+      GNUNET_CRYPTO_hash_from_string (challenge_response_s,
+                                      &challenge_response);
+
+      if (0 != GNUNET_memcmp (&challenge_response,
+                              decrypted_truth))
       {
         GNUNET_break (0);
         return;
@@ -169,9 +159,10 @@ AH_handler_truth_get (struct MHD_Connection *connection,
         qs = db->get_key_share (db->cls,
                                 &uuid,
                                 &encrypted_keyshare,
-                                sizeof (&encrypted_keyshare)); 
+                                sizeof (&encrypted_keyshare));
 
-        if (qs != ANASTASIS_DB_STATUS_SUCCESS_ONE_RESULT) {
+        if (qs != ANASTASIS_DB_STATUS_SUCCESS_ONE_RESULT)
+        {
           return qs;
         }
 
@@ -189,13 +180,13 @@ AH_handler_truth_get (struct MHD_Connection *connection,
         MHD_destroy_response (resp);
         return ret;
       }
-      
+
     }
   }
 
   return MHD_NO;
 
-  error:
-    GNUNET_free_non_null (decrypted_truth);
-    return ret;
+error:
+  GNUNET_free_non_null (decrypted_truth);
+  return ret;
 }
\ No newline at end of file
diff --git a/src/lib/anastasis_api_truth_store.c 
b/src/lib/anastasis_api_truth_store.c
new file mode 100644
index 0000000..b66798d
--- /dev/null
+++ b/src/lib/anastasis_api_truth_store.c
@@ -0,0 +1,431 @@
+/*
+  This file is part of ANASTASIS
+  Copyright (C) 2014-2019 GNUnet e.V. and INRIA
+
+  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 2.1,
+  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 Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with ANASTASIS; see the file COPYING.LGPL.  If not,
+  see <http://www.gnu.org/licenses/>
+*/
+
+/**
+ * @file lib/anastasis_api_policy_store.c
+ * @brief Implementation of the /policy GET and POST
+ * @author Christian Grothoff
+ * @author Dennis Neufeld
+ * @author Dominik Meister
+ */
+#include "platform.h"
+#include <curl/curl.h>
+#include <jansson.h>
+#include <microhttpd.h> /* just for HTTP status codes */
+#include <gnunet/gnunet_util_lib.h>
+#include <gnunet/gnunet_curl_lib.h>
+#include <taler/taler_signatures.h>
+#include <taler/taler_json_lib.h>
+#include <taler/taler_curl_lib.h>
+#include <taler/taler_util.h>
+#include "anastasis_service.h"
+#include "anastasis_api_curl_defaults.h"
+
+
+struct ANASTASIS_TruthStoreOperation
+{
+  /**
+   * Complete URL where the backend offers /truth
+   */
+  char *url;
+
+  /**
+   * Handle for the request.
+   */
+  struct GNUNET_CURL_Job *job;
+
+  /**
+   * The CURL context to connect to the backend
+   */
+  struct GNUNET_CURL_Context *ctx;
+
+  /**
+   * The callback to pass the backend response to
+   */
+  ANASTASIS_TruthStoreCallback cb;
+
+  /**
+   * Closure for @e cb.
+   */
+  void *cb_cls;
+
+  /**
+   * Payment URI we received from the service, or NULL.
+   */
+  char *pay_uri;
+
+  /**
+   * Hash of the data we are uploading.
+   */
+  struct GNUNET_HashCode new_recovery_data_hash;
+};
+
+/**
+ * Cancel a POST /policy request.
+ *
+ * @param pso the policy store operation to cancel
+ */
+void
+ANASTASIS_policy_store_cancel (struct
+                               ANASTASIS_TruthStoreOperation *pso)
+{
+  if (NULL != pso->job)
+  {
+    GNUNET_CURL_job_cancel (pso->job);
+    pso->job = NULL;
+  }
+  GNUNET_free_non_null (pso->pay_uri);
+  GNUNET_free (pso->url);
+  GNUNET_free (pso);
+}
+
+
+/**
+ * Callback to process POST /policy response
+ *
+ * @param cls the `struct ANASTASIS_TruthStoreOperation`
+ * @param response_code HTTP response code, 0 on error
+ * @param data
+ * @param data_size
+ */
+static void
+handle_policy_store_finished (void *cls,
+                              long response_code,
+                              const void *data,
+                              size_t data_size)
+{
+  struct ANASTASIS_TruthStoreOperation *pso = cls;
+  enum TALER_ErrorCode ec = TALER_EC_INVALID;
+  struct ANASTASIS_UploadDetails ud;
+  struct ANASTASIS_UploadDetails *udp;
+
+  pso->job = NULL;
+  udp = NULL;
+  memset (&ud, 0, sizeof (ud));
+  switch (response_code)
+  {
+  case 0:
+    break;
+  case MHD_HTTP_NO_CONTENT:
+    ud.us = ANASTASIS_US_SUCCESS;
+    ud.details.curr_backup_hash = &pso->new_recovery_data_hash;
+    udp = &ud;
+    ec = TALER_EC_NONE;
+    break;
+  case MHD_HTTP_NOT_MODIFIED:
+    ud.us = ANASTASIS_US_SUCCESS;
+    ud.details.curr_backup_hash = &pso->new_recovery_data_hash;
+    udp = &ud;
+    ec = TALER_EC_NONE;
+    break;
+  case MHD_HTTP_BAD_REQUEST:
+    GNUNET_break (0);
+    ec = TALER_JSON_get_error_code2 (data,
+                                     data_size);
+    break;
+  case MHD_HTTP_PAYMENT_REQUIRED:
+    ud.us = ANASTASIS_US_PAYMENT_REQUIRED;
+    ud.details.payment_request = pso->pay_uri;
+    udp = &ud;
+    ec = TALER_EC_NONE;
+    break;
+  case MHD_HTTP_FORBIDDEN:
+    GNUNET_break (0);
+    ec = TALER_JSON_get_error_code2 (data,
+                                     data_size);
+    break;
+  case MHD_HTTP_CONFLICT:
+    ud.us = ANASTASIS_US_CONFLICTING_POLICY;
+    GNUNET_CRYPTO_hash (data,
+                        data_size,
+                        &ud.details.recovered_backup.existing_backup_hash);
+    ud.details.recovered_backup.existing_backup_size
+      = data_size;
+    ud.details.recovered_backup.existing_backup
+      = data;
+    udp = &ud;
+    ec = TALER_EC_NONE;
+    break;
+  case MHD_HTTP_GONE:
+    ec = TALER_JSON_get_error_code2 (data,
+                                     data_size);
+    break;
+  case MHD_HTTP_LENGTH_REQUIRED:
+    GNUNET_break (0);
+    break;
+  case MHD_HTTP_REQUEST_ENTITY_TOO_LARGE:
+    ec = TALER_JSON_get_error_code2 (data,
+                                     data_size);
+    break;
+  case MHD_HTTP_TOO_MANY_REQUESTS:
+    ec = TALER_JSON_get_error_code2 (data,
+                                     data_size);
+    break;
+  }
+  if (NULL != pso->cb)
+  {
+    pso->cb (pso->cb_cls,
+             ec,
+             response_code,
+             udp);
+    pso->cb = NULL;
+  }
+  ANASTASIS_policy_store_cancel (pso);
+}
+
+
+/**
+ * Handle HTTP header received by curl.
+ *
+ * @param buffer one line of HTTP header data
+ * @param size size of an item
+ * @param nitems number of items passed
+ * @param userdata our `struct ANASTASIS_StorePolicyOperation *`
+ * @return `size * nitems`
+ */
+static size_t
+handle_header (char *buffer,
+               size_t size,
+               size_t nitems,
+               void *userdata)
+{
+  struct ANASTASIS_TruthStoreOperation *pso = userdata;
+  size_t total = size * nitems;
+  char *ndup;
+  const char *hdr_type;
+  char *hdr_val;
+
+  ndup = GNUNET_strndup (buffer,
+                         total);
+  hdr_type = strtok (ndup,
+                     ":");
+  if (NULL == hdr_type)
+  {
+    GNUNET_free (ndup);
+    return total;
+  }
+  hdr_val = strtok (NULL,
+                    "");
+  if (NULL == hdr_val)
+  {
+    GNUNET_free (ndup);
+    return total;
+  }
+  if (' ' == *hdr_val)
+    hdr_val++;
+  if (0 == strcasecmp (hdr_type,
+                       "Taler"))
+  {
+    /* found payment URI we care about! */
+    pso->pay_uri = GNUNET_strdup (hdr_val);
+  }
+  GNUNET_free (ndup);
+  return total;
+}
+
+
+/**
+ * Store policies, does a POST /policy/$AccountPub
+ *
+ * @param ctx the CURL context used to connect to the backend
+ * @param backend_url backend's base URL, including final "/"
+ * @param anastasis_pub public key of the user's account
+ * @param anastasis_priv private key of the user's account
+ * @param prev_recovery_data_hash hash of the previous uploaded recovery 
document
+ * @param recovery_data policy data to be stored
+ * @param recovery_data_size number of bytes in @a recovery_data
+ * @param payment_requested #GNUNET_YES if the client wants to pay more for 
the account now
+ * @param paymentSecretP payment identifier of last payment
+ * @param cb callback processing the response from /policy
+ * @param cb_cls closure for cb
+ * @return handle for the operation
+ */
+struct ANASTASIS_TruthStoreOperation *
+ANASTASIS_policy_store (struct GNUNET_CURL_Context *ctx,
+                        const char *backend_url,
+                        const struct
+                        ANASTASIS_AccountPrivP *anastasis_priv,
+                        const struct
+                        GNUNET_HashCode *prev_recovery_data_hash,
+                        const void *recovery_data,
+                        size_t recovery_data_size,
+                        int payment_requested,
+                        const struct
+                        ANASTASIS_PaymentSecretP *paymentSecretP,
+                        ANASTASIS_TruthStoreCallback cb,
+                        void *cb_cls)
+{
+  struct ANASTASIS_TruthStoreOperation *pso;
+  struct ANASTASIS_AccountSignatureP account_sig;
+  struct ANASTASIS_UploadSignaturePS usp;
+  CURL *eh;
+  struct curl_slist *job_headers;
+
+  memset (&usp, 0, sizeof (usp));
+  usp.purpose.purpose = htonl (TALER_SIGNATURE_ANASTASIS_POLICY_UPLOAD);
+  usp.purpose.size = htonl (sizeof (usp));
+  if (NULL != prev_recovery_data_hash)
+    usp.old_recovery_data_hash = *prev_recovery_data_hash;
+  GNUNET_CRYPTO_hash (recovery_data,
+                      recovery_data_size,
+                      &usp.new_recovery_data_hash);
+  if (GNUNET_OK !=
+      GNUNET_CRYPTO_eddsa_sign (&anastasis_priv->priv,
+                                &usp.purpose,
+                                &account_sig.eddsa_sig))
+  {
+    GNUNET_break (0);
+    return NULL;
+  }
+  /* setup our HTTP headers */
+  job_headers = NULL;
+  {
+    struct curl_slist *ext;
+    char *val;
+    char *hdr;
+
+    /* Set Anastasis-Policy-Signature header */
+    val = GNUNET_STRINGS_data_to_string_alloc (&account_sig,
+                                               sizeof (account_sig));
+    GNUNET_asprintf (&hdr,
+                     "Anastasis-Policy-Signature: %s",
+                     val);
+    GNUNET_free (val);
+    ext = curl_slist_append (job_headers,
+                             hdr);
+    GNUNET_free (hdr);
+    if (NULL == ext)
+    {
+      GNUNET_break (0);
+      curl_slist_free_all (job_headers);
+      return NULL;
+    }
+    job_headers = ext;
+
+    /* set Etag header */
+    val = GNUNET_STRINGS_data_to_string_alloc (&usp.new_recovery_data_hash,
+                                               sizeof (struct 
GNUNET_HashCode));
+    GNUNET_asprintf (&hdr,
+                     "Etag: %s",
+                     val);
+    GNUNET_free (val);
+    ext = curl_slist_append (job_headers,
+                             hdr);
+    GNUNET_free (hdr);
+    if (NULL == ext)
+    {
+      GNUNET_break (0);
+      curl_slist_free_all (job_headers);
+      return NULL;
+    }
+    job_headers = ext;
+
+    /* Setup If-Match header */
+    if (NULL != prev_recovery_data_hash)
+    {
+      val = GNUNET_STRINGS_data_to_string_alloc (&usp.old_recovery_data_hash,
+                                                 sizeof (struct
+                                                         GNUNET_HashCode));
+      GNUNET_asprintf (&hdr,
+                       "If-Match: %s",
+                       val);
+      GNUNET_free (val);
+      ext = curl_slist_append (job_headers,
+                               hdr);
+      GNUNET_free (hdr);
+      if (NULL == ext)
+      {
+        GNUNET_break (0);
+        curl_slist_free_all (job_headers);
+        return NULL;
+      }
+      job_headers = ext;
+    }
+
+    /* Setup Payment-Identifier header */
+    if (NULL != paymentSecretP)
+    {
+      val = GNUNET_STRINGS_data_to_string_alloc (&paymentSecretP,
+                                                 sizeof (paymentSecretP));
+      GNUNET_asprintf (&hdr,
+                       "Payment-Identifier: %s",
+                       val);
+      GNUNET_free (val);
+      ext = curl_slist_append (job_headers,
+                               hdr);
+      GNUNET_free (hdr);
+      if (NULL == ext)
+      {
+        GNUNET_break (0);
+        curl_slist_free_all (job_headers);
+        return NULL;
+      }
+      job_headers = ext;
+    }
+  }
+  /* Finished setting up headers */
+
+  pso = GNUNET_new (struct ANASTASIS_TruthStoreOperation);
+  pso->new_recovery_data_hash = usp.new_recovery_data_hash;
+  {
+    char *acc_pub_str;
+    char *path;
+    struct ANASTASIS_AccountPubP pub;
+
+    GNUNET_CRYPTO_eddsa_key_get_public (&anastasis_priv->priv,
+                                        &pub.pub);
+
+    acc_pub_str = GNUNET_STRINGS_data_to_string_alloc (&pub,
+                                                       sizeof (pub));
+    GNUNET_asprintf (&path,
+                     "policy/%s",
+                     acc_pub_str);
+    GNUNET_free (acc_pub_str);
+    pso->url = TALER_url_join (backend_url,
+                               path);
+    GNUNET_free (path);
+  }
+  pso->ctx = ctx;
+  pso->cb = cb;
+  pso->cb_cls = cb_cls;
+  eh = ANASTASIS_curl_easy_get_ (pso->url);
+  GNUNET_assert (CURLE_OK ==
+                 curl_easy_setopt (eh,
+                                   CURLOPT_POSTFIELDS,
+                                   recovery_data));
+  GNUNET_assert (CURLE_OK ==
+                 curl_easy_setopt (eh,
+                                   CURLOPT_POSTFIELDSIZE,
+                                   (long) recovery_data_size));
+  GNUNET_assert (CURLE_OK ==
+                 curl_easy_setopt (eh,
+                                   CURLOPT_HEADERFUNCTION,
+                                   &handle_header));
+  GNUNET_assert (CURLE_OK ==
+                 curl_easy_setopt (eh,
+                                   CURLOPT_HEADERDATA,
+                                   pso));
+  pso->job = GNUNET_CURL_job_add_raw (ctx,
+                                      eh,
+                                      job_headers,
+                                      &handle_policy_store_finished,
+                                      pso);
+  curl_slist_free_all (job_headers);
+  return pso;
+}
diff --git a/src/stasis/plugin_anastasis_postgres.c 
b/src/stasis/plugin_anastasis_postgres.c
index 5fea5dc..6462859 100644
--- a/src/stasis/plugin_anastasis_postgres.c
+++ b/src/stasis/plugin_anastasis_postgres.c
@@ -804,7 +804,7 @@ postgres_store_truth (void *cls,
  *
  * @param cls closure
  * @param uuid the identifier for the Truth
- * @param truth contains the encrypted truth 
+ * @param truth contains the encrypted truth
  * @param truth_size size of encrypted truth
  * @param truth_mime mime type of truth
  * @return transaction status
@@ -829,9 +829,9 @@ postgres_get_escrow_challenge (void *cls,
                                          truth,
                                          truth_size),
     GNUNET_PQ_result_spec_string ("aes_gcm_tag",
-                                          aes_gcm_tag),
+                                  aes_gcm_tag),
     GNUNET_PQ_result_spec_uint32 ("nonce",
-                                  nonce),                                    
+                                  nonce),
     GNUNET_PQ_result_spec_string ("truth_mime",
                                   truth_mime),
     GNUNET_PQ_result_spec_string ("method",

-- 
To stop receiving notification emails like this one, please contact
address@hidden.



reply via email to

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