summaryrefslogtreecommitdiff
path: root/src/exchange
diff options
context:
space:
mode:
Diffstat (limited to 'src/exchange')
-rw-r--r--src/exchange/taler-exchange-httpd.c10
-rw-r--r--src/exchange/taler-exchange-httpd_auditors.c5
-rw-r--r--src/exchange/taler-exchange-httpd_csr.c361
-rw-r--r--src/exchange/taler-exchange-httpd_csr.h25
-rw-r--r--src/exchange/taler-exchange-httpd_deposit.c2
-rw-r--r--src/exchange/taler-exchange-httpd_keys.c92
-rw-r--r--src/exchange/taler-exchange-httpd_management_post_keys.c5
-rw-r--r--src/exchange/taler-exchange-httpd_melt.c21
-rw-r--r--src/exchange/taler-exchange-httpd_recoup.c23
-rw-r--r--src/exchange/taler-exchange-httpd_refreshes_reveal.c29
-rw-r--r--src/exchange/taler-exchange-httpd_refund.c4
-rw-r--r--src/exchange/taler-exchange-httpd_withdraw.c31
12 files changed, 359 insertions, 249 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 d750ec70e..5a401abb7 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..f9a79a411 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;
}
-
- meta->age_mask = load_age_mask (section_name);
-
+ if (GNUNET_OK !=
+ TALER_config_get_denom_fees (TEH_cfg,
+ TEH_currency,
+ section_name,
+ &meta->fees))
+ return GNUNET_SYSERR;
+ meta->age_restrictions = 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 8bfdf8cef..cada8e7b0 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 4ac997e9c..32df3c4c9 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,
@@ -409,9 +409,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 1f0782aaa..9c0a665b7 100644
--- a/src/exchange/taler-exchange-httpd_refreshes_reveal.c
+++ b/src/exchange/taler-exchange-httpd_refreshes_reveal.c
@@ -116,10 +116,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;
};
@@ -296,6 +305,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,
@@ -344,7 +356,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,
@@ -439,7 +451,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 */
@@ -812,6 +832,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 ()
};
@@ -852,6 +875,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,