gnunet-svn
[Top][All Lists]
Advanced

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

[taler-exchange] branch master updated (7378b5a0 -> bf2cdc7e)


From: gnunet
Subject: [taler-exchange] branch master updated (7378b5a0 -> bf2cdc7e)
Date: Fri, 17 Jan 2020 19:03:38 +0100

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

grothoff pushed a change to branch master
in repository exchange.

    from 7378b5a0 amount rounding a la Christian
     new 33d71e72 clean up KS keystate logic
     new bf2cdc7e comment out fixme

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 src/exchange/taler-exchange-httpd_deposit.c      | 136 +++++-----
 src/exchange/taler-exchange-httpd_keystate.c     |   7 +-
 src/exchange/taler-exchange-httpd_payback.c      | 149 +++++-----
 src/exchange/taler-exchange-httpd_refresh_melt.c | 331 +++++++++++------------
 4 files changed, 314 insertions(+), 309 deletions(-)

diff --git a/src/exchange/taler-exchange-httpd_deposit.c 
b/src/exchange/taler-exchange-httpd_deposit.c
index 38cc4307..0e4e0b26 100644
--- a/src/exchange/taler-exchange-httpd_deposit.c
+++ b/src/exchange/taler-exchange-httpd_deposit.c
@@ -256,7 +256,6 @@ verify_and_execute_deposit (struct MHD_Connection 
*connection,
   int mhd_ret;
   struct TALER_Amount amount_without_fee;
   struct DepositContext dc;
-  struct TEH_KS_StateHandle *mks;
   const struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki;
   enum TALER_ErrorCode ec;
   unsigned int hc;
@@ -288,32 +287,35 @@ verify_and_execute_deposit (struct MHD_Connection 
*connection,
   }
 
   /* check denomination */
-  mks = TEH_KS_acquire (GNUNET_TIME_absolute_get ());
-  if (NULL == mks)
-  {
-    TALER_LOG_ERROR ("Lacking keys to operate\n");
-    return TALER_MHD_reply_with_error (connection,
-                                       MHD_HTTP_INTERNAL_SERVER_ERROR,
-                                       TALER_EC_EXCHANGE_BAD_CONFIGURATION,
-                                       "no keys");
-  }
-  dki = TEH_KS_denomination_key_lookup_by_hash (mks,
-                                                &deposit->coin.denom_pub_hash,
-                                                TEH_KS_DKU_DEPOSIT,
-                                                &ec,
-                                                &hc);
-  if (NULL == dki)
   {
+    struct TEH_KS_StateHandle *mks;
+
+    mks = TEH_KS_acquire (GNUNET_TIME_absolute_get ());
+    if (NULL == mks)
+    {
+      TALER_LOG_ERROR ("Lacking keys to operate\n");
+      return TALER_MHD_reply_with_error (connection,
+                                         MHD_HTTP_INTERNAL_SERVER_ERROR,
+                                         TALER_EC_EXCHANGE_BAD_CONFIGURATION,
+                                         "no keys");
+    }
+    dki = TEH_KS_denomination_key_lookup_by_hash (mks,
+                                                  
&deposit->coin.denom_pub_hash,
+                                                  TEH_KS_DKU_DEPOSIT,
+                                                  &ec,
+                                                  &hc);
+    if (NULL == dki)
+    {
+      TEH_KS_release (mks);
+      return TALER_MHD_reply_with_error (connection,
+                                         hc,
+                                         ec,
+                                         "Could not find denomination key used 
in deposit");
+    }
+    TALER_amount_ntoh (&dc.value,
+                       &dki->issue.properties.value);
     TEH_KS_release (mks);
-    return TALER_MHD_reply_with_error (connection,
-                                       hc,
-                                       ec,
-                                       "Could not find denomination key used 
in deposit");
   }
-  TALER_amount_ntoh (&dc.value,
-                     &dki->issue.properties.value);
-  TEH_KS_release (mks);
-
   /* execute transaction */
   dc.deposit = deposit;
   if (GNUNET_OK !=
@@ -406,7 +408,6 @@ TEH_DEPOSIT_handler_deposit (struct TEH_RequestHandler *rh,
   unsigned int hc;
   struct TALER_EXCHANGEDB_Deposit deposit;
   struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki;
-  struct TEH_KS_StateHandle *key_state;
   struct GNUNET_HashCode my_h_wire;
   struct GNUNET_JSON_Specification spec[] = {
     GNUNET_JSON_spec_json ("wire", &wire),
@@ -503,50 +504,53 @@ TEH_DEPOSIT_handler_deposit (struct TEH_RequestHandler 
*rh,
   }
 
   /* check denomination exists and is valid */
-  key_state = TEH_KS_acquire (GNUNET_TIME_absolute_get ());
-  if (NULL == key_state)
-  {
-    TALER_LOG_ERROR ("Lacking keys to operate\n");
-    GNUNET_JSON_parse_free (spec);
-    return TALER_MHD_reply_with_error (connection,
-                                       MHD_HTTP_INTERNAL_SERVER_ERROR,
-                                       TALER_EC_EXCHANGE_BAD_CONFIGURATION,
-                                       "no keys");
-  }
-  dki = TEH_KS_denomination_key_lookup_by_hash (key_state,
-                                                &deposit.coin.denom_pub_hash,
-                                                TEH_KS_DKU_DEPOSIT,
-                                                &ec,
-                                                &hc);
-  if (NULL == dki)
   {
+    struct TEH_KS_StateHandle *key_state;
+
+    key_state = TEH_KS_acquire (GNUNET_TIME_absolute_get ());
+    if (NULL == key_state)
+    {
+      TALER_LOG_ERROR ("Lacking keys to operate\n");
+      GNUNET_JSON_parse_free (spec);
+      return TALER_MHD_reply_with_error (connection,
+                                         MHD_HTTP_INTERNAL_SERVER_ERROR,
+                                         TALER_EC_EXCHANGE_BAD_CONFIGURATION,
+                                         "no keys");
+    }
+    dki = TEH_KS_denomination_key_lookup_by_hash (key_state,
+                                                  &deposit.coin.denom_pub_hash,
+                                                  TEH_KS_DKU_DEPOSIT,
+                                                  &ec,
+                                                  &hc);
+    if (NULL == dki)
+    {
+      TEH_KS_release (key_state);
+      TALER_LOG_WARNING ("Unknown denomination key in /deposit request\n");
+      GNUNET_JSON_parse_free (spec);
+      return TALER_MHD_reply_with_error (connection,
+                                         hc,
+                                         ec,
+                                         "Could not find denomination key used 
in deposit");
+    }
+    TALER_amount_ntoh (&deposit.deposit_fee,
+                       &dki->issue.properties.fee_deposit);
+    /* check coin signature */
+    if (GNUNET_YES !=
+        TALER_test_coin_valid (&deposit.coin,
+                               &dki->denom_pub))
+    {
+      TALER_LOG_WARNING ("Invalid coin passed for /deposit\n");
+      TEH_KS_release (key_state);
+      GNUNET_JSON_parse_free (spec);
+      return TALER_MHD_reply_with_error (connection,
+                                         MHD_HTTP_UNAUTHORIZED,
+                                         
TALER_EC_DEPOSIT_DENOMINATION_SIGNATURE_INVALID,
+                                         "ub_sig");
+    }
+    TALER_amount_ntoh (&deposit.deposit_fee,
+                       &dki->issue.properties.fee_deposit);
     TEH_KS_release (key_state);
-    TALER_LOG_WARNING ("Unknown denomination key in /deposit request\n");
-    GNUNET_JSON_parse_free (spec);
-    return TALER_MHD_reply_with_error (connection,
-                                       hc,
-                                       ec,
-                                       "Could not find denomination key used 
in deposit");
-  }
-  TALER_amount_ntoh (&deposit.deposit_fee,
-                     &dki->issue.properties.fee_deposit);
-  /* check coin signature */
-  if (GNUNET_YES !=
-      TALER_test_coin_valid (&deposit.coin,
-                             &dki->denom_pub))
-  {
-    TALER_LOG_WARNING ("Invalid coin passed for /deposit\n");
-    TEH_KS_release (key_state);
-    GNUNET_JSON_parse_free (spec);
-    return TALER_MHD_reply_with_error (connection,
-                                       MHD_HTTP_UNAUTHORIZED,
-                                       
TALER_EC_DEPOSIT_DENOMINATION_SIGNATURE_INVALID,
-                                       "ub_sig");
   }
-  TALER_amount_ntoh (&deposit.deposit_fee,
-                     &dki->issue.properties.fee_deposit);
-  TEH_KS_release (key_state);
-
   if (0 < TALER_amount_cmp (&deposit.deposit_fee,
                             &deposit.amount_with_fee))
   {
diff --git a/src/exchange/taler-exchange-httpd_keystate.c 
b/src/exchange/taler-exchange-httpd_keystate.c
index 8b40144d..b9de15b2 100644
--- a/src/exchange/taler-exchange-httpd_keystate.c
+++ b/src/exchange/taler-exchange-httpd_keystate.c
@@ -448,6 +448,7 @@ ks_release (struct TEH_KS_StateHandle *key_state)
   key_state->refcnt--;
   if (0 == key_state->refcnt)
   {
+    GNUNET_assert (key_state != internal_key_state);
     if (NULL != key_state->denomkey_map)
     {
       GNUNET_CONTAINER_multihashmap_iterate (key_state->denomkey_map,
@@ -476,7 +477,6 @@ ks_release (struct TEH_KS_StateHandle *key_state)
     GNUNET_array_grow (key_state->krd_array,
                        key_state->krd_array_length,
                        0);
-    GNUNET_assert (key_state != internal_key_state);
     GNUNET_free (key_state);
   }
 }
@@ -1261,11 +1261,12 @@ setup_general_response_headers (const struct 
TEH_KS_StateHandle *key_state,
     m = GNUNET_TIME_relative_to_absolute (TEH_max_keys_caching);
     m = GNUNET_TIME_absolute_min (m,
                                   key_state->next_reload);
-    get_date_string (m,
-                     dat);
     // FIXME: setting 'm' to FOREVER here exposes
     // a crash-bug in lib/ where we access /keys
     // data after it was already free'd!
+    // m = GNUNET_TIME_UNIT_FOREVER_ABS;
+    get_date_string (m,
+                     dat);
     GNUNET_break (MHD_YES ==
                   MHD_add_response_header (response,
                                            MHD_HTTP_HEADER_EXPIRES,
diff --git a/src/exchange/taler-exchange-httpd_payback.c 
b/src/exchange/taler-exchange-httpd_payback.c
index bfd0f413..1a6a67d5 100644
--- a/src/exchange/taler-exchange-httpd_payback.c
+++ b/src/exchange/taler-exchange-httpd_payback.c
@@ -420,7 +420,6 @@ verify_and_execute_payback (struct MHD_Connection 
*connection,
                             int refreshed)
 {
   struct PaybackContext pc;
-  struct TEH_KS_StateHandle *key_state;
   const struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki;
   struct TALER_PaybackRequestPS pr;
   struct GNUNET_HashCode c_hash;
@@ -430,86 +429,88 @@ verify_and_execute_payback (struct MHD_Connection 
*connection,
   unsigned int hc;
 
   /* check denomination exists and is in payback mode */
-  key_state = TEH_KS_acquire (GNUNET_TIME_absolute_get ());
-  if (NULL == key_state)
   {
-    TALER_LOG_ERROR ("Lacking keys to operate\n");
-    return TALER_MHD_reply_with_error (connection,
-                                       MHD_HTTP_INTERNAL_SERVER_ERROR,
-                                       TALER_EC_EXCHANGE_BAD_CONFIGURATION,
-                                       "no keys");
-  }
-  dki = TEH_KS_denomination_key_lookup_by_hash (key_state,
-                                                &coin->denom_pub_hash,
-                                                TEH_KS_DKU_PAYBACK,
-                                                &ec,
-                                                &hc);
-  if (NULL == dki)
-  {
-    TEH_KS_release (key_state);
-    TALER_LOG_WARNING (
-      "Denomination key in /payback request not in payback mode\n");
-    return TALER_MHD_reply_with_error (connection,
-                                       hc,
-                                       ec,
-                                       "denomination not allowing payback");
-  }
-  TALER_amount_ntoh (&pc.value,
-                     &dki->issue.properties.value);
+    struct TEH_KS_StateHandle *key_state;
 
-  /* check denomination signature */
-  if (GNUNET_YES !=
-      TALER_test_coin_valid (coin,
-                             &dki->denom_pub))
-  {
-    TALER_LOG_WARNING ("Invalid coin passed for /payback\n");
-    TEH_KS_release (key_state);
-    return TALER_MHD_reply_with_error (connection,
-                                       MHD_HTTP_FORBIDDEN,
-                                       
TALER_EC_PAYBACK_DENOMINATION_SIGNATURE_INVALID,
-                                       "denom_sig");
-  }
+    key_state = TEH_KS_acquire (GNUNET_TIME_absolute_get ());
+    if (NULL == key_state)
+    {
+      TALER_LOG_ERROR ("Lacking keys to operate\n");
+      return TALER_MHD_reply_with_error (connection,
+                                         MHD_HTTP_INTERNAL_SERVER_ERROR,
+                                         TALER_EC_EXCHANGE_BAD_CONFIGURATION,
+                                         "no keys");
+    }
+    dki = TEH_KS_denomination_key_lookup_by_hash (key_state,
+                                                  &coin->denom_pub_hash,
+                                                  TEH_KS_DKU_PAYBACK,
+                                                  &ec,
+                                                  &hc);
+    if (NULL == dki)
+    {
+      TEH_KS_release (key_state);
+      TALER_LOG_WARNING (
+        "Denomination key in /payback request not in payback mode\n");
+      return TALER_MHD_reply_with_error (connection,
+                                         hc,
+                                         ec,
+                                         "denomination not allowing payback");
+    }
+    TALER_amount_ntoh (&pc.value,
+                       &dki->issue.properties.value);
 
-  /* check payback request signature */
-  pr.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_PAYBACK);
-  pr.purpose.size = htonl (sizeof (struct TALER_PaybackRequestPS));
-  pr.coin_pub = coin->coin_pub;
-  pr.h_denom_pub = dki->issue.properties.denom_hash;
-  pr.coin_blind = *coin_bks;
+    /* check denomination signature */
+    if (GNUNET_YES !=
+        TALER_test_coin_valid (coin,
+                               &dki->denom_pub))
+    {
+      TALER_LOG_WARNING ("Invalid coin passed for /payback\n");
+      TEH_KS_release (key_state);
+      return TALER_MHD_reply_with_error (connection,
+                                         MHD_HTTP_FORBIDDEN,
+                                         
TALER_EC_PAYBACK_DENOMINATION_SIGNATURE_INVALID,
+                                         "denom_sig");
+    }
 
-  if (GNUNET_OK !=
-      GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_PAYBACK,
-                                  &pr.purpose,
-                                  &coin_sig->eddsa_signature,
-                                  &coin->coin_pub.eddsa_pub))
-  {
-    TALER_LOG_WARNING ("Invalid signature on /payback request\n");
-    TEH_KS_release (key_state);
-    return TALER_MHD_reply_with_error (connection,
-                                       MHD_HTTP_FORBIDDEN,
-                                       TALER_EC_PAYBACK_SIGNATURE_INVALID,
-                                       "coin_sig");
-  }
+    /* check payback request signature */
+    pr.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_PAYBACK);
+    pr.purpose.size = htonl (sizeof (struct TALER_PaybackRequestPS));
+    pr.coin_pub = coin->coin_pub;
+    pr.h_denom_pub = dki->issue.properties.denom_hash;
+    pr.coin_blind = *coin_bks;
 
-  GNUNET_CRYPTO_hash (&coin->coin_pub.eddsa_pub,
-                      sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey),
-                      &c_hash);
-  if (GNUNET_YES !=
-      GNUNET_CRYPTO_rsa_blind (&c_hash,
-                               &coin_bks->bks,
-                               dki->denom_pub.rsa_public_key,
-                               &coin_ev,
-                               &coin_ev_size))
-  {
-    GNUNET_break (0);
+    if (GNUNET_OK !=
+        GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_PAYBACK,
+                                    &pr.purpose,
+                                    &coin_sig->eddsa_signature,
+                                    &coin->coin_pub.eddsa_pub))
+    {
+      TALER_LOG_WARNING ("Invalid signature on /payback request\n");
+      TEH_KS_release (key_state);
+      return TALER_MHD_reply_with_error (connection,
+                                         MHD_HTTP_FORBIDDEN,
+                                         TALER_EC_PAYBACK_SIGNATURE_INVALID,
+                                         "coin_sig");
+    }
+    GNUNET_CRYPTO_hash (&coin->coin_pub.eddsa_pub,
+                        sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey),
+                        &c_hash);
+    if (GNUNET_YES !=
+        GNUNET_CRYPTO_rsa_blind (&c_hash,
+                                 &coin_bks->bks,
+                                 dki->denom_pub.rsa_public_key,
+                                 &coin_ev,
+                                 &coin_ev_size))
+    {
+      GNUNET_break (0);
+      TEH_KS_release (key_state);
+      return TALER_MHD_reply_with_error (connection,
+                                         MHD_HTTP_INTERNAL_SERVER_ERROR,
+                                         TALER_EC_PAYBACK_BLINDING_FAILED,
+                                         "coin_bks");
+    }
     TEH_KS_release (key_state);
-
-    return TALER_MHD_reply_with_error (connection,
-                                       MHD_HTTP_INTERNAL_SERVER_ERROR,
-                                       TALER_EC_PAYBACK_BLINDING_FAILED,
-                                       "coin_bks");
   }
-  TEH_KS_release (key_state);
   GNUNET_CRYPTO_hash (coin_ev,
                       coin_ev_size,
                       &pc.h_blind);
diff --git a/src/exchange/taler-exchange-httpd_refresh_melt.c 
b/src/exchange/taler-exchange-httpd_refresh_melt.c
index e0a4d836..e2d92c50 100644
--- a/src/exchange/taler-exchange-httpd_refresh_melt.c
+++ b/src/exchange/taler-exchange-httpd_refresh_melt.c
@@ -51,7 +51,7 @@ static int
 reply_refresh_melt_insufficient_funds (struct MHD_Connection *connection,
                                        const struct
                                        TALER_CoinSpendPublicKeyP *coin_pub,
-                                       struct TALER_Amount coin_value,
+                                       const struct TALER_Amount *coin_value,
                                        struct TALER_EXCHANGEDB_TransactionList 
*
                                        tl,
                                        const struct TALER_Amount *requested,
@@ -77,7 +77,7 @@ reply_refresh_melt_insufficient_funds (struct MHD_Connection 
*connection,
                                     "coin_pub",
                                     GNUNET_JSON_from_data_auto (coin_pub),
                                     "original_value",
-                                    TALER_JSON_from_amount (&coin_value),
+                                    TALER_JSON_from_amount (coin_value),
                                     "residual_value",
                                     TALER_JSON_from_amount (residual),
                                     "requested_value",
@@ -144,12 +144,17 @@ struct RefreshMeltContext
   struct TALER_EXCHANGEDB_RefreshSession refresh_session;
 
   /**
-   * Information about the @e coin's denomination.
+   * Information about the @e coin's value.
    */
-  struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki;
+  struct TALER_Amount coin_value;
 
   /**
-   * Set to #GNUNET_YES if this @a dki was revoked and the operation
+   * Information about the @e coin's refresh fee.
+   */
+  struct TALER_Amount coin_refresh_fee;
+
+  /**
+   * Set to #GNUNET_YES if this coin's denomination was revoked and the 
operation
    * is thus only allowed for zombie coins where the transaction
    * history includes a #TALER_EXCHANGEDB_TT_OLD_COIN_PAYBACK.
    */
@@ -175,12 +180,9 @@ refresh_check_melt (struct MHD_Connection *connection,
                     int *mhd_ret)
 {
   struct TALER_EXCHANGEDB_TransactionList *tl;
-  struct TALER_Amount coin_value;
   struct TALER_Amount spent;
   enum GNUNET_DB_QueryStatus qs;
 
-  TALER_amount_ntoh (&coin_value,
-                     &rmc->dki->issue.properties.value);
   /* Start with cost of this melt transaction */
   spent = rmc->refresh_session.amount_with_fee;
 
@@ -242,7 +244,7 @@ refresh_check_melt (struct MHD_Connection *connection,
 
   /* Refuse to refresh when the coin's value is insufficient
      for the cost of all transactions. */
-  if (TALER_amount_cmp (&coin_value,
+  if (TALER_amount_cmp (&rmc->coin_value,
                         &spent) < 0)
   {
     struct TALER_Amount coin_residual;
@@ -254,7 +256,7 @@ refresh_check_melt (struct MHD_Connection *connection,
     *mhd_ret = reply_refresh_melt_insufficient_funds (connection,
                                                       
&rmc->refresh_session.coin
                                                       .coin_pub,
-                                                      coin_value,
+                                                      &rmc->coin_value,
                                                       tl,
                                                       &rmc->refresh_session.
                                                       amount_with_fee,
@@ -374,22 +376,6 @@ static int
 handle_refresh_melt (struct MHD_Connection *connection,
                      struct RefreshMeltContext *rmc)
 {
-  /* sanity-check that "total melt amount > melt fee" */
-  {
-    struct TALER_Amount fee_refresh;
-
-    TALER_amount_ntoh (&fee_refresh,
-                       &rmc->dki->issue.properties.fee_refresh);
-    if (TALER_amount_cmp (&fee_refresh,
-                          &rmc->refresh_session.amount_with_fee) > 0)
-    {
-      GNUNET_break_op (0);
-      return TALER_MHD_reply_with_error (connection,
-                                         MHD_HTTP_BAD_REQUEST,
-                                         
TALER_EC_REFRESH_MELT_FEES_EXCEED_CONTRIBUTION,
-                                         "melt amount smaller than melting 
fee");
-    }
-  }
 
   /* verify signature of coin for melt operation */
   {
@@ -401,7 +387,8 @@ handle_refresh_melt (struct MHD_Connection *connection,
     body.rc = rmc->refresh_session.rc;
     TALER_amount_hton (&body.amount_with_fee,
                        &rmc->refresh_session.amount_with_fee);
-    body.melt_fee = rmc->dki->issue.properties.fee_refresh;
+    TALER_amount_hton (&body.melt_fee,
+                       &rmc->coin_refresh_fee);
     body.coin_pub = rmc->refresh_session.coin.coin_pub;
 
     if (GNUNET_OK !=
@@ -440,6 +427,155 @@ handle_refresh_melt (struct MHD_Connection *connection,
 }
 
 
+/**
+ * Check for information about the melted coin's denomination,
+ * extracting its validity status and fee structure.
+ *
+ * @param connection HTTP connection we are handling
+ * @param rmc parsed request information
+ * @return MHD status code
+ */
+static int
+check_for_denomination_key (struct MHD_Connection *connection,
+                            struct RefreshMeltContext *rmc)
+{
+  struct TEH_KS_StateHandle *key_state;
+
+  key_state = TEH_KS_acquire (GNUNET_TIME_absolute_get ());
+  if (NULL == key_state)
+  {
+    TALER_LOG_ERROR ("Lacking keys to operate\n");
+    return TALER_MHD_reply_with_error (connection,
+                                       MHD_HTTP_INTERNAL_SERVER_ERROR,
+                                       TALER_EC_EXCHANGE_BAD_CONFIGURATION,
+                                       "no keys");
+  }
+
+  {
+    /* Baseline: check if deposits/refreshs are generally
+       simply still allowed for this denomination */
+    struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki;
+    unsigned int hc;
+    enum TALER_ErrorCode ec;
+
+    dki = TEH_KS_denomination_key_lookup_by_hash (key_state,
+                                                  &rmc->refresh_session.coin.
+                                                  denom_pub_hash,
+                                                  TEH_KS_DKU_DEPOSIT,
+                                                  &ec,
+                                                  &hc);
+    /* Consider case that denomination was revoked but
+       this coin was already seen and thus refresh is OK. */
+    if (NULL == dki)
+    {
+      dki = TEH_KS_denomination_key_lookup_by_hash (key_state,
+                                                    &rmc->refresh_session.coin.
+                                                    denom_pub_hash,
+                                                    TEH_KS_DKU_PAYBACK,
+                                                    &ec,
+                                                    &hc);
+      if (NULL != dki)
+      {
+        struct GNUNET_HashCode denom_hash;
+        enum GNUNET_DB_QueryStatus qs;
+
+        qs = TEH_plugin->get_coin_denomination (TEH_plugin->cls,
+                                                NULL,
+                                                &rmc->refresh_session.coin.
+                                                coin_pub,
+                                                &denom_hash);
+        if (0 > qs)
+        {
+          TEH_KS_release (key_state);
+          return TALER_MHD_reply_with_error (connection,
+                                             MHD_HTTP_INTERNAL_SERVER_ERROR,
+                                             
TALER_EC_REFRESH_MELT_DB_FETCH_ERROR,
+                                             "failed to find information about 
old coin");
+        }
+        GNUNET_break (0 ==
+                      GNUNET_memcmp (&denom_hash,
+                                     
&rmc->refresh_session.coin.denom_pub_hash));
+        if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs)
+        {
+          /* We never saw this coin before, so _this_ justification is not OK 
*/
+          dki = NULL;
+        }
+      }
+    }
+
+    /* Consider the case that the denomination expired for deposits,
+       but /refresh/payback refilled the balance of the 'zombie' coin
+       and we should thus allow the refresh during the legal period. */
+    if (NULL == dki)
+    {
+      dki = TEH_KS_denomination_key_lookup_by_hash (key_state,
+                                                    &rmc->refresh_session.coin.
+                                                    denom_pub_hash,
+                                                    TEH_KS_DKU_ZOMBIE,
+                                                    &ec,
+                                                    &hc);
+      if (NULL != dki)
+        rmc->zombie_required = GNUNET_YES;
+    }
+    if (NULL == dki)
+    {
+      TEH_KS_release (key_state);
+      TALER_LOG_WARNING ("Unknown denomination key in /refresh/melt 
request\n");
+      return TALER_MHD_reply_with_error (connection,
+                                         hc,
+                                         ec,
+                                         "unknown denomination");
+    }
+    TALER_amount_ntoh (&rmc->coin_refresh_fee,
+                       &dki->issue.properties.fee_refresh);
+    TALER_amount_ntoh (&rmc->coin_value,
+                       &dki->issue.properties.value);
+    if (GNUNET_OK !=
+        TALER_test_coin_valid (&rmc->refresh_session.coin,
+                               &dki->denom_pub))
+    {
+      GNUNET_break_op (0);
+      TEH_KS_release (key_state);
+      return TALER_MHD_reply_with_error (connection,
+                                         MHD_HTTP_FORBIDDEN,
+                                         
TALER_EC_REFRESH_MELT_DENOMINATION_SIGNATURE_INVALID,
+                                         "denom_sig");
+    }
+  }
+  TEH_KS_release (key_state);
+
+  /* run actual logic, now that the request was parsed */
+  /* make sure coin is 'known' in database */
+  {
+    struct TEH_DB_KnowCoinContext kcc;
+    int mhd_ret;
+
+    kcc.coin = &rmc->refresh_session.coin;
+    kcc.connection = connection;
+    if (GNUNET_OK !=
+        TEH_DB_run_transaction (connection,
+                                "know coin for refresh-melt",
+                                &mhd_ret,
+                                &TEH_DB_know_coin_transaction,
+                                &kcc))
+      return mhd_ret;
+  }
+
+  /* sanity-check that "total melt amount > melt fee" */
+  if (TALER_amount_cmp (&rmc->coin_refresh_fee,
+                        &rmc->refresh_session.amount_with_fee) > 0)
+  {
+    GNUNET_break_op (0);
+    return TALER_MHD_reply_with_error (connection,
+                                       MHD_HTTP_BAD_REQUEST,
+                                       
TALER_EC_REFRESH_MELT_FEES_EXCEED_CONTRIBUTION,
+                                       "melt amount smaller than melting fee");
+  }
+  return handle_refresh_melt (connection,
+                              rmc);
+}
+
+
 /**
  * Handle a "/refresh/melt" request.  Parses the request into the JSON
  * components and then hands things of to #handle_refresh_melt_json()
@@ -463,9 +599,6 @@ TEH_REFRESH_handler_refresh_melt (struct TEH_RequestHandler 
*rh,
   json_t *root;
   struct RefreshMeltContext rmc;
   int res;
-  unsigned int hc;
-  enum TALER_ErrorCode ec;
-  struct TEH_KS_StateHandle *key_state;
   struct GNUNET_JSON_Specification spec[] = {
     GNUNET_JSON_spec_fixed_auto ("coin_pub",
                                  &rmc.refresh_session.coin.coin_pub),
@@ -504,143 +637,9 @@ TEH_REFRESH_handler_refresh_melt (struct 
TEH_RequestHandler *rh,
   if (GNUNET_OK != res)
     return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES;
 
-  key_state = TEH_KS_acquire (GNUNET_TIME_absolute_get ());
-  if (NULL == key_state)
-  {
-    TALER_LOG_ERROR ("Lacking keys to operate\n");
-    res = TALER_MHD_reply_with_error (connection,
-                                      MHD_HTTP_INTERNAL_SERVER_ERROR,
-                                      TALER_EC_EXCHANGE_BAD_CONFIGURATION,
-                                      "no keys");
-    goto cleanup;
-  }
-
-  /* Baseline: check if deposits/refreshs are generally
-     simply still allowed for this denomination */
-  rmc.dki = TEH_KS_denomination_key_lookup_by_hash (key_state,
-                                                    &rmc.refresh_session.coin.
-                                                    denom_pub_hash,
-                                                    TEH_KS_DKU_DEPOSIT,
-                                                    &ec,
-                                                    &hc);
-  /* Consider case that denomination was revoked but
-     this coin was already seen and thus refresh is OK. */
-  if (NULL == rmc.dki)
-  {
-    struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki;
-
-    dki = TEH_KS_denomination_key_lookup_by_hash (key_state,
-                                                  &rmc.refresh_session.coin.
-                                                  denom_pub_hash,
-                                                  TEH_KS_DKU_PAYBACK,
-                                                  &ec,
-                                                  &hc);
-    if (NULL != dki)
-    {
-      struct TALER_CoinPublicInfo coin_info;
-      enum GNUNET_DB_QueryStatus qs;
-
-      qs = TEH_plugin->get_known_coin (TEH_plugin->cls,
-                                       NULL,
-                                       &rmc.refresh_session.coin.coin_pub,
-                                       &coin_info);
-      if (0 > qs)
-      {
-        GNUNET_break (0);
-        res = TALER_MHD_reply_with_error (connection,
-                                          MHD_HTTP_INTERNAL_SERVER_ERROR,
-                                          TALER_EC_REFRESH_MELT_DB_FETCH_ERROR,
-                                          "failed to find information about 
old coin");
-        goto cleanup;
-      }
-      if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs)
-      {
-        /* Coin was known beforehand, so we should allow the refresh */
-        rmc.dki = dki;
-        GNUNET_CRYPTO_rsa_signature_free (coin_info.denom_sig.rsa_signature);
-      }
-    }
-  }
-
-  /* Consider the case that the denomination expired for deposits,
-     but /refresh/payback refilled the balance of the 'zombie' coin
-     and we should thus allow the refresh during the legal period. */
-  if (NULL == rmc.dki)
-  {
-    struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki;
-
-    dki = TEH_KS_denomination_key_lookup_by_hash (key_state,
-                                                  &rmc.refresh_session.coin.
-                                                  denom_pub_hash,
-                                                  TEH_KS_DKU_ZOMBIE,
-                                                  &ec,
-                                                  &hc);
-    if (NULL != dki)
-    {
-      rmc.dki = dki;
-      rmc.zombie_required = GNUNET_YES;
-    }
-  }
-
-  if (NULL == rmc.dki)
-  {
-    TALER_LOG_WARNING ("Unknown denomination key in /refresh/melt request\n");
-    res = TALER_MHD_reply_with_error (connection,
-                                      hc,
-                                      ec,
-                                      "unknown denomination");
-    goto cleanup;
-  }
-
-  if (GNUNET_OK !=
-      TALER_test_coin_valid (&rmc.refresh_session.coin,
-                             &rmc.dki->denom_pub))
-  {
-    GNUNET_break_op (0);
-    GNUNET_JSON_parse_free (spec);
-    TEH_KS_release (key_state);
-    return TALER_MHD_reply_with_error (connection,
-                                       MHD_HTTP_FORBIDDEN,
-                                       
TALER_EC_REFRESH_MELT_DENOMINATION_SIGNATURE_INVALID,
-                                       "denom_sig");
-  }
-
-  /* run actual logic, now that the request was parsed */
-
-  /* make sure coin is 'known' in database */
-  {
-    struct TEH_DB_KnowCoinContext kcc;
-    int mhd_ret;
-
-    kcc.coin = &rmc.refresh_session.coin;
-    kcc.connection = connection;
-    if (GNUNET_OK !=
-        TEH_DB_run_transaction (connection,
-                                "know coin for refresh-melt",
-                                &mhd_ret,
-                                &TEH_DB_know_coin_transaction,
-                                &kcc))
-      return mhd_ret;
-  }
-
-  res = handle_refresh_melt (connection,
-                             &rmc);
-
-
-cleanup:
-  if (NULL != key_state)
-  {
-    TEH_KS_release (key_state);
-    key_state = NULL;
-  }
-  if (NULL != rmc.refresh_session.coin.denom_sig.rsa_signature)
-  {
-    GNUNET_CRYPTO_rsa_signature_free (
-      rmc.refresh_session.coin.denom_sig.rsa_signature);
-    rmc.refresh_session.coin.denom_sig.rsa_signature = NULL;
-  }
+  res = check_for_denomination_key (connection,
+                                    &rmc);
   GNUNET_JSON_parse_free (spec);
-
   return res;
 }
 

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



reply via email to

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