gnunet-svn
[Top][All Lists]
Advanced

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

[taler-exchange] branch master updated: -fix #7428


From: gnunet
Subject: [taler-exchange] branch master updated: -fix #7428
Date: Tue, 08 Nov 2022 15:15:44 +0100

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

grothoff pushed a commit to branch master
in repository exchange.

The following commit(s) were added to refs/heads/master by this push:
     new fe18c104 -fix #7428
     new 0c32c48a Merge branch 'master' of git+ssh://git.taler.net/exchange
fe18c104 is described below

commit fe18c104d8a8d3667b3c872078549c7e78c71db0
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Tue Nov 8 14:56:32 2022 +0100

    -fix #7428
---
 contrib/gana                                       |   2 +-
 src/exchange/taler-exchange-httpd_batch-withdraw.c |   1 +
 .../taler-exchange-httpd_reserves_history.c        |   2 +-
 src/exchange/taler-exchange-httpd_reserves_open.c  |   1 +
 src/exchange/taler-exchange-httpd_responses.c      |  11 +-
 src/exchange/taler-exchange-httpd_responses.h      |   2 +
 src/exchange/taler-exchange-httpd_withdraw.c       |   1 +
 src/lib/exchange_api_common.h                      |  10 +-
 src/lib/exchange_api_reserves_open.c               | 129 +++++++++++++++++++--
 9 files changed, 135 insertions(+), 24 deletions(-)

