gnunet-svn
[Top][All Lists]
Advanced

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

[taler-exchange] branch master updated: -fix recoup ugliness


From: gnunet
Subject: [taler-exchange] branch master updated: -fix recoup ugliness
Date: Thu, 16 Dec 2021 20:18:50 +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 1acc851d -fix recoup ugliness
1acc851d is described below

commit 1acc851deb38c52e4212823100eec8a00d5f385a
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Thu Dec 16 20:18:44 2021 +0100

    -fix recoup ugliness
---
 src/auditor/taler-helper-auditor-coins.c    | 53 +++++++++++----------------
 src/auditor/taler-helper-auditor-reserves.c | 49 ++++++++++---------------
 src/exchange/taler-exchange-httpd_recoup.c  | 45 +++++++++++++----------
 src/exchangedb/exchange-0001.sql            |  5 ---
 src/exchangedb/plugin_exchangedb_postgres.c |  4 +-
 src/exchangedb/test_exchangedb.c            | 39 +++++++++++---------
 src/include/taler_crypto_lib.h              | 57 +++++++++++++++++++++++++++++
 src/include/taler_signatures.h              | 11 +++---
 src/lib/exchange_api_common.c               | 46 +++++++++++------------
 src/lib/exchange_api_recoup.c               | 30 +++++++--------
 src/testing/test_exchange_api.c             |  2 +-
 src/testing/test_exchange_api_revocation.c  | 20 +++++-----
 src/util/wallet_signatures.c                | 47 ++++++++++++++++++++++++
 13 files changed, 248 insertions(+), 160 deletions(-)

diff --git a/src/auditor/taler-helper-auditor-coins.c 
b/src/auditor/taler-helper-auditor-coins.c
index 937613cc..393fc464 100644
--- a/src/auditor/taler-helper-auditor-coins.c
+++ b/src/auditor/taler-helper-auditor-coins.c
@@ -1983,38 +1983,29 @@ check_recoup (struct CoinContext *cc,
     cc->qs = qs;
     return GNUNET_SYSERR;
   }
