gnunet-svn
[Top][All Lists]
Advanced

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

[taler-exchange] branch master updated: -fix issue with missing signatur


From: gnunet
Subject: [taler-exchange] branch master updated: -fix issue with missing signature over denomination and age restriction hash in purse deposit
Date: Tue, 28 Jun 2022 20:25:50 +0200

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 ded7f9ca -fix issue with missing signature over denomination and age 
restriction hash in purse deposit
ded7f9ca is described below

commit ded7f9ca189d8abbfcb6eb874d68bdc1a644da8f
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Tue Jun 28 20:25:45 2022 +0200

    -fix issue with missing signature over denomination and age restriction 
hash in purse deposit
---
 src/auditor/taler-helper-auditor-coins.c           |  2 +
 src/auditor/taler-helper-auditor-reserves.c        | 50 +++++++++++-----------
 src/exchange/taler-exchange-httpd_purses_create.c  | 47 ++++++++++++++------
 src/exchange/taler-exchange-httpd_purses_deposit.c | 46 ++++++++++++++------
 src/exchange/taler-exchange-httpd_responses.c      |  7 +++
 src/exchangedb/plugin_exchangedb_postgres.c        | 16 +++++++
 src/include/taler_crypto_lib.h                     |  8 ++++
 src/include/taler_exchangedb_plugin.h              | 17 +++++---
 src/lib/exchange_api_common.c                      | 19 ++++++++
 src/lib/exchange_api_common.h                      |  4 ++
 src/lib/exchange_api_purse_create_with_deposit.c   | 30 +++++++++++--
 src/lib/exchange_api_purse_deposit.c               | 46 +++++++++++++++-----
 src/util/wallet_signatures.c                       | 23 ++++++++--
 13 files changed, 240 insertions(+), 75 deletions(-)

diff --git a/src/auditor/taler-helper-auditor-coins.c 
b/src/auditor/taler-helper-auditor-coins.c
index 56afdeb9..6940369f 100644
--- a/src/auditor/taler-helper-auditor-coins.c
+++ b/src/auditor/taler-helper-auditor-coins.c
@@ -2414,6 +2414,8 @@ purse_deposit_cb (
         : TALER_ARL_exchange_url,
         &deposit->purse_pub,
         &deposit->amount,
+        &dh,
+        &deposit->h_age_commitment,
         &deposit->coin_pub,
         &deposit->coin_sig))
   {
diff --git a/src/auditor/taler-helper-auditor-reserves.c 
b/src/auditor/taler-helper-auditor-reserves.c
index f0c92c26..54d3db7c 100644
--- a/src/auditor/taler-helper-auditor-reserves.c
+++ b/src/auditor/taler-helper-auditor-reserves.c
@@ -1289,38 +1289,15 @@ handle_purse_deposits (
   struct TALER_Amount amount_minus_fee;
   struct TALER_Amount new_balance;
   struct ReserveSummary *rs;
+  struct TALER_DenominationHashP h_denom_pub;
 
   /* should be monotonically increasing */
   GNUNET_assert (rowid >= ppr.last_purse_deposits_serial_id);
   ppr.last_purse_deposits_serial_id = rowid + 1;
 
-  if (GNUNET_OK !=
-      TALER_wallet_purse_deposit_verify (base_url,
-                                         &deposit->purse_pub,
-                                         &deposit->amount,
-                                         &deposit->coin_pub,
-                                         &deposit->coin_sig))
-  {
-    TALER_ARL_report (report_bad_sig_losses,
-                      GNUNET_JSON_PACK (
-                        GNUNET_JSON_pack_string ("operation",
-                                                 "purse-deposit"),
-                        GNUNET_JSON_pack_uint64 ("row",
-                                                 rowid),
-                        TALER_JSON_pack_amount ("loss",
-                                                &deposit->amount),
-                        GNUNET_JSON_pack_data_auto ("key_pub",
-                                                    &deposit->coin_pub)));
-    TALER_ARL_amount_add (&total_bad_sig_loss,
-                          &total_bad_sig_loss,
-                          &deposit->amount);
-    return GNUNET_OK;
-  }
-
   {
     const struct TALER_EXCHANGEDB_DenominationKeyInformation *issue;
     enum GNUNET_DB_QueryStatus qs;
-    struct TALER_DenominationHashP h_denom_pub;
 
     qs = TALER_ARL_get_denomination_info (denom_pub,
                                           &issue,
@@ -1349,6 +1326,31 @@ handle_purse_deposits (
                                &issue->fees.deposit);
   }
 
+  if (GNUNET_OK !=
+      TALER_wallet_purse_deposit_verify (base_url,
+                                         &deposit->purse_pub,
+                                         &deposit->amount,
+                                         &h_denom_pub,
+                                         &deposit->h_age_commitment,
+                                         &deposit->coin_pub,
+                                         &deposit->coin_sig))
+  {
+    TALER_ARL_report (report_bad_sig_losses,
+                      GNUNET_JSON_PACK (
+                        GNUNET_JSON_pack_string ("operation",
+                                                 "purse-deposit"),
+                        GNUNET_JSON_pack_uint64 ("row",
+                                                 rowid),
+                        TALER_JSON_pack_amount ("loss",
+                                                &deposit->amount),
+                        GNUNET_JSON_pack_data_auto ("key_pub",
+                                                    &deposit->coin_pub)));
+    TALER_ARL_amount_add (&total_bad_sig_loss,
+                          &total_bad_sig_loss,
+                          &deposit->amount);
+    return GNUNET_OK;
+  }
+
   TALER_ARL_amount_add (&new_balance,
                         auditor_balance,
                         &amount_minus_fee);
diff --git a/src/exchange/taler-exchange-httpd_purses_create.c 
b/src/exchange/taler-exchange-httpd_purses_create.c
index 2c803234..b016aeee 100644
--- a/src/exchange/taler-exchange-httpd_purses_create.c
+++ b/src/exchange/taler-exchange-httpd_purses_create.c
@@ -335,6 +335,8 @@ create_transaction (void *cls,
       struct TALER_Amount amount;
       struct TALER_CoinSpendPublicKeyP coin_pub;
       struct TALER_CoinSpendSignatureP coin_sig;
+      struct TALER_DenominationHashP h_denom_pub;
+      struct TALER_AgeCommitmentHash phac;
       char *partner_url = NULL;
 
       TEH_plugin->rollback (TEH_plugin->cls);
@@ -342,6 +344,8 @@ create_transaction (void *cls,
                                           pcc->purse_pub,
                                           &coin->cpi.coin_pub,
                                           &amount,
+                                          &h_denom_pub,
+                                          &phac,
                                           &coin_sig,
                                           &partner_url);
       if (qs < 0)
@@ -366,6 +370,10 @@ create_transaction (void *cls,
                                         &coin_pub),
             GNUNET_JSON_pack_data_auto ("coin_sig",
                                         &coin_sig),
+            GNUNET_JSON_pack_data_auto ("h_denom_pub",
+                                        &h_denom_pub),
+            GNUNET_JSON_pack_data_auto ("h_age_restrictions",
+                                        &phac),
             GNUNET_JSON_pack_allow_null (
               GNUNET_JSON_pack_string ("partner_url",
                                        partner_url)),
@@ -493,22 +501,33 @@ parse_coin (struct MHD_Connection *connection,
       return res;
   }
 
-  if (GNUNET_OK !=
-      TALER_wallet_purse_deposit_verify (TEH_base_url,
-                                         pcc->purse_pub,
-                                         &coin->amount,
-                                         &coin->cpi.coin_pub,
-                                         &coin->coin_sig))
   {
-    TALER_LOG_WARNING (
-      "Invalid coin signature on /purses/$PID/create request\n");
-    GNUNET_JSON_parse_free (spec);
-    return (MHD_YES ==
-            TALER_MHD_reply_with_error (connection,
-                                        MHD_HTTP_FORBIDDEN,
-                                        
TALER_EC_EXCHANGE_PURSE_CREATE_COIN_SIGNATURE_INVALID,
-                                        TEH_base_url))
+    struct TALER_AgeCommitmentHash h_age;
+
+    if (no_age_commitment)
+      memset (&h_age, 0, sizeof (h_age));
+    else
+      TALER_age_commitment_hash (&age_commitment,
+                                 &h_age);
+    if (GNUNET_OK !=
+        TALER_wallet_purse_deposit_verify (TEH_base_url,
+                                           pcc->purse_pub,
+                                           &coin->amount,
+                                           &coin->cpi.denom_pub_hash,
+                                           &h_age,
+                                           &coin->cpi.coin_pub,
+                                           &coin->coin_sig))
+    {
+      TALER_LOG_WARNING (
+        "Invalid coin signature on /purses/$PID/create request\n");
+      GNUNET_JSON_parse_free (spec);
+      return (MHD_YES ==
+              TALER_MHD_reply_with_error (connection,
+                                          MHD_HTTP_FORBIDDEN,
+                                          
TALER_EC_EXCHANGE_PURSE_CREATE_COIN_SIGNATURE_INVALID,
+                                          TEH_base_url))
            ? GNUNET_NO : GNUNET_SYSERR;
+    }
   }
   /* check denomination exists and is valid */
   {
diff --git a/src/exchange/taler-exchange-httpd_purses_deposit.c 
b/src/exchange/taler-exchange-httpd_purses_deposit.c
index af7200f1..4158b293 100644
--- a/src/exchange/taler-exchange-httpd_purses_deposit.c
+++ b/src/exchange/taler-exchange-httpd_purses_deposit.c
@@ -239,6 +239,8 @@ deposit_transaction (void *cls,
       struct TALER_Amount amount;
       struct TALER_CoinSpendPublicKeyP coin_pub;
       struct TALER_CoinSpendSignatureP coin_sig;
+      struct TALER_DenominationHashP h_denom_pub;
+      struct TALER_AgeCommitmentHash phac;
       char *partner_url = NULL;
 
       TEH_plugin->rollback (TEH_plugin->cls);
@@ -246,6 +248,8 @@ deposit_transaction (void *cls,
                                           pcc->purse_pub,
                                           &coin->cpi.coin_pub,
                                           &amount,
+                                          &h_denom_pub,
+                                          &phac,
                                           &coin_sig,
                                           &partner_url);
       if (qs < 0)
@@ -268,6 +272,10 @@ deposit_transaction (void *cls,
               TALER_EC_EXCHANGE_PURSE_DEPOSIT_CONFLICTING_META_DATA),
             GNUNET_JSON_pack_data_auto ("coin_pub",
                                         &coin_pub),
+            GNUNET_JSON_pack_data_auto ("h_denom_pub",
+                                        &h_denom_pub),
+            GNUNET_JSON_pack_data_auto ("h_age_commitment",
+                                        &phac),
             GNUNET_JSON_pack_data_auto ("coin_sig",
                                         &coin_sig),
             GNUNET_JSON_pack_allow_null (
@@ -336,21 +344,33 @@ parse_coin (struct MHD_Connection *connection,
     if (GNUNET_OK != res)
       return res;
   }
-  if (GNUNET_OK !=
-      TALER_wallet_purse_deposit_verify (TEH_base_url,
-                                         pcc->purse_pub,
-                                         &coin->amount,
-                                         &coin->cpi.coin_pub,
-                                         &coin->coin_sig))
   {
-    TALER_LOG_WARNING ("Invalid signature on /purses/$PID/deposit request\n");
-    GNUNET_JSON_parse_free (spec);
-    return (MHD_YES ==
-            TALER_MHD_reply_with_error (connection,
-                                        MHD_HTTP_FORBIDDEN,
-                                        
TALER_EC_EXCHANGE_PURSE_DEPOSIT_COIN_SIGNATURE_INVALID,
-                                        TEH_base_url))
+    struct TALER_AgeCommitmentHash h_age;
+
+    if (no_age_commitment)
+      memset (&h_age, 0, sizeof (h_age));
+    else
+      TALER_age_commitment_hash (&age_commitment,
+                                 &h_age);
+
+    if (GNUNET_OK !=
+        TALER_wallet_purse_deposit_verify (TEH_base_url,
+                                           pcc->purse_pub,
+                                           &coin->amount,
+                                           &coin->cpi.denom_pub_hash,
+                                           &h_age,
+                                           &coin->cpi.coin_pub,
+                                           &coin->coin_sig))
+    {
+      TALER_LOG_WARNING ("Invalid signature on /purses/$PID/deposit 
request\n");
+      GNUNET_JSON_parse_free (spec);
+      return (MHD_YES ==
+              TALER_MHD_reply_with_error (connection,
+                                          MHD_HTTP_FORBIDDEN,
+                                          
TALER_EC_EXCHANGE_PURSE_DEPOSIT_COIN_SIGNATURE_INVALID,
+                                          TEH_base_url))
            ? GNUNET_NO : GNUNET_SYSERR;
+    }
   }
   /* check denomination exists and is valid */
   {
diff --git a/src/exchange/taler-exchange-httpd_responses.c 
b/src/exchange/taler-exchange-httpd_responses.c
index 429647e1..92c585b4 100644
--- a/src/exchange/taler-exchange-httpd_responses.c
+++ b/src/exchange/taler-exchange-httpd_responses.c
@@ -391,6 +391,10 @@ TEH_RESPONSE_compile_transaction_history (
       {
         struct TALER_EXCHANGEDB_PurseDepositListEntry *pd
           = pos->details.purse_deposit;
+        const struct TALER_AgeCommitmentHash *phac = NULL;
+
+        if (! pd->no_age_commitment)
+          phac = &pd->h_age_commitment;
 
         if (0 !=
             json_array_append_new (
@@ -404,6 +408,9 @@ TEH_RESPONSE_compile_transaction_history (
                                          NULL == pd->exchange_base_url
                                          ? TEH_base_url
                                          : pd->exchange_base_url),
+                GNUNET_JSON_pack_allow_null (
+                  GNUNET_JSON_pack_data_auto ("h_age_commitment",
+                                              phac)),
                 GNUNET_JSON_pack_data_auto ("purse_pub",
                                             &pd->purse_pub),
                 GNUNET_JSON_pack_bool ("refunded",
diff --git a/src/exchangedb/plugin_exchangedb_postgres.c 
b/src/exchangedb/plugin_exchangedb_postgres.c
index d3bbb4d6..5985fa95 100644
--- a/src/exchangedb/plugin_exchangedb_postgres.c
+++ b/src/exchangedb/plugin_exchangedb_postgres.c
@@ -1275,6 +1275,7 @@ prepare_statements (struct PostgresClosure *pg)
       ",denoms.fee_deposit_val"
       ",denoms.fee_deposit_frac"
       ",pd.purse_pub"
+      ",kc.age_commitment_hash"
       ",pd.coin_sig"
       ",pd.purse_deposit_serial_id"
       ",pr.refunded"
@@ -4199,9 +4200,13 @@ prepare_statements (struct PostgresClosure *pg)
       " coin_sig"
       ",amount_with_fee_val"
       ",amount_with_fee_frac"
+      ",denom_pub_hash"
+      ",age_commitment_hash"
       ",partner_base_url"
       " FROM purse_deposits"
       " LEFT JOIN partners USING (partner_serial_id)"
+      " JOIN known_coins kc USING (coin_pub)"
+      " JOIN denominations USING (denominations_serial)"
       " WHERE coin_pub=$2"
       "   AND purse_pub=$1;",
       2),
@@ -8571,6 +8576,8 @@ add_coin_purse_deposit (void *cls,
           NULL),
         GNUNET_PQ_result_spec_auto_from_type ("coin_sig",
                                               &deposit->coin_sig),
+        GNUNET_PQ_result_spec_auto_from_type ("age_commitment_hash",
+                                              &deposit->h_age_commitment),
         GNUNET_PQ_result_spec_bool ("refunded",
                                     &deposit->refunded),
         GNUNET_PQ_result_spec_end
@@ -8586,6 +8593,7 @@ add_coin_purse_deposit (void *cls,
         chc->failed = true;
         return;
       }
+      deposit->no_age_commitment = GNUNET_is_zero (&deposit->h_age_commitment);
     }
     tl = GNUNET_new (struct TALER_EXCHANGEDB_TransactionList);
     tl->next = chc->head;
@@ -15623,6 +15631,8 @@ postgres_set_purse_balance (
  * @param purse_pub purse to credit
  * @param coin_pub coin to deposit (debit)
  * @param[out] amount set fraction of the coin's value that was deposited 
(with fee)
+ * @param[out] h_denom_pub set to hash of denomination of the coin
+ * @param[out] phac set to hash of age restriction on the coin
  * @param[out] coin_sig set to signature affirming the operation
  * @param[out] partner_url set to the URL of the partner exchange, or NULL for 
ourselves, must be freed by caller
  * @return transaction status code
@@ -15633,6 +15643,8 @@ postgres_get_purse_deposit (
   const struct TALER_PurseContractPublicKeyP *purse_pub,
   const struct TALER_CoinSpendPublicKeyP *coin_pub,
   struct TALER_Amount *amount,
+  struct TALER_DenominationHashP *h_denom_pub,
+  struct TALER_AgeCommitmentHash *phac,
   struct TALER_CoinSpendSignatureP *coin_sig,
   char **partner_url)
 {
@@ -15644,6 +15656,10 @@ postgres_get_purse_deposit (
   };
   bool is_null;
   struct GNUNET_PQ_ResultSpec rs[] = {
+    GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash",
+                                          h_denom_pub),
+    GNUNET_PQ_result_spec_auto_from_type ("age_commitment_hash",
+                                          phac),
     GNUNET_PQ_result_spec_auto_from_type ("coin_sig",
                                           coin_sig),
     TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee",
diff --git a/src/include/taler_crypto_lib.h b/src/include/taler_crypto_lib.h
index 274a18de..fa13a29c 100644
--- a/src/include/taler_crypto_lib.h
+++ b/src/include/taler_crypto_lib.h
@@ -2887,6 +2887,8 @@ TALER_wallet_purse_status_verify (
  * @param exchange_base_url URL of the exchange hosting the purse
  * @param purse_pub purse’s public key
  * @param amount amount of the coin's value to transfer to the purse
+ * @param h_denom_pub hash of the coin's denomination
+ * @param h_age_commitment hash of the coin's age commitment
  * @param coin_priv key identifying the coin to be deposited
  * @param[out] coin_sig resulting signature
  */
@@ -2895,6 +2897,8 @@ TALER_wallet_purse_deposit_sign (
   const char *exchange_base_url,
   const struct TALER_PurseContractPublicKeyP *purse_pub,
   const struct TALER_Amount *amount,
+  const struct TALER_DenominationHashP *h_denom_pub,
+  const struct TALER_AgeCommitmentHash *h_age_commitment,
   const struct TALER_CoinSpendPrivateKeyP *coin_priv,
   struct TALER_CoinSpendSignatureP *coin_sig);
 
@@ -2905,6 +2909,8 @@ TALER_wallet_purse_deposit_sign (
  * @param exchange_base_url URL of the exchange hosting the purse
  * @param purse_pub purse’s public key
  * @param amount amount of the coin's value to transfer to the purse
+ * @param h_denom_pub hash of the coin's denomination
+ * @param h_age_commitment hash of the coin's age commitment
  * @param coin_pub key identifying the coin that is being deposited
  * @param[out] coin_sig resulting signature
  * @return #GNUNET_OK if the signature is valid
@@ -2914,6 +2920,8 @@ TALER_wallet_purse_deposit_verify (
   const char *exchange_base_url,
   const struct TALER_PurseContractPublicKeyP *purse_pub,
   const struct TALER_Amount *amount,
+  const struct TALER_DenominationHashP *h_denom_pub,
+  const struct TALER_AgeCommitmentHash *h_age_commitment,
   const struct TALER_CoinSpendPublicKeyP *coin_pub,
   const struct TALER_CoinSpendSignatureP *coin_sig);
 
diff --git a/src/include/taler_exchangedb_plugin.h 
b/src/include/taler_exchangedb_plugin.h
index 42a6795f..4ec2b6c7 100644
--- a/src/include/taler_exchangedb_plugin.h
+++ b/src/include/taler_exchangedb_plugin.h
@@ -1687,20 +1687,21 @@ struct TALER_EXCHANGEDB_PurseDepositListEntry
   struct TALER_CoinSpendSignatureP coin_sig;
 
   /**
-   * FIXME-Oec: probably needed here, not yet used
-   * anywhere!
-   *
    * Hash of the age commitment used to sign the coin, if age restriction was
-   * applicable to the denomination.  May be all zeroes if no age restriction
-   * applies.
+   * applicable to the denomination.
    */
-  struct TALER_AgeCommitmentHash h_age_commitment_FIXME;
+  struct TALER_AgeCommitmentHash h_age_commitment;
 
   /**
    * Set to true if the coin was refunded.
    */
   bool refunded;
 
+  /**
+   * Set to true if there was no age commitment.
+   */
+  bool no_age_commitment;
+
 };
 
 
@@ -5349,6 +5350,8 @@ struct TALER_EXCHANGEDB_Plugin
    * @param purse_pub purse to credit
    * @param coin_pub coin to deposit (debit)
    * @param[out] amount set fraction of the coin's value that was deposited 
(with fee)
+   * @param[out] h_denom_pub set to hash of denomination of the coin
+   * @param[out] phac set to hash of age restriction on the coin
    * @param[out] coin_sig set to signature affirming the operation
    * @param[out] partner_url set to the URL of the partner exchange, or NULL 
for ourselves, must be freed by caller
    * @return transaction status code
@@ -5359,6 +5362,8 @@ struct TALER_EXCHANGEDB_Plugin
     const struct TALER_PurseContractPublicKeyP *purse_pub,
     const struct TALER_CoinSpendPublicKeyP *coin_pub,
     struct TALER_Amount *amount,
+    struct TALER_DenominationHashP *h_denom_pub,
+    struct TALER_AgeCommitmentHash *phac,
     struct TALER_CoinSpendSignatureP *coin_sig,
     char **partner_url);
 
diff --git a/src/lib/exchange_api_common.c b/src/lib/exchange_api_common.c
index 4b36aa93..26ddb3c0 100644
--- a/src/lib/exchange_api_common.c
+++ b/src/lib/exchange_api_common.c
@@ -1170,13 +1170,22 @@ help_purse_deposit (struct CoinHistoryParseContext *pc,
   struct TALER_CoinSpendSignatureP coin_sig;
   const char *exchange_base_url;
   bool refunded;
+  struct TALER_AgeCommitmentHash phac = { 0 };
   struct GNUNET_JSON_Specification spec[] = {
     GNUNET_JSON_spec_fixed_auto ("purse_pub",
                                  &purse_pub),
     GNUNET_JSON_spec_fixed_auto ("coin_sig",
                                  &coin_sig),
+    GNUNET_JSON_spec_mark_optional (
+      GNUNET_JSON_spec_fixed_auto ("h_age_commitment",
+                                   &coin_sig),
+      NULL),
     GNUNET_JSON_spec_string ("exchange_base_url",
                              &exchange_base_url),
+    GNUNET_JSON_spec_mark_optional (
+      GNUNET_JSON_spec_fixed_auto ("h_age_commitment",
+                                   &phac),
+      NULL),
     GNUNET_JSON_spec_bool ("refunded",
                            &refunded),
     GNUNET_JSON_spec_end ()
@@ -1195,6 +1204,8 @@ help_purse_deposit (struct CoinHistoryParseContext *pc,
         exchange_base_url,
         &purse_pub,
         amount,
+        &pc->dk->h_key,
+        &phac,
         pc->coin_pub,
         &coin_sig))
   {
@@ -1560,12 +1571,18 @@ TALER_EXCHANGE_check_purse_coin_conflict_ (
   const struct TALER_PurseContractPublicKeyP *purse_pub,
   const char *exchange_url,
   const json_t *proof,
+  struct TALER_DenominationHashP *h_denom_pub,
+  struct TALER_AgeCommitmentHash *phac,
   struct TALER_CoinSpendPublicKeyP *coin_pub,
   struct TALER_CoinSpendSignatureP *coin_sig)
 {
   const char *partner_url = NULL;
   struct TALER_Amount amount;
   struct GNUNET_JSON_Specification spec[] = {
+    GNUNET_JSON_spec_fixed_auto ("h_denom_pub",
+                                 h_denom_pub),
+    GNUNET_JSON_spec_fixed_auto ("h_age_commitment",
+                                 phac),
     GNUNET_JSON_spec_fixed_auto ("coin_sig",
                                  coin_sig),
     GNUNET_JSON_spec_fixed_auto ("coin_pub",
@@ -1594,6 +1611,8 @@ TALER_EXCHANGE_check_purse_coin_conflict_ (
         partner_url,
         purse_pub,
         &amount,
+        h_denom_pub,
+        phac,
         coin_pub,
         coin_sig))
   {
diff --git a/src/lib/exchange_api_common.h b/src/lib/exchange_api_common.h
index 5721b376..f4737ca9 100644
--- a/src/lib/exchange_api_common.h
+++ b/src/lib/exchange_api_common.h
@@ -75,6 +75,8 @@ TALER_EXCHANGE_check_purse_merge_conflict_ (
  * @param purse_pub the public key of the purse
  * @param exchange_url base URL of our exchange
  * @param proof the proof to check
+ * @param[out] h_denom_pub hash of the coin's denomination
+ * @param[out] phac age commitment hash of the coin
  * @param[out] coin_pub set to the conflicting coin
  * @param[out] coin_sig set to the conflicting signature
  * @return #GNUNET_OK if the @a proof is OK for @a purse_pub and showing that 
@a coin_pub was spent using @a coin_sig.
@@ -84,6 +86,8 @@ TALER_EXCHANGE_check_purse_coin_conflict_ (
   const struct TALER_PurseContractPublicKeyP *purse_pub,
   const char *exchange_url,
   const json_t *proof,
+  struct TALER_DenominationHashP *h_denom_pub,
+  struct TALER_AgeCommitmentHash *phac,
   struct TALER_CoinSpendPublicKeyP *coin_pub,
   struct TALER_CoinSpendSignatureP *coin_sig);
 
diff --git a/src/lib/exchange_api_purse_create_with_deposit.c 
b/src/lib/exchange_api_purse_create_with_deposit.c
index fa1de60b..3a5b7df5 100644
--- a/src/lib/exchange_api_purse_create_with_deposit.c
+++ b/src/lib/exchange_api_purse_create_with_deposit.c
@@ -54,6 +54,11 @@ struct Deposit
    */
   struct TALER_DenominationHashP h_denom_pub;
 
+  /**
+   * Age restriction hash for the coin.
+   */
+  struct TALER_AgeCommitmentHash ahac;
+
   /**
    * How much did we say the coin contributed.
    */
@@ -375,6 +380,8 @@ handle_purse_create_deposit_finished (void *cls,
         {
           struct TALER_CoinSpendPublicKeyP coin_pub;
           struct TALER_CoinSpendSignatureP coin_sig;
+          struct TALER_DenominationHashP h_denom_pub;
+          struct TALER_AgeCommitmentHash phac;
           bool found = false;
 
           if (GNUNET_OK !=
@@ -382,6 +389,8 @@ handle_purse_create_deposit_finished (void *cls,
                 &pch->purse_pub,
                 pch->exchange->url,
                 j,
+                &h_denom_pub,
+                &phac,
                 &coin_pub,
                 &coin_sig))
           {
@@ -398,6 +407,20 @@ handle_purse_create_deposit_finished (void *cls,
                 GNUNET_memcmp (&coin_pub,
                                &deposit->coin_pub))
               continue;
+            if (0 !=
+                GNUNET_memcmp (&deposit->h_denom_pub,
+                               &h_denom_pub))
+            {
+              found = true;
+              break;
+            }
+            if (0 !=
+                GNUNET_memcmp (&deposit->ahac,
+                               &phac))
+            {
+              found = true;
+              break;
+            }
             if (0 ==
                 GNUNET_memcmp (&coin_sig,
                                &deposit->coin_sig))
@@ -571,7 +594,6 @@ TALER_EXCHANGE_purse_create_with_deposit (
     const struct TALER_AgeCommitmentProof *acp = deposit->age_commitment_proof;
     struct Deposit *d = &pch->deposits[i];
     json_t *jdeposit;
-    struct TALER_AgeCommitmentHash agh;
     struct TALER_AgeCommitmentHash *aghp = NULL;
     struct TALER_AgeAttestation attest;
     struct TALER_AgeAttestation *attestp = NULL;
@@ -579,8 +601,8 @@ TALER_EXCHANGE_purse_create_with_deposit (
     if (NULL != acp)
     {
       TALER_age_commitment_hash (&acp->commitment,
-                                 &agh);
-      aghp = &agh;
+                                 &d->ahac);
+      aghp = &d->ahac;
       if (GNUNET_OK !=
           TALER_age_commitment_attest (acp,
                                        min_age,
@@ -601,6 +623,8 @@ TALER_EXCHANGE_purse_create_with_deposit (
       url,
       &pch->purse_pub,
       &deposit->amount,
+      &d->h_denom_pub,
+      &d->ahac,
       &deposit->coin_priv,
       &d->coin_sig);
     jdeposit = GNUNET_JSON_PACK (
diff --git a/src/lib/exchange_api_purse_deposit.c 
b/src/lib/exchange_api_purse_deposit.c
index 836183bb..92225101 100644
--- a/src/lib/exchange_api_purse_deposit.c
+++ b/src/lib/exchange_api_purse_deposit.c
@@ -54,6 +54,11 @@ struct Coin
    */
   struct TALER_DenominationHashP h_denom_pub;
 
+  /**
+   * Age restriction hash for the coin.
+   */
+  struct TALER_AgeCommitmentHash ahac;
+
   /**
    * How much did we say the coin contributed.
    */
@@ -234,6 +239,8 @@ handle_purse_deposit_finished (void *cls,
       {
         struct TALER_CoinSpendPublicKeyP coin_pub;
         struct TALER_CoinSpendSignatureP coin_sig;
+        struct TALER_DenominationHashP h_denom_pub;
+        struct TALER_AgeCommitmentHash phac;
         bool found = false;
 
         if (GNUNET_OK !=
@@ -241,6 +248,8 @@ handle_purse_deposit_finished (void *cls,
               &pch->purse_pub,
               pch->base_url,
               j,
+              &h_denom_pub,
+              &phac,
               &coin_pub,
               &coin_sig))
         {
@@ -251,18 +260,32 @@ handle_purse_deposit_finished (void *cls,
         }
         for (unsigned int i = 0; i<pch->num_deposits; i++)
         {
-          if (0 == GNUNET_memcmp (&coin_pub,
-                                  &pch->coins[i].coin_pub))
+          struct Coin *coin = &pch->coins[i];
+          if (0 != GNUNET_memcmp (&coin_pub,
+                                  &coin->coin_pub))
+            continue;
+          if (0 !=
+              GNUNET_memcmp (&coin->h_denom_pub,
+                             &h_denom_pub))
+          {
+            found = true;
+            break;
+          }
+          if (0 !=
+              GNUNET_memcmp (&coin->ahac,
+                             &phac))
           {
-            if (0 == GNUNET_memcmp (&coin_sig,
-                                    &pch->coins[i].coin_sig))
-            {
-              /* identical signature => not a conflict */
-              continue;
-            }
             found = true;
             break;
           }
+          if (0 == GNUNET_memcmp (&coin_sig,
+                                  &coin->coin_sig))
+          {
+            /* identical signature => not a conflict */
+            continue;
+          }
+          found = true;
+          break;
         }
         if (! found)
         {
@@ -488,7 +511,6 @@ TALER_EXCHANGE_purse_deposit (
     const struct TALER_AgeCommitmentProof *acp = deposit->age_commitment_proof;
     struct Coin *coin = &pch->coins[i];
     json_t *jdeposit;
-    struct TALER_AgeCommitmentHash ach;
     struct TALER_AgeCommitmentHash *achp = NULL;
     struct TALER_AgeAttestation attest;
     struct TALER_AgeAttestation *attestp = NULL;
@@ -496,8 +518,8 @@ TALER_EXCHANGE_purse_deposit (
     if (NULL != acp)
     {
       TALER_age_commitment_hash (&acp->commitment,
-                                 &ach);
-      achp = &ach;
+                                 &coin->ahac);
+      achp = &coin->ahac;
       if (GNUNET_OK !=
           TALER_age_commitment_attest (acp,
                                        min_age,
@@ -520,6 +542,8 @@ TALER_EXCHANGE_purse_deposit (
       pch->base_url,
       &pch->purse_pub,
       &deposit->amount,
+      &coin->h_denom_pub,
+      &coin->ahac,
       &deposit->coin_priv,
       &coin->coin_sig);
     jdeposit = GNUNET_JSON_PACK (
diff --git a/src/util/wallet_signatures.c b/src/util/wallet_signatures.c
index 1b801562..f4efb271 100644
--- a/src/util/wallet_signatures.c
+++ b/src/util/wallet_signatures.c
@@ -898,9 +898,16 @@ struct TALER_PurseDepositPS
    */
   struct TALER_AmountNBO coin_amount;
 
-  // FIXME-CG: also sign over age commitment hash AND
-  // denomination hash, needed for proper known-coin
-  // conflict proofs!
+  /**
+   * Hash over the denomination public key used to sign the coin.
+   */
+  struct TALER_DenominationHashP h_denom_pub GNUNET_PACKED;
+
+  /**
+   * Hash over the age commitment that went into the coin. Maybe all zero, if
+   * age commitment isn't applicable to the denomination.
+   */
+  struct TALER_AgeCommitmentHash h_age_commitment GNUNET_PACKED;
 
   /**
    * Purse to deposit funds into.
@@ -911,7 +918,7 @@ struct TALER_PurseDepositPS
    * Hash of the base URL of the exchange hosting the
    * @e purse_pub.
    */
-  struct GNUNET_HashCode h_exchange_base_url;
+  struct GNUNET_HashCode h_exchange_base_url GNUNET_PACKED;
 };
 
 
@@ -920,6 +927,8 @@ TALER_wallet_purse_deposit_sign (
   const char *exchange_base_url,
   const struct TALER_PurseContractPublicKeyP *purse_pub,
   const struct TALER_Amount *amount,
+  const struct TALER_DenominationHashP *h_denom_pub,
+  const struct TALER_AgeCommitmentHash *h_age_commitment,
   const struct TALER_CoinSpendPrivateKeyP *coin_priv,
   struct TALER_CoinSpendSignatureP *coin_sig)
 {
@@ -927,6 +936,8 @@ TALER_wallet_purse_deposit_sign (
     .purpose.size = htonl (sizeof (pm)),
     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_DEPOSIT),
     .purse_pub = *purse_pub,
+    .h_denom_pub = *h_denom_pub,
+    .h_age_commitment = *h_age_commitment
   };
 
   GNUNET_CRYPTO_hash (exchange_base_url,
@@ -945,6 +956,8 @@ TALER_wallet_purse_deposit_verify (
   const char *exchange_base_url,
   const struct TALER_PurseContractPublicKeyP *purse_pub,
   const struct TALER_Amount *amount,
+  const struct TALER_DenominationHashP *h_denom_pub,
+  const struct TALER_AgeCommitmentHash *h_age_commitment,
   const struct TALER_CoinSpendPublicKeyP *coin_pub,
   const struct TALER_CoinSpendSignatureP *coin_sig)
 {
@@ -952,6 +965,8 @@ TALER_wallet_purse_deposit_verify (
     .purpose.size = htonl (sizeof (pm)),
     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_DEPOSIT),
     .purse_pub = *purse_pub,
+    .h_denom_pub = *h_denom_pub,
+    .h_age_commitment = *h_age_commitment
   };
 
   GNUNET_CRYPTO_hash (exchange_base_url,

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