diff options
| author | Özgür Kesim <oec-taler@kesim.org> | 2022-02-18 00:44:55 +0100 | 
|---|---|---|
| committer | Özgür Kesim <oec-taler@kesim.org> | 2022-02-18 00:50:31 +0100 | 
| commit | f4f502d037a84a38db4bc21a1db06324a05d26aa (patch) | |
| tree | abd1d813c9e1a9303d60edd3600a9e39f9d3d91a /src/lib | |
| parent | a78b3345fbf017b1cddfd09afb4b2c29287b0bba (diff) | |
| parent | 22fe5da700df7328de183470c1c7f59b21c9f4f9 (diff) | |
-minor merge conflict resolves
Diffstat (limited to 'src/lib')
| -rw-r--r-- | src/lib/Makefile.am | 3 | ||||
| -rw-r--r-- | src/lib/exchange_api_common.c | 21 | ||||
| -rw-r--r-- | src/lib/exchange_api_csr_melt.c (renamed from src/lib/exchange_api_csr.c) | 59 | ||||
| -rw-r--r-- | src/lib/exchange_api_csr_withdraw.c | 284 | ||||
| -rw-r--r-- | src/lib/exchange_api_deposit.c | 8 | ||||
| -rw-r--r-- | src/lib/exchange_api_handle.c | 43 | ||||
| -rw-r--r-- | src/lib/exchange_api_melt.c | 36 | ||||
| -rw-r--r-- | src/lib/exchange_api_recoup.c | 2 | ||||
| -rw-r--r-- | src/lib/exchange_api_recoup_refresh.c | 2 | ||||
| -rw-r--r-- | src/lib/exchange_api_refresh_common.c | 10 | ||||
| -rw-r--r-- | src/lib/exchange_api_refreshes_reveal.c | 9 | ||||
| -rw-r--r-- | src/lib/exchange_api_withdraw.c | 42 | ||||
| -rw-r--r-- | src/lib/exchange_api_withdraw2.c | 2 | 
13 files changed, 407 insertions, 114 deletions
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index fe2a0b6b..17ad7937 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -24,7 +24,8 @@ libtalerexchange_la_SOURCES = \    exchange_api_auditor_add_denomination.c \    exchange_api_curl_defaults.c exchange_api_curl_defaults.h \    exchange_api_common.c \ -  exchange_api_csr.c \ +  exchange_api_csr_melt.c \ +  exchange_api_csr_withdraw.c \    exchange_api_handle.c exchange_api_handle.h \    exchange_api_deposit.c \    exchange_api_deposits_get.c \ diff --git a/src/lib/exchange_api_common.c b/src/lib/exchange_api_common.c index d0340924..4f3e878d 100644 --- a/src/lib/exchange_api_common.c +++ b/src/lib/exchange_api_common.c @@ -171,10 +171,10 @@ TALER_EXCHANGE_parse_reserve_history (                                                             &h_denom_pub);          if ( (GNUNET_YES !=                TALER_amount_cmp_currency (&withdraw_fee, -                                         &dki->fee_withdraw)) || +                                         &dki->fees.withdraw)) ||               (0 !=                TALER_amount_cmp (&withdraw_fee, -                                &dki->fee_withdraw)) ) +                                &dki->fees.withdraw)) )          {            GNUNET_break_op (0);            GNUNET_JSON_parse_free (withdraw_spec); @@ -529,10 +529,10 @@ TALER_EXCHANGE_verify_coin_history (          /* check that deposit fee matches our expectations from /keys! */          if ( (GNUNET_YES !=                TALER_amount_cmp_currency (&fee, -                                         &dk->fee_deposit)) || +                                         &dk->fees.deposit)) ||               (0 !=                TALER_amount_cmp (&fee, -                                &dk->fee_deposit)) ) +                                &dk->fees.deposit)) )          {            GNUNET_break_op (0);            return GNUNET_SYSERR; @@ -575,10 +575,10 @@ TALER_EXCHANGE_verify_coin_history (          /* check that melt fee matches our expectations from /keys! */          if ( (GNUNET_YES !=                TALER_amount_cmp_currency (&fee, -                                         &dk->fee_refresh)) || +                                         &dk->fees.refresh)) ||               (0 !=                TALER_amount_cmp (&fee, -                                &dk->fee_refresh)) ) +                                &dk->fees.refresh)) )          {            GNUNET_break_op (0);            return GNUNET_SYSERR; @@ -669,10 +669,10 @@ TALER_EXCHANGE_verify_coin_history (        {          if ( (GNUNET_YES !=                TALER_amount_cmp_currency (&refund_fee, -                                         &dk->fee_refund)) || +                                         &dk->fees.refund)) ||               (0 !=                TALER_amount_cmp (&refund_fee, -                                &dk->fee_refund)) ) +                                &dk->fees.refund)) )          {            GNUNET_break_op (0);            return GNUNET_SYSERR; @@ -863,6 +863,11 @@ TALER_EXCHANGE_verify_coin_history (        }        add = GNUNET_NO;      } +    else if (0 == strcasecmp (type, +                              "LOCK_NONCE")) +    { +      GNUNET_break (0); // FIXME: implement! +    }      else      {        /* signature not supported, new version on server? */ diff --git a/src/lib/exchange_api_csr.c b/src/lib/exchange_api_csr_melt.c index 220dfba1..9de8cd8d 100644 --- a/src/lib/exchange_api_csr.c +++ b/src/lib/exchange_api_csr_melt.c @@ -15,8 +15,8 @@    <http://www.gnu.org/licenses/>  */  /** - * @file lib/exchange_api_csr.c - * @brief Implementation of /csr requests (get R in exchange used for Clause Schnorr withdraw and refresh) + * @file lib/exchange_api_csr_melt.c + * @brief Implementation of /csr-melt requests (get R in exchange used for Clause Schnorr refresh)   * @author Lucien Heuzeveldt   * @author Gian Demarmels   */ @@ -36,7 +36,7 @@  /**   * @brief A Clause Schnorr R Handle   */ -struct TALER_EXCHANGE_CsRHandle +struct TALER_EXCHANGE_CsRMeltHandle  {    /**     * The connection to exchange this request handle will use @@ -46,7 +46,7 @@ struct TALER_EXCHANGE_CsRHandle    /**     * Function to call with the result.     */ -  TALER_EXCHANGE_CsRCallback cb; +  TALER_EXCHANGE_CsRMeltCallback cb;    /**     * Closure for @a cb. @@ -86,13 +86,13 @@ struct TALER_EXCHANGE_CsRHandle   * @return #GNUNET_OK on success, #GNUNET_SYSERR on errors   */  static enum GNUNET_GenericReturnValue -csr_ok (struct TALER_EXCHANGE_CsRHandle *csrh, -        json_t *arr, +csr_ok (struct TALER_EXCHANGE_CsRMeltHandle *csrh, +        const json_t *arr,          struct TALER_EXCHANGE_HttpResponse *hr)  {    unsigned int alen = json_array_size (arr);    struct TALER_ExchangeWithdrawValues alg_values[GNUNET_NZL (alen)]; -  struct TALER_EXCHANGE_CsRResponse csrr = { +  struct TALER_EXCHANGE_CsRMeltResponse csrr = {      .hr = *hr,      .details.success.alg_values_len = alen,      .details.success.alg_values = alg_values @@ -127,7 +127,7 @@ csr_ok (struct TALER_EXCHANGE_CsRHandle *csrh,  /**   * Function called when we're done processing the HTTP /csr request.   * - * @param cls the `struct TALER_EXCHANGE_CsRHandle` + * @param cls the `struct TALER_EXCHANGE_CsRMeltHandle`   * @param response_code HTTP response code, 0 on error   * @param response parsed JSON result, NULL on error   */ @@ -136,13 +136,13 @@ handle_csr_finished (void *cls,                       long response_code,                       const void *response)  { -  struct TALER_EXCHANGE_CsRHandle *csrh = cls; +  struct TALER_EXCHANGE_CsRMeltHandle *csrh = cls;    const json_t *j = response;    struct TALER_EXCHANGE_HttpResponse hr = {      .reply = j,      .http_status = (unsigned int) response_code    }; -  struct TALER_EXCHANGE_CsRResponse csrr = { +  struct TALER_EXCHANGE_CsRMeltResponse csrr = {      .hr = hr    }; @@ -171,7 +171,7 @@ handle_csr_finished (void *cls,          break;        }      } -    TALER_EXCHANGE_csr_cancel (csrh); +    TALER_EXCHANGE_csr_melt_cancel (csrh);      return;    case MHD_HTTP_BAD_REQUEST:      /* This should never happen, either us or the exchange is buggy @@ -215,18 +215,19 @@ handle_csr_finished (void *cls,    csrh->cb (csrh->cb_cls,              &csrr);    csrh->cb = NULL; -  TALER_EXCHANGE_csr_cancel (csrh); +  TALER_EXCHANGE_csr_melt_cancel (csrh);  } -struct TALER_EXCHANGE_CsRHandle * -TALER_EXCHANGE_csr (struct TALER_EXCHANGE_Handle *exchange, -                    unsigned int nks_len, -                    struct TALER_EXCHANGE_NonceKey *nks, -                    TALER_EXCHANGE_CsRCallback res_cb, -                    void *res_cb_cls) +struct TALER_EXCHANGE_CsRMeltHandle * +TALER_EXCHANGE_csr_melt (struct TALER_EXCHANGE_Handle *exchange, +                         const struct TALER_RefreshMasterSecretP *rms, +                         unsigned int nks_len, +                         struct TALER_EXCHANGE_NonceKey *nks, +                         TALER_EXCHANGE_CsRMeltCallback res_cb, +                         void *res_cb_cls)  { -  struct TALER_EXCHANGE_CsRHandle *csrh; +  struct TALER_EXCHANGE_CsRMeltHandle *csrh;    json_t *csr_arr;    if (0 == nks_len) @@ -240,12 +241,10 @@ TALER_EXCHANGE_csr (struct TALER_EXCHANGE_Handle *exchange,        GNUNET_break (0);        return NULL;      } - -  csrh = GNUNET_new (struct TALER_EXCHANGE_CsRHandle); +  csrh = GNUNET_new (struct TALER_EXCHANGE_CsRMeltHandle);    csrh->exchange = exchange;    csrh->cb = res_cb;    csrh->cb_cls = res_cb_cls; -    csr_arr = json_array ();    GNUNET_assert (NULL != csr_arr);    for (unsigned int i = 0; i<nks_len; i++) @@ -254,19 +253,17 @@ TALER_EXCHANGE_csr (struct TALER_EXCHANGE_Handle *exchange,      json_t *csr_obj;      csr_obj = GNUNET_JSON_PACK ( -      GNUNET_JSON_pack_data_varsize ("nonce", -                                     &nk->nonce, -                                     sizeof(struct TALER_CsNonce)), -      GNUNET_JSON_pack_data_varsize ("denom_pub_hash", -                                     &nk->pk->h_key, -                                     sizeof(struct TALER_DenominationHash))); +      GNUNET_JSON_pack_uint64 ("coin_offset", +                               nk->cnc_num), +      GNUNET_JSON_pack_data_auto ("denom_pub_hash", +                                  &nk->pk->h_key));      GNUNET_assert (NULL != csr_obj);      GNUNET_assert (0 ==                     json_array_append_new (csr_arr,                                            csr_obj));    }    csrh->url = TEAH_path_to_url (exchange, -                                "/csr"); +                                "/csr-melt");    if (NULL == csrh->url)    {      json_decref (csr_arr); @@ -279,6 +276,8 @@ TALER_EXCHANGE_csr (struct TALER_EXCHANGE_Handle *exchange,      json_t *req;      req = GNUNET_JSON_PACK ( +      GNUNET_JSON_pack_data_auto ("rms", +                                  rms),        GNUNET_JSON_pack_array_steal ("nks",                                      csr_arr));      ctx = TEAH_handle_to_context (exchange); @@ -309,7 +308,7 @@ TALER_EXCHANGE_csr (struct TALER_EXCHANGE_Handle *exchange,  void -TALER_EXCHANGE_csr_cancel (struct TALER_EXCHANGE_CsRHandle *csrh) +TALER_EXCHANGE_csr_melt_cancel (struct TALER_EXCHANGE_CsRMeltHandle *csrh)  {    if (NULL != csrh->job)    { diff --git a/src/lib/exchange_api_csr_withdraw.c b/src/lib/exchange_api_csr_withdraw.c new file mode 100644 index 00000000..d23f8ef8 --- /dev/null +++ b/src/lib/exchange_api_csr_withdraw.c @@ -0,0 +1,284 @@ +/* +  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 General Public License as published by the Free Software +  Foundation; either version 3, 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 General Public License for more details. + +  You should have received a copy of the GNU General Public License along with +  TALER; see the file COPYING.  If not, see +  <http://www.gnu.org/licenses/> +*/ +/** + * @file lib/exchange_api_csr_withdraw.c + * @brief Implementation of /csr-withdraw requests (get R in exchange used for Clause Schnorr withdraw and refresh) + * @author Lucien Heuzeveldt + * @author Gian Demarmels + */ +#include "platform.h" +#include <jansson.h> +#include <microhttpd.h> /* just for HTTP status codes */ +#include <gnunet/gnunet_util_lib.h> +#include <gnunet/gnunet_json_lib.h> +#include <gnunet/gnunet_curl_lib.h> +#include "taler_exchange_service.h" +#include "taler_json_lib.h" +#include "exchange_api_handle.h" +#include "taler_signatures.h" +#include "exchange_api_curl_defaults.h" + + +/** + * @brief A Clause Schnorr R Handle + */ +struct TALER_EXCHANGE_CsRWithdrawHandle +{ +  /** +   * The connection to exchange this request handle will use +   */ +  struct TALER_EXCHANGE_Handle *exchange; + +  /** +   * Function to call with the result. +   */ +  TALER_EXCHANGE_CsRWithdrawCallback cb; + +  /** +   * Closure for @a cb. +   */ +  void *cb_cls; + +  /** +   * The url for this request. +   */ +  char *url; + +  /** +   * Handle for the request. +   */ +  struct GNUNET_CURL_Job *job; + +  /** +   * Context for #TEH_curl_easy_post(). Keeps the data that must +   * persist for Curl to make the upload. +   */ +  struct TALER_CURL_PostContext post_ctx; +}; + + +/** + * We got a 200 OK response for the /reserves/$RESERVE_PUB/withdraw operation. + * Extract the coin's signature and return it to the caller.  The signature we + * get from the exchange is for the blinded value.  Thus, we first must + * unblind it and then should verify its validity against our coin's hash. + * + * If everything checks out, we return the unblinded signature + * to the application via the callback. + * + * @param csrh operation handle + * @param av reply from the exchange + * @param hr http response details + * @return #GNUNET_OK on success, #GNUNET_SYSERR on errors + */ +static enum GNUNET_GenericReturnValue +csr_ok (struct TALER_EXCHANGE_CsRWithdrawHandle *csrh, +        const json_t *av, +        struct TALER_EXCHANGE_HttpResponse *hr) +{ +  struct TALER_EXCHANGE_CsRWithdrawResponse csrr = { +    .hr = *hr, +  }; +  struct GNUNET_JSON_Specification spec[] = { +    TALER_JSON_spec_exchange_withdraw_values ( +      "ewv", +      &csrr.details.success.alg_values), +    GNUNET_JSON_spec_end () +  }; + +  if (GNUNET_OK != +      GNUNET_JSON_parse (av, +                         spec, +                         NULL, NULL)) +  { +    GNUNET_break_op (0); +    return GNUNET_SYSERR; +  } +  csrh->cb (csrh->cb_cls, +            &csrr); +  return GNUNET_OK; +} + + +/** + * Function called when we're done processing the HTTP /csr request. + * + * @param cls the `struct TALER_EXCHANGE_CsRWithdrawHandle` + * @param response_code HTTP response code, 0 on error + * @param response parsed JSON result, NULL on error + */ +static void +handle_csr_finished (void *cls, +                     long response_code, +                     const void *response) +{ +  struct TALER_EXCHANGE_CsRWithdrawHandle *csrh = cls; +  const json_t *j = response; +  struct TALER_EXCHANGE_HttpResponse hr = { +    .reply = j, +    .http_status = (unsigned int) response_code +  }; +  struct TALER_EXCHANGE_CsRWithdrawResponse csrr = { +    .hr = hr +  }; + +  csrh->job = NULL; +  switch (response_code) +  { +  case 0: +    csrr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; +    break; +  case MHD_HTTP_OK: +    { +      if (GNUNET_OK != +          csr_ok (csrh, +                  response, +                  &hr)) +      { +        GNUNET_break_op (0); +        csrr.hr.http_status = 0; +        csrr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; +        break; +      } +    } +    TALER_EXCHANGE_csr_withdraw_cancel (csrh); +    return; +  case MHD_HTTP_BAD_REQUEST: +    /* This should never happen, either us or the exchange is buggy +       (or API version conflict); just pass JSON reply to the application */ +    csrr.hr.ec = TALER_JSON_get_error_code (j); +    csrr.hr.hint = TALER_JSON_get_error_hint (j); +    break; +  case MHD_HTTP_NOT_FOUND: +    /* Nothing really to verify, the exchange basically just says +       that it doesn't know the /csr endpoint or denomination. +       Can happen if the exchange doesn't support Clause Schnorr. +       We should simply pass the JSON reply to the application. */ +    csrr.hr.ec = TALER_JSON_get_error_code (j); +    csrr.hr.hint = TALER_JSON_get_error_hint (j); +    break; +  case MHD_HTTP_GONE: +    /* could happen if denomination was revoked */ +    /* Note: one might want to check /keys for revocation +       signature here, alas tricky in case our /keys +       is outdated => left to clients */ +    csrr.hr.ec = TALER_JSON_get_error_code (j); +    csrr.hr.hint = TALER_JSON_get_error_hint (j); +    break; +  case MHD_HTTP_INTERNAL_SERVER_ERROR: +    /* Server had an internal issue; we should retry, but this API +       leaves this to the application */ +    csrr.hr.ec = TALER_JSON_get_error_code (j); +    csrr.hr.hint = TALER_JSON_get_error_hint (j); +    break; +  default: +    /* unexpected response code */ +    GNUNET_break_op (0); +    csrr.hr.ec = TALER_JSON_get_error_code (j); +    csrr.hr.hint = TALER_JSON_get_error_hint (j); +    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, +                "Unexpected response code %u/%d for CS R request\n", +                (unsigned int) response_code, +                (int) hr.ec); +    break; +  } +  csrh->cb (csrh->cb_cls, +            &csrr); +  csrh->cb = NULL; +  TALER_EXCHANGE_csr_withdraw_cancel (csrh); +} + + +struct TALER_EXCHANGE_CsRWithdrawHandle * +TALER_EXCHANGE_csr_withdraw (struct TALER_EXCHANGE_Handle *exchange, +                             const struct TALER_EXCHANGE_DenomPublicKey *pk, +                             const struct TALER_CsNonce *nonce, +                             TALER_EXCHANGE_CsRWithdrawCallback res_cb, +                             void *res_cb_cls) +{ +  struct TALER_EXCHANGE_CsRWithdrawHandle *csrh; + +  if (TALER_DENOMINATION_CS != pk->key.cipher) +  { +    GNUNET_break (0); +    return NULL; +  } +  csrh = GNUNET_new (struct TALER_EXCHANGE_CsRWithdrawHandle); +  csrh->exchange = exchange; +  csrh->cb = res_cb; +  csrh->cb_cls = res_cb_cls; +  csrh->url = TEAH_path_to_url (exchange, +                                "/csr-withdraw"); +  if (NULL == csrh->url) +  { +    GNUNET_free (csrh); +    return NULL; +  } + +  { +    CURL *eh; +    struct GNUNET_CURL_Context *ctx; +    json_t *req; + +    req = GNUNET_JSON_PACK ( +      GNUNET_JSON_pack_data_varsize ("nonce", +                                     nonce, +                                     sizeof(struct TALER_CsNonce)), +      GNUNET_JSON_pack_data_varsize ("denom_pub_hash", +                                     &pk->h_key, +                                     sizeof(struct TALER_DenominationHash))); +    GNUNET_assert (NULL != req); +    ctx = TEAH_handle_to_context (exchange); +    eh = TALER_EXCHANGE_curl_easy_get_ (csrh->url); +    if ( (NULL == eh) || +         (GNUNET_OK != +          TALER_curl_easy_post (&csrh->post_ctx, +                                eh, +                                req)) ) +    { +      GNUNET_break (0); +      if (NULL != eh) +        curl_easy_cleanup (eh); +      json_decref (req); +      GNUNET_free (csrh->url); +      GNUNET_free (csrh); +      return NULL; +    } +    json_decref (req); +    csrh->job = GNUNET_CURL_job_add2 (ctx, +                                      eh, +                                      csrh->post_ctx.headers, +                                      &handle_csr_finished, +                                      csrh); +  } +  return csrh; +} + + +void +TALER_EXCHANGE_csr_withdraw_cancel (struct +                                    TALER_EXCHANGE_CsRWithdrawHandle *csrh) +{ +  if (NULL != csrh->job) +  { +    GNUNET_CURL_job_cancel (csrh->job); +    csrh->job = NULL; +  } +  GNUNET_free (csrh->url); +  TALER_curl_easy_post_finished (&csrh->post_ctx); +  GNUNET_free (csrh); +} diff --git a/src/lib/exchange_api_deposit.c b/src/lib/exchange_api_deposit.c index 2cd40556..82ee064b 100644 --- a/src/lib/exchange_api_deposit.c +++ b/src/lib/exchange_api_deposit.c @@ -491,7 +491,7 @@ verify_signatures (const struct TALER_EXCHANGE_DenomPublicKey *dki,  {    if (GNUNET_OK !=        TALER_wallet_deposit_verify (amount, -                                   &dki->fee_deposit, +                                   &dki->fees.deposit,                                     h_wire,                                     h_contract_terms,                                     h_age_commitment, @@ -508,7 +508,7 @@ verify_signatures (const struct TALER_EXCHANGE_DenomPublicKey *dki,      TALER_LOG_DEBUG ("... amount_with_fee was %s\n",                       TALER_amount2s (amount));      TALER_LOG_DEBUG ("... deposit_fee was %s\n", -                     TALER_amount2s (&dki->fee_deposit)); +                     TALER_amount2s (&dki->fees.deposit));      return GNUNET_SYSERR;    } @@ -536,7 +536,7 @@ verify_signatures (const struct TALER_EXCHANGE_DenomPublicKey *dki,    }    /* Check coin does make a contribution */ -  if (0 < TALER_amount_cmp (&dki->fee_deposit, +  if (0 < TALER_amount_cmp (&dki->fees.deposit,                              amount))    {      GNUNET_break_op (0); @@ -628,7 +628,7 @@ TALER_EXCHANGE_deposit (    if (0 >        TALER_amount_subtract (&amount_without_fee,                               amount, -                             &dki->fee_deposit)) +                             &dki->fees.deposit))    {      *ec = TALER_EC_EXCHANGE_DEPOSIT_FEE_ABOVE_AMOUNT;      GNUNET_break_op (0); diff --git a/src/lib/exchange_api_handle.c b/src/lib/exchange_api_handle.c index 3243f5e9..ee5f44a0 100644 --- a/src/lib/exchange_api_handle.c +++ b/src/lib/exchange_api_handle.c @@ -305,6 +305,7 @@ parse_json_signkey (struct TALER_EXCHANGE_SigningPublicKey *sign_key,  /**   * Parse a exchange's denomination key encoded in JSON.   * + * @param currency expected currency of all fees   * @param[out] denom_key where to return the result   * @param check_sigs should we check signatures?   * @param[in] denom_key_obj json to parse @@ -314,7 +315,8 @@ parse_json_signkey (struct TALER_EXCHANGE_SigningPublicKey *sign_key,   *        invalid or the json malformed.   */  static enum GNUNET_GenericReturnValue -parse_json_denomkey (struct TALER_EXCHANGE_DenomPublicKey *denom_key, +parse_json_denomkey (const char *currency, +                     struct TALER_EXCHANGE_DenomPublicKey *denom_key,                       int check_sigs,                       json_t *denom_key_obj,                       struct TALER_MasterPublicKeyP *master_key, @@ -331,16 +333,12 @@ parse_json_denomkey (struct TALER_EXCHANGE_DenomPublicKey *denom_key,                                  &denom_key->valid_from),      GNUNET_JSON_spec_timestamp ("stamp_expire_legal",                                  &denom_key->expire_legal), -    TALER_JSON_spec_amount_any ("value", -                                &denom_key->value), -    TALER_JSON_spec_amount_any ("fee_withdraw", -                                &denom_key->fee_withdraw), -    TALER_JSON_spec_amount_any ("fee_deposit", -                                &denom_key->fee_deposit), -    TALER_JSON_spec_amount_any ("fee_refresh", -                                &denom_key->fee_refresh), -    TALER_JSON_spec_amount_any ("fee_refund", -                                &denom_key->fee_refund), +    TALER_JSON_spec_amount ("value", +                            currency, +                            &denom_key->value), +    TALER_JSON_SPEC_DENOM_FEES ("fee", +                                currency, +                                &denom_key->fees),      TALER_JSON_spec_denom_pub ("denom_pub",                                 &denom_key->key),      GNUNET_JSON_spec_end () @@ -372,10 +370,7 @@ parse_json_denomkey (struct TALER_EXCHANGE_DenomPublicKey *denom_key,              denom_key->expire_deposit,              denom_key->expire_legal,              &denom_key->value, -            &denom_key->fee_withdraw, -            &denom_key->fee_deposit, -            &denom_key->fee_refresh, -            &denom_key->fee_refund, +            &denom_key->fees,              master_key,              &denom_key->master_sig));    return GNUNET_OK; @@ -492,10 +487,7 @@ parse_json_auditor (struct TALER_EXCHANGE_AuditorInformation *auditor,              dk->expire_deposit,              dk->expire_legal,              &dk->value, -            &dk->fee_withdraw, -            &dk->fee_deposit, -            &dk->fee_refresh, -            &dk->fee_refund, +            &dk->fees,              &auditor->auditor_pub,              &auditor_sig))        { @@ -883,7 +875,8 @@ decode_keys_json (const json_t *resp_obj,                  0,                  sizeof (dk));          EXITIF (GNUNET_SYSERR == -                parse_json_denomkey (&dk, +                parse_json_denomkey (key_data->currency, +                                     &dk,                                       check_sig,                                       denom_key_obj,                                       &key_data->master_pub, @@ -1728,14 +1721,8 @@ TALER_EXCHANGE_serialize_data (struct TALER_EXCHANGE_Handle *exchange)                                    dk->expire_legal),        TALER_JSON_pack_amount ("value",                                &dk->value), -      TALER_JSON_pack_amount ("fee_withdraw", -                              &dk->fee_withdraw), -      TALER_JSON_pack_amount ("fee_deposit", -                              &dk->fee_deposit), -      TALER_JSON_pack_amount ("fee_refresh", -                              &dk->fee_refresh), -      TALER_JSON_pack_amount ("fee_refund", -                              &dk->fee_refund), +      TALER_JSON_PACK_DENOM_FEES ("fee", +                                  &dk->fees),        GNUNET_JSON_pack_data_auto ("master_sig",                                    &dk->master_sig),        TALER_JSON_pack_denom_pub ("denom_pub", diff --git a/src/lib/exchange_api_melt.c b/src/lib/exchange_api_melt.c index 18596d89..71e6f55f 100644 --- a/src/lib/exchange_api_melt.c +++ b/src/lib/exchange_api_melt.c @@ -94,7 +94,7 @@ struct TALER_EXCHANGE_MeltHandle    /**     * Handle for the preflight request, or NULL.     */ -  struct TALER_EXCHANGE_CsRHandle *csr; +  struct TALER_EXCHANGE_CsRMeltHandle *csr;    /**     * Public key of the coin being melted. @@ -111,6 +111,10 @@ struct TALER_EXCHANGE_MeltHandle     */    uint32_t noreveal_index; +  /** +   * True if we need to include @e rms in our melt request. +   */ +  bool send_rms;  }; @@ -488,7 +492,13 @@ start_melt (struct TALER_EXCHANGE_MeltHandle *mh)      TALER_JSON_pack_amount ("value_with_fee",                              &mh->md.melted_coin.melt_amount_with_fee),      GNUNET_JSON_pack_data_auto ("rc", -                                &mh->md.rc)); +                                &mh->md.rc), +    GNUNET_JSON_pack_allow_null ( +      mh->send_rms +       ? GNUNET_JSON_pack_data_auto ("rms", +                                     &mh->rms) +       : GNUNET_JSON_pack_string ("rms", +                                  NULL)));    {      char pub_str[sizeof (struct TALER_CoinSpendPublicKeyP) * 2];      char *end; @@ -571,7 +581,7 @@ fail_mh (struct TALER_EXCHANGE_MeltHandle *mh,   */  static void  csr_cb (void *cls, -        const struct TALER_EXCHANGE_CsRResponse *csrr) +        const struct TALER_EXCHANGE_CsRMeltResponse *csrr)  {    struct TALER_EXCHANGE_MeltHandle *mh = cls;    unsigned int nks_off = 0; @@ -583,7 +593,7 @@ csr_cb (void *cls,        .hr = csrr->hr      }; -    mr.hr.hint = "/csr failed"; +    mr.hr.hint = "/csr-melt failed";      mh->melt_cb (mh->melt_cb_cls,                   &mr);      TALER_EXCHANGE_melt_cancel (mh); @@ -612,6 +622,7 @@ csr_cb (void *cls,        break;      }    } +  mh->send_rms = true;    if (GNUNET_OK !=        start_melt (mh))    { @@ -668,20 +679,19 @@ TALER_EXCHANGE_melt (struct TALER_EXCHANGE_Handle *exchange,      case TALER_DENOMINATION_CS:        wv->cipher = TALER_DENOMINATION_CS;        nks[nks_off].pk = fresh_pk; -      TALER_cs_refresh_nonce_derive (rms, -                                     i, -                                     &nks[nks_off].nonce); +      nks[nks_off].cnc_num = nks_off;        nks_off++;        break;      }    }    if (0 != nks_off)    { -    mh->csr = TALER_EXCHANGE_csr (exchange, -                                  nks_off, -                                  nks, -                                  &csr_cb, -                                  mh); +    mh->csr = TALER_EXCHANGE_csr_melt (exchange, +                                       rms, +                                       nks_off, +                                       nks, +                                       &csr_cb, +                                       mh);      if (NULL == mh->csr)      {        GNUNET_break (0); @@ -711,7 +721,7 @@ TALER_EXCHANGE_melt_cancel (struct TALER_EXCHANGE_MeltHandle *mh)    }    if (NULL != mh->csr)    { -    TALER_EXCHANGE_csr_cancel (mh->csr); +    TALER_EXCHANGE_csr_melt_cancel (mh->csr);      mh->csr = NULL;    }    TALER_EXCHANGE_free_melt_data_ (&mh->md); /* does not free 'md' itself */ diff --git a/src/lib/exchange_api_recoup.c b/src/lib/exchange_api_recoup.c index 9b7201cd..c94296c7 100644 --- a/src/lib/exchange_api_recoup.c +++ b/src/lib/exchange_api_recoup.c @@ -178,7 +178,7 @@ handle_recoup_finished (void *cls,                                   "history");        if (GNUNET_OK !=            TALER_EXCHANGE_verify_coin_history (dki, -                                              dki->fee_deposit.currency, +                                              dki->fees.deposit.currency,                                                &ph->coin_pub,                                                history,                                                &h_denom_pub, diff --git a/src/lib/exchange_api_recoup_refresh.c b/src/lib/exchange_api_recoup_refresh.c index 02e99415..0fff3a23 100644 --- a/src/lib/exchange_api_recoup_refresh.c +++ b/src/lib/exchange_api_recoup_refresh.c @@ -192,7 +192,7 @@ handle_recoup_refresh_finished (void *cls,                                   "history");        if (GNUNET_OK !=            TALER_EXCHANGE_verify_coin_history (dki, -                                              dki->fee_deposit.currency, +                                              dki->fees.deposit.currency,                                                &ph->coin_pub,                                                history,                                                &h_denom_pub, diff --git a/src/lib/exchange_api_refresh_common.c b/src/lib/exchange_api_refresh_common.c index 30711d78..b15e0d0d 100644 --- a/src/lib/exchange_api_refresh_common.c +++ b/src/lib/exchange_api_refresh_common.c @@ -64,6 +64,7 @@ TALER_EXCHANGE_get_melt_data_ (    struct TALER_Amount total;    struct TALER_CoinSpendPublicKeyP coin_pub;    struct TALER_CsNonce nonces[rd->fresh_pks_len]; +  bool uses_cs = false;    GNUNET_CRYPTO_eddsa_key_get_public (&rd->melt_priv.eddsa_priv,                                        &coin_pub.eddsa_pub); @@ -74,7 +75,7 @@ TALER_EXCHANGE_get_melt_data_ (    md->num_fresh_coins = rd->fresh_pks_len;    md->melted_coin.coin_priv = rd->melt_priv;    md->melted_coin.melt_amount_with_fee = rd->melt_amount; -  md->melted_coin.fee_melt = rd->melt_pk.fee_refresh; +  md->melted_coin.fee_melt = rd->melt_pk.fees.refresh;    md->melted_coin.original_value = rd->melt_pk.value;    md->melted_coin.expire_deposit = rd->melt_pk.expire_deposit;    md->melted_coin.age_commitment = rd->age_commitment; @@ -100,6 +101,7 @@ TALER_EXCHANGE_get_melt_data_ (      }      if (TALER_DENOMINATION_CS == alg_values[j].cipher)      { +      uses_cs = true;        TALER_cs_refresh_nonce_derive (          rms,          j, @@ -114,7 +116,7 @@ TALER_EXCHANGE_get_melt_data_ (           (0 >            TALER_amount_add (&total,                              &total, -                            &rd->fresh_pks[j].fee_withdraw)) ) +                            &rd->fresh_pks[j].fees.withdraw)) )      {        GNUNET_break (0);        TALER_EXCHANGE_free_melt_data_ (md); @@ -141,6 +143,7 @@ TALER_EXCHANGE_get_melt_data_ (      TALER_planchet_secret_to_transfer_priv (        rms, +      &rd->melt_priv,        i,        &md->transfer_priv[i]); @@ -239,6 +242,9 @@ TALER_EXCHANGE_get_melt_data_ (      }      TALER_refresh_get_commitment (&md->rc,                                    TALER_CNC_KAPPA, +                                  uses_cs +                                  ? rms +                                  : NULL,                                    rd->fresh_pks_len,                                    rce,                                    &coin_pub, diff --git a/src/lib/exchange_api_refreshes_reveal.c b/src/lib/exchange_api_refreshes_reveal.c index d5f2265c..89625890 100644 --- a/src/lib/exchange_api_refreshes_reveal.c +++ b/src/lib/exchange_api_refreshes_reveal.c @@ -340,6 +340,7 @@ TALER_EXCHANGE_refreshes_reveal (    struct GNUNET_CURL_Context *ctx;    struct MeltData md;    char arg_str[sizeof (struct TALER_RefreshCommitmentP) * 2 + 32]; +  bool send_rms = false;    GNUNET_assert (num_coins == rd->fresh_pks_len);    if (noreveal_index >= TALER_CNC_KAPPA) @@ -376,6 +377,8 @@ TALER_EXCHANGE_refreshes_reveal (      const struct TALER_RefreshCoinData *rcd = &md.rcd[noreveal_index][i];      struct TALER_DenominationHash denom_hash; +    if (TALER_DENOMINATION_CS == md.fcds[i].fresh_pk.cipher) +      send_rms = true;      TALER_denom_pub_hash (&md.fcds[i].fresh_pk,                            &denom_hash);      GNUNET_assert (0 == @@ -428,6 +431,12 @@ TALER_EXCHANGE_refreshes_reveal (    reveal_obj = GNUNET_JSON_PACK (      GNUNET_JSON_pack_data_auto ("transfer_pub",                                  &md.transfer_pub[noreveal_index]), +    GNUNET_JSON_pack_allow_null ( +      send_rms +      ? GNUNET_JSON_pack_data_auto ("rms", +                                    rms) +      : GNUNET_JSON_pack_string ("rms", +                                 NULL)),      GNUNET_JSON_pack_array_steal ("transfer_privs",                                    transfer_privs),      GNUNET_JSON_pack_array_steal ("link_sigs", diff --git a/src/lib/exchange_api_withdraw.c b/src/lib/exchange_api_withdraw.c index efc8a99c..01b6e8ba 100644 --- a/src/lib/exchange_api_withdraw.c +++ b/src/lib/exchange_api_withdraw.c @@ -106,7 +106,7 @@ struct TALER_EXCHANGE_WithdrawHandle    /**     * Handler for the CS R request (only used for TALER_DENOMINATION_CS denominations)     */ -  struct TALER_EXCHANGE_CsRHandle *csrh; +  struct TALER_EXCHANGE_CsRWithdrawHandle *csrh;  }; @@ -192,11 +192,12 @@ handle_reserve_withdraw_finished (   * Function called when stage 1 of CS withdraw is finished (request r_pub's)   *   * @param cls the `struct TALER_EXCHANGE_WithdrawHandle` - * @param csrr replies from the /csr request + * @param csrr replies from the /csr-withdraw request   */  static void -withdraw_cs_stage_two_callback (void *cls, -                                const struct TALER_EXCHANGE_CsRResponse *csrr) +withdraw_cs_stage_two_callback ( +  void *cls, +  const struct TALER_EXCHANGE_CsRWithdrawResponse *csrr)  {    struct TALER_EXCHANGE_WithdrawHandle *wh = cls;    struct TALER_EXCHANGE_WithdrawResponse wr = { @@ -208,13 +209,7 @@ withdraw_cs_stage_two_callback (void *cls,    switch (csrr->hr.http_status)    {    case MHD_HTTP_OK: -    if (1 != csrr->details.success.alg_values_len) -    { -      GNUNET_break (0); -      wr.hr.http_status = 0; -      break; -    } -    wh->alg_values = csrr->details.success.alg_values[0]; +    wh->alg_values = csrr->details.success.alg_values;      TALER_planchet_setup_coin_priv (&wh->ps,                                      &wh->alg_values,                                      &wh->priv); @@ -306,22 +301,19 @@ TALER_EXCHANGE_withdraw (      }    case TALER_DENOMINATION_CS:      { -      struct TALER_EXCHANGE_NonceKey nk = { -        .pk = pk, -      }; - -      TALER_cs_withdraw_nonce_derive (ps, -                                      &nk.nonce); +      TALER_cs_withdraw_nonce_derive ( +        ps, +        &wh->pd.blinded_planchet.details.cs_blinded_planchet.nonce);        /* Note that we only initialize the first half           of the blinded_planchet here; the other part -         will be done after the /csr request! */ +         will be done after the /csr-withdraw request! */        wh->pd.blinded_planchet.cipher = TALER_DENOMINATION_CS; -      wh->pd.blinded_planchet.details.cs_blinded_planchet.nonce = nk.nonce; -      wh->csrh = TALER_EXCHANGE_csr (exchange, -                                     1, /* "array" length */ -                                     &nk, -                                     &withdraw_cs_stage_two_callback, -                                     wh); +      wh->csrh = TALER_EXCHANGE_csr_withdraw ( +        exchange, +        pk, +        &wh->pd.blinded_planchet.details.cs_blinded_planchet.nonce, +        &withdraw_cs_stage_two_callback, +        wh);        break;      }    default: @@ -339,7 +331,7 @@ TALER_EXCHANGE_withdraw_cancel (struct TALER_EXCHANGE_WithdrawHandle *wh)    TALER_blinded_planchet_free (&wh->pd.blinded_planchet);    if (NULL != wh->csrh)    { -    TALER_EXCHANGE_csr_cancel (wh->csrh); +    TALER_EXCHANGE_csr_withdraw_cancel (wh->csrh);      wh->csrh = NULL;    }    if (NULL != wh->wh2) diff --git a/src/lib/exchange_api_withdraw2.c b/src/lib/exchange_api_withdraw2.c index c0643b9a..2441a141 100644 --- a/src/lib/exchange_api_withdraw2.c +++ b/src/lib/exchange_api_withdraw2.c @@ -403,7 +403,7 @@ TALER_EXCHANGE_withdraw2 (    if (0 >        TALER_amount_add (&wh->requested_amount,                          &dk->value, -                        &dk->fee_withdraw)) +                        &dk->fees.withdraw))    {      /* Overflow here? Very strange, our CPU must be fried... */      GNUNET_break (0);  | 
