gnunet-svn
[Top][All Lists]
Advanced

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

[taler-exchange] branch master updated: -towards fixing the protocol


From: gnunet
Subject: [taler-exchange] branch master updated: -towards fixing the protocol
Date: Mon, 14 Feb 2022 23:02:28 +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 bd77bcb5 -towards fixing the protocol
bd77bcb5 is described below

commit bd77bcb52dcad4b761f3db0acaa6b71b112a31c2
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Mon Feb 14 23:02:25 2022 +0100

    -towards fixing the protocol
---
 src/exchange/taler-exchange-httpd_link.c            |  8 +++++++-
 src/exchange/taler-exchange-httpd_recoup-refresh.c  | 12 ++++++++++++
 src/exchange/taler-exchange-httpd_recoup.c          | 12 ++++++++++++
 .../taler-exchange-httpd_refreshes_reveal.c         |  7 +++++++
 src/exchange/taler-exchange-httpd_withdraw.c        |  4 ++++
 src/exchangedb/plugin_exchangedb_postgres.c         | 10 ++++++++++
 src/include/taler_exchangedb_plugin.h               |  9 +++++++++
 src/lib/exchange_api_link.c                         | 17 +++++++++++++++++
 src/lib/exchange_api_recoup.c                       | 19 +++++++++++++++++++
 src/lib/exchange_api_recoup_refresh.c               | 21 +++++++++++++++++++++
 src/util/denom.c                                    |  6 ++----
 11 files changed, 120 insertions(+), 5 deletions(-)

diff --git a/src/exchange/taler-exchange-httpd_link.c 
b/src/exchange/taler-exchange-httpd_link.c
index de10f8b8..47b803ff 100644
--- a/src/exchange/taler-exchange-httpd_link.c
+++ b/src/exchange/taler-exchange-httpd_link.c
@@ -91,7 +91,13 @@ handle_link_data (void *cls,
       TALER_JSON_pack_exchange_withdraw_values ("ewv",
                                                 &pos->alg_values),
       GNUNET_JSON_pack_data_auto ("link_sig",
-                                  &pos->orig_coin_link_sig));
+                                  &pos->orig_coin_link_sig),
+      GNUNET_JSON_pack_allow_null (
+        pos->have_nonce
+        ? GNUNET_JSON_pack_data_auto ("cs_nonce",
+                                      &pos->nonce)
+        : GNUNET_JSON_pack_string ("cs_nonce",
+                                   NULL)));
     if ( (NULL == obj) ||
          (0 !=
           json_array_append_new (list,
diff --git a/src/exchange/taler-exchange-httpd_recoup-refresh.c 
b/src/exchange/taler-exchange-httpd_recoup-refresh.c
index 3e058894..829e2cbd 100644
--- a/src/exchange/taler-exchange-httpd_recoup-refresh.c
+++ b/src/exchange/taler-exchange-httpd_recoup-refresh.c
@@ -174,6 +174,7 @@ verify_and_execute_recoup_refresh (
   const struct TALER_CoinPublicInfo *coin,
   const struct TALER_ExchangeWithdrawValues *exchange_vals,
   const union TALER_DenominationBlindingKeyP *coin_bks,
+  const struct TALER_CsNonce *nonce,
   const struct TALER_CoinSpendSignatureP *coin_sig)
 {
   struct RecoupContext pc;
@@ -263,6 +264,9 @@ verify_and_execute_recoup_refresh (
         TALER_EC_EXCHANGE_RECOUP_REFRESH_BLINDING_FAILED,
         NULL);
     }
+    if (TALER_DENOMINATION_CS == blinded_planchet.cipher)
+      blinded_planchet.details.cs_blinded_planchet.nonce
+        = *nonce;
     TALER_coin_ev_hash (&blinded_planchet,
                         &coin->denom_pub_hash,
                         &h_blind);
@@ -360,6 +364,7 @@ TEH_handler_recoup_refresh (struct MHD_Connection 
*connection,
   union TALER_DenominationBlindingKeyP coin_bks;
   struct TALER_CoinSpendSignatureP coin_sig;
   struct TALER_ExchangeWithdrawValues exchange_vals;
+  struct TALER_CsNonce nonce;
   struct GNUNET_JSON_Specification spec[] = {
     GNUNET_JSON_spec_fixed_auto ("denom_pub_hash",
                                  &coin.denom_pub_hash),
@@ -371,12 +376,18 @@ TEH_handler_recoup_refresh (struct MHD_Connection 
*connection,
                                  &coin_bks),
     GNUNET_JSON_spec_fixed_auto ("coin_sig",
                                  &coin_sig),
+    GNUNET_JSON_spec_mark_optional (
+      GNUNET_JSON_spec_fixed_auto ("cs_nonce",
+                                   &nonce)),
     GNUNET_JSON_spec_end ()
   };
 
   memset (&coin,
           0,
           sizeof (coin));
+  memset (&nonce,
+          0,
+          sizeof (nonce));
   coin.coin_pub = *coin_pub;
   ret = TALER_MHD_parse_json_data (connection,
                                    root,
@@ -392,6 +403,7 @@ TEH_handler_recoup_refresh (struct MHD_Connection 
*connection,
                                              &coin,
                                              &exchange_vals,
                                              &coin_bks,
+                                             &nonce,
                                              &coin_sig);
     GNUNET_JSON_parse_free (spec);
     return res;
diff --git a/src/exchange/taler-exchange-httpd_recoup.c 
b/src/exchange/taler-exchange-httpd_recoup.c
index f4e426fb..c635769c 100644
--- a/src/exchange/taler-exchange-httpd_recoup.c
+++ b/src/exchange/taler-exchange-httpd_recoup.c
@@ -177,6 +177,7 @@ verify_and_execute_recoup (
   const struct TALER_CoinPublicInfo *coin,
   const struct TALER_ExchangeWithdrawValues *exchange_vals,
   const union TALER_DenominationBlindingKeyP *coin_bks,
+  const struct TALER_CsNonce *nonce,
   const struct TALER_CoinSpendSignatureP *coin_sig)
 {
   struct RecoupContext pc;
@@ -268,6 +269,9 @@ verify_and_execute_recoup (
         TALER_EC_EXCHANGE_RECOUP_BLINDING_FAILED,
         NULL);
     }
+    if (TALER_DENOMINATION_CS == blinded_planchet.cipher)
+      blinded_planchet.details.cs_blinded_planchet.nonce
+        = *nonce;
     if (GNUNET_OK !=
         TALER_coin_ev_hash (&blinded_planchet,
                             &coin->denom_pub_hash,
@@ -373,6 +377,7 @@ TEH_handler_recoup (struct MHD_Connection *connection,
   union TALER_DenominationBlindingKeyP coin_bks;
   struct TALER_CoinSpendSignatureP coin_sig;
   struct TALER_ExchangeWithdrawValues exchange_vals;
+  struct TALER_CsNonce nonce;
   struct GNUNET_JSON_Specification spec[] = {
     GNUNET_JSON_spec_fixed_auto ("denom_pub_hash",
                                  &coin.denom_pub_hash),
@@ -384,12 +389,18 @@ TEH_handler_recoup (struct MHD_Connection *connection,
                                  &coin_bks),
     GNUNET_JSON_spec_fixed_auto ("coin_sig",
                                  &coin_sig),
+    GNUNET_JSON_spec_mark_optional (
+      GNUNET_JSON_spec_fixed_auto ("cs_nonce",
+                                   &nonce)),
     GNUNET_JSON_spec_end ()
   };
 
   memset (&coin,
           0,
           sizeof (coin));
+  memset (&nonce,
+          0,
+          sizeof (nonce));
   coin.coin_pub = *coin_pub;
   ret = TALER_MHD_parse_json_data (connection,
                                    root,
@@ -408,6 +419,7 @@ TEH_handler_recoup (struct MHD_Connection *connection,
                                      &coin,
                                      &exchange_vals,
                                      &coin_bks,
+                                     &nonce,
                                      &coin_sig);
     GNUNET_JSON_parse_free (spec);
     return res;
diff --git a/src/exchange/taler-exchange-httpd_refreshes_reveal.c 
b/src/exchange/taler-exchange-httpd_refreshes_reveal.c
index 0d8f7bf9..779b9df4 100644
--- a/src/exchange/taler-exchange-httpd_refreshes_reveal.c
+++ b/src/exchange/taler-exchange-httpd_refreshes_reveal.c
@@ -634,6 +634,13 @@ resolve_refreshes_reveal_denominations (struct 
MHD_Connection *connection,
 
       rrc->blinded_planchet = rcds[i].blinded_planchet;
     }
+    // FIXME: in CS-case, we MUST check if signatures
+    // already exist under the given nonce
+    // (TODO: check: refresh session hash OK?), and if so,
+    // we MUST return the existing signatures (c0/c1 may have changed!)
+    // and MUST NOT return the fresh signatures!
+    // => change this to a 'do_refresh_reveal' and
+    // change SQL to return existing signatures (if any)!
     qs = TEH_plugin->insert_refresh_reveal (TEH_plugin->cls,
                                             melt_serial_id,
                                             num_fresh_coins,
diff --git a/src/exchange/taler-exchange-httpd_withdraw.c 
b/src/exchange/taler-exchange-httpd_withdraw.c
index 7572f85d..3799187c 100644
--- a/src/exchange/taler-exchange-httpd_withdraw.c
+++ b/src/exchange/taler-exchange-httpd_withdraw.c
@@ -535,6 +535,10 @@ TEH_handler_withdraw (struct TEH_RequestContext *rc,
   /* Clean up and send back final response */
   GNUNET_JSON_parse_free (spec);
 
+  // FIXME: in CS-case, we MUST re-transmit any _existing_ signature
+  // (if database had a record matching the nonce)
+  // instead of sending a 'fresh' one back (as c0/c1 may differ in
+  // a client attack!
   {
     MHD_RESULT ret;
 
diff --git a/src/exchangedb/plugin_exchangedb_postgres.c 
b/src/exchangedb/plugin_exchangedb_postgres.c
index dfa18e9e..ce184f48 100644
--- a/src/exchangedb/plugin_exchangedb_postgres.c
+++ b/src/exchangedb/plugin_exchangedb_postgres.c
@@ -1218,6 +1218,7 @@ prepare_statements (struct PostgresClosure *pg)
       ",rrc.ewv"
       ",rrc.link_sig"
       ",rrc.freshcoin_index"
+      ",rrc.coin_ev"
       " FROM refresh_commitments"
       "     JOIN refresh_revealed_coins rrc"
       "       USING (melt_serial_id)"
@@ -6385,6 +6386,7 @@ add_ldl (void *cls,
 
     pos = GNUNET_new (struct TALER_EXCHANGEDB_LinkList);
     {
+      struct TALER_BlindedPlanchet bp;
       struct GNUNET_PQ_ResultSpec rs[] = {
         GNUNET_PQ_result_spec_auto_from_type ("transfer_pub",
                                               &transfer_pub),
@@ -6398,6 +6400,8 @@ add_ldl (void *cls,
                                                        &pos->alg_values),
         TALER_PQ_result_spec_denom_pub ("denom_pub",
                                         &pos->denom_pub),
+        TALER_PQ_result_spec_blinded_planchet ("coin_ev",
+                                               &bp),
         GNUNET_PQ_result_spec_end
       };
 
@@ -6411,6 +6415,12 @@ add_ldl (void *cls,
         ldctx->status = GNUNET_SYSERR;
         return;
       }
+      if (TALER_DENOMINATION_CS == bp.cipher)
+      {
+        pos->nonce = bp.details.cs_blinded_planchet.nonce;
+        pos->have_nonce = true;
+      }
+      TALER_blinded_planchet_free (&bp);
     }
     if ( (NULL != ldctx->last) &&
          (0 == GNUNET_memcmp (&transfer_pub,
diff --git a/src/include/taler_exchangedb_plugin.h 
b/src/include/taler_exchangedb_plugin.h
index 844de585..eea170c1 100644
--- a/src/include/taler_exchangedb_plugin.h
+++ b/src/include/taler_exchangedb_plugin.h
@@ -1380,12 +1380,21 @@ struct TALER_EXCHANGEDB_LinkList
    */
   struct TALER_CoinSpendSignatureP orig_coin_link_sig;
 
+  /**
+   * CS nonce, if cipher is CS.
+   */
+  struct TALER_CsNonce nonce;
+
   /**
    * Offset that generated this coin in the refresh
    * operation.
    */
   uint32_t coin_refresh_offset;
 
+  /**
+   * Set to true if @e nonce was initialized.
+   */
+  bool have_nonce;
 };
 
 
diff --git a/src/lib/exchange_api_link.c b/src/lib/exchange_api_link.c
index 6ebb7227..a44ccdce 100644
--- a/src/lib/exchange_api_link.c
+++ b/src/lib/exchange_api_link.c
@@ -92,6 +92,7 @@ parse_link_coin (const struct TALER_EXCHANGE_LinkHandle *lh,
   struct TALER_CoinSpendSignatureP link_sig;
   union TALER_DenominationBlindingKeyP bks;
   struct TALER_ExchangeWithdrawValues alg_values;
+  struct TALER_CsNonce nonce;
   uint32_t coin_idx;
   struct GNUNET_JSON_Specification spec[] = {
     TALER_JSON_spec_denom_pub ("denom_pub",
@@ -104,6 +105,9 @@ parse_link_coin (const struct TALER_EXCHANGE_LinkHandle *lh,
                                  &link_sig),
     GNUNET_JSON_spec_uint32 ("coin_idx",
                              &coin_idx),
+    GNUNET_JSON_spec_mark_optional (
+      GNUNET_JSON_spec_fixed_auto ("cs_nonce",
+                                   &nonce)),
     GNUNET_JSON_spec_end ()
   };
   struct TALER_TransferSecretP secret;
@@ -111,6 +115,9 @@ parse_link_coin (const struct TALER_EXCHANGE_LinkHandle *lh,
   struct TALER_CoinPubHash c_hash;
 
   /* parse reply */
+  memset (&nonce,
+          0,
+          sizeof (nonce));
   if (GNUNET_OK !=
       GNUNET_JSON_parse (json,
                          spec,
@@ -143,6 +150,16 @@ parse_link_coin (const struct TALER_EXCHANGE_LinkHandle 
*lh,
     GNUNET_JSON_parse_free (spec);
     return GNUNET_SYSERR;
   }
+  if (TALER_DENOMINATION_CS == alg_values.cipher)
+  {
+    if (GNUNET_is_zero (&nonce))
+    {
+      GNUNET_break_op (0);
+      GNUNET_JSON_parse_free (spec);
+      return GNUNET_SYSERR;
+    }
+    pd.blinded_planchet.details.cs_blinded_planchet.nonce = nonce;
+  }
   /* extract coin and signature */
   if (GNUNET_OK !=
       TALER_denom_sig_unblind (&lci->sig,
diff --git a/src/lib/exchange_api_recoup.c b/src/lib/exchange_api_recoup.c
index a4ad0cce..9b7201cd 100644
--- a/src/lib/exchange_api_recoup.c
+++ b/src/lib/exchange_api_recoup.c
@@ -328,6 +328,25 @@ TALER_EXCHANGE_recoup (struct TALER_EXCHANGE_Handle 
*exchange,
                                 &coin_sig),
     GNUNET_JSON_pack_data_auto ("coin_blind_key_secret",
                                 &bks));
+  if (TALER_DENOMINATION_CS == denom_sig->cipher)
+  {
+    struct TALER_CsNonce nonce;
+
+    // FIXME: add this to the spec!
+    /* NOTE: this is not elegant, and as per the note in TALER_coin_ev_hash()
+       it is not strictly clear that the nonce is needed. Best case would be
+       to find a way to include it more 'naturally' somehow, for example with
+       the variant union version of bks! */
+    TALER_cs_withdraw_nonce_derive (ps,
+                                    &nonce);
+    GNUNET_assert (
+      0 ==
+      json_object_set_new (recoup_obj,
+                           "cs_nonce",
+                           GNUNET_JSON_from_data_auto (
+                             &nonce)));
+  }
+
   {
     char pub_str[sizeof (struct TALER_CoinSpendPublicKeyP) * 2];
     char *end;
diff --git a/src/lib/exchange_api_recoup_refresh.c 
b/src/lib/exchange_api_recoup_refresh.c
index 9133e594..02e99415 100644
--- a/src/lib/exchange_api_recoup_refresh.c
+++ b/src/lib/exchange_api_recoup_refresh.c
@@ -332,6 +332,27 @@ TALER_EXCHANGE_recoup_refresh (
                                 &coin_sig),
     GNUNET_JSON_pack_data_auto ("coin_blind_key_secret",
                                 &bks));
+
+  if (TALER_DENOMINATION_CS == denom_sig->cipher)
+  {
+    struct TALER_CsNonce nonce;
+
+    // FIXME: add this to the spec!
+    /* NOTE: this is not elegant, and as per the note in TALER_coin_ev_hash()
+       it is not strictly clear that the nonce is needed. Best case would be
+       to find a way to include it more 'naturally' somehow, for example with
+       the variant union version of bks! */
+    TALER_cs_refresh_nonce_derive (rms,
+                                   idx,
+                                   &nonce);
+    GNUNET_assert (
+      0 ==
+      json_object_set_new (recoup_obj,
+                           "cs_nonce",
+                           GNUNET_JSON_from_data_auto (
+                             &nonce)));
+  }
+
   {
     char pub_str[sizeof (struct TALER_CoinSpendPublicKeyP) * 2];
     char *end;
diff --git a/src/util/denom.c b/src/util/denom.c
index 69e72350..30e8dc9d 100644
--- a/src/util/denom.c
+++ b/src/util/denom.c
@@ -806,18 +806,16 @@ TALER_coin_ev_hash (const struct TALER_BlindedPlanchet 
*blinded_planchet,
       blinded_planchet->details.rsa_blinded_planchet.blinded_msg_size);
     break;
   case TALER_DENOMINATION_CS:
+    // FIMXE: c-values MUST NOT be included in idempotency check
+    // during withdraw/refresh, but right now they are!!!
     GNUNET_CRYPTO_hash_context_read (
       hash_context,
       &blinded_planchet->details.cs_blinded_planchet.c[0],
       sizeof (struct GNUNET_CRYPTO_CsC) * 2);
-#if FIXME
-    /* Must include this for refresh check, but
-       must EXCLUDE this in link signature (see TALER_LinkDataPS!) */
     GNUNET_CRYPTO_hash_context_read (
       hash_context,
       &blinded_planchet->details.cs_blinded_planchet.nonce,
       sizeof (struct TALER_CsNonce));
-#endif
     break;
   default:
     GNUNET_break (0);

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