diff options
author | Christian Grothoff <christian@grothoff.org> | 2022-06-05 14:07:23 +0200 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2022-06-05 14:07:23 +0200 |
commit | b9963f75255e416ca79b2f5c3081bde4ba78fab0 (patch) | |
tree | 9575e9558b6f8960798c09dec681dc277f96babc /src/lib/exchange_api_recoup_refresh.c | |
parent | 6c81796d6f39e932d58b4fc1729b472d0e46e3d1 (diff) | |
download | exchange-b9963f75255e416ca79b2f5c3081bde4ba78fab0.tar.xz |
complete P2P/W2W conflict handling, deduplicate code across handlers
Diffstat (limited to 'src/lib/exchange_api_recoup_refresh.c')
-rw-r--r-- | src/lib/exchange_api_recoup_refresh.c | 117 |
1 files changed, 40 insertions, 77 deletions
diff --git a/src/lib/exchange_api_recoup_refresh.c b/src/lib/exchange_api_recoup_refresh.c index 8ae8f9764..d551df743 100644 --- a/src/lib/exchange_api_recoup_refresh.c +++ b/src/lib/exchange_api_recoup_refresh.c @@ -27,6 +27,7 @@ #include <gnunet/gnunet_curl_lib.h> #include "taler_json_lib.h" #include "taler_exchange_service.h" +#include "exchange_api_common.h" #include "exchange_api_handle.h" #include "taler_signatures.h" #include "exchange_api_curl_defaults.h" @@ -79,6 +80,11 @@ struct TALER_EXCHANGE_RecoupRefreshHandle */ struct TALER_CoinSpendPublicKeyP coin_pub; + /** + * Signature affirming the recoup-refresh operation. + */ + struct TALER_CoinSpendSignatureP coin_sig; + }; @@ -140,8 +146,10 @@ handle_recoup_refresh_finished (void *cls, .reply = j, .http_status = (unsigned int) response_code }; + const struct TALER_EXCHANGE_Keys *keys; ph->job = NULL; + keys = TALER_EXCHANGE_get_keys (ph->exchange); switch (response_code) { case 0: @@ -180,76 +188,34 @@ handle_recoup_refresh_finished (void *cls, break; case MHD_HTTP_CONFLICT: { - /* Insufficient funds, proof attached */ - json_t *history; - struct TALER_Amount total; - struct TALER_DenominationHashP h_denom_pub; - const struct TALER_EXCHANGE_DenomPublicKey *dki; - enum TALER_ErrorCode ec; - - dki = &ph->pk; - history = json_object_get (j, - "history"); + struct TALER_Amount min_key; + + hr.ec = TALER_JSON_get_error_code (j); + hr.hint = TALER_JSON_get_error_hint (j); if (GNUNET_OK != - TALER_EXCHANGE_verify_coin_history (dki, - dki->fees.deposit.currency, - &ph->coin_pub, - history, - &h_denom_pub, - &total)) + TALER_EXCHANGE_get_min_denomination_ (keys, + &min_key)) { - GNUNET_break_op (0); - hr.http_status = 0; + GNUNET_break (0); hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; + hr.http_status = 0; + break; } - else - { - hr.ec = TALER_JSON_get_error_code (j); - hr.hint = TALER_JSON_get_error_hint (j); - } - ec = TALER_JSON_get_error_code (j); - switch (ec) + if (GNUNET_OK != + TALER_EXCHANGE_check_coin_conflict_ ( + keys, + j, + &ph->pk, + &ph->coin_pub, + &ph->coin_sig, + &min_key)) { - case TALER_EC_EXCHANGE_GENERIC_INSUFFICIENT_FUNDS: - if (0 > TALER_amount_cmp (&total, - &dki->value)) - { - /* recoup MAY have still been possible */ - /* FIXME: This code may falsely complain, as we do not - know that the smallest denomination offered by the - exchange is here. We should look at the key - structure of ph->exchange, and find the smallest - _currently withdrawable_ denomination and check - if the value remaining would suffice... */ - GNUNET_break_op (0); - hr.http_status = 0; - hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; - break; - } - break; - case TALER_EC_EXCHANGE_GENERIC_COIN_CONFLICTING_DENOMINATION_KEY: - if (0 == GNUNET_memcmp (&ph->pk.h_key, - &h_denom_pub)) - { - /* invalid proof provided */ - GNUNET_break_op (0); - hr.http_status = 0; - hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; - break; - } - /* valid error from exchange */ - break; - default: - GNUNET_break_op (0); - hr.http_status = 0; + GNUNET_break (0); hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; + hr.http_status = 0; break; } - ph->cb (ph->cb_cls, - &hr, - NULL); - TALER_EXCHANGE_recoup_refresh_cancel (ph); - return; + break; } case MHD_HTTP_GONE: /* Kind of normal: the money was already sent to the merchant @@ -295,8 +261,6 @@ TALER_EXCHANGE_recoup_refresh ( { struct TALER_EXCHANGE_RecoupRefreshHandle *ph; struct GNUNET_CURL_Context *ctx; - struct TALER_CoinSpendSignatureP coin_sig; - struct TALER_CoinSpendPublicKeyP coin_pub; struct TALER_DenominationHashP h_denom_pub; json_t *recoup_obj; CURL *eh; @@ -307,6 +271,14 @@ TALER_EXCHANGE_recoup_refresh ( GNUNET_assert (NULL != recoup_cb); GNUNET_assert (GNUNET_YES == TEAH_handle_is_ready (exchange)); + ph = GNUNET_new (struct TALER_EXCHANGE_RecoupRefreshHandle); + ph->exchange = exchange; + ph->pk = *pk; + memset (&ph->pk.key, + 0, + sizeof (ph->pk.key)); /* zero out, as lifetime cannot be warranted */ + ph->cb = recoup_cb; + ph->cb_cls = recoup_cb_cls; TALER_planchet_setup_coin_priv (ps, exchange_vals, &coin_priv); @@ -314,13 +286,13 @@ TALER_EXCHANGE_recoup_refresh ( exchange_vals, &bks); GNUNET_CRYPTO_eddsa_key_get_public (&coin_priv.eddsa_priv, - &coin_pub.eddsa_pub); + &ph->coin_pub.eddsa_pub); TALER_denom_pub_hash (&pk->key, &h_denom_pub); TALER_wallet_recoup_refresh_sign (&h_denom_pub, &bks, &coin_priv, - &coin_sig); + &ph->coin_sig); recoup_obj = GNUNET_JSON_PACK ( GNUNET_JSON_pack_data_auto ("denom_pub_hash", &h_denom_pub), @@ -329,7 +301,7 @@ TALER_EXCHANGE_recoup_refresh ( TALER_JSON_pack_exchange_withdraw_values ("ewv", exchange_vals), GNUNET_JSON_pack_data_auto ("coin_sig", - &coin_sig), + &ph->coin_sig), GNUNET_JSON_pack_data_auto ("coin_blind_key_secret", &bks)); @@ -358,7 +330,7 @@ TALER_EXCHANGE_recoup_refresh ( char *end; end = GNUNET_STRINGS_data_to_string ( - &coin_pub, + &ph->coin_pub, sizeof (struct TALER_CoinSpendPublicKeyP), pub_str, sizeof (pub_str)); @@ -369,15 +341,6 @@ TALER_EXCHANGE_recoup_refresh ( pub_str); } - ph = GNUNET_new (struct TALER_EXCHANGE_RecoupRefreshHandle); - ph->coin_pub = coin_pub; - ph->exchange = exchange; - ph->pk = *pk; - memset (&ph->pk.key, - 0, - sizeof (ph->pk.key)); /* zero out, as lifetime cannot be warranted */ - ph->cb = recoup_cb; - ph->cb_cls = recoup_cb_cls; ph->url = TEAH_path_to_url (exchange, arg_str); if (NULL == ph->url) |