diff options
author | Christian Grothoff <christian@grothoff.org> | 2023-07-10 10:37:25 +0200 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2023-07-10 10:37:25 +0200 |
commit | 3ebb5281bc62ca6231f6131e0601471d9ef03b8b (patch) | |
tree | 28037cedcb8383e5b32c8d11ae527612efb0609c /src/lib/merchant_api_tip_pickup.c | |
parent | c4b27ca9b9a5ef4291257e4a8b8f4bac56720b89 (diff) |
tip -> reward
Diffstat (limited to 'src/lib/merchant_api_tip_pickup.c')
-rw-r--r-- | src/lib/merchant_api_tip_pickup.c | 440 |
1 files changed, 0 insertions, 440 deletions
diff --git a/src/lib/merchant_api_tip_pickup.c b/src/lib/merchant_api_tip_pickup.c deleted file mode 100644 index eb0e3fb3..00000000 --- a/src/lib/merchant_api_tip_pickup.c +++ /dev/null @@ -1,440 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2022 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file merchant_api_tip_pickup.c - * @brief Implementation of the /tip-pickup request of the merchant's HTTP API - * @author Marcello Stanisci - * @author Christian Grothoff - */ -#include "platform.h" -#include <curl/curl.h> -#include <jansson.h> -#include <microhttpd.h> /* just for HTTP status codes */ -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_curl_lib.h> -#include "taler_merchant_service.h" -#include <taler/taler_json_lib.h> -#include <taler/taler_signatures.h> -#include <taler/taler_curl_lib.h> - - -/** - * Data we keep per planchet. - */ -struct PlanchetData -{ - /** - * Secrets of the planchet. - */ - struct TALER_PlanchetMasterSecretP ps; - - /** - * Denomination key we are withdrawing. - */ - struct TALER_EXCHANGE_DenomPublicKey pk; - - /** - * Hash of the public key of the coin we are signing. - */ - struct TALER_CoinPubHashP c_hash; - - /** - * Nonce used for @e csr request, if any. - */ - struct TALER_CsNonce nonce; - - /** - * Handle for a /csr request we may optionally need - * to trigger. - */ - struct TALER_EXCHANGE_CsRWithdrawHandle *csr; - - /** - * Handle for the /tip-pickup operation we are part of. - */ - struct TALER_MERCHANT_TipPickupHandle *tp; - - /** - * Offset of this entry in the array. - */ - unsigned int off; -}; - - -/** - * Handle for a /tip-pickup operation. - */ -struct TALER_MERCHANT_TipPickupHandle -{ - - /** - * Function to call with the result. - */ - TALER_MERCHANT_TipPickupCallback cb; - - /** - * Closure for @a cb. - */ - void *cb_cls; - - /** - * Handle for the actual (internal) withdraw operation. - */ - struct TALER_MERCHANT_TipPickup2Handle *tpo2; - - /** - * Array of length @e num_planchets. - */ - struct PlanchetData *planchets; - - /** - * Array of length @e num_planchets. - */ - struct TALER_EXCHANGE_PrivateCoinDetails *pcds; - - /** - * Context for making HTTP requests. - */ - struct GNUNET_CURL_Context *ctx; - - /** - * URL of the merchant backend. - */ - char *backend_url; - - /** - * ID of the tip we are picking up. - */ - struct TALER_TipIdentifierP tip_id; - - /** - * Number of planchets/coins used for this operation. - */ - unsigned int num_planchets; - - /** - * Number of remaining active /csr-withdraw requests. - */ - unsigned int csr_active; -}; - - -/** - * Fail the pickup operation @a tp, returning @a ec. - * Also cancels @a tp. - * - * @param[in] tp operation to fail - * @param ec reason for the failure - */ -static void -fail_pickup (struct TALER_MERCHANT_TipPickupHandle *tp, - enum TALER_ErrorCode ec) -{ - struct TALER_MERCHANT_PickupDetails pd = { - .hr.ec = ec - }; - - tp->cb (tp->cb_cls, - &pd); - TALER_MERCHANT_tip_pickup_cancel (tp); -} - - -/** - * Callback for a /tip-pickup request. Returns the result of the operation. - * Note that the client MUST still do the unblinding of the @a blind_sigs. - * - * @param cls closure, a `struct TALER_MERCHANT_TipPickupHandle *` - * @param tpr response details - */ -static void -pickup_done_cb (void *cls, - const struct TALER_MERCHANT_TipPickup2Response *tpr) -{ - struct TALER_MERCHANT_TipPickupHandle *tp = cls; - struct TALER_MERCHANT_PickupDetails pd = { - .hr = tpr->hr - }; - - tp->tpo2 = NULL; - if (MHD_HTTP_OK != tpr->hr.http_status) - { - tp->cb (tp->cb_cls, - &pd); - TALER_MERCHANT_tip_pickup_cancel (tp); - return; - } - { - enum GNUNET_GenericReturnValue ok = GNUNET_OK; - - for (unsigned int i = 0; i<tpr->details.ok.num_blind_sigs; i++) - { - const struct TALER_BlindedDenominationSignature *blind_sig - = &tpr->details.ok.blind_sigs[i]; - struct TALER_EXCHANGE_PrivateCoinDetails *pcd - = &tp->pcds[i]; - struct TALER_FreshCoin fc; - - if (GNUNET_OK != - TALER_planchet_to_coin (&tp->planchets[i].pk.key, - blind_sig, - &pcd->bks, - &pcd->coin_priv, - NULL, - &tp->planchets[i].c_hash, - &pcd->exchange_vals, - &fc)) - { - ok = GNUNET_SYSERR; - break; - } - pcd->sig = fc.sig; - } - if (GNUNET_OK != ok) - { - pd.hr.ec = TALER_EC_MERCHANT_TIP_PICKUP_UNBLIND_FAILURE; - } - else - { - pd.details.ok.num_sigs = tpr->details.ok.num_blind_sigs; - pd.details.ok.pcds = tp->pcds; - } - tp->cb (tp->cb_cls, - &pd); - } - TALER_MERCHANT_tip_pickup_cancel (tp); -} - - -/** - * We have obtained all of the exchange inputs. Continue the pickup. - * - * @param[in,out] tp operation to continue - */ -static void -pickup_post_csr (struct TALER_MERCHANT_TipPickupHandle *tp) -{ - struct TALER_PlanchetDetail details[tp->num_planchets]; - - for (unsigned int i = 0; i<tp->num_planchets; i++) - { - const struct PlanchetData *pd = &tp->planchets[i]; - struct TALER_EXCHANGE_PrivateCoinDetails *pcd = &tp->pcds[i]; - - TALER_planchet_setup_coin_priv (&pd->ps, - &pcd->exchange_vals, - &pcd->coin_priv); - TALER_planchet_blinding_secret_create (&pd->ps, - &pcd->exchange_vals, - &pcd->bks); - if (TALER_DENOMINATION_CS == pcd->exchange_vals.cipher) - { - details[i].blinded_planchet.details.cs_blinded_planchet.nonce - = pd->nonce; - } - if (GNUNET_OK != - TALER_planchet_prepare (&pd->pk.key, - &pcd->exchange_vals, - &pcd->bks, - &pcd->coin_priv, - NULL, - &tp->planchets[i].c_hash, - &details[i])) - { - GNUNET_break (0); - for (unsigned int j = 0; j<i; j++) - TALER_planchet_detail_free (&details[j]); - fail_pickup (tp, - TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE); - return; - } - } - tp->tpo2 = TALER_MERCHANT_tip_pickup2 (tp->ctx, - tp->backend_url, - &tp->tip_id, - tp->num_planchets, - details, - &pickup_done_cb, - tp); - for (unsigned int j = 0; j<tp->num_planchets; j++) - TALER_planchet_detail_free (&details[j]); - if (NULL == tp->tpo2) - { - GNUNET_break (0); - fail_pickup (tp, - TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE); - return; - } -} - - -/** - * Callbacks of this type are used to serve the result of submitting a - * CS R request to a exchange. - * - * @param cls a `struct TALER_MERCHANT_TipPickupHandle` - * @param csrr response details - */ -static void -csr_cb (void *cls, - const struct TALER_EXCHANGE_CsRWithdrawResponse *csrr) -{ - struct PlanchetData *pd = cls; - struct TALER_MERCHANT_TipPickupHandle *tp = pd->tp; - - pd->csr = NULL; - tp->csr_active--; - switch (csrr->hr.http_status) - { - case MHD_HTTP_OK: - { - struct TALER_EXCHANGE_PrivateCoinDetails *pcd = &tp->pcds[pd->off]; - - pcd->exchange_vals = csrr->details.ok.alg_values; - } - if (0 != tp->csr_active) - return; - pickup_post_csr (tp); - return; - default: - { - struct TALER_MERCHANT_PickupDetails pd = { - .hr.hint = "/csr-withdraw failed", - .hr.exchange_http_status = csrr->hr.http_status - }; - - tp->cb (tp->cb_cls, - &pd); - TALER_MERCHANT_tip_pickup_cancel (tp); - return; - } - } -} - - -struct TALER_MERCHANT_TipPickupHandle * -TALER_MERCHANT_tip_pickup ( - struct GNUNET_CURL_Context *ctx, - const char *exchange_url, - const char *backend_url, - const struct TALER_TipIdentifierP *tip_id, - unsigned int num_planchets, - const struct TALER_MERCHANT_PlanchetData pds[static num_planchets], - TALER_MERCHANT_TipPickupCallback pickup_cb, - void *pickup_cb_cls) -{ - struct TALER_MERCHANT_TipPickupHandle *tp; - - if (0 == num_planchets) - { - GNUNET_break (0); - return NULL; - } - tp = GNUNET_new (struct TALER_MERCHANT_TipPickupHandle); - tp->cb = pickup_cb; - tp->cb_cls = pickup_cb_cls; - tp->ctx = ctx; - tp->backend_url = GNUNET_strdup (backend_url); - tp->tip_id = *tip_id; - tp->num_planchets = num_planchets; - tp->planchets = GNUNET_new_array (num_planchets, - struct PlanchetData); - tp->pcds = GNUNET_new_array (num_planchets, - struct TALER_EXCHANGE_PrivateCoinDetails); - for (unsigned int i = 0; i<num_planchets; i++) - { - const struct TALER_MERCHANT_PlanchetData *mpd = &pds[i]; - const struct TALER_EXCHANGE_DenomPublicKey *pk = mpd->pk; - struct TALER_EXCHANGE_PrivateCoinDetails *pcd = &tp->pcds[i]; - struct PlanchetData *pd = &tp->planchets[i]; - - pd->off = i; - pd->tp = tp; - tp->planchets[i].ps = mpd->ps; - tp->planchets[i].pk = *pds[i].pk; - TALER_denom_pub_deep_copy (&tp->planchets[i].pk.key, - &pds[i].pk->key); - switch (pk->key.cipher) - { - case TALER_DENOMINATION_RSA: - pcd->exchange_vals.cipher = TALER_DENOMINATION_RSA; - break; - case TALER_DENOMINATION_CS: - { - TALER_cs_withdraw_nonce_derive (&pd->ps, - &pd->nonce); - pd->csr = TALER_EXCHANGE_csr_withdraw (ctx, - exchange_url, - &pd->pk, - &pd->nonce, - &csr_cb, - pd); - if (NULL == pd->csr) - { - GNUNET_break (0); - TALER_MERCHANT_tip_pickup_cancel (tp); - return NULL; - } - tp->csr_active++; - break; - } - default: - GNUNET_break (0); - TALER_MERCHANT_tip_pickup_cancel (tp); - return NULL; - } - } - if (0 == tp->csr_active) - { - pickup_post_csr (tp); - return tp; - } - return tp; -} - - -void -TALER_MERCHANT_tip_pickup_cancel (struct TALER_MERCHANT_TipPickupHandle *tp) -{ - for (unsigned int i = 0; i<tp->num_planchets; i++) - { - struct TALER_EXCHANGE_PrivateCoinDetails *pcd = &tp->pcds[i]; - struct PlanchetData *pd = &tp->planchets[i]; - - TALER_denom_sig_free (&pcd->sig); - TALER_denom_pub_free (&tp->planchets[i].pk.key); - if (NULL != pd->csr) - { - TALER_EXCHANGE_csr_withdraw_cancel (pd->csr); - pd->csr = NULL; - } - } - GNUNET_array_grow (tp->planchets, - tp->num_planchets, - 0); - if (NULL != tp->tpo2) - { - TALER_MERCHANT_tip_pickup2_cancel (tp->tpo2); - tp->tpo2 = NULL; - } - GNUNET_free (tp->backend_url); - GNUNET_free (tp->pcds); - GNUNET_free (tp); -} - - -/* end of merchant_api_tip_pickup.c */ |