+  if (GNUNET_OK !=
+      TALER_wallet_recoup_verify (&coin->denom_pub_hash,
+                                  coin_blind,
+                                  amount,
+                                  &coin->coin_pub,
+                                  coin_sig))
   {
-    struct TALER_RecoupRequestPS pr = {
-      .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_RECOUP),
-      .purpose.size = htonl (sizeof (pr)),
-      .coin_pub = coin->coin_pub,
-      .coin_blind = *coin_blind,
-      .h_denom_pub = coin->denom_pub_hash
-    };
-
-    if (GNUNET_OK !=
-        GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_RECOUP,
-                                    &pr,
-                                    &coin_sig->eddsa_signature,
-                                    &coin->coin_pub.eddsa_pub))
-    {
-      TALER_ARL_report (report_bad_sig_losses,
-                        GNUNET_JSON_PACK (
-                          GNUNET_JSON_pack_string ("operation",
-                                                   operation),
-                          GNUNET_JSON_pack_uint64 ("row",
-                                                   rowid),
-                          TALER_JSON_pack_amount ("loss",
-                                                  amount),
-                          GNUNET_JSON_pack_data_auto ("coin_pub",
-                                                      &coin->coin_pub)));
-      TALER_ARL_amount_add (&total_bad_sig_loss,
-                            &total_bad_sig_loss,
-                            amount);
-      if (TALER_ARL_do_abort ())
-        return GNUNET_SYSERR;
-      return GNUNET_OK;
-    }
+    TALER_ARL_report (report_bad_sig_losses,
+                      GNUNET_JSON_PACK (
+                        GNUNET_JSON_pack_string ("operation",
+                                                 operation),
+                        GNUNET_JSON_pack_uint64 ("row",
+                                                 rowid),
+                        TALER_JSON_pack_amount ("loss",
+                                                amount),
+                        GNUNET_JSON_pack_data_auto ("coin_pub",
+                                                    &coin->coin_pub)));
+    TALER_ARL_amount_add (&total_bad_sig_loss,
+                          &total_bad_sig_loss,
+                          amount);
+    if (TALER_ARL_do_abort ())
+      return GNUNET_SYSERR;
+    return GNUNET_OK;
   }
   ds = get_denomination_summary (cc,
                                  issue,
diff --git a/src/auditor/taler-helper-auditor-reserves.c 
b/src/auditor/taler-helper-auditor-reserves.c
index 2ce12020..b6b969fe 100644
--- a/src/auditor/taler-helper-auditor-reserves.c
+++ b/src/auditor/taler-helper-auditor-reserves.c
@@ -684,7 +684,7 @@ handle_reserve_out (void *cls,
  * @param coin_blind blinding factor used to blind the coin
  * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop
  */
-static int
+static enum GNUNET_GenericReturnValue
 handle_recoup_by_reserve (
   void *cls,
   uint64_t rowid,
@@ -711,35 +711,26 @@ handle_recoup_by_reserve (
   ppr.last_reserve_recoup_serial_id = rowid + 1;
   /* We know that denom_pub matches denom_pub_hash because this
      is how the SQL statement joined the tables. */
+  if (GNUNET_OK !=
+      TALER_wallet_recoup_verify (&coin->denom_pub_hash,
+                                  coin_blind,
+                                  amount,
+                                  &coin->coin_pub,
+                                  coin_sig))
   {
-    struct TALER_RecoupRequestPS pr = {
-      .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_RECOUP),
-      .purpose.size = htonl (sizeof (pr)),
-      .h_denom_pub = coin->denom_pub_hash,
-      .coin_pub = coin->coin_pub,
-      .coin_blind = *coin_blind
-    };
-
-    if (GNUNET_OK !=
-        GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_RECOUP,
-                                    &pr,
-                                    &coin_sig->eddsa_signature,
-                                    &coin->coin_pub.eddsa_pub))
-    {
-      TALER_ARL_report (report_bad_sig_losses,
-                        GNUNET_JSON_PACK (
-                          GNUNET_JSON_pack_string ("operation",
-                                                   "recoup"),
-                          GNUNET_JSON_pack_uint64 ("row",
-                                                   rowid),
-                          TALER_JSON_pack_amount ("loss",
-                                                  amount),
-                          GNUNET_JSON_pack_data_auto ("key_pub",
-                                                      &coin->coin_pub)));
-      TALER_ARL_amount_add (&total_bad_sig_loss,
-                            &total_bad_sig_loss,
-                            amount);
-    }
+    TALER_ARL_report (report_bad_sig_losses,
+                      GNUNET_JSON_PACK (
+                        GNUNET_JSON_pack_string ("operation",
+                                                 "recoup"),
+                        GNUNET_JSON_pack_uint64 ("row",
+                                                 rowid),
+                        TALER_JSON_pack_amount ("loss",
+                                                amount),
+                        GNUNET_JSON_pack_data_auto ("key_pub",
+                                                    &coin->coin_pub)));
+    TALER_ARL_amount_add (&total_bad_sig_loss,
+                          &total_bad_sig_loss,
+                          amount);
   }
 
   /* check that the coin was eligible for recoup!*/
diff --git a/src/exchange/taler-exchange-httpd_recoup.c 
b/src/exchange/taler-exchange-httpd_recoup.c
index ec67efc2..58495e53 100644
--- a/src/exchange/taler-exchange-httpd_recoup.c
+++ b/src/exchange/taler-exchange-httpd_recoup.c
@@ -87,6 +87,7 @@ struct RecoupContext
    * Set by #recoup_transaction() to the amount that will be paid back
    */
   struct TALER_Amount amount;
+  const struct TALER_Amount *requested_amount;
 
   /**
    * Set by #recoup_transaction to the timestamp when the recoup
@@ -234,6 +235,15 @@ recoup_transaction (void *cls,
   TEH_plugin->free_coin_transaction_list (TEH_plugin->cls,
                                           tl);
   pc->now = GNUNET_TIME_timestamp_get ();
+  if (0 != TALER_amount_cmp (&pc->amount,
+                             pc->requested_amount))
+  {
+    *mhd_ret = TALER_MHD_reply_with_error (connection,
+                                           MHD_HTTP_CONFLICT,
+                                           
TALER_EC_EXCHANGE_GENERIC_INSUFFICIENT_FUNDS,
+                                           TALER_amount2s (&pc->amount));
+    return GNUNET_DB_STATUS_HARD_ERROR;
+  }
 
   /* add coin to list of wire transfers for recoup */
   if (pc->refreshed)
@@ -284,6 +294,7 @@ recoup_transaction (void *cls,
  * @param coin information about the coin
  * @param coin_bks blinding data of the coin (to be checked)
  * @param coin_sig signature of the coin
+ * @param requested_amount requested amount to be recouped
  * @param refreshed true if the coin was refreshed
  * @return MHD result code
  */
@@ -293,6 +304,7 @@ verify_and_execute_recoup (
   const struct TALER_CoinPublicInfo *coin,
   const union TALER_DenominationBlindingKeyP *coin_bks,
   const struct TALER_CoinSpendSignatureP *coin_sig,
+  const struct TALER_Amount *requested_amount,
   bool refreshed)
 {
   struct RecoupContext pc;
@@ -352,27 +364,18 @@ verify_and_execute_recoup (
   }
 
   /* check recoup request signature */
+  if (GNUNET_OK !=
+      TALER_wallet_recoup_verify (&coin->denom_pub_hash,
+                                  coin_bks,
+                                  requested_amount,
+                                  &coin->coin_pub,
+                                  coin_sig))
   {
-    struct TALER_RecoupRequestPS pr = {
-      .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_RECOUP),
-      .purpose.size = htonl (sizeof (pr)),
-      .coin_pub = coin->coin_pub,
-      .h_denom_pub = coin->denom_pub_hash,
-      .coin_blind = *coin_bks
-    };
-
-    if (GNUNET_OK !=
-        GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_RECOUP,
-                                    &pr,
-                                    &coin_sig->eddsa_signature,
-                                    &coin->coin_pub.eddsa_pub))
-    {
-      TALER_LOG_WARNING ("Invalid signature on recoup request\n");
-      return TALER_MHD_reply_with_error (connection,
-                                         MHD_HTTP_FORBIDDEN,
-                                         
TALER_EC_EXCHANGE_RECOUP_SIGNATURE_INVALID,
-                                         NULL);
-    }
+    GNUNET_break_op (0);
+    return TALER_MHD_reply_with_error (connection,
+                                       MHD_HTTP_FORBIDDEN,
+                                       
TALER_EC_EXCHANGE_RECOUP_SIGNATURE_INVALID,
+                                       NULL);
   }
 
   {
@@ -404,6 +407,7 @@ verify_and_execute_recoup (
   pc.coin_bks = coin_bks;
   pc.coin = coin;
   pc.refreshed = refreshed;
+  pc.requested_amount = requested_amount;
 
   {
     MHD_RESULT mhd_ret = MHD_NO;
@@ -552,6 +556,7 @@ TEH_handler_recoup (struct MHD_Connection *connection,
                                      &coin,
                                      &coin_bks,
                                      &coin_sig,
+                                     &amount,
                                      refreshed);
     GNUNET_JSON_parse_free (spec);
     return res;
diff --git a/src/exchangedb/exchange-0001.sql b/src/exchangedb/exchange-0001.sql
index 1725b70e..a267fe13 100644
--- a/src/exchangedb/exchange-0001.sql
+++ b/src/exchangedb/exchange-0001.sql
@@ -697,8 +697,6 @@ CREATE INDEX IF NOT EXISTS revolving_work_shards_index
 -- Stored procedures
 
 
-DROP FUNCTION IF EXISTS 
exchange_do_withdraw(bigint,integer,bytea,bytea,bytea,bytea,bytea,bigint,bigint)
 ;
-
 CREATE OR REPLACE FUNCTION exchange_do_withdraw(
   IN amount_val INT8,
   IN amount_frac INT4,
@@ -857,9 +855,6 @@ COMMENT ON FUNCTION exchange_do_withdraw(INT8, INT4, BYTEA, 
BYTEA, BYTEA, BYTEA,
 
 
 
-DROP FUNCTION IF EXISTS 
exchange_do_withdraw_limit_check(bigint,bigint,bigint,int) ;
-
-
 CREATE OR REPLACE FUNCTION exchange_do_withdraw_limit_check(
   IN ruuid INT8,
   IN start_time INT8,
diff --git a/src/exchangedb/plugin_exchangedb_postgres.c 
b/src/exchangedb/plugin_exchangedb_postgres.c
index 23307bf8..99ebd7c7 100644
--- a/src/exchangedb/plugin_exchangedb_postgres.c
+++ b/src/exchangedb/plugin_exchangedb_postgres.c
@@ -3246,8 +3246,8 @@ postgres_get_denomination_info (
                                                  rs);
   if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs)
     return qs;
-  issue->properties.purpose.size = htonl (sizeof (struct
-                                                  
TALER_DenominationKeyValidityPS));
+  issue->properties.purpose.size
+    = htonl (sizeof (struct TALER_DenominationKeyValidityPS));
   issue->properties.purpose.purpose = htonl (
     TALER_SIGNATURE_MASTER_DENOMINATION_KEY_VALIDITY);
   issue->properties.denom_hash = *denom_pub_hash;
diff --git a/src/exchangedb/test_exchangedb.c b/src/exchangedb/test_exchangedb.c
index a8a9f3e1..65689d87 100644
--- a/src/exchangedb/test_exchangedb.c
+++ b/src/exchangedb/test_exchangedb.c
@@ -238,23 +238,26 @@ create_denom_key_pair (unsigned int size,
           sizeof (struct TALER_EXCHANGEDB_DenominationKey));
   dki.denom_pub = dkp->pub;
   dki.issue.properties.start = GNUNET_TIME_timestamp_hton (now);
-  dki.issue.properties.expire_withdraw = GNUNET_TIME_timestamp_hton
-                                           (GNUNET_TIME_absolute_to_timestamp
-                                             (GNUNET_TIME_absolute_add (
-                                               now.abs_time,
-                                               GNUNET_TIME_UNIT_HOURS)));
-  dki.issue.properties.expire_deposit = GNUNET_TIME_timestamp_hton (
-    GNUNET_TIME_absolute_to_timestamp
-      (GNUNET_TIME_absolute_add
-        (now.abs_time,
-        GNUNET_TIME_relative_multiply (
-          GNUNET_TIME_UNIT_HOURS, 2))));
-  dki.issue.properties.expire_legal = GNUNET_TIME_timestamp_hton (
-    GNUNET_TIME_absolute_to_timestamp
-      (GNUNET_TIME_absolute_add
-        (now.abs_time,
-        GNUNET_TIME_relative_multiply (
-          GNUNET_TIME_UNIT_HOURS, 3))));
+  dki.issue.properties.expire_withdraw
+    = GNUNET_TIME_timestamp_hton
+        (GNUNET_TIME_absolute_to_timestamp
+          (GNUNET_TIME_absolute_add (
+            now.abs_time,
+            GNUNET_TIME_UNIT_HOURS)));
+  dki.issue.properties.expire_deposit
+    = GNUNET_TIME_timestamp_hton (
+        GNUNET_TIME_absolute_to_timestamp
+          (GNUNET_TIME_absolute_add
+            (now.abs_time,
+            GNUNET_TIME_relative_multiply (
+              GNUNET_TIME_UNIT_HOURS, 2))));
+  dki.issue.properties.expire_legal
+    = GNUNET_TIME_timestamp_hton (
+        GNUNET_TIME_absolute_to_timestamp
+          (GNUNET_TIME_absolute_add
+            (now.abs_time,
+            GNUNET_TIME_relative_multiply (
+              GNUNET_TIME_UNIT_HOURS, 3))));
   TALER_amount_hton (&dki.issue.properties.value, value);
   TALER_amount_hton (&dki.issue.properties.fee_withdraw, fee_withdraw);
   TALER_amount_hton (&dki.issue.properties.fee_deposit, fee_deposit);
@@ -276,6 +279,8 @@ create_denom_key_pair (unsigned int size,
     destroy_denom_key_pair (dkp);
     return NULL;
   }
+  memset (&issue2, 0, sizeof (issue2));
+  plugin->commit (plugin->cls);
   if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
       plugin->get_denomination_info (plugin->cls,
                                      &dki.issue.properties.denom_hash,
diff --git a/src/include/taler_crypto_lib.h b/src/include/taler_crypto_lib.h
index 0a59ab9e..5292cd09 100644
--- a/src/include/taler_crypto_lib.h
+++ b/src/include/taler_crypto_lib.h
@@ -1738,6 +1738,63 @@ TALER_wallet_link_verify (
   const struct TALER_CoinSpendPublicKeyP *old_coin_pub,
   const struct TALER_CoinSpendSignatureP *coin_sig);
 
+
+/**
+ * Sign link data.
+ *
+ * @param h_denom_pub hash of the denomiantion public key of the new coin
+ * @param transfer_pub transfer public key
+ * @param coin_ev coin envelope
+ * @param coin_ev_size number of bytes in @a coin_ev
+ * @param old_coin_priv private key to sign with
+ * @param[out] coin_sig resulting signature
+ */
+void
+TALER_wallet_link_sign (const struct TALER_DenominationHash *h_denom_pub,
+                        const struct TALER_TransferPublicKeyP *transfer_pub,
+                        const void *coin_ev,
+                        size_t coin_ev_size,
+                        const struct TALER_CoinSpendPrivateKeyP *old_coin_priv,
+                        struct TALER_CoinSpendSignatureP *coin_sig);
+
+
+/**
+ * Verify recoup signature.
+ *
+ * @param h_denom_pub hash of the denomiantion public key of the coin
+ * @param coin_bks blinding factor used when withdrawing the coin
+ * @param requested_amount amount that is left to be recouped
+ * @param coin_pub coin key of the coin to be recouped
+ * @param coin_sig resulting signature
+ * @return #GNUNET_OK if the signature is valid
+ */
+enum GNUNET_GenericReturnValue
+TALER_wallet_recoup_verify (
+  const struct TALER_DenominationHash *h_denom_pub,
+  const union TALER_DenominationBlindingKeyP *coin_bks,
+  const struct TALER_Amount *requested_amount,
+  const struct TALER_CoinSpendPublicKeyP *coin_pub,
+  const struct TALER_CoinSpendSignatureP *coin_sig);
+
+
+/**
+ * Create recoup signature.
+ *
+ * @param h_denom_pub hash of the denomiantion public key of the coin
+ * @param coin_bks blinding factor used when withdrawing the coin
+ * @param requested_amount amount that is left to be recouped
+ * @param coin_priv coin key of the coin to be recouped
+ * @param coin_sig resulting signature
+ */
+void
+TALER_wallet_recoup_sign (
+  const struct TALER_DenominationHash *h_denom_pub,
+  const union TALER_DenominationBlindingKeyP *coin_bks,
+  const struct TALER_Amount *requested_amount,
+  const struct TALER_CoinSpendPrivateKeyP *coin_priv,
+  struct TALER_CoinSpendSignatureP *coin_sig);
+
+
 /* ********************* offline signing ************************** */
 
 
diff --git a/src/include/taler_signatures.h b/src/include/taler_signatures.h
index 87a004e3..643aa80d 100644
--- a/src/include/taler_signatures.h
+++ b/src/include/taler_signatures.h
@@ -1496,11 +1496,6 @@ struct TALER_RecoupRequestPS
    */
   struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
 
-  /**
-   * Public key of the coin to be refunded.
-   */
-  struct TALER_CoinSpendPublicKeyP coin_pub;
-
   /**
    * Hash of the (revoked) denomination public key of the coin.
    */
@@ -1510,6 +1505,12 @@ struct TALER_RecoupRequestPS
    * Blinding factor that was used to withdraw the coin.
    */
   union TALER_DenominationBlindingKeyP coin_blind;
+
+  /**
+   * How much of the coin's value will be recouped?
+   */
+  struct TALER_AmountNBO recoup_amount;
+
 };
 
 
diff --git a/src/lib/exchange_api_common.c b/src/lib/exchange_api_common.c
index b14714ac..93b992e6 100644
--- a/src/lib/exchange_api_common.c
+++ b/src/lib/exchange_api_common.c
@@ -688,17 +688,16 @@ TALER_EXCHANGE_verify_coin_history (
         .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP),
         .coin_pub = *coin_pub
       };
-      struct TALER_RecoupRequestPS rr = {
-        .purpose.size = htonl (sizeof (pc)),
-        .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_RECOUP),
-        .coin_pub = *coin_pub
-      };
+      union TALER_DenominationBlindingKeyP coin_bks;
+      struct TALER_Amount recoup_amount;
       struct TALER_ExchangePublicKeyP exchange_pub;
       struct TALER_ExchangeSignatureP exchange_sig;
       struct TALER_CoinSpendSignatureP coin_sig;
       struct GNUNET_JSON_Specification spec[] = {
         TALER_JSON_spec_amount_any_nbo ("amount",
                                         &pc.recoup_amount),
+        TALER_JSON_spec_amount_any ("amount",
+                                    &recoup_amount),
         GNUNET_JSON_spec_fixed_auto ("exchange_sig",
                                      &exchange_sig),
         GNUNET_JSON_spec_fixed_auto ("exchange_pub",
@@ -708,9 +707,9 @@ TALER_EXCHANGE_verify_coin_history (
         GNUNET_JSON_spec_fixed_auto ("coin_sig",
                                      &coin_sig),
         GNUNET_JSON_spec_fixed_auto ("coin_blind",
-                                     &rr.coin_blind),
+                                     &coin_bks),
         GNUNET_JSON_spec_fixed_auto ("h_denom_pub",
-                                     &rr.h_denom_pub),
+                                     h_denom_pub),
         GNUNET_JSON_spec_timestamp_nbo ("timestamp",
                                         &pc.timestamp),
         GNUNET_JSON_spec_end ()
@@ -736,15 +735,15 @@ TALER_EXCHANGE_verify_coin_history (
         return GNUNET_SYSERR;
       }
       if (GNUNET_OK !=
-          GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_RECOUP,
-                                      &rr,
-                                      &coin_sig.eddsa_signature,
-                                      &coin_pub->eddsa_pub))
+          TALER_wallet_recoup_verify (h_denom_pub,
+                                      &coin_bks,
+                                      &recoup_amount,
+                                      coin_pub,
+                                      &coin_sig))
       {
         GNUNET_break_op (0);
         return GNUNET_SYSERR;
       }
-      *h_denom_pub = rr.h_denom_pub;
       add = GNUNET_YES;
     }
     else if (0 == strcasecmp (type,
@@ -758,17 +757,16 @@ TALER_EXCHANGE_verify_coin_history (
           TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_REFRESH),
         .coin_pub = *coin_pub
       };
-      struct TALER_RecoupRequestPS rr = {
-        .purpose.size = htonl (sizeof (pc)),
-        .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_RECOUP),
-        .coin_pub = *coin_pub
-      };
+      union TALER_DenominationBlindingKeyP coin_bks;
+      struct TALER_Amount recoup_amount;
       struct TALER_ExchangePublicKeyP exchange_pub;
       struct TALER_ExchangeSignatureP exchange_sig;
       struct TALER_CoinSpendSignatureP coin_sig;
       struct GNUNET_JSON_Specification spec[] = {
         TALER_JSON_spec_amount_any_nbo ("amount",
                                         &pc.recoup_amount),
+        TALER_JSON_spec_amount_any ("amount",
+                                    &recoup_amount),
         GNUNET_JSON_spec_fixed_auto ("exchange_sig",
                                      &exchange_sig),
         GNUNET_JSON_spec_fixed_auto ("exchange_pub",
@@ -778,9 +776,9 @@ TALER_EXCHANGE_verify_coin_history (
         GNUNET_JSON_spec_fixed_auto ("old_coin_pub",
                                      &pc.old_coin_pub),
         GNUNET_JSON_spec_fixed_auto ("coin_blind",
-                                     &rr.coin_blind),
+                                     &coin_bks),
         GNUNET_JSON_spec_fixed_auto ("h_denom_pub",
-                                     &rr.h_denom_pub),
+                                     h_denom_pub),
         GNUNET_JSON_spec_timestamp_nbo ("timestamp",
                                         &pc.timestamp),
         GNUNET_JSON_spec_end ()
@@ -807,15 +805,15 @@ TALER_EXCHANGE_verify_coin_history (
         return GNUNET_SYSERR;
       }
       if (GNUNET_OK !=
-          GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_RECOUP,
-                                      &rr,
-                                      &coin_sig.eddsa_signature,
-                                      &coin_pub->eddsa_pub))
+          TALER_wallet_recoup_verify (h_denom_pub,
+                                      &coin_bks,
+                                      &recoup_amount,
+                                      coin_pub,
+                                      &coin_sig))
       {
         GNUNET_break_op (0);
         return GNUNET_SYSERR;
       }
-      *h_denom_pub = rr.h_denom_pub;
       add = GNUNET_YES;
     }
     else if (0 == strcasecmp (type,
diff --git a/src/lib/exchange_api_recoup.c b/src/lib/exchange_api_recoup.c
index 92b59f4b..05012926 100644
--- a/src/lib/exchange_api_recoup.c
+++ b/src/lib/exchange_api_recoup.c
@@ -95,7 +95,7 @@ struct TALER_EXCHANGE_RecoupHandle
  * @return #GNUNET_OK if the signature is valid and we called the callback;
  *         #GNUNET_SYSERR if not (callback must still be called)
  */
-static int
+static enum GNUNET_GenericReturnValue
 process_recoup_response (const struct TALER_EXCHANGE_RecoupHandle *ph,
                          const json_t *json)
 {
@@ -312,8 +312,8 @@ TALER_EXCHANGE_recoup (struct TALER_EXCHANGE_Handle 
*exchange,
 {
   struct TALER_EXCHANGE_RecoupHandle *ph;
   struct GNUNET_CURL_Context *ctx;
-  struct TALER_RecoupRequestPS pr;
   struct TALER_CoinSpendSignatureP coin_sig;
+  struct TALER_CoinSpendPublicKeyP coin_pub;
   struct TALER_DenominationHash h_denom_pub;
   json_t *recoup_obj;
   CURL *eh;
@@ -321,17 +321,15 @@ TALER_EXCHANGE_recoup (struct TALER_EXCHANGE_Handle 
*exchange,
 
   GNUNET_assert (GNUNET_YES ==
                  TEAH_handle_is_ready (exchange));
-  pr.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_RECOUP);
-  pr.purpose.size = htonl (sizeof (struct TALER_RecoupRequestPS));
   GNUNET_CRYPTO_eddsa_key_get_public (&ps->coin_priv.eddsa_priv,
-                                      &pr.coin_pub.eddsa_pub);
+                                      &coin_pub.eddsa_pub);
   TALER_denom_pub_hash (&pk->key,
                         &h_denom_pub);
-  pr.h_denom_pub = pk->h_key;
-  pr.coin_blind = ps->blinding_key;
-  GNUNET_CRYPTO_eddsa_sign (&ps->coin_priv.eddsa_priv,
-                            &pr,
-                            &coin_sig.eddsa_signature);
+  TALER_wallet_recoup_sign (&h_denom_pub,
+                            &ps->blinding_key,
+                            amount,
+                            &ps->coin_priv,
+                            &coin_sig);
   recoup_obj = GNUNET_JSON_PACK (
     GNUNET_JSON_pack_data_auto ("denom_pub_hash",
                                 &h_denom_pub),
@@ -349,11 +347,11 @@ TALER_EXCHANGE_recoup (struct TALER_EXCHANGE_Handle 
*exchange,
     char pub_str[sizeof (struct TALER_CoinSpendPublicKeyP) * 2];
     char *end;
 
-    end = GNUNET_STRINGS_data_to_string (&pr.coin_pub,
-                                         sizeof (struct
-                                                 TALER_CoinSpendPublicKeyP),
-                                         pub_str,
-                                         sizeof (pub_str));
+    end = GNUNET_STRINGS_data_to_string (
+      &coin_pub,
+      sizeof (struct TALER_CoinSpendPublicKeyP),
+      pub_str,
+      sizeof (pub_str));
     *end = '\0';
     GNUNET_snprintf (arg_str,
                      sizeof (arg_str),
@@ -362,7 +360,7 @@ TALER_EXCHANGE_recoup (struct TALER_EXCHANGE_Handle 
*exchange,
   }
 
   ph = GNUNET_new (struct TALER_EXCHANGE_RecoupHandle);
-  ph->coin_pub = pr.coin_pub;
+  ph->coin_pub = coin_pub;
   ph->exchange = exchange;
   ph->pk = *pk;
   memset (&ph->pk.key,
diff --git a/src/testing/test_exchange_api.c b/src/testing/test_exchange_api.c
index 3e1df384..6dced3e3 100644
--- a/src/testing/test_exchange_api.c
+++ b/src/testing/test_exchange_api.c
@@ -855,7 +855,7 @@ run (void *cls,
                               MHD_HTTP_OK,
                               "recoup-withdraw-coin-2a",
                               NULL,
-                              NULL),
+                              "EUR:0.5"),
     TALER_TESTING_cmd_deposit ("recoup-deposit-revoked",
                                "recoup-withdraw-coin-2b",
                                0,
diff --git a/src/testing/test_exchange_api_revocation.c 
b/src/testing/test_exchange_api_revocation.c
index 9b66e20b..1a334a71 100644
--- a/src/testing/test_exchange_api_revocation.c
+++ b/src/testing/test_exchange_api_revocation.c
@@ -139,7 +139,7 @@ run (void *cls,
                               MHD_HTTP_GONE,
                               "refresh-reveal-1#0",
                               "refresh-melt-1",
-                              NULL),
+                              "EUR:0.1"),
     /* Make refreshed coin invalid */
     TALER_TESTING_cmd_revoke ("revoke-2-EUR:5",
                               MHD_HTTP_OK,
@@ -155,44 +155,44 @@ run (void *cls,
                               MHD_HTTP_CONFLICT,
                               "withdraw-revocation-coin-2",
                               NULL,
-                              NULL),
+                              "EUR:0.1"),
     /* Refund coin to original coin */
     TALER_TESTING_cmd_recoup ("recoup-1a",
                               MHD_HTTP_OK,
                               "refresh-reveal-1#0",
                               "refresh-melt-1",
-                              NULL),
+                              "EUR:1"),
     TALER_TESTING_cmd_recoup ("recoup-1b",
                               MHD_HTTP_OK,
                               "refresh-reveal-1#1",
                               "refresh-melt-1",
-                              NULL),
+                              "EUR:1"),
     TALER_TESTING_cmd_recoup ("recoup-1c",
                               MHD_HTTP_OK,
                               "refresh-reveal-1#2",
                               "refresh-melt-1",
-                              NULL),
+                              "EUR:1"),
     /* Repeat recoup to test idempotency */
     TALER_TESTING_cmd_recoup ("recoup-1c",
                               MHD_HTTP_OK,
                               "refresh-reveal-1#2",
                               "refresh-melt-1",
-                              NULL),
+                              "EUR:1"),
     TALER_TESTING_cmd_recoup ("recoup-1c",
                               MHD_HTTP_OK,
                               "refresh-reveal-1#2",
                               "refresh-melt-1",
-                              NULL),
+                              "EUR:1"),
     TALER_TESTING_cmd_recoup ("recoup-1c",
                               MHD_HTTP_OK,
                               "refresh-reveal-1#2",
                               "refresh-melt-1",
-                              NULL),
+                              "EUR:1"),
     TALER_TESTING_cmd_recoup ("recoup-1c",
                               MHD_HTTP_OK,
                               "refresh-reveal-1#2",
                               "refresh-melt-1",
-                              NULL),
+                              "EUR:1"),
     /* Now we have EUR:3.83 EUR back after 3x EUR:1 in recoups */
     /* Melt original coin AGAIN, but only create one 0.1 EUR coin;
        This costs EUR:0.03 in refresh and EUR:01 in withdraw fees,
@@ -223,7 +223,7 @@ run (void *cls,
                               MHD_HTTP_OK,
                               "refresh-reveal-2",
                               "refresh-melt-2",
-                              NULL),
+                              "EUR:0.1"),
     /* Due to recoup, original coin is now at EUR:3.79 */
     /* Refund original (now zombie) coin to reserve */
     TALER_TESTING_cmd_recoup ("recoup-3",
diff --git a/src/util/wallet_signatures.c b/src/util/wallet_signatures.c
index b895de14..81ce9cc5 100644
--- a/src/util/wallet_signatures.c
+++ b/src/util/wallet_signatures.c
@@ -155,4 +155,51 @@ TALER_wallet_link_verify (
 }
 
 
+enum GNUNET_GenericReturnValue
+TALER_wallet_recoup_verify (
+  const struct TALER_DenominationHash *h_denom_pub,
+  const union TALER_DenominationBlindingKeyP *coin_bks,
+  const struct TALER_Amount *requested_amount,
+  const struct TALER_CoinSpendPublicKeyP *coin_pub,
+  const struct TALER_CoinSpendSignatureP *coin_sig)
+{
+  struct TALER_RecoupRequestPS pr = {
+    .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_RECOUP),
+    .purpose.size = htonl (sizeof (pr)),
+    .h_denom_pub = *h_denom_pub,
+    .coin_blind = *coin_bks
+  };
+
+  TALER_amount_hton (&pr.recoup_amount,
+                     requested_amount);
+  return GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_RECOUP,
+                                     &pr,
+                                     &coin_sig->eddsa_signature,
+                                     &coin_pub->eddsa_pub);
+}
+
+
+void
+TALER_wallet_recoup_sign (
+  const struct TALER_DenominationHash *h_denom_pub,
+  const union TALER_DenominationBlindingKeyP *coin_bks,
+  const struct TALER_Amount *requested_amount,
+  const struct TALER_CoinSpendPrivateKeyP *coin_priv,
+  struct TALER_CoinSpendSignatureP *coin_sig)
+{
+  struct TALER_RecoupRequestPS pr = {
+    .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_RECOUP),
+    .purpose.size = htonl (sizeof (struct TALER_RecoupRequestPS)),
+    .h_denom_pub = *h_denom_pub,
+    .coin_blind = *coin_bks
+  };
+
+  TALER_amount_hton (&pr.recoup_amount,
+                     requested_amount);
+  GNUNET_CRYPTO_eddsa_sign (&coin_priv->eddsa_priv,
+                            &pr,
+                            &coin_sig->eddsa_signature);
+}
+
+
 /* end of wallet_signatures.c */

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



reply via email to

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