diff options
Diffstat (limited to 'src/exchange/taler-exchange-httpd_recoup.c')
-rw-r--r-- | src/exchange/taler-exchange-httpd_recoup.c | 77 |
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; |