summaryrefslogtreecommitdiff
path: root/src/exchange
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2022-02-15 17:07:13 +0100
committerChristian Grothoff <christian@grothoff.org>2022-02-15 17:07:13 +0100
commitef938e0f7aca4232cbae322fdc7b68ed21fcd679 (patch)
tree9ea7af8c56ca6a5fd0bc2131bbde8549dc2eef13 /src/exchange
parent8ecbdeb55b5f9dfcd39d0ee1eaa2fc3f00aa9c5d (diff)
downloadexchange-ef938e0f7aca4232cbae322fdc7b68ed21fcd679.tar.gz
exchange-ef938e0f7aca4232cbae322fdc7b68ed21fcd679.tar.bz2
exchange-ef938e0f7aca4232cbae322fdc7b68ed21fcd679.zip
-correctly implement CS idempotency check on withdraw
Diffstat (limited to 'src/exchange')
-rw-r--r--src/exchange/taler-exchange-httpd_recoup.c24
-rw-r--r--src/exchange/taler-exchange-httpd_withdraw.c25
2 files changed, 31 insertions, 18 deletions
diff --git a/src/exchange/taler-exchange-httpd_recoup.c b/src/exchange/taler-exchange-httpd_recoup.c
index c635769c6..ea319d11c 100644
--- a/src/exchange/taler-exchange-httpd_recoup.c
+++ b/src/exchange/taler-exchange-httpd_recoup.c
@@ -1,6 +1,6 @@
/*
This file is part of TALER
- Copyright (C) 2017-2021 Taler Systems SA
+ Copyright (C) 2017-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
@@ -40,9 +40,9 @@
struct RecoupContext
{
/**
- * Hash of the blinded coin.
+ * Hash identifying the withdraw request.
*/
- struct TALER_BlindedCoinHash h_blind;
+ struct TALER_WithdrawIdentificationHash wih;
/**
* Set by #recoup_transaction() to the reserve that will
@@ -273,9 +273,9 @@ verify_and_execute_recoup (
blinded_planchet.details.cs_blinded_planchet.nonce
= *nonce;
if (GNUNET_OK !=
- TALER_coin_ev_hash (&blinded_planchet,
- &coin->denom_pub_hash,
- &pc.h_blind))
+ TALER_withdraw_request_hash (&blinded_planchet,
+ &coin->denom_pub_hash,
+ &pc.wih))
{
GNUNET_break (0);
return TALER_MHD_reply_with_error (connection,
@@ -308,10 +308,10 @@ verify_and_execute_recoup (
{
enum GNUNET_DB_QueryStatus qs;
- qs = TEH_plugin->get_reserve_by_h_blind (TEH_plugin->cls,
- &pc.h_blind,
- &pc.reserve_pub,
- &pc.reserve_out_serial_id);
+ qs = TEH_plugin->get_reserve_by_wih (TEH_plugin->cls,
+ &pc.wih,
+ &pc.reserve_pub,
+ &pc.reserve_out_serial_id);
if (0 > qs)
{
GNUNET_break (0);
@@ -319,13 +319,13 @@ verify_and_execute_recoup (
connection,
MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_GENERIC_DB_FETCH_FAILED,
- "get_reserve_by_h_blind");
+ "get_reserve_by_wih");
}
if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
{
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Recoup requested for unknown envelope %s\n",
- GNUNET_h2s (&pc.h_blind.hash));
+ GNUNET_h2s (&pc.wih.hash));
return TALER_MHD_reply_with_error (
connection,
MHD_HTTP_NOT_FOUND,
diff --git a/src/exchange/taler-exchange-httpd_withdraw.c b/src/exchange/taler-exchange-httpd_withdraw.c
index 3799187c1..a3ac1de33 100644
--- a/src/exchange/taler-exchange-httpd_withdraw.c
+++ b/src/exchange/taler-exchange-httpd_withdraw.c
@@ -92,6 +92,11 @@ struct WithdrawContext
{
/**
+ * Hash that uniquely identifies the withdraw request.
+ */
+ struct TALER_WithdrawIdentificationHash wih;
+
+ /**
* Hash of the (blinded) message to be signed by the Exchange.
*/
struct TALER_BlindedCoinHash h_coin_envelope;
@@ -155,6 +160,7 @@ withdraw_transaction (void *cls,
now = GNUNET_TIME_timestamp_get ();
qs = TEH_plugin->do_withdraw (TEH_plugin->cls,
+ &wc->wih,
&wc->collectable,
now,
&found,
@@ -294,7 +300,7 @@ check_request_idempotent (struct TEH_RequestContext *rc,
enum GNUNET_DB_QueryStatus qs;
qs = TEH_plugin->get_withdraw_info (TEH_plugin->cls,
- &wc->collectable.h_coin_envelope,
+ &wc->wih,
&wc->collectable);
if (0 > qs)
{
@@ -496,7 +502,18 @@ TEH_handler_withdraw (struct TEH_RequestContext *rc,
NULL);
}
- // TODO: if CS: check nonce for reuse
+ if (GNUNET_OK !=
+ TALER_withdraw_request_hash (&wc.blinded_planchet,
+ &wc.collectable.denom_pub_hash,
+ &wc.wih))
+ {
+ GNUNET_break (0);
+ GNUNET_JSON_parse_free (spec);
+ return TALER_MHD_reply_with_error (rc->connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE,
+ NULL);
+ }
/* Sign before transaction! */
ec = TEH_keys_denomination_sign (
@@ -535,10 +552,6 @@ 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;