diff options
Diffstat (limited to 'src/exchange')
-rw-r--r-- | src/exchange/taler-exchange-httpd.c | 10 | ||||
-rw-r--r-- | src/exchange/taler-exchange-httpd_auditors.c | 5 | ||||
-rw-r--r-- | src/exchange/taler-exchange-httpd_csr.c | 361 | ||||
-rw-r--r-- | src/exchange/taler-exchange-httpd_csr.h | 25 | ||||
-rw-r--r-- | src/exchange/taler-exchange-httpd_deposit.c | 2 | ||||
-rw-r--r-- | src/exchange/taler-exchange-httpd_keys.c | 90 | ||||
-rw-r--r-- | src/exchange/taler-exchange-httpd_management_post_keys.c | 5 | ||||
-rw-r--r-- | src/exchange/taler-exchange-httpd_melt.c | 21 | ||||
-rw-r--r-- | src/exchange/taler-exchange-httpd_recoup.c | 23 | ||||
-rw-r--r-- | src/exchange/taler-exchange-httpd_refreshes_reveal.c | 29 | ||||
-rw-r--r-- | src/exchange/taler-exchange-httpd_refund.c | 4 | ||||
-rw-r--r-- | src/exchange/taler-exchange-httpd_withdraw.c | 31 |
12 files changed, 358 insertions, 248 deletions
diff --git a/src/exchange/taler-exchange-httpd.c b/src/exchange/taler-exchange-httpd.c index a0d0aa3b6..efaf63114 100644 --- a/src/exchange/taler-exchange-httpd.c +++ b/src/exchange/taler-exchange-httpd.c @@ -925,9 +925,15 @@ handle_mhd_request (void *cls, }, /* request R, used in clause schnorr withdraw and refresh */ { - .url = "csr", + .url = "csr-melt", .method = MHD_HTTP_METHOD_POST, - .handler.post = &TEH_handler_csr, + .handler.post = &TEH_handler_csr_melt, + .nargs = 0 + }, + { + .url = "csr-withdraw", + .method = MHD_HTTP_METHOD_POST, + .handler.post = &TEH_handler_csr_withdraw, .nargs = 0 }, /* Withdrawing coins / interaction with reserves */ diff --git a/src/exchange/taler-exchange-httpd_auditors.c b/src/exchange/taler-exchange-httpd_auditors.c index 1b8af311c..b9ebbe582 100644 --- a/src/exchange/taler-exchange-httpd_auditors.c +++ b/src/exchange/taler-exchange-httpd_auditors.c @@ -150,10 +150,7 @@ add_auditor_denom_sig (void *cls, meta.expire_deposit, meta.expire_legal, &meta.value, - &meta.fee_withdraw, - &meta.fee_deposit, - &meta.fee_refresh, - &meta.fee_refund, + &meta.fees, awc->auditor_pub, &awc->auditor_sig)) { diff --git a/src/exchange/taler-exchange-httpd_csr.c b/src/exchange/taler-exchange-httpd_csr.c index 47694d30b..423835979 100644 --- a/src/exchange/taler-exchange-httpd_csr.c +++ b/src/exchange/taler-exchange-httpd_csr.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014-2021 Taler Systems SA + 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 Affero General Public License as @@ -33,15 +33,16 @@ MHD_RESULT -TEH_handler_csr (struct TEH_RequestContext *rc, - const json_t *root, - const char *const args[]) +TEH_handler_csr_melt (struct TEH_RequestContext *rc, + const json_t *root, + const char *const args[]) { + struct TALER_RefreshMasterSecretP rms; unsigned int csr_requests_num; json_t *csr_requests; - json_t *csr_response_ewvs; - json_t *csr_response; struct GNUNET_JSON_Specification spec[] = { + GNUNET_JSON_spec_fixed_auto ("rms", + &rms), GNUNET_JSON_spec_json ("nks", &csr_requests), GNUNET_JSON_spec_end () @@ -50,8 +51,7 @@ TEH_handler_csr (struct TEH_RequestContext *rc, struct TEH_DenominationKey *dk; (void) args; - - // parse input + /* parse input */ { enum GNUNET_GenericReturnValue res; @@ -62,7 +62,8 @@ TEH_handler_csr (struct TEH_RequestContext *rc, return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES; } csr_requests_num = json_array_size (csr_requests); - if (TALER_MAX_FRESH_COINS <= csr_requests_num) + if ( (TALER_MAX_FRESH_COINS <= csr_requests_num) || + (0 == csr_requests_num) ) { GNUNET_JSON_parse_free (spec); return TALER_MHD_reply_with_error ( @@ -71,109 +72,253 @@ TEH_handler_csr (struct TEH_RequestContext *rc, TALER_EC_EXCHANGE_GENERIC_NEW_DENOMS_ARRAY_SIZE_EXCESSIVE, NULL); } - struct TALER_CsNonce nonces[GNUNET_NZL (csr_requests_num)]; - struct TALER_DenominationHash denom_pub_hashes[GNUNET_NZL (csr_requests_num)]; - for (unsigned int i = 0; i < csr_requests_num; i++) - { - struct TALER_CsNonce *nonce = &nonces[i]; - struct TALER_DenominationHash *denom_pub_hash = &denom_pub_hashes[i]; - struct GNUNET_JSON_Specification csr_spec[] = { - GNUNET_JSON_spec_fixed ("nonce", - nonce, - sizeof (struct TALER_CsNonce)), - GNUNET_JSON_spec_fixed ("denom_pub_hash", - denom_pub_hash, - sizeof (struct TALER_DenominationHash)), - GNUNET_JSON_spec_end () - }; - enum GNUNET_GenericReturnValue res; - - res = TALER_MHD_parse_json_array (rc->connection, - csr_requests, - csr_spec, - i, - -1); - if (GNUNET_OK != res) - { - GNUNET_JSON_parse_free (spec); - return (GNUNET_NO == res) ? MHD_YES : MHD_NO; - } - } - GNUNET_JSON_parse_free (spec); - struct TALER_ExchangeWithdrawValues ewvs[GNUNET_NZL (csr_requests_num)]; - for (unsigned int i = 0; i < csr_requests_num; i++) { - const struct TALER_CsNonce *nonce = &nonces[i]; - const struct TALER_DenominationHash *denom_pub_hash = &denom_pub_hashes[i]; - struct TALER_DenominationCSPublicRPairP *r_pub - = &ewvs[i].details.cs_values; + struct TALER_ExchangeWithdrawValues ewvs[csr_requests_num]; - ewvs[i].cipher = TALER_DENOMINATION_CS; - // check denomination referenced by denom_pub_hash { - struct TEH_KeyStateHandle *ksh; + struct TALER_CsNonce nonces[csr_requests_num]; + struct TALER_DenominationHash denom_pub_hashes[csr_requests_num]; - ksh = TEH_keys_get_state (); - if (NULL == ksh) + for (unsigned int i = 0; i < csr_requests_num; i++) { - return TALER_MHD_reply_with_error (rc->connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_EXCHANGE_GENERIC_KEYS_MISSING, - NULL); - } - dk = TEH_keys_denomination_by_hash2 (ksh, - denom_pub_hash, - NULL, - NULL); - if (NULL == dk) - { - return TEH_RESPONSE_reply_unknown_denom_pub_hash ( - rc->connection, - &denom_pub_hash[i]); - } - if (GNUNET_TIME_absolute_is_past (dk->meta.expire_withdraw.abs_time)) - { - /* This denomination is past the expiration time for withdraws/refreshes*/ - return TEH_RESPONSE_reply_expired_denom_pub_hash ( - rc->connection, - denom_pub_hash, - TALER_EC_EXCHANGE_GENERIC_DENOMINATION_EXPIRED, - "CSR"); - } - if (GNUNET_TIME_absolute_is_future (dk->meta.start.abs_time)) - { - /* This denomination is not yet valid, no need to check - for idempotency! */ - return TEH_RESPONSE_reply_expired_denom_pub_hash ( - rc->connection, - denom_pub_hash, - TALER_EC_EXCHANGE_GENERIC_DENOMINATION_VALIDITY_IN_FUTURE, - "CSR"); + uint32_t coin_off; + struct TALER_DenominationHash *denom_pub_hash = &denom_pub_hashes[i]; + struct GNUNET_JSON_Specification csr_spec[] = { + GNUNET_JSON_spec_uint32 ("coin_offset", + &coin_off), + GNUNET_JSON_spec_fixed_auto ("denom_pub_hash", + denom_pub_hash), + GNUNET_JSON_spec_end () + }; + enum GNUNET_GenericReturnValue res; + + res = TALER_MHD_parse_json_array (rc->connection, + csr_requests, + csr_spec, + i, + -1); + if (GNUNET_OK != res) + { + GNUNET_JSON_parse_free (spec); + return (GNUNET_NO == res) ? MHD_YES : MHD_NO; + } + TALER_cs_refresh_nonce_derive (&rms, + coin_off, + &nonces[i]); } - if (dk->recoup_possible) + GNUNET_JSON_parse_free (spec); + + for (unsigned int i = 0; i < csr_requests_num; i++) { - /* This denomination has been revoked */ - return TEH_RESPONSE_reply_expired_denom_pub_hash ( - rc->connection, - denom_pub_hash, - TALER_EC_EXCHANGE_GENERIC_DENOMINATION_REVOKED, - "CSR"); + const struct TALER_CsNonce *nonce = &nonces[i]; + const struct TALER_DenominationHash *denom_pub_hash = + &denom_pub_hashes[i]; + struct TALER_DenominationCSPublicRPairP *r_pub + = &ewvs[i].details.cs_values; + + ewvs[i].cipher = TALER_DENOMINATION_CS; + /* check denomination referenced by denom_pub_hash */ + { + struct TEH_KeyStateHandle *ksh; + + ksh = TEH_keys_get_state (); + if (NULL == ksh) + { + return TALER_MHD_reply_with_error (rc->connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_EXCHANGE_GENERIC_KEYS_MISSING, + NULL); + } + dk = TEH_keys_denomination_by_hash2 (ksh, + denom_pub_hash, + NULL, + NULL); + if (NULL == dk) + { + return TEH_RESPONSE_reply_unknown_denom_pub_hash ( + rc->connection, + &denom_pub_hash[i]); + } + if (GNUNET_TIME_absolute_is_past (dk->meta.expire_withdraw.abs_time)) + { + /* This denomination is past the expiration time for withdraws/refreshes*/ + return TEH_RESPONSE_reply_expired_denom_pub_hash ( + rc->connection, + denom_pub_hash, + TALER_EC_EXCHANGE_GENERIC_DENOMINATION_EXPIRED, + "csr-melt"); + } + if (GNUNET_TIME_absolute_is_future (dk->meta.start.abs_time)) + { + /* This denomination is not yet valid, no need to check + for idempotency! */ + return TEH_RESPONSE_reply_expired_denom_pub_hash ( + rc->connection, + denom_pub_hash, + TALER_EC_EXCHANGE_GENERIC_DENOMINATION_VALIDITY_IN_FUTURE, + "csr-melt"); + } + if (dk->recoup_possible) + { + /* This denomination has been revoked */ + return TEH_RESPONSE_reply_expired_denom_pub_hash ( + rc->connection, + denom_pub_hash, + TALER_EC_EXCHANGE_GENERIC_DENOMINATION_REVOKED, + "csr-melt"); + } + if (TALER_DENOMINATION_CS != dk->denom_pub.cipher) + { + /* denomination is valid but not for CS */ + return TEH_RESPONSE_reply_invalid_denom_cipher_for_operation ( + rc->connection, + denom_pub_hash); + } + } + + /* derive r_pub */ + // FIXME: bundle all requests into one derivation request (TEH_keys_..., crypto helper, security module) + ec = TEH_keys_denomination_cs_r_pub (denom_pub_hash, + nonce, + r_pub); + if (TALER_EC_NONE != ec) + { + GNUNET_break (0); + return TALER_MHD_reply_with_ec (rc->connection, + ec, + NULL); + } } - if (TALER_DENOMINATION_CS != dk->denom_pub.cipher) + } + + /* send response */ + { + json_t *csr_response_ewvs; + json_t *csr_response; + + csr_response_ewvs = json_array (); + for (unsigned int i = 0; i < csr_requests_num; i++) { - // denomination is valid but not CS - return TEH_RESPONSE_reply_invalid_denom_cipher_for_operation ( - rc->connection, - denom_pub_hash); + json_t *csr_obj; + + csr_obj = GNUNET_JSON_PACK ( + TALER_JSON_pack_exchange_withdraw_values ("ewv", + &ewvs[i])); + GNUNET_assert (NULL != csr_obj); + GNUNET_assert (0 == + json_array_append_new (csr_response_ewvs, + csr_obj)); } + csr_response = GNUNET_JSON_PACK ( + GNUNET_JSON_pack_array_steal ("ewvs", + csr_response_ewvs)); + GNUNET_assert (NULL != csr_response); + return TALER_MHD_reply_json_steal (rc->connection, + csr_response, + MHD_HTTP_OK); + } + } +} + + +MHD_RESULT +TEH_handler_csr_withdraw (struct TEH_RequestContext *rc, + const json_t *root, + const char *const args[]) +{ + struct TALER_CsNonce nonce; + struct TALER_DenominationHash denom_pub_hash; + struct TALER_ExchangeWithdrawValues ewv = { + .cipher = TALER_DENOMINATION_CS + }; + struct GNUNET_JSON_Specification spec[] = { + GNUNET_JSON_spec_fixed ("nonce", + &nonce, + sizeof (struct TALER_CsNonce)), + GNUNET_JSON_spec_fixed ("denom_pub_hash", + &denom_pub_hash, + sizeof (struct TALER_DenominationHash)), + GNUNET_JSON_spec_end () + }; + struct TEH_DenominationKey *dk; + + (void) args; + { + enum GNUNET_GenericReturnValue res; + + res = TALER_MHD_parse_json_data (rc->connection, + root, + spec); + if (GNUNET_OK != res) + return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES; + } + + { + struct TEH_KeyStateHandle *ksh; + + ksh = TEH_keys_get_state (); + if (NULL == ksh) + { + return TALER_MHD_reply_with_error (rc->connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_EXCHANGE_GENERIC_KEYS_MISSING, + NULL); + } + dk = TEH_keys_denomination_by_hash2 (ksh, + &denom_pub_hash, + NULL, + NULL); + if (NULL == dk) + { + return TEH_RESPONSE_reply_unknown_denom_pub_hash ( + rc->connection, + &denom_pub_hash); + } + if (GNUNET_TIME_absolute_is_past (dk->meta.expire_withdraw.abs_time)) + { + /* This denomination is past the expiration time for withdraws/refreshes*/ + return TEH_RESPONSE_reply_expired_denom_pub_hash ( + rc->connection, + &denom_pub_hash, + TALER_EC_EXCHANGE_GENERIC_DENOMINATION_EXPIRED, + "csr-withdraw"); + } + if (GNUNET_TIME_absolute_is_future (dk->meta.start.abs_time)) + { + /* This denomination is not yet valid, no need to check + for idempotency! */ + return TEH_RESPONSE_reply_expired_denom_pub_hash ( + rc->connection, + &denom_pub_hash, + TALER_EC_EXCHANGE_GENERIC_DENOMINATION_VALIDITY_IN_FUTURE, + "csr-withdraw"); + } + if (dk->recoup_possible) + { + /* This denomination has been revoked */ + return TEH_RESPONSE_reply_expired_denom_pub_hash ( + rc->connection, + &denom_pub_hash, + TALER_EC_EXCHANGE_GENERIC_DENOMINATION_REVOKED, + "csr-withdraw"); + } + if (TALER_DENOMINATION_CS != dk->denom_pub.cipher) + { + /* denomination is valid but not for CS */ + return TEH_RESPONSE_reply_invalid_denom_cipher_for_operation ( + rc->connection, + &denom_pub_hash); } + } + + /* derive r_pub */ + { + enum TALER_ErrorCode ec; - // derive r_pub - // FIXME: bundle all requests into one derivation request (TEH_keys_..., crypto helper, security module) - ec = TEH_keys_denomination_cs_r_pub (denom_pub_hash, - nonce, - r_pub); + ec = TEH_keys_denomination_cs_r_pub (&denom_pub_hash, + &nonce, + &ewv.details.cs_values); if (TALER_EC_NONE != ec) { GNUNET_break (0); @@ -183,27 +328,17 @@ TEH_handler_csr (struct TEH_RequestContext *rc, } } - // send response - csr_response_ewvs = json_array (); - for (unsigned int i = 0; i < csr_requests_num; i++) { json_t *csr_obj; csr_obj = GNUNET_JSON_PACK ( TALER_JSON_pack_exchange_withdraw_values ("ewv", - &ewvs[i])); + &ewv)); GNUNET_assert (NULL != csr_obj); - GNUNET_assert (0 == - json_array_append_new (csr_response_ewvs, - csr_obj)); + return TALER_MHD_reply_json_steal (rc->connection, + csr_obj, + MHD_HTTP_OK); } - csr_response = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_array_steal ("ewvs", - csr_response_ewvs)); - GNUNET_assert (NULL != csr_response); - return TALER_MHD_reply_json_steal (rc->connection, - csr_response, - MHD_HTTP_OK); } diff --git a/src/exchange/taler-exchange-httpd_csr.h b/src/exchange/taler-exchange-httpd_csr.h index 3bd98742b..615255f94 100644 --- a/src/exchange/taler-exchange-httpd_csr.h +++ b/src/exchange/taler-exchange-httpd_csr.h @@ -15,7 +15,7 @@ */ /** * @file taler-exchange-httpd_csr.h - * @brief Handle /csr requests + * @brief Handle /csr-* requests * @author Lucien Heuzeveldt * @author Gian Demarmles */ @@ -27,8 +27,7 @@ /** - * Handle a "/csr" request. Parses the "nonce" and - * the "denom_pub_hash" (identifying a denomination) used to derive the r_pub. + * Handle a "/csr-melt" request. * * @param rc request context * @param root uploaded JSON data @@ -36,8 +35,22 @@ * @return MHD result code */ MHD_RESULT -TEH_handler_csr (struct TEH_RequestContext *rc, - const json_t *root, - const char *const args[]); +TEH_handler_csr_melt (struct TEH_RequestContext *rc, + const json_t *root, + const char *const args[]); + + +/** + * Handle a "/csr-withdraw" request. + * + * @param rc request context + * @param root uploaded JSON data + * @param args empty array + * @return MHD result code + */ +MHD_RESULT +TEH_handler_csr_withdraw (struct TEH_RequestContext *rc, + const json_t *root, + const char *const args[]); #endif diff --git a/src/exchange/taler-exchange-httpd_deposit.c b/src/exchange/taler-exchange-httpd_deposit.c index 11a53ceaa..7cd78119a 100644 --- a/src/exchange/taler-exchange-httpd_deposit.c +++ b/src/exchange/taler-exchange-httpd_deposit.c @@ -370,7 +370,7 @@ TEH_handler_deposit (struct MHD_Connection *connection, NULL); } - deposit.deposit_fee = dk->meta.fee_deposit; + deposit.deposit_fee = dk->meta.fees.deposit; /* check coin signature */ if (GNUNET_YES != TALER_test_coin_valid (&deposit.coin, diff --git a/src/exchange/taler-exchange-httpd_keys.c b/src/exchange/taler-exchange-httpd_keys.c index d1dfb28b9..695ce9777 100644 --- a/src/exchange/taler-exchange-httpd_keys.c +++ b/src/exchange/taler-exchange-httpd_keys.c @@ -2113,14 +2113,8 @@ finish_keys_response (struct TEH_KeyStateHandle *ksh) &dk->denom_pub), TALER_JSON_pack_amount ("value", &dk->meta.value), - TALER_JSON_pack_amount ("fee_withdraw", - &dk->meta.fee_withdraw), - TALER_JSON_pack_amount ("fee_deposit", - &dk->meta.fee_deposit), - TALER_JSON_pack_amount ("fee_refresh", - &dk->meta.fee_refresh), - TALER_JSON_pack_amount ("fee_refund", - &dk->meta.fee_refund)); + TALER_JSON_PACK_DENOM_FEES ("fee", + &dk->meta.fees)); /* Put the denom into the correct array depending on the settings and * the properties of the denomination. Also, we build up the right @@ -2810,74 +2804,22 @@ load_extension_data (const char *section_name, section_name); return GNUNET_SYSERR; } - if (GNUNET_OK != - TALER_config_get_amount (TEH_cfg, - section_name, - "FEE_WITHDRAW", - &meta->fee_withdraw)) - { - GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, - "Need amount for option `%s' in section `%s'\n", - "FEE_WITHDRAW", - section_name); - return GNUNET_SYSERR; - } - if (GNUNET_OK != - TALER_config_get_amount (TEH_cfg, - section_name, - "FEE_DEPOSIT", - &meta->fee_deposit)) - { - GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, - "Need amount for option `%s' in section `%s'\n", - "FEE_DEPOSIT", - section_name); - return GNUNET_SYSERR; - } - if (GNUNET_OK != - TALER_config_get_amount (TEH_cfg, - section_name, - "FEE_REFRESH", - &meta->fee_refresh)) - { - GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, - "Need amount for option `%s' in section `%s'\n", - "FEE_REFRESH", - section_name); - return GNUNET_SYSERR; - } - if (GNUNET_OK != - TALER_config_get_amount (TEH_cfg, - section_name, - "FEE_REFUND", - &meta->fee_refund)) - { - GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, - "Need amount for option `%s' in section `%s'\n", - "FEE_REFUND", - section_name); - return GNUNET_SYSERR; - } - if ( (0 != strcasecmp (TEH_currency, - meta->value.currency)) || - (0 != strcasecmp (TEH_currency, - meta->fee_withdraw.currency)) || - (0 != strcasecmp (TEH_currency, - meta->fee_deposit.currency)) || - (0 != strcasecmp (TEH_currency, - meta->fee_refresh.currency)) || - (0 != strcasecmp (TEH_currency, - meta->fee_refund.currency)) ) + if (0 != strcasecmp (TEH_currency, + meta->value.currency)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Need amounts in section `%s' to use currency `%s'\n", + "Need denomination value in section `%s' to use currency `%s'\n", section_name, TEH_currency); return GNUNET_SYSERR; } - + if (GNUNET_OK != + TALER_config_get_denom_fees (TEH_cfg, + TEH_currency, + section_name, + &meta->fees)) + return GNUNET_SYSERR; meta->age_mask = load_age_mask (section_name); - return GNUNET_OK; } @@ -3040,14 +2982,8 @@ add_future_denomkey_cb (void *cls, meta.expire_legal), TALER_JSON_pack_denom_pub ("denom_pub", &hd->denom_pub), - TALER_JSON_pack_amount ("fee_withdraw", - &meta.fee_withdraw), - TALER_JSON_pack_amount ("fee_deposit", - &meta.fee_deposit), - TALER_JSON_pack_amount ("fee_refresh", - &meta.fee_refresh), - TALER_JSON_pack_amount ("fee_refund", - &meta.fee_refund), + TALER_JSON_PACK_DENOM_FEES ("fee", + &meta.fees), GNUNET_JSON_pack_data_auto ("denom_secmod_sig", &hd->sm_sig), GNUNET_JSON_pack_string ("section_name", diff --git a/src/exchange/taler-exchange-httpd_management_post_keys.c b/src/exchange/taler-exchange-httpd_management_post_keys.c index c353a9959..2e48497a5 100644 --- a/src/exchange/taler-exchange-httpd_management_post_keys.c +++ b/src/exchange/taler-exchange-httpd_management_post_keys.c @@ -187,10 +187,7 @@ add_keys (void *cls, meta.expire_deposit, meta.expire_legal, &meta.value, - &meta.fee_withdraw, - &meta.fee_deposit, - &meta.fee_refresh, - &meta.fee_refund, + &meta.fees, &TEH_master_public_key, &d->master_sig)) { diff --git a/src/exchange/taler-exchange-httpd_melt.c b/src/exchange/taler-exchange-httpd_melt.c index 769b13e4d..1585af71f 100644 --- a/src/exchange/taler-exchange-httpd_melt.c +++ b/src/exchange/taler-exchange-httpd_melt.c @@ -105,6 +105,11 @@ struct MeltContext struct TALER_Amount coin_refresh_fee; /** + * Refresh master secret, if any of the fresh denominations use CS. + */ + struct TALER_RefreshMasterSecretP rms; + + /** * Set to true if this coin's denomination was revoked and the operation * is thus only allowed for zombie coins where the transaction * history includes a #TALER_EXCHANGEDB_TT_OLD_COIN_RECOUP. @@ -117,6 +122,10 @@ struct MeltContext */ bool coin_is_dirty; + /** + * True if @e rms is set. + */ + bool have_rms; }; @@ -155,6 +164,9 @@ melt_transaction (void *cls, if (0 > (qs = TEH_plugin->do_melt (TEH_plugin->cls, + rmc->have_rms + ? &rmc->rms + : NULL, &rmc->refresh_session, rmc->known_coin_id, &rmc->zombie_required, @@ -300,7 +312,7 @@ check_melt_valid (struct MHD_Connection *connection, "MELT"); } - rmc->coin_refresh_fee = dk->meta.fee_refresh; + rmc->coin_refresh_fee = dk->meta.fees.refresh; rmc->coin_value = dk->meta.value; GNUNET_log (GNUNET_ERROR_TYPE_INFO, @@ -422,6 +434,9 @@ TEH_handler_melt (struct MHD_Connection *connection, &rmc.refresh_session.amount_with_fee), GNUNET_JSON_spec_fixed_auto ("rc", &rmc.refresh_session.rc), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_fixed_auto ("rms", + &rmc.rms)), GNUNET_JSON_spec_end () }; @@ -429,7 +444,6 @@ TEH_handler_melt (struct MHD_Connection *connection, 0, sizeof (rmc)); rmc.refresh_session.coin.coin_pub = *coin_pub; - { enum GNUNET_GenericReturnValue ret; ret = TALER_MHD_parse_json_data (connection, @@ -438,7 +452,8 @@ TEH_handler_melt (struct MHD_Connection *connection, if (GNUNET_OK != ret) return (GNUNET_SYSERR == ret) ? MHD_NO : MHD_YES; } - + rmc.have_rms = (NULL != json_object_get (root, + "rms")); { MHD_RESULT res; diff --git a/src/exchange/taler-exchange-httpd_recoup.c b/src/exchange/taler-exchange-httpd_recoup.c index 00753251b..0f6bb2460 100644 --- a/src/exchange/taler-exchange-httpd_recoup.c +++ b/src/exchange/taler-exchange-httpd_recoup.c @@ -42,7 +42,7 @@ struct RecoupContext /** * Hash identifying the withdraw request. */ - struct TALER_WithdrawIdentificationHash wih; + struct TALER_BlindedCoinHash h_coin_ev; /** * Set by #recoup_transaction() to the reserve that will @@ -273,9 +273,9 @@ verify_and_execute_recoup ( blinded_planchet.details.cs_blinded_planchet.nonce = *nonce; if (GNUNET_OK != - TALER_withdraw_request_hash (&blinded_planchet, - &coin->denom_pub_hash, - &pc.wih)) + TALER_coin_ev_hash (&blinded_planchet, + &coin->denom_pub_hash, + &pc.h_coin_ev)) { GNUNET_break (0); return TALER_MHD_reply_with_error (connection, @@ -308,10 +308,10 @@ verify_and_execute_recoup ( { enum GNUNET_DB_QueryStatus qs; - qs = TEH_plugin->get_reserve_by_wih (TEH_plugin->cls, - &pc.wih, - &pc.reserve_pub, - &pc.reserve_out_serial_id); + qs = TEH_plugin->get_reserve_by_h_blind (TEH_plugin->cls, + &pc.h_coin_ev, + &pc.reserve_pub, + &pc.reserve_out_serial_id); if (0 > qs) { GNUNET_break (0); @@ -319,13 +319,13 @@ verify_and_execute_recoup ( connection, MHD_HTTP_INTERNAL_SERVER_ERROR, TALER_EC_GENERIC_DB_FETCH_FAILED, - "get_reserve_by_wih"); + "get_reserve_by_h_blind"); } if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) { GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Recoup requested for unknown envelope %s\n", - GNUNET_h2s (&pc.wih.hash)); + GNUNET_h2s (&pc.h_coin_ev.hash)); return TALER_MHD_reply_with_error ( connection, MHD_HTTP_NOT_FOUND, @@ -412,9 +412,6 @@ TEH_handler_recoup (struct MHD_Connection *connection, return MHD_NO; /* hard failure */ if (GNUNET_NO == ret) return MHD_YES; /* failure */ - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Recoup coin with BKS=%s\n", - TALER_B2S (&coin_bks)); { MHD_RESULT res; diff --git a/src/exchange/taler-exchange-httpd_refreshes_reveal.c b/src/exchange/taler-exchange-httpd_refreshes_reveal.c index 32195f8db..9e47f4664 100644 --- a/src/exchange/taler-exchange-httpd_refreshes_reveal.c +++ b/src/exchange/taler-exchange-httpd_refreshes_reveal.c @@ -122,10 +122,19 @@ struct RevealContext struct TALER_RefreshCoinData *rcds; /** + * Refresh master secret. + */ + struct TALER_RefreshMasterSecretP rms; + + /** * Size of the @e dks, @e rcds and @e ev_sigs arrays (if non-NULL). */ unsigned int num_fresh_coins; + /** + * True if @e rms was provided. + */ + bool have_rms; }; @@ -321,6 +330,9 @@ check_commitment (struct RevealContext *rctx, } TALER_refresh_get_commitment (&rc_expected, TALER_CNC_KAPPA, + rctx->have_rms + ? &rctx->rms + : NULL, rctx->num_fresh_coins, rcs, &rctx->melt.session.coin.coin_pub, @@ -369,7 +381,7 @@ check_commitment (struct RevealContext *rctx, if ( (0 > TALER_amount_add (&total, - &rctx->dks[i]->meta.fee_withdraw, + &rctx->dks[i]->meta.fees.withdraw, &rctx->dks[i]->meta.value)) || (0 > TALER_amount_add (&refresh_cost, @@ -464,7 +476,15 @@ resolve_refreshes_reveal_denominations (struct MHD_Connection *connection, &ret); if (NULL == dks[i]) return ret; - + if ( (TALER_DENOMINATION_CS == dks[i]->denom_pub.cipher) && + (! rctx->have_rms) ) + { + return TALER_MHD_reply_with_error ( + connection, + MHD_HTTP_BAD_REQUEST, + TALER_EC_GENERIC_PARAMETER_MISSING, + "rms"); + } if (GNUNET_TIME_absolute_is_past (dks[i]->meta.expire_withdraw.abs_time)) { /* This denomination is past the expiration time for withdraws */ @@ -907,6 +927,9 @@ TEH_handler_reveal (struct TEH_RequestContext *rc, GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_json ("old_age_commitment", &old_age_commitment)), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_fixed_auto ("rms", + &rctx.rms)), GNUNET_JSON_spec_end () }; @@ -947,6 +970,8 @@ TEH_handler_reveal (struct TEH_RequestContext *rc, return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES; } } + rctx.have_rms = (NULL != json_object_get (root, + "rms")); /* Check we got enough transfer private keys */ /* Note we do +1 as 1 row (cut-and-choose!) is missing! */ diff --git a/src/exchange/taler-exchange-httpd_refund.c b/src/exchange/taler-exchange-httpd_refund.c index 9cc019a14..628fe6993 100644 --- a/src/exchange/taler-exchange-httpd_refund.c +++ b/src/exchange/taler-exchange-httpd_refund.c @@ -264,8 +264,8 @@ verify_and_execute_refund (struct MHD_Connection *connection, GNUNET_break (0); return mret; } - refund->details.refund_fee = dk->meta.fee_refund; - rctx.deposit_fee = dk->meta.fee_deposit; + refund->details.refund_fee = dk->meta.fees.refund; + rctx.deposit_fee = dk->meta.fees.deposit; } /* Finally run the actual transaction logic */ diff --git a/src/exchange/taler-exchange-httpd_withdraw.c b/src/exchange/taler-exchange-httpd_withdraw.c index a3ac1de33..cc6e92edf 100644 --- a/src/exchange/taler-exchange-httpd_withdraw.c +++ b/src/exchange/taler-exchange-httpd_withdraw.c @@ -92,11 +92,6 @@ struct WithdrawContext { /** - * Hash that uniquely identifies the withdraw request. - */ - struct TALER_WithdrawIdentificationHash wih; - - /** * Hash of the (blinded) message to be signed by the Exchange. */ struct TALER_BlindedCoinHash h_coin_envelope; @@ -157,10 +152,17 @@ withdraw_transaction (void *cls, bool balance_ok = false; struct GNUNET_TIME_Timestamp now; uint64_t ruuid; + const struct TALER_CsNonce *nonce; + const struct TALER_BlindedPlanchet *bp; now = GNUNET_TIME_timestamp_get (); + bp = &wc->blinded_planchet; + nonce = + (TALER_DENOMINATION_CS == bp->cipher) + ? &bp->details.cs_blinded_planchet.nonce + : NULL; qs = TEH_plugin->do_withdraw (TEH_plugin->cls, - &wc->wih, + nonce, &wc->collectable, now, &found, @@ -300,7 +302,7 @@ check_request_idempotent (struct TEH_RequestContext *rc, enum GNUNET_DB_QueryStatus qs; qs = TEH_plugin->get_withdraw_info (TEH_plugin->cls, - &wc->wih, + &wc->h_coin_envelope, &wc->collectable); if (0 > qs) { @@ -465,7 +467,7 @@ TEH_handler_withdraw (struct TEH_RequestContext *rc, if (0 > TALER_amount_add (&wc.collectable.amount_with_fee, &dk->meta.value, - &dk->meta.fee_withdraw)) + &dk->meta.fees.withdraw)) { GNUNET_JSON_parse_free (spec); return TALER_MHD_reply_with_error (rc->connection, @@ -502,19 +504,6 @@ TEH_handler_withdraw (struct TEH_RequestContext *rc, NULL); } - if (GNUNET_OK != - TALER_withdraw_request_hash (&wc.blinded_planchet, - &wc.collectable.denom_pub_hash, - &wc.wih)) - { - GNUNET_break (0); - GNUNET_JSON_parse_free (spec); - return TALER_MHD_reply_with_error (rc->connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE, - NULL); - } - /* Sign before transaction! */ ec = TEH_keys_denomination_sign ( &wc.collectable.denom_pub_hash, |