summaryrefslogtreecommitdiff
path: root/src/lib/merchant_api_tip_pickup.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/merchant_api_tip_pickup.c')
-rw-r--r--src/lib/merchant_api_tip_pickup.c446
1 files changed, 0 insertions, 446 deletions
diff --git a/src/lib/merchant_api_tip_pickup.c b/src/lib/merchant_api_tip_pickup.c
deleted file mode 100644
index 593efa43..00000000
--- a/src/lib/merchant_api_tip_pickup.c
+++ /dev/null
@@ -1,446 +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 hr HTTP response details
- * @param num_blind_sigs length of the @a reserve_sigs array, 0 on error
- * @param blind_sigs array of blind signatures over the planchets, NULL on error
- */
-static void
-pickup_done_cb (void *cls,
- const struct TALER_MERCHANT_HttpResponse *hr,
- unsigned int num_blind_sigs,
- const struct TALER_BlindedDenominationSignature *blind_sigs)
-{
- struct TALER_MERCHANT_TipPickupHandle *tp = cls;
- struct TALER_MERCHANT_PickupDetails pd = {
- .hr = *hr
- };
-
- tp->tpo2 = NULL;
- if (NULL == blind_sigs)
- {
- 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<num_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_sigs[i],
- &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)
- {
- struct TALER_MERCHANT_HttpResponse hrx = {
- .reply = hr->reply,
- .ec = TALER_EC_MERCHANT_TIP_PICKUP_UNBLIND_FAILURE
- };
-
- pd.hr = hrx;
- tp->cb (tp->cb_cls,
- &pd);
- }
- else
- {
- pd.details.success.num_sigs = num_blind_sigs;
- pd.details.success.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.success.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,
- struct TALER_EXCHANGE_Handle *exchange,
- const char *backend_url,
- const struct TALER_TipIdentifierP *tip_id,
- unsigned int num_planchets,
- const struct TALER_MERCHANT_PlanchetData *pds,
- 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 (exchange,
- &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 */