gnunet-svn
[Top][All Lists]
Advanced

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

[taler-exchange] branch master updated: -fixes to tests, and half-baked


From: gnunet
Subject: [taler-exchange] branch master updated: -fixes to tests, and half-baked fixes for CS-/link (still fails)
Date: Thu, 10 Feb 2022 23:39:04 +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 532d4ad0 -fixes to tests, and half-baked fixes for CS-/link (still 
fails)
532d4ad0 is described below

commit 532d4ad0dca62055056e5b6093e82daa3541f690
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Thu Feb 10 23:39:00 2022 +0100

    -fixes to tests, and half-baked fixes for CS-/link (still fails)
---
 src/exchange/taler-exchange-httpd_link.c           |   6 +-
 .../taler-exchange-httpd_refreshes_reveal.c        |  19 ++--
 src/exchangedb/exchange-0001.sql                   |   3 +
 src/exchangedb/irbt_callbacks.c                    |   2 +
 src/exchangedb/lrbt_callbacks.c                    |   3 +
 src/exchangedb/plugin_exchangedb_postgres.c        |  24 ++++-
 src/exchangedb/test_exchangedb.c                   |   7 ++
 src/include/taler_exchangedb_plugin.h              |  18 ++++
 src/include/taler_pq_lib.h                         |  27 +++++-
 src/lib/exchange_api_link.c                        |  26 ++++-
 src/lib/exchange_api_refresh_common.c              |   4 +
 src/pq/pq_query_helper.c                           |  88 +++++++++++++++++
 src/pq/pq_result_helper.c                          | 108 ++++++++++++++++++++-
 src/testing/test_exchange_api.c                    |  41 +++++++-
 src/util/crypto.c                                  |   1 +
 15 files changed, 354 insertions(+), 23 deletions(-)

diff --git a/src/exchange/taler-exchange-httpd_link.c 
b/src/exchange/taler-exchange-httpd_link.c
index d3c0d6a5..de10f8b8 100644
--- a/src/exchange/taler-exchange-httpd_link.c
+++ b/src/exchange/taler-exchange-httpd_link.c
@@ -1,6 +1,6 @@
 /*
   This file is part of TALER
-  Copyright (C) 2014-2019 Taler Systems SA
+  Copyright (C) 2014-2019, 2022 Taler Systems SA
 
   TALER is free software; you can redistribute it and/or modify it under the
   terms of the GNU Affero General Public License as published by the Free 
Software
@@ -86,6 +86,10 @@ handle_link_data (void *cls,
                                  &pos->denom_pub),
       TALER_JSON_pack_blinded_denom_sig ("ev_sig",
                                          &pos->ev_sig),
+      GNUNET_JSON_pack_uint64 ("coin_idx",
+                               pos->coin_refresh_offset),
+      TALER_JSON_pack_exchange_withdraw_values ("ewv",
+                                                &pos->alg_values),
       GNUNET_JSON_pack_data_auto ("link_sig",
                                   &pos->orig_coin_link_sig));
     if ( (NULL == obj) ||
diff --git a/src/exchange/taler-exchange-httpd_refreshes_reveal.c 
b/src/exchange/taler-exchange-httpd_refreshes_reveal.c
index 56827814..e0d97bb3 100644
--- a/src/exchange/taler-exchange-httpd_refreshes_reveal.c
+++ b/src/exchange/taler-exchange-httpd_refreshes_reveal.c
@@ -105,7 +105,10 @@ struct RevealContext
   /**
    * Array of information about fresh coins being revealed.
    */
