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) | |
download | exchange-f4f502d037a84a38db4bc21a1db06324a05d26aa.tar.xz |
-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 fe2a0b6b1..17ad7937d 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 d03409244..4f3e878d4 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 220dfba11..9de8cd8d9 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 000000000..d23f8ef85 --- /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 2cd405561..82ee064b9 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 3243f5e95..ee5f44a00 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 18596d891..71e6f55f0 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 9b7201cd0..c94296c74 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 02e994155..0fff3a23b 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 30711d781..b15e0d0d7 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 d5f2265c4..896258903 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 efc8a99c2..01b6e8bab 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 c0643b9af..2441a1417 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); |