LCOV - code coverage report
Current view: top level - lib - exchange_api_withdraw.c (source / functions) Hit Total Coverage
Test: GNU Taler exchange coverage report Lines: 31 39 79.5 %
Date: 2021-08-30 06:43:37 Functions: 3 3 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :   This file is part of TALER
       3             :   Copyright (C) 2014-2020 Taler Systems SA
       4             : 
       5             :   TALER is free software; you can redistribute it and/or modify it under the
       6             :   terms of the GNU General Public License as published by the Free Software
       7             :   Foundation; either version 3, or (at your option) any later version.
       8             : 
       9             :   TALER is distributed in the hope that it will be useful, but WITHOUT ANY
      10             :   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
      11             :   A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
      12             : 
      13             :   You should have received a copy of the GNU General Public License along with
      14             :   TALER; see the file COPYING.  If not, see
      15             :   <http://www.gnu.org/licenses/>
      16             : */
      17             : /**
      18             :  * @file lib/exchange_api_withdraw.c
      19             :  * @brief Implementation of /reserves/$RESERVE_PUB/withdraw requests with blinding/unblinding
      20             :  * @author Christian Grothoff
      21             :  */
      22             : #include "platform.h"
      23             : #include <jansson.h>
      24             : #include <microhttpd.h> /* just for HTTP status codes */
      25             : #include <gnunet/gnunet_util_lib.h>
      26             : #include <gnunet/gnunet_json_lib.h>
      27             : #include <gnunet/gnunet_curl_lib.h>
      28             : #include "taler_exchange_service.h"
      29             : #include "taler_json_lib.h"
      30             : #include "exchange_api_handle.h"
      31             : #include "taler_signatures.h"
      32             : #include "exchange_api_curl_defaults.h"
      33             : 
      34             : 
      35             : /**
      36             :  * @brief A Withdraw Handle
      37             :  */
      38             : struct TALER_EXCHANGE_WithdrawHandle
      39             : {
      40             : 
      41             :   /**
      42             :    * The connection to exchange this request handle will use
      43             :    */
      44             :   struct TALER_EXCHANGE_Handle *exchange;
      45             : 
      46             :   /**
      47             :    * Handle for the actual (internal) withdraw operation.
      48             :    */
      49             :   struct TALER_EXCHANGE_Withdraw2Handle *wh2;
      50             : 
      51             :   /**
      52             :    * Function to call with the result.
      53             :    */
      54             :   TALER_EXCHANGE_WithdrawCallback cb;
      55             : 
      56             :   /**
      57             :    * Closure for @a cb.
      58             :    */
      59             :   void *cb_cls;
      60             : 
      61             :   /**
      62             :    * Secrets of the planchet.
      63             :    */
      64             :   struct TALER_PlanchetSecretsP ps;
      65             : 
      66             :   /**
      67             :    * Denomination key we are withdrawing.
      68             :    */
      69             :   struct TALER_EXCHANGE_DenomPublicKey pk;
      70             : 
      71             :   /**
      72             :    * Hash of the public key of the coin we are signing.
      73             :    */
      74             :   struct GNUNET_HashCode c_hash;
      75             : 
      76             : };
      77             : 
      78             : 
      79             : /**
      80             :  * Function called when we're done processing the
      81             :  * HTTP /reserves/$RESERVE_PUB/withdraw request.
      82             :  *
      83             :  * @param cls the `struct TALER_EXCHANGE_WithdrawHandle`
      84             :  * @param hr HTTP response data
      85             :  * @param blind_sig blind signature over the coin, NULL on error
      86             :  */
      87             : static void
      88          39 : handle_reserve_withdraw_finished (
      89             :   void *cls,
      90             :   const struct TALER_EXCHANGE_HttpResponse *hr,
      91             :   const struct GNUNET_CRYPTO_RsaSignature *blind_sig)
      92             : {
      93          39 :   struct TALER_EXCHANGE_WithdrawHandle *wh = cls;
      94             : 
      95          39 :   wh->wh2 = NULL;
      96          39 :   if (MHD_HTTP_OK != hr->http_status)
      97             :   {
      98           4 :     wh->cb (wh->cb_cls,
      99             :             hr,
     100             :             NULL);
     101             :   }
     102             :   else
     103             :   {
     104             :     struct TALER_FreshCoin fc;
     105             : 
     106          35 :     if (GNUNET_OK !=
     107          35 :         TALER_planchet_to_coin (&wh->pk.key,
     108             :                                 blind_sig,
     109          35 :                                 &wh->ps,
     110          35 :                                 &wh->c_hash,
     111             :                                 &fc))
     112             :     {
     113           0 :       struct TALER_EXCHANGE_HttpResponse hrx = {
     114           0 :         .reply = hr->reply,
     115             :         .http_status = 0,
     116             :         .ec = TALER_EC_EXCHANGE_WITHDRAW_UNBLIND_FAILURE
     117             :       };
     118             : 
     119           0 :       wh->cb (wh->cb_cls,
     120             :               &hrx,
     121             :               NULL);
     122             :     }
     123             :     else
     124             :     {
     125          35 :       wh->cb (wh->cb_cls,
     126             :               hr,
     127             :               &fc.sig);
     128          35 :       GNUNET_CRYPTO_rsa_signature_free (fc.sig.rsa_signature);
     129             :     }
     130             : 
     131             :   }
     132          39 :   TALER_EXCHANGE_withdraw_cancel (wh);
     133          39 : }
     134             : 
     135             : 
     136             : /**
     137             :  * Withdraw a coin from the exchange using a /reserve/withdraw request.  Note
     138             :  * that to ensure that no money is lost in case of hardware failures,
     139             :  * the caller must have committed (most of) the arguments to disk
     140             :  * before calling, and be ready to repeat the request with the same
     141             :  * arguments in case of failures.
     142             :  *
     143             :  * @param exchange the exchange handle; the exchange must be ready to operate
     144             :  * @param pk kind of coin to create
     145             :  * @param reserve_priv private key of the reserve to withdraw from
     146             :  * @param ps secrets of the planchet
     147             :  *        caller must have committed this value to disk before the call (with @a pk)
     148             :  * @param res_cb the callback to call when the final result for this request is available
     149             :  * @param res_cb_cls closure for the above callback
     150             :  * @return handle for the operation on success, NULL on error, i.e.
     151             :  *         if the inputs are invalid (i.e. denomination key not with this exchange).
     152             :  *         In this case, the callback is not called.
     153             :  */
     154             : struct TALER_EXCHANGE_WithdrawHandle *
     155          39 : TALER_EXCHANGE_withdraw (
     156             :   struct TALER_EXCHANGE_Handle *exchange,
     157             :   const struct TALER_EXCHANGE_DenomPublicKey *pk,
     158             :   const struct TALER_ReservePrivateKeyP *reserve_priv,
     159             :   const struct TALER_PlanchetSecretsP *ps,
     160             :   TALER_EXCHANGE_WithdrawCallback res_cb,
     161             :   void *res_cb_cls)
     162             : {
     163             :   struct TALER_PlanchetDetail pd;
     164             :   struct TALER_EXCHANGE_WithdrawHandle *wh;
     165             : 
     166          39 :   wh = GNUNET_new (struct TALER_EXCHANGE_WithdrawHandle);
     167          39 :   wh->exchange = exchange;
     168          39 :   wh->cb = res_cb;
     169          39 :   wh->cb_cls = res_cb_cls;
     170          39 :   wh->pk = *pk;
     171          39 :   wh->ps = *ps;
     172          39 :   if (GNUNET_OK !=
     173          39 :       TALER_planchet_prepare (&pk->key,
     174             :                               ps,
     175             :                               &wh->c_hash,
     176             :                               &pd))
     177             :   {
     178           0 :     GNUNET_break (0);
     179           0 :     GNUNET_free (wh);
     180           0 :     return NULL;
     181             :   }
     182             :   wh->pk.key.rsa_public_key
     183          39 :     = GNUNET_CRYPTO_rsa_public_key_dup (pk->key.rsa_public_key);
     184          39 :   wh->wh2 = TALER_EXCHANGE_withdraw2 (exchange,
     185             :                                       &pd,
     186             :                                       reserve_priv,
     187             :                                       &handle_reserve_withdraw_finished,
     188             :                                       wh);
     189          39 :   GNUNET_free (pd.coin_ev);
     190          39 :   return wh;
     191             : }
     192             : 
     193             : 
     194             : /**
     195             :  * Cancel a withdraw status request.  This function cannot be used
     196             :  * on a request handle if a response is already served for it.
     197             :  *
     198             :  * @param wh the withdraw sign request handle
     199             :  */
     200             : void
     201          39 : TALER_EXCHANGE_withdraw_cancel (struct TALER_EXCHANGE_WithdrawHandle *wh)
     202             : {
     203          39 :   if (NULL != wh->wh2)
     204             :   {
     205           0 :     TALER_EXCHANGE_withdraw2_cancel (wh->wh2);
     206           0 :     wh->wh2 = NULL;
     207             :   }
     208          39 :   GNUNET_CRYPTO_rsa_public_key_free (wh->pk.key.rsa_public_key);
     209          39 :   GNUNET_free (wh);
     210          39 : }

Generated by: LCOV version 1.14