diff --git a/contrib/gana b/contrib/gana
index 6b9824cb..17b05a07 160000
--- a/contrib/gana
+++ b/contrib/gana
@@ -1 +1 @@
-Subproject commit 6b9824cb4d4561f1167c7f518998a226a82222d6
+Subproject commit 17b05a076510c359911993eceb55258e29a3ef7d
diff --git a/src/exchange/taler-exchange-httpd_batch-withdraw.c 
b/src/exchange/taler-exchange-httpd_batch-withdraw.c
index cf238204..541d6572 100644
--- a/src/exchange/taler-exchange-httpd_batch-withdraw.c
+++ b/src/exchange/taler-exchange-httpd_batch-withdraw.c
@@ -240,6 +240,7 @@ batch_withdraw_transaction (void *cls,
     TEH_plugin->rollback (TEH_plugin->cls);
     *mhd_ret = TEH_RESPONSE_reply_reserve_insufficient_balance (
       connection,
+      TALER_EC_EXCHANGE_WITHDRAW_INSUFFICIENT_FUNDS,
       &wc->batch_total,
       wc->reserve_pub);
     return GNUNET_DB_STATUS_HARD_ERROR;
diff --git a/src/exchange/taler-exchange-httpd_reserves_history.c 
b/src/exchange/taler-exchange-httpd_reserves_history.c
index aa3f8ab5..ffdc6eaa 100644
--- a/src/exchange/taler-exchange-httpd_reserves_history.c
+++ b/src/exchange/taler-exchange-httpd_reserves_history.c
@@ -159,7 +159,7 @@ reserve_history_transaction (void *cls,
     {
       return TALER_MHD_reply_with_error (connection,
                                          MHD_HTTP_CONFLICT,
-                                         
TALER_EC_EXCHANGE_WITHDRAW_HISTORY_ERROR_INSUFFICIENT_FUNDS,
+                                         
TALER_EC_EXCHANGE_GET_RESERVE_HISTORY_ERROR_INSUFFICIENT_BALANCE,
                                          NULL);
     }
     if (idempotent)
diff --git a/src/exchange/taler-exchange-httpd_reserves_open.c 
b/src/exchange/taler-exchange-httpd_reserves_open.c
index ced291d7..6909c862 100644
--- a/src/exchange/taler-exchange-httpd_reserves_open.c
+++ b/src/exchange/taler-exchange-httpd_reserves_open.c
@@ -288,6 +288,7 @@ reserve_open_transaction (void *cls,
     *mhd_ret
       = TEH_RESPONSE_reply_reserve_insufficient_balance (
           connection,
+          TALER_EC_EXCHANGE_RESERVES_OPEN_INSUFFICIENT_FUNDS,
           &rsc->reserve_payment,
           rsc->reserve_pub);
     return GNUNET_DB_STATUS_HARD_ERROR;
diff --git a/src/exchange/taler-exchange-httpd_responses.c 
b/src/exchange/taler-exchange-httpd_responses.c
index ca110ad4..4120405f 100644
--- a/src/exchange/taler-exchange-httpd_responses.c
+++ b/src/exchange/taler-exchange-httpd_responses.c
@@ -1000,8 +1000,9 @@ TEH_RESPONSE_compile_reserve_history (
  * @return MHD result code
  */
 static MHD_RESULT
-reply_withdraw_insufficient_funds (
+reply_reserve_insufficient_funds (
   struct MHD_Connection *connection,
+  enum TALER_ErrorCode ec,
   const struct TALER_Amount *ebalance,
   const struct TALER_Amount *withdraw_amount,
   const struct TALER_EXCHANGEDB_ReserveHistory *rh)
@@ -1012,12 +1013,12 @@ reply_withdraw_insufficient_funds (
   if (NULL == json_history)
     return TALER_MHD_reply_with_error (connection,
                                        MHD_HTTP_INTERNAL_SERVER_ERROR,
-                                       
TALER_EC_EXCHANGE_WITHDRAW_HISTORY_ERROR_INSUFFICIENT_FUNDS,
+                                       
TALER_EC_EXCHANGE_RESERVE_HISTORY_ERROR_INSUFFICIENT_FUNDS,
                                        NULL);
   return TALER_MHD_REPLY_JSON_PACK (
     connection,
     MHD_HTTP_CONFLICT,
-    TALER_JSON_pack_ec (TALER_EC_EXCHANGE_WITHDRAW_INSUFFICIENT_FUNDS),
+    TALER_JSON_pack_ec (ec),
     TALER_JSON_pack_amount ("balance",
                             ebalance),
     TALER_JSON_pack_amount ("requested_amount",
@@ -1030,6 +1031,7 @@ reply_withdraw_insufficient_funds (
 MHD_RESULT
 TEH_RESPONSE_reply_reserve_insufficient_balance (
   struct MHD_Connection *connection,
+  enum TALER_ErrorCode ec,
   const struct TALER_Amount *balance_required,
   const struct TALER_ReservePublicKeyP *reserve_pub)
 {
@@ -1063,8 +1065,9 @@ TEH_RESPONSE_reply_reserve_insufficient_balance (
                                        TALER_EC_GENERIC_DB_FETCH_FAILED,
                                        "reserve history");
   }
-  mhd_ret = reply_withdraw_insufficient_funds (
+  mhd_ret = reply_reserve_insufficient_funds (
     connection,
+    ec,
     &balance,
     balance_required,
     rh);
diff --git a/src/exchange/taler-exchange-httpd_responses.h 
b/src/exchange/taler-exchange-httpd_responses.h
index 3eebf027..ba6577b2 100644
--- a/src/exchange/taler-exchange-httpd_responses.h
+++ b/src/exchange/taler-exchange-httpd_responses.h
@@ -63,6 +63,7 @@ TEH_RESPONSE_reply_unknown_denom_pub_hash (
  * an insufficient balance for the given operation.
  *
  * @param connection connection to the client
+ * @param ec specific error code to return with the reserve history
  * @param balance_required the balance required for the operation
  * @param reserve_pub the reserve with insufficient balance
  * @return MHD result code
@@ -70,6 +71,7 @@ TEH_RESPONSE_reply_unknown_denom_pub_hash (
 MHD_RESULT
 TEH_RESPONSE_reply_reserve_insufficient_balance (
   struct MHD_Connection *connection,
+  enum TALER_ErrorCode ec,
   const struct TALER_Amount *balance_required,
   const struct TALER_ReservePublicKeyP *reserve_pub);
 
diff --git a/src/exchange/taler-exchange-httpd_withdraw.c 
b/src/exchange/taler-exchange-httpd_withdraw.c
index 57020ee8..27b17672 100644
--- a/src/exchange/taler-exchange-httpd_withdraw.c
+++ b/src/exchange/taler-exchange-httpd_withdraw.c
@@ -217,6 +217,7 @@ withdraw_transaction (void *cls,
     TEH_plugin->rollback (TEH_plugin->cls);
     *mhd_ret = TEH_RESPONSE_reply_reserve_insufficient_balance (
       connection,
+      TALER_EC_EXCHANGE_WITHDRAW_INSUFFICIENT_FUNDS,
       &wc->collectable.amount_with_fee,
       &wc->collectable.reserve_pub);
     return GNUNET_DB_STATUS_HARD_ERROR;
diff --git a/src/lib/exchange_api_common.h b/src/lib/exchange_api_common.h
index 80c36daf..1b9ddce3 100644
--- a/src/lib/exchange_api_common.h
+++ b/src/lib/exchange_api_common.h
@@ -129,12 +129,10 @@ TALER_EXCHANGE_check_coin_amount_conflict_ (
 
 
 /**
- * Verify that @a proof contains a coin history
- * that demonstrates that @a coin_pub was previously
- * used with a denomination key that is different
- * from @a ch_denom_pub.  Note that the coin history
- * MUST have been checked before using
- * #TALER_EXCHANGE_check_coin_amount_conflict_().
+ * Verify that @a proof contains a coin history that demonstrates that @a
+ * coin_pub was previously used with a denomination key that is different from
+ * @a ch_denom_pub.  Note that the coin history MUST have been checked before
+ * using #TALER_EXCHANGE_check_coin_amount_conflict_().
  *
  * @param proof a proof to check
  * @param ch_denom_pub hash of the conflicting denomination
diff --git a/src/lib/exchange_api_reserves_open.c 
b/src/lib/exchange_api_reserves_open.c
index 64d259ba..2b7ef0d9 100644
--- a/src/lib/exchange_api_reserves_open.c
+++ b/src/lib/exchange_api_reserves_open.c
@@ -27,11 +27,39 @@
 #include <gnunet/gnunet_curl_lib.h>
 #include "taler_exchange_service.h"
 #include "taler_json_lib.h"
+#include "exchange_api_common.h"
 #include "exchange_api_handle.h"
 #include "taler_signatures.h"
 #include "exchange_api_curl_defaults.h"
 
 
+/**
+ * Information we keep per coin to validate the reply.
+ */
+struct CoinData
+{
+  /**
+   * Public key of the coin.
+   */
+  struct TALER_CoinSpendPublicKeyP coin_pub;
+
+  /**
+   * Signature by the coin.
+   */
+  struct TALER_CoinSpendSignatureP coin_sig;
+
+  /**
+   * The hash of the denomination's public key
+   */
+  struct TALER_DenominationHashP h_denom_pub;
+
+  /**
+   * How much did this coin contribute.
+   */
+  struct TALER_Amount contribution;
+};
+
+
 /**
  * @brief A /reserves/$RID/open Handle
  */
@@ -69,6 +97,16 @@ struct TALER_EXCHANGE_ReservesOpenHandle
    */
   void *cb_cls;
 
+  /**
+   * Information we keep per coin to validate the reply.
+   */
+  struct CoinData *coins;
+
+  /**
+   * Length of the @e coins array.
+   */
+  unsigned int num_coins;
+
   /**
    * Public key of the reserve we are querying.
    */
@@ -282,12 +320,74 @@ handle_reserves_open_finished (void *cls,
     rs.hr.hint = TALER_JSON_get_error_hint (j);
     break;
   case MHD_HTTP_CONFLICT:
-    // FIXME: not yet specified (#7428), but needed in
-    // case of double-spending or insufficient
-    // reserve balance!
-    rs.hr.ec = TALER_JSON_get_error_code (j);
-    rs.hr.hint = TALER_JSON_get_error_hint (j);
-    break;
+    {
+      const struct TALER_EXCHANGE_Keys *keys;
+      const struct CoinData *cd = NULL;
+      struct TALER_CoinSpendPublicKeyP coin_pub;
+      const struct TALER_EXCHANGE_DenomPublicKey *dk;
+      struct GNUNET_JSON_Specification spec[] = {
+        GNUNET_JSON_spec_fixed_auto ("coin_pub",
+                                     &coin_pub),
+        GNUNET_JSON_spec_end ()
+      };
+
+      keys = TALER_EXCHANGE_get_keys (roh->exchange);
+      GNUNET_assert (NULL != keys);
+      if (GNUNET_OK !=
+          GNUNET_JSON_parse (j,
+                             spec,
+                             NULL,
+                             NULL))
+      {
+        GNUNET_break_op (0);
+        rs.hr.http_status = 0;
+        rs.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
+        break;
+      }
+      for (unsigned int i = 0; i<roh->num_coins; i++)
+      {
+        const struct CoinData *cdi = &roh->coins[i];
+
+        if (0 == GNUNET_memcmp (&coin_pub,
+                                &cdi->coin_pub))
+        {
+          cd = cdi;
+          break;
+        }
+      }
+      if (NULL == cd)
+      {
+        GNUNET_break_op (0);
+        rs.hr.http_status = 0;
+        rs.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
+        break;
+      }
+      dk = TALER_EXCHANGE_get_denomination_key_by_hash (keys,
+                                                        &cd->h_denom_pub);
+      if (NULL == dk)
+      {
+        GNUNET_break_op (0);
+        rs.hr.http_status = 0;
+        rs.hr.ec = TALER_EC_GENERIC_CLIENT_INTERNAL_ERROR;
+        break;
+      }
+      if (GNUNET_OK !=
+          TALER_EXCHANGE_check_coin_conflict_ (keys,
+                                               j,
+                                               dk,
+                                               &coin_pub,
+                                               &cd->coin_sig,
+                                               &cd->contribution))
+      {
+        GNUNET_break_op (0);
+        rs.hr.http_status = 0;
+        rs.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
+        break;
+      }
+      rs.hr.ec = TALER_JSON_get_error_code (j);
+      rs.hr.hint = TALER_JSON_get_error_hint (j);
+      break;
+    }
   case MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS:
     if (GNUNET_OK !=
         handle_reserves_open_kyc (roh,
@@ -402,18 +502,21 @@ TALER_EXCHANGE_reserves_open (
                                   min_purses,
                                   reserve_priv,
                                   &roh->reserve_sig);
+  roh->coins = GNUNET_new_array (coin_payments_length,
+                                 struct CoinData);
   cpa = json_array ();
   GNUNET_assert (NULL != cpa);
   for (unsigned int i = 0; i<coin_payments_length; i++)
   {
     const struct TALER_EXCHANGE_PurseDeposit *pd = &coin_payments[i];
-    struct TALER_CoinSpendSignatureP coin_sig;
-    struct TALER_CoinSpendPublicKeyP coin_pub;
     const struct TALER_AgeCommitmentProof *acp = pd->age_commitment_proof;
     struct TALER_AgeCommitmentHash ahac;
     struct TALER_AgeCommitmentHash *achp = NULL;
+    struct CoinData *cd = &roh->coins[i];
     json_t *cp;
 
+    cd->contribution = pd->amount;
+    cd->h_denom_pub = pd->h_denom_pub;
     if (NULL != acp)
     {
       TALER_age_commitment_hash (&acp->commitment,
@@ -423,9 +526,9 @@ TALER_EXCHANGE_reserves_open (
     TALER_wallet_reserve_open_deposit_sign (&pd->amount,
                                             &roh->reserve_sig,
                                             &pd->coin_priv,
-                                            &coin_sig);
+                                            &cd->coin_sig);
     GNUNET_CRYPTO_eddsa_key_get_public (&pd->coin_priv.eddsa_priv,
-                                        &coin_pub.eddsa_pub);
+                                        &cd->coin_pub.eddsa_pub);
 
     cp = GNUNET_JSON_PACK (
       GNUNET_JSON_pack_allow_null (
@@ -438,9 +541,9 @@ TALER_EXCHANGE_reserves_open (
       TALER_JSON_pack_denom_sig ("ub_sig",
                                  &pd->denom_sig),
       GNUNET_JSON_pack_data_auto ("coin_pub",
-                                  &coin_pub),
+                                  &cd->coin_pub),
       GNUNET_JSON_pack_data_auto ("coin_sig",
-                                  &coin_sig));
+                                  &cd->coin_sig));
     GNUNET_assert (0 ==
                    json_array_append_new (cpa,
                                           cp));
@@ -468,6 +571,7 @@ TALER_EXCHANGE_reserves_open (
       GNUNET_break (0);
       curl_easy_cleanup (eh);
       json_decref (open_obj);
+      GNUNET_free (roh->coins);
       GNUNET_free (roh->url);
       GNUNET_free (roh);
       return NULL;
@@ -494,6 +598,7 @@ TALER_EXCHANGE_reserves_open_cancel (
     roh->job = NULL;
   }
   TALER_curl_easy_post_finished (&roh->post_ctx);
+  GNUNET_free (roh->coins);
   GNUNET_free (roh->url);
   GNUNET_free (roh);
 }

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