-  const struct TALER_EXCHANGEDB_RefreshRevealedCoin *rrcs;
+  /* FIXME: const would be nicer here, but we initalize
+     the 'alg_values' in the verification
+     routine; suboptimal to be fixed... */
+  struct TALER_EXCHANGEDB_RefreshRevealedCoin *rrcs;
 
   /**
    * Envelopes to be signed.
@@ -141,7 +144,6 @@ check_commitment (struct RevealContext *rctx,
                   struct MHD_Connection *connection,
                   MHD_RESULT *mhd_ret)
 {
-  struct TALER_ExchangeWithdrawValues alg_values[rctx->num_fresh_coins];
   struct TALER_CsNonce nonces[rctx->num_fresh_coins];
   unsigned int aoff = 0;
 
@@ -184,8 +186,10 @@ check_commitment (struct RevealContext *rctx,
   for (unsigned int j = 0; j<rctx->num_fresh_coins; j++)
   {
     const struct TALER_DenominationPublicKey *dk = &rctx->dks[j]->denom_pub;
+    struct TALER_ExchangeWithdrawValues *alg_values
+      = &rctx->rrcs[j].exchange_vals;
 
-    alg_values[j].cipher = dk->cipher;
+    alg_values->cipher = dk->cipher;
     switch (dk->cipher)
     {
     case TALER_DENOMINATION_INVALID:
@@ -200,7 +204,7 @@ check_commitment (struct RevealContext *rctx,
         ec = TEH_keys_denomination_cs_r_pub (
           &rctx->rrcs[j].h_denom_pub,
           &nonces[aoff],
-          &alg_values[j].details.cs_values.r_pub_pair);
+          &alg_values->details.cs_values.r_pub_pair);
         if (TALER_EC_NONE != ec)
         {
           *mhd_ret = TALER_MHD_reply_with_error (connection,
@@ -251,12 +255,13 @@ check_commitment (struct RevealContext *rctx,
         aoff = 0;
         for (unsigned int j = 0; j<rctx->num_fresh_coins; j++)
         {
-          const struct TALER_DenominationPublicKey *dk =
-            &rctx->dks[j]->denom_pub;
+          const struct TALER_DenominationPublicKey *dk
+            = &rctx->dks[j]->denom_pub;
           struct TALER_RefreshCoinData *rcd = &rce->new_coins[j];
           struct TALER_CoinSpendPrivateKeyP coin_priv;
           union TALER_DenominationBlindingKeyP bks;
-          const struct TALER_ExchangeWithdrawValues *alg_value = 
&alg_values[j];
+          const struct TALER_ExchangeWithdrawValues *alg_value
+            = &rctx->rrcs[j].exchange_vals;
           struct TALER_PlanchetDetail pd;
           struct TALER_CoinPubHash c_hash;
           struct TALER_PlanchetSecretsP ps;
diff --git a/src/exchangedb/exchange-0001.sql b/src/exchangedb/exchange-0001.sql
index a8e79335..66856f60 100644
--- a/src/exchangedb/exchange-0001.sql
+++ b/src/exchangedb/exchange-0001.sql
@@ -377,6 +377,7 @@ CREATE TABLE IF NOT EXISTS refresh_revealed_coins
   ,coin_ev BYTEA NOT NULL -- UNIQUE
   ,h_coin_ev BYTEA NOT NULL CHECK(LENGTH(h_coin_ev)=64) -- UNIQUE
   ,ev_sig BYTEA NOT NULL
+  ,ewv BYTEA NOT NULL
   --  ,PRIMARY KEY (melt_serial_id, freshcoin_index) -- done per shard
   )
   PARTITION BY HASH (melt_serial_id);
@@ -390,6 +391,8 @@ COMMENT ON COLUMN refresh_revealed_coins.freshcoin_index
   IS 'index of the fresh coin being created (one melt operation may result in 
multiple fresh coins)';
 COMMENT ON COLUMN refresh_revealed_coins.coin_ev
   IS 'envelope of the new coin to be signed';
+COMMENT ON COLUMN refresh_revealed_coins.ewv
+  IS 'exchange contributed values in the creation of the fresh coin (see 
/csr)';
 COMMENT ON COLUMN refresh_revealed_coins.h_coin_ev
   IS 'hash of the envelope of the new coin to be signed (for lookups)';
 COMMENT ON COLUMN refresh_revealed_coins.ev_sig
diff --git a/src/exchangedb/irbt_callbacks.c b/src/exchangedb/irbt_callbacks.c
index 0e0264e8..cb0685ba 100644
--- a/src/exchangedb/irbt_callbacks.c
+++ b/src/exchangedb/irbt_callbacks.c
@@ -440,6 +440,8 @@ irbt_cb_table_refresh_revealed_coins (
     GNUNET_PQ_query_param_auto_from_type (&h_coin_ev),
     TALER_PQ_query_param_blinded_denom_sig (
       &td->details.refresh_revealed_coins.ev_sig),
+    TALER_PQ_query_param_exchange_withdraw_values (
+      &td->details.refresh_revealed_coins.ewv),
     GNUNET_PQ_query_param_uint64 (
       &td->details.refresh_revealed_coins.denominations_serial),
     GNUNET_PQ_query_param_uint64 (
diff --git a/src/exchangedb/lrbt_callbacks.c b/src/exchangedb/lrbt_callbacks.c
index 04be9869..dd785213 100644
--- a/src/exchangedb/lrbt_callbacks.c
+++ b/src/exchangedb/lrbt_callbacks.c
@@ -790,6 +790,9 @@ lrbt_cb_table_refresh_revealed_coins (void *cls,
       TALER_PQ_result_spec_blinded_denom_sig (
         "ev_sig",
         &td.details.refresh_revealed_coins.ev_sig),
+      TALER_PQ_result_spec_exchange_withdraw_values (
+        "ewv",
+        &td.details.refresh_revealed_coins.ewv),
       GNUNET_PQ_result_spec_uint64 (
         "denominations_serial",
         &td.details.refresh_revealed_coins.denominations_serial),
diff --git a/src/exchangedb/plugin_exchangedb_postgres.c 
b/src/exchangedb/plugin_exchangedb_postgres.c
index 9694b73c..7b8763eb 100644
--- a/src/exchangedb/plugin_exchangedb_postgres.c
+++ b/src/exchangedb/plugin_exchangedb_postgres.c
@@ -891,13 +891,14 @@ prepare_statements (struct PostgresClosure *pg)
       ",link_sig "
       ",denominations_serial "
       ",coin_ev"
+      ",ewv"
       ",h_coin_ev"
       ",ev_sig"
       ") SELECT $1, $2, $3, "
-      "         denominations_serial, $5, $6, $7"
+      "         denominations_serial, $5, $6, $7, $8"
       "    FROM denominations"
       "   WHERE denom_pub_hash=$4;",
-      7),
+      8),
     /* Obtain information about the coins created in a refresh
        operation, used in #postgres_get_refresh_reveal() */
     GNUNET_PQ_make_prepare (
@@ -908,6 +909,7 @@ prepare_statements (struct PostgresClosure *pg)
       ",rrc.h_coin_ev"
       ",rrc.link_sig"
       ",rrc.coin_ev"
+      ",rrc.ewv"
       ",rrc.ev_sig"
       " FROM refresh_commitments"
       "    JOIN refresh_revealed_coins rrc"
@@ -1213,7 +1215,9 @@ prepare_statements (struct PostgresClosure *pg)
       " tp.transfer_pub"
       ",denoms.denom_pub"
       ",rrc.ev_sig"
+      ",rrc.ewv"
       ",rrc.link_sig"
+      ",rrc.freshcoin_index"
       " FROM refresh_commitments"
       "     JOIN refresh_revealed_coins rrc"
       "       USING (melt_serial_id)"
@@ -2241,6 +2245,7 @@ prepare_statements (struct PostgresClosure *pg)
       ",link_sig"
       ",coin_ev"
       ",ev_sig"
+      ",ewv"
       ",denominations_serial"
       ",melt_serial_id"
       " FROM refresh_revealed_coins"
@@ -2532,11 +2537,12 @@ prepare_statements (struct PostgresClosure *pg)
       ",coin_ev"
       ",h_coin_ev"
       ",ev_sig"
+      ",ewv"
       ",denominations_serial"
       ",melt_serial_id"
       ") VALUES "
-      "($1, $2, $3, $4, $5, $6, $7, $8);",
-      8),
+      "($1, $2, $3, $4, $5, $6, $7, $8, $9);",
+      9),
     GNUNET_PQ_make_prepare (
       "insert_into_table_refresh_transfer_keys",
       "INSERT INTO refresh_transfer_keys"
@@ -6095,6 +6101,8 @@ postgres_insert_refresh_reveal (
       GNUNET_PQ_query_param_auto_from_type (&rrc->orig_coin_link_sig),
       GNUNET_PQ_query_param_auto_from_type (&rrc->h_denom_pub),
       TALER_PQ_query_param_blinded_planchet (&rrc->blinded_planchet),
+      // FIXME: needed? review link protocol!
+      TALER_PQ_query_param_exchange_withdraw_values (&rrc->exchange_vals),
       GNUNET_PQ_query_param_auto_from_type (&rrc->coin_envelope_hash),
       TALER_PQ_query_param_blinded_denom_sig (&rrc->coin_sig),
       GNUNET_PQ_query_param_end
@@ -6203,6 +6211,9 @@ add_revealed_coins (void *cls,
                                               &rrc->coin_envelope_hash),
         TALER_PQ_result_spec_blinded_planchet ("coin_ev",
                                                &rrc->blinded_planchet),
+        // FIXME: needed? review link protocol!
+        TALER_PQ_result_spec_exchange_withdraw_values ("ewv",
+                                                       &rrc->exchange_vals),
         TALER_PQ_result_spec_blinded_denom_sig ("ev_sig",
                                                 &rrc->coin_sig),
         GNUNET_PQ_result_spec_end
@@ -6384,6 +6395,11 @@ add_ldl (void *cls,
                                               &pos->orig_coin_link_sig),
         TALER_PQ_result_spec_blinded_denom_sig ("ev_sig",
                                                 &pos->ev_sig),
+        GNUNET_PQ_result_spec_uint32 ("freshcoin_index",
+                                      &pos->coin_refresh_offset),
+        // FIXME: needed? review link protocol!
+        TALER_PQ_result_spec_exchange_withdraw_values ("ewv",
+                                                       &pos->alg_values),
         TALER_PQ_result_spec_denom_pub ("denom_pub",
                                         &pos->denom_pub),
         GNUNET_PQ_result_spec_end
diff --git a/src/exchangedb/test_exchangedb.c b/src/exchangedb/test_exchangedb.c
index f86f5451..e290502c 100644
--- a/src/exchangedb/test_exchangedb.c
+++ b/src/exchangedb/test_exchangedb.c
@@ -1565,6 +1565,8 @@ run (void *cls)
                    TALER_denom_sig_unblind (&ds,
                                             &cbc2.sig,
                                             &bks,
+                                            &c_hash,
+                                            &alg_values,
                                             &dkp->pub));
     FAILIF (GNUNET_OK !=
             TALER_denom_pub_verify (&dkp->pub,
@@ -1582,6 +1584,8 @@ run (void *cls)
                  TALER_denom_sig_unblind (&deposit.coin.denom_sig,
                                           &cbc.sig,
                                           &bks,
+                                          &c_hash,
+                                          &alg_values,
                                           &dkp->pub));
   deadline = GNUNET_TIME_timestamp_get ();
   {
@@ -1760,6 +1764,7 @@ run (void *cls)
                                   rp->blinded_msg_size);
       TALER_denom_pub_hash (&new_dkp[cnt]->pub,
                             &ccoin->h_denom_pub);
+      ccoin->exchange_vals = alg_values;
       TALER_coin_ev_hash (bp,
                           &ccoin->h_denom_pub,
                           &ccoin->coin_envelope_hash);
@@ -2167,6 +2172,8 @@ run (void *cls)
                  TALER_denom_sig_unblind (&deposit.coin.denom_sig,
                                           &cbc.sig,
                                           &bks,
+                                          &c_hash,
+                                          &alg_values,
                                           &dkp->pub));
   RND_BLK (&deposit.csig);
   RND_BLK (&deposit.merchant_pub);
diff --git a/src/include/taler_exchangedb_plugin.h 
b/src/include/taler_exchangedb_plugin.h
index 8269672f..1cd90c28 100644
--- a/src/include/taler_exchangedb_plugin.h
+++ b/src/include/taler_exchangedb_plugin.h
@@ -317,6 +317,7 @@ struct TALER_EXCHANGEDB_TableData
       uint64_t denominations_serial;
       void *coin_ev;
       size_t coin_ev_size;
+      struct TALER_ExchangeWithdrawValues ewv;
       // h_coin_ev omitted, to be recomputed!
       struct TALER_BlindedDenominationSignature ev_sig;
     } refresh_revealed_coins;
@@ -1368,12 +1369,23 @@ struct TALER_EXCHANGEDB_LinkList
    */
   struct TALER_BlindedDenominationSignature ev_sig;
 
+  /**
+   * Exchange-provided values during the coin generation.
+   */
+  struct TALER_ExchangeWithdrawValues alg_values;
+
   /**
    * Signature of the original coin being refreshed over the
    * link data, of type #TALER_SIGNATURE_WALLET_COIN_LINK
    */
   struct TALER_CoinSpendSignatureP orig_coin_link_sig;
 
+  /**
+   * Offset that generated this coin in the refresh
+   * operation.
+   */
+  uint32_t coin_refresh_offset;
+
 };
 
 
@@ -1645,6 +1657,12 @@ struct TALER_EXCHANGEDB_RefreshRevealedCoin
    */
   struct TALER_BlindedDenominationSignature coin_sig;
 
+  /**
+   * Values contributed from the exchange to the
+   * coin generation (see /csr).
+   */
+  struct TALER_ExchangeWithdrawValues exchange_vals;
+
   /**
    * Blinded message to be signed (in envelope).
    */
diff --git a/src/include/taler_pq_lib.h b/src/include/taler_pq_lib.h
index fa312846..81f5c987 100644
--- a/src/include/taler_pq_lib.h
+++ b/src/include/taler_pq_lib.h
@@ -1,6 +1,6 @@
 /*
   This file is part of TALER
-  Copyright (C) 2014, 2015, 2016 Taler Systems SA
+  Copyright (C) 2014-2022 Taler Systems SA
 
   TALER is free software; you can redistribute it and/or modify it under the
   terms of the GNU General Public License as published by the Free Software
@@ -102,6 +102,18 @@ TALER_PQ_query_param_blinded_denom_sig (
   const struct TALER_BlindedDenominationSignature *denom_sig);
 
 
+/**
+ * Generate query parameter for the exchange's contribution during a
+ * withdraw. Internally, the various attributes of the @a alg_values will be
+ * serialized into on variable-size BLOB.
+ *
+ * @param x pointer to the query parameter to pass
+ */
+struct GNUNET_PQ_QueryParam
+TALER_PQ_query_param_exchange_withdraw_values (
+  const struct TALER_ExchangeWithdrawValues *alg_values);
+
+
 /**
  * Generate query parameter for a JSON object (stored as a string
  * in the DB).  Note that @a x must really be a JSON object or array,
@@ -179,6 +191,19 @@ TALER_PQ_result_spec_blinded_denom_sig (
   struct TALER_BlindedDenominationSignature *denom_sig);
 
 
+/**
+ * Exchange withdraw values expected.
+ *
+ * @param name name of the field in the table
+ * @param[out] ewv where to store the exchange values
+ * @return array entry for the result specification to use
+ */
+struct GNUNET_PQ_ResultSpec
+TALER_PQ_result_spec_exchange_withdraw_values (
+  const char *name,
+  struct TALER_ExchangeWithdrawValues *ewv);
+
+
 /**
  * Blinded planchet expected.
  *
diff --git a/src/lib/exchange_api_link.c b/src/lib/exchange_api_link.c
index cfa70617..0b2a1336 100644
--- a/src/lib/exchange_api_link.c
+++ b/src/lib/exchange_api_link.c
@@ -95,18 +95,25 @@ parse_link_coin (const struct TALER_EXCHANGE_LinkHandle *lh,
   struct TALER_DenominationPublicKey rpub;
   struct TALER_CoinSpendSignatureP link_sig;
   union TALER_DenominationBlindingKeyP bks;
+  struct TALER_ExchangeWithdrawValues alg_values;
+  uint32_t coin_idx;
   struct GNUNET_JSON_Specification spec[] = {
     TALER_JSON_spec_denom_pub ("denom_pub",
                                &rpub),
     TALER_JSON_spec_blinded_denom_sig ("ev_sig",
                                        &bsig),
+    // FIXME: add to spec!
+    TALER_JSON_spec_exchange_withdraw_values ("ewv",
+                                              &alg_values),
     GNUNET_JSON_spec_fixed_auto ("link_sig",
                                  &link_sig),
+    // FIXME: add to spec!
+    GNUNET_JSON_spec_uint32 ("coin_idx",
+                             &coin_idx),
     GNUNET_JSON_spec_end ()
   };
   struct TALER_TransferSecretP secret;
   struct TALER_PlanchetSecretsP ps;
-  struct TALER_ExchangeWithdrawValues alg_values;
   struct TALER_PlanchetDetail pd;
   struct TALER_CoinPubHash c_hash;
 
@@ -125,9 +132,6 @@ parse_link_coin (const struct TALER_EXCHANGE_LinkHandle *lh,
   TALER_transfer_secret_to_planchet_secret (&secret,
                                             coin_num,
                                             &ps);
-
-  // TODO: implement cipher handling
-  alg_values.cipher = TALER_DENOMINATION_RSA;
   TALER_planchet_setup_coin_priv (&ps,
                                   &alg_values,
                                   coin_priv);
@@ -165,6 +169,20 @@ parse_link_coin (const struct TALER_EXCHANGE_LinkHandle 
*lh,
 
     GNUNET_CRYPTO_eddsa_key_get_public (&lh->coin_priv.eddsa_priv,
                                         &old_coin_pub.eddsa_pub);
+    // FIXME-NEXT: this is probably the wrong 'ps'!
+    // However, the 'right' PS is not something the
+    // exchange could even give us. So probably we
+    // really need to change the derivation structure
+    // during refresh to derive the nonces differently
+    // and make /link possible!
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Link using PS(%u)=%s\n",
+                (unsigned int) coin_idx,
+                TALER_B2S (&ps));
+    TALER_cs_refresh_nonce_derive (
+      &ps,
+      coin_idx,
+      &pd.blinded_planchet.details.cs_blinded_planchet.nonce);
     TALER_coin_ev_hash (&pd.blinded_planchet,
                         &pd.denom_pub_hash,
                         &coin_envelope_hash);
diff --git a/src/lib/exchange_api_refresh_common.c 
b/src/lib/exchange_api_refresh_common.c
index b901bab3..c1552736 100644
--- a/src/lib/exchange_api_refresh_common.c
+++ b/src/lib/exchange_api_refresh_common.c
@@ -150,6 +150,10 @@ TALER_EXCHANGE_get_melt_data_ (
          so this computation is redundant, and here additionally
          repeated KAPPA times. Could be avoided with slightly
          more bookkeeping in the future */
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                  "Refresh using PS(%u)=%s\n",
+                  j,
+                  TALER_B2S (&ps));
       TALER_cs_refresh_nonce_derive (
         ps,
         j,
diff --git a/src/pq/pq_query_helper.c b/src/pq/pq_query_helper.c
index 8d6df60c..9bffdd32 100644
--- a/src/pq/pq_query_helper.c
+++ b/src/pq/pq_query_helper.c
@@ -527,6 +527,94 @@ TALER_PQ_query_param_blinded_planchet (
 }
 
 
+/**
+ * Function called to convert input argument into SQL parameters.
+ *
+ * @param cls closure
+ * @param data pointer to input argument
+ * @param data_len number of bytes in @a data (if applicable)
+ * @param[out] param_values SQL data to set
+ * @param[out] param_lengths SQL length data to set
+ * @param[out] param_formats SQL format data to set
+ * @param param_length number of entries available in the @a param_values, @a 
param_lengths and @a param_formats arrays
+ * @param[out] scratch buffer for dynamic allocations (to be done via 
#GNUNET_malloc()
+ * @param scratch_length number of entries left in @a scratch
+ * @return -1 on error, number of offsets used in @a scratch otherwise
+ */
+static int
+qconv_exchange_withdraw_values (void *cls,
+                                const void *data,
+                                size_t data_len,
+                                void *param_values[],
+                                int param_lengths[],
+                                int param_formats[],
+                                unsigned int param_length,
+                                void *scratch[],
+                                unsigned int scratch_length)
+{
+  const struct TALER_ExchangeWithdrawValues *alg_values = data;
+  size_t tlen;
+  size_t len;
+  uint32_t be[2];
+  char *buf;
+
+  (void) cls;
+  (void) data_len;
+  GNUNET_assert (1 == param_length);
+  GNUNET_assert (scratch_length > 0);
+  GNUNET_break (NULL == cls);
+  be[0] = htonl ((uint32_t) alg_values->cipher);
+  be[1] = htonl (0x010000); /* magic marker: EWV */
+  switch (alg_values->cipher)
+  {
+  case TALER_DENOMINATION_RSA:
+    tlen = 0;
+    break;
+  case TALER_DENOMINATION_CS:
+    tlen = sizeof (struct TALER_ExchangeWithdrawCsValues);
+    break;
+  default:
+    GNUNET_assert (0);
+  }
+  len = tlen + sizeof (be);
+  buf = GNUNET_malloc (len);
+  memcpy (buf,
+          &be,
+          sizeof (be));
+  switch (alg_values->cipher)
+  {
+  case TALER_DENOMINATION_RSA:
+    break;
+  case TALER_DENOMINATION_CS:
+    memcpy (&buf[sizeof (be)],
+            &alg_values->details.cs_values,
+            tlen);
+    break;
+  default:
+    GNUNET_assert (0);
+  }
+  scratch[0] = buf;
+  param_values[0] = (void *) buf;
+  param_lengths[0] = len;
+  param_formats[0] = 1;
+  return 1;
+}
+
+
+struct GNUNET_PQ_QueryParam
+TALER_PQ_query_param_exchange_withdraw_values (
+  const struct TALER_ExchangeWithdrawValues *alg_values)
+{
+  struct GNUNET_PQ_QueryParam res = {
+    .conv = &qconv_exchange_withdraw_values,
+    .data = alg_values,
+    .num_params = 1
+  };
+
+  return res;
+}
+
+
 /**
  * Function called to convert input argument into SQL parameters.
  *
diff --git a/src/pq/pq_result_helper.c b/src/pq/pq_result_helper.c
index 6ee5da53..33edc889 100644
--- a/src/pq/pq_result_helper.c
+++ b/src/pq/pq_result_helper.c
@@ -1,6 +1,6 @@
 /*
   This file is part of TALER
-  Copyright (C) 2014, 2015, 2016, 2021 Taler Systems SA
+  Copyright (C) 2014-2022 Taler Systems SA
 
   TALER is free software; you can redistribute it and/or modify it under the
   terms of the GNU General Public License as published by the Free Software
@@ -855,4 +855,110 @@ TALER_PQ_result_spec_blinded_planchet (
 }
 
 
+/**
+ * Extract data from a Postgres database @a result at row @a row.
+ *
+ * @param cls closure
+ * @param result where to extract data from
+ * @param int row to extract data from
+ * @param fname name (or prefix) of the fields to extract from
+ * @param[in,out] dst_size where to store size of result, may be NULL
+ * @param[out] dst where to store the result
+ * @return
+ *   #GNUNET_YES if all results could be extracted
+ *   #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
+ */
+static enum GNUNET_GenericReturnValue
+extract_exchange_withdraw_values (void *cls,
+                                  PGresult *result,
+                                  int row,
+                                  const char *fname,
+                                  size_t *dst_size,
+                                  void *dst)
+{
+  struct TALER_ExchangeWithdrawValues *alg_values = dst;
+  size_t len;
+  const char *res;
+  int fnum;
+  uint32_t be[2];
+
+  (void) cls;
+  (void) dst_size;
+  fnum = PQfnumber (result,
+                    fname);
+  if (fnum < 0)
+  {
+    GNUNET_break (0);
+    return GNUNET_SYSERR;
+  }
+  if (PQgetisnull (result,
+                   row,
+                   fnum))
+    return GNUNET_NO;
+
+  /* if a field is null, continue but
+   * remember that we now return a different result */
+  len = PQgetlength (result,
+                     row,
+                     fnum);
+  res = PQgetvalue (result,
+                    row,
+                    fnum);
+  if (len < sizeof (be))
+  {
+    GNUNET_break (0);
+    return GNUNET_SYSERR;
+  }
+  memcpy (&be,
+          res,
+          sizeof (be));
+  if (0x010000 != ntohl (be[1])) /* magic marker: EWV */
+  {
+    GNUNET_break (0);
+    return GNUNET_SYSERR;
+  }
+  res += sizeof (be);
+  len -= sizeof (be);
+  alg_values->cipher = ntohl (be[0]);
+  switch (alg_values->cipher)
+  {
+  case TALER_DENOMINATION_RSA:
+    if (0 != len)
+    {
+      GNUNET_break (0);
+      return GNUNET_SYSERR;
+    }
+    return GNUNET_OK;
+  case TALER_DENOMINATION_CS:
+    if (sizeof (struct TALER_ExchangeWithdrawCsValues) != len)
+    {
+      GNUNET_break (0);
+      return GNUNET_SYSERR;
+    }
+    memcpy (&alg_values->details.cs_values,
+            res,
+            len);
+    return GNUNET_OK;
+  default:
+    GNUNET_break (0);
+  }
+  return GNUNET_SYSERR;
+}
+
+
+struct GNUNET_PQ_ResultSpec
+TALER_PQ_result_spec_exchange_withdraw_values (
+  const char *name,
+  struct TALER_ExchangeWithdrawValues *ewv)
+{
+  struct GNUNET_PQ_ResultSpec res = {
+    .conv = &extract_exchange_withdraw_values,
+    .dst = (void *) ewv,
+    .fname = name
+  };
+
+  return res;
+}
+
+
 /* end of pq_result_helper.c */
diff --git a/src/testing/test_exchange_api.c b/src/testing/test_exchange_api.c
index 1b31b646..d045c21e 100644
--- a/src/testing/test_exchange_api.c
+++ b/src/testing/test_exchange_api.c
@@ -1,6 +1,6 @@
 /*
   This file is part of TALER
-  Copyright (C) 2014--2020 Taler Systems SA
+  Copyright (C) 2014--2022 Taler Systems SA
 
   TALER is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as
@@ -41,9 +41,12 @@
  */
 static char *config_file;
 
+/**
+ * Special configuration file to use when we want reserves
+ * to expire 'immediately'.
+ */
 static char *config_file_expire_reserve_now;
 
-
 /**
  * Exchange configuration data.
  */
@@ -54,6 +57,14 @@ static struct TALER_TESTING_ExchangeConfiguration ec;
  */
 static struct TALER_TESTING_BankConfiguration bc;
 
+/**
+ * Some tests behave differently when using CS as we cannot
+ * re-use the coin private key for different denominations
+ * due to the derivation of it with the /csr values. Hence
+ * some tests behave differently in CS mode, hence this
+ * flag.
+ */
+static bool uses_cs;
 
 /**
  * Execute the taler-exchange-wirewatch command with
@@ -142,6 +153,11 @@ run (void *cls,
     /**
      * Withdraw EUR:1 using the SAME private coin key as for the previous coin
      * (in violation of the specification, to be detected on spending!).
+     * However, note that this does NOT work with 'CS', as for a different
+     * denomination we get different R0/R1 values from the exchange, and
+     * thus will generate a different coin private key as R0/R1 are hashed
+     * into the coin priv. So here, we fail to 'reuse' the key due to the
+     * cryptographic construction!
      */
     TALER_TESTING_cmd_withdraw_amount_reuse_key ("withdraw-coin-1x",
                                                  "create-reserve-1",
@@ -180,6 +196,13 @@ run (void *cls,
     TALER_TESTING_cmd_deposit_replay ("deposit-simple-replay",
                                       "deposit-simple",
                                       MHD_HTTP_OK),
+    /* This creates a conflict, as we have the same coin public key (reuse!),
+       but different denomination public keys (which is not allowed).
+       However, note that this does NOT work with 'CS', as for a different
+       denomination we get different R0/R1 values from the exchange, and
+       thus will generate a different coin private key as R0/R1 are hashed
+       into the coin priv. So here, we fail to 'reuse' the key due to the
+       cryptographic construction! */
     TALER_TESTING_cmd_deposit ("deposit-reused-coin-key-failure",
                                "withdraw-coin-1x",
                                0,
@@ -187,7 +210,9 @@ run (void *cls,
                                "{\"items\":[{\"name\":\"ice 
cream\",\"value\":1}]}",
                                GNUNET_TIME_UNIT_ZERO,
                                "EUR:1",
-                               MHD_HTTP_CONFLICT),
+                               uses_cs
+                               ? MHD_HTTP_OK
+                               : MHD_HTTP_CONFLICT),
     /**
      * Try to double spend using different wire details.
      */
@@ -230,7 +255,10 @@ run (void *cls,
   struct TALER_TESTING_Command refresh[] = {
     /**
      * Try to melt the coin that shared the private key with another
-     * coin (should fail). */
+     * coin (should fail). Note that in the CS-case, we fail also
+     * with MHD_HTTP_CONFLICT, but for a different reason: here it
+     * is not a denomination conflict, but a double-spending conflict.
+     */
     TALER_TESTING_cmd_melt ("refresh-melt-reused-coin-key-failure",
                             "withdraw-coin-1x",
                             MHD_HTTP_CONFLICT,
@@ -839,7 +867,9 @@ run (void *cls,
                               config_file),
     /* Check recoup is failing for the coin with the reused coin key */
     TALER_TESTING_cmd_recoup ("recoup-2x",
-                              MHD_HTTP_CONFLICT,
+                              uses_cs
+                              ? MHD_HTTP_OK
+                              : MHD_HTTP_CONFLICT,
                               "withdraw-coin-1x",
                               "EUR:1"),
     TALER_TESTING_cmd_recoup ("recoup-2",
@@ -988,6 +1018,7 @@ main (int argc,
                     NULL);
   cipher = GNUNET_TESTING_get_testname_from_underscore (argv[0]);
   GNUNET_assert (NULL != cipher);
+  uses_cs = (0 == strcmp (cipher, "cs"));
   GNUNET_asprintf (&config_file,
                    "test_exchange_api-%s.conf",
                    cipher);
diff --git a/src/util/crypto.c b/src/util/crypto.c
index 447805bf..76657f41 100644
--- a/src/util/crypto.c
+++ b/src/util/crypto.c
@@ -277,6 +277,7 @@ TALER_planchet_blinding_secret_create (
 }
 
 
+// FIXME: move to denom.c?
 void
 TALER_planchet_setup_coin_priv (
   const struct TALER_PlanchetSecretsP *ps,

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