summaryrefslogtreecommitdiff
path: root/src/exchange/taler-exchange-httpd_recoup.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/exchange/taler-exchange-httpd_recoup.c')
-rw-r--r--src/exchange/taler-exchange-httpd_recoup.c77
1 files changed, 58 insertions, 19 deletions
diff --git a/src/exchange/taler-exchange-httpd_recoup.c b/src/exchange/taler-exchange-httpd_recoup.c
index 0deaa8bbb..afbbd7474 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_BlindedCoinHashP h_coin_ev;
/**
* Set by #recoup_transaction() to the reserve that will
@@ -58,7 +58,7 @@ struct RecoupContext
/**
* Key used to blind the coin.
*/
- const union TALER_DenominationBlindingKeyP *coin_bks;
+ const union GNUNET_CRYPTO_BlindingSecretP *coin_bks;
/**
* Signature of the coin requesting recoup.
@@ -149,6 +149,7 @@ recoup_transaction (void *cls,
*mhd_ret = TEH_RESPONSE_reply_coin_insufficient_funds (
connection,
TALER_EC_EXCHANGE_GENERIC_INSUFFICIENT_FUNDS,
+ &pc->coin->denom_pub_hash,
&pc->coin->coin_pub);
return GNUNET_DB_STATUS_HARD_ERROR;
}
@@ -165,7 +166,10 @@ recoup_transaction (void *cls,
*
* @param connection the MHD connection to handle
* @param coin information about the coin
+ * @param exchange_vals values contributed by the exchange
+ * during withdrawal
* @param coin_bks blinding data of the coin (to be checked)
+ * @param nonce coin's nonce if CS is used
* @param coin_sig signature of the coin
* @return MHD result code
*/
@@ -173,7 +177,9 @@ static MHD_RESULT
verify_and_execute_recoup (
struct MHD_Connection *connection,
const struct TALER_CoinPublicInfo *coin,
- const union TALER_DenominationBlindingKeyP *coin_bks,
+ const struct TALER_ExchangeWithdrawValues *exchange_vals,
+ const union GNUNET_CRYPTO_BlindingSecretP *coin_bks,
+ const union GNUNET_CRYPTO_BlindSessionNonce *nonce,
const struct TALER_CoinSpendSignatureP *coin_sig)
{
struct RecoupContext pc;
@@ -215,6 +221,17 @@ verify_and_execute_recoup (
}
/* check denomination signature */
+ switch (dk->denom_pub.bsign_pub_key->cipher)
+ {
+ case GNUNET_CRYPTO_BSA_RSA:
+ TEH_METRICS_num_verifications[TEH_MT_SIGNATURE_RSA]++;
+ break;
+ case GNUNET_CRYPTO_BSA_CS:
+ TEH_METRICS_num_verifications[TEH_MT_SIGNATURE_CS]++;
+ break;
+ default:
+ break;
+ }
if (GNUNET_YES !=
TALER_test_coin_valid (coin,
&dk->denom_pub))
@@ -228,6 +245,7 @@ verify_and_execute_recoup (
}
/* check recoup request signature */
+ TEH_METRICS_num_verifications[TEH_MT_SIGNATURE_EDDSA]++;
if (GNUNET_OK !=
TALER_wallet_recoup_verify (&coin->denom_pub_hash,
coin_bks,
@@ -242,19 +260,22 @@ verify_and_execute_recoup (
NULL);
}
+ /* re-compute client-side blinding so we can
+ (a bit later) check that this coin was indeed
+ signed by us. */
{
- void *coin_ev;
- size_t coin_ev_size;
- struct TALER_CoinPubHash c_hash;
+ struct TALER_CoinPubHashP c_hash;
+ struct TALER_BlindedPlanchet blinded_planchet;
if (GNUNET_OK !=
TALER_denom_blind (&dk->denom_pub,
coin_bks,
- NULL, /* FIXME-Oec: TALER_AgeHash * */
+ nonce,
+ &coin->h_age_commitment,
&coin->coin_pub,
+ exchange_vals,
&c_hash,
- &coin_ev,
- &coin_ev_size))
+ &blinded_planchet))
{
GNUNET_break (0);
return TALER_MHD_reply_with_error (
@@ -263,10 +284,10 @@ verify_and_execute_recoup (
TALER_EC_EXCHANGE_RECOUP_BLINDING_FAILED,
NULL);
}
- TALER_coin_ev_hash (coin_ev,
- coin_ev_size,
- &pc.h_blind);
- GNUNET_free (coin_ev);
+ TALER_coin_ev_hash (&blinded_planchet,
+ &coin->denom_pub_hash,
+ &pc.h_coin_ev);
+ TALER_blinded_planchet_free (&blinded_planchet);
}
pc.coin_sig = coin_sig;
@@ -292,7 +313,7 @@ verify_and_execute_recoup (
enum GNUNET_DB_QueryStatus qs;
qs = TEH_plugin->get_reserve_by_h_blind (TEH_plugin->cls,
- &pc.h_blind,
+ &pc.h_coin_ev,
&pc.reserve_pub,
&pc.reserve_out_serial_id);
if (0 > qs)
@@ -308,7 +329,7 @@ verify_and_execute_recoup (
{
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Recoup requested for unknown envelope %s\n",
- GNUNET_h2s (&pc.h_blind.hash));
+ GNUNET_h2s (&pc.h_coin_ev.hash));
return TALER_MHD_reply_with_error (
connection,
MHD_HTTP_NOT_FOUND,
@@ -324,7 +345,7 @@ verify_and_execute_recoup (
if (GNUNET_OK !=
TEH_DB_run_transaction (connection,
"run recoup",
- TEH_MT_OTHER,
+ TEH_MT_REQUEST_OTHER,
&mhd_ret,
&recoup_transaction,
&pc))
@@ -357,17 +378,31 @@ TEH_handler_recoup (struct MHD_Connection *connection,
{
enum GNUNET_GenericReturnValue ret;
struct TALER_CoinPublicInfo coin;
- union TALER_DenominationBlindingKeyP coin_bks;
+ union GNUNET_CRYPTO_BlindingSecretP coin_bks;
struct TALER_CoinSpendSignatureP coin_sig;
+ struct TALER_ExchangeWithdrawValues exchange_vals;
+ union GNUNET_CRYPTO_BlindSessionNonce nonce;
+ bool no_nonce;
struct GNUNET_JSON_Specification spec[] = {
GNUNET_JSON_spec_fixed_auto ("denom_pub_hash",
&coin.denom_pub_hash),
TALER_JSON_spec_denom_sig ("denom_sig",
&coin.denom_sig),
+ TALER_JSON_spec_exchange_withdraw_values ("ewv",
+ &exchange_vals),
GNUNET_JSON_spec_fixed_auto ("coin_blind_key_secret",
&coin_bks),
GNUNET_JSON_spec_fixed_auto ("coin_sig",
&coin_sig),
+ GNUNET_JSON_spec_mark_optional (
+ GNUNET_JSON_spec_fixed_auto ("h_age_commitment",
+ &coin.h_age_commitment),
+ &coin.no_age_commitment),
+ // FIXME: should be renamed to just 'nonce'!
+ GNUNET_JSON_spec_mark_optional (
+ GNUNET_JSON_spec_fixed_auto ("cs_nonce",
+ &nonce),
+ &no_nonce),
GNUNET_JSON_spec_end ()
};
@@ -387,7 +422,11 @@ TEH_handler_recoup (struct MHD_Connection *connection,
res = verify_and_execute_recoup (connection,
&coin,
+ &exchange_vals,
&coin_bks,
+ no_nonce
+ ? NULL
+ : &nonce,
&coin_sig);
GNUNET_JSON_parse_free (spec);
return res;