summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2020-07-05 20:43:28 +0200
committerChristian Grothoff <christian@grothoff.org>2020-07-05 20:43:28 +0200
commit6de49ea2c02e311e5f5366005bd3497a9bb25187 (patch)
treea221b9c784b4e004eb5972e18516653d1aea6a5c /src/lib
parente428783e2e0295186dc4eae273df8a3f8b75df60 (diff)
parented5b98a2c2308fbd44b906a30286d2689fd304dd (diff)
downloadexchange-6de49ea2c02e311e5f5366005bd3497a9bb25187.tar.gz
exchange-6de49ea2c02e311e5f5366005bd3497a9bb25187.tar.bz2
exchange-6de49ea2c02e311e5f5366005bd3497a9bb25187.zip
Merge branch 'protocolv8'
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/auditor_api_deposit_confirmation.c17
-rw-r--r--src/lib/exchange_api_common.c36
-rw-r--r--src/lib/exchange_api_deposit.c66
-rw-r--r--src/lib/exchange_api_deposits_get.c72
-rw-r--r--src/lib/exchange_api_handle.c2
-rw-r--r--src/lib/exchange_api_melt.c10
-rw-r--r--src/lib/exchange_api_refund.c29
-rw-r--r--src/lib/exchange_api_transfers_get.c170
-rw-r--r--src/lib/exchange_api_withdraw2.c2
9 files changed, 226 insertions, 178 deletions
diff --git a/src/lib/auditor_api_deposit_confirmation.c b/src/lib/auditor_api_deposit_confirmation.c
index cddfe8b14..1856a89f4 100644
--- a/src/lib/auditor_api_deposit_confirmation.c
+++ b/src/lib/auditor_api_deposit_confirmation.c
@@ -148,7 +148,7 @@ handle_deposit_confirmation_finished (void *cls,
*
* @param h_wire hash of merchant wire details
* @param h_contract_terms hash of the contact of the merchant with the customer (further details are never disclosed to the auditor)
- * @param timestamp timestamp when the contract was finalized, must not be too far in the future
+ * @param exchange_timestamp timestamp when the deposit was received by the wallet
* @param refund_deadline date until which the merchant can issue a refund to the customer via the auditor (can be zero if refunds are not allowed); must not be after the @a wire_deadline
* @param amount_without_fee the amount confirmed to be wired by the exchange to the merchant
* @param coin_pub coin’s public key
@@ -165,7 +165,7 @@ handle_deposit_confirmation_finished (void *cls,
static int
verify_signatures (const struct GNUNET_HashCode *h_wire,
const struct GNUNET_HashCode *h_contract_terms,
- struct GNUNET_TIME_Absolute timestamp,
+ struct GNUNET_TIME_Absolute exchange_timestamp,
struct GNUNET_TIME_Absolute refund_deadline,
const struct TALER_Amount *amount_without_fee,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
@@ -184,7 +184,7 @@ verify_signatures (const struct GNUNET_HashCode *h_wire,
.purpose.size = htonl (sizeof (dc)),
.h_contract_terms = *h_contract_terms,
.h_wire = *h_wire,
- .timestamp = GNUNET_TIME_absolute_hton (timestamp),
+ .exchange_timestamp = GNUNET_TIME_absolute_hton (exchange_timestamp),
.refund_deadline = GNUNET_TIME_absolute_hton (refund_deadline),
.coin_pub = *coin_pub,
.merchant = *merchant_pub
@@ -256,7 +256,7 @@ verify_signatures (const struct GNUNET_HashCode *h_wire,
* @param auditor the auditor handle; the auditor must be ready to operate
* @param h_wire hash of merchant wire details
* @param h_contract_terms hash of the contact of the merchant with the customer (further details are never disclosed to the auditor)
- * @param timestamp timestamp when the contract was finalized, must not be too far in the future
+ * @param exchange_timestamp timestamp when deposit was received by the exchange
* @param refund_deadline date until which the merchant can issue a refund to the customer via the auditor (can be zero if refunds are not allowed); must not be after the @a wire_deadline
* @param amount_without_fee the amount confirmed to be wired by the exchange to the merchant
* @param coin_pub coin’s public key
@@ -278,7 +278,7 @@ TALER_AUDITOR_deposit_confirmation (
struct TALER_AUDITOR_Handle *auditor,
const struct GNUNET_HashCode *h_wire,
const struct GNUNET_HashCode *h_contract_terms,
- struct GNUNET_TIME_Absolute timestamp,
+ struct GNUNET_TIME_Absolute exchange_timestamp,
struct GNUNET_TIME_Absolute refund_deadline,
const struct TALER_Amount *amount_without_fee,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
@@ -298,7 +298,7 @@ TALER_AUDITOR_deposit_confirmation (
json_t *deposit_confirmation_obj;
CURL *eh;
- (void) GNUNET_TIME_round_abs (&timestamp);
+ (void) GNUNET_TIME_round_abs (&exchange_timestamp);
(void) GNUNET_TIME_round_abs (&refund_deadline);
(void) GNUNET_TIME_round_abs (&ep_start);
(void) GNUNET_TIME_round_abs (&ep_expire);
@@ -308,7 +308,7 @@ TALER_AUDITOR_deposit_confirmation (
if (GNUNET_OK !=
verify_signatures (h_wire,
h_contract_terms,
- timestamp,
+ exchange_timestamp,
refund_deadline,
amount_without_fee,
coin_pub,
@@ -336,7 +336,8 @@ TALER_AUDITOR_deposit_confirmation (
"h_wire", GNUNET_JSON_from_data_auto (h_wire),
"h_contract_terms", GNUNET_JSON_from_data_auto (
h_contract_terms),
- "timestamp", GNUNET_JSON_from_time_abs (timestamp),
+ "exchange_timestamp", GNUNET_JSON_from_time_abs (
+ exchange_timestamp),
"refund_deadline", GNUNET_JSON_from_time_abs (refund_deadline),
"amount_without_fee", TALER_JSON_from_amount (
amount_without_fee),
diff --git a/src/lib/exchange_api_common.c b/src/lib/exchange_api_common.c
index 2cde8d136..e7e87487b 100644
--- a/src/lib/exchange_api_common.c
+++ b/src/lib/exchange_api_common.c
@@ -146,11 +146,12 @@ TALER_EXCHANGE_parse_reserve_history (
{
struct TALER_ReserveSignatureP sig;
struct TALER_WithdrawRequestPS withdraw_purpose;
+ struct TALER_Amount withdraw_fee;
struct GNUNET_JSON_Specification withdraw_spec[] = {
GNUNET_JSON_spec_fixed_auto ("reserve_sig",
&sig),
- TALER_JSON_spec_amount_nbo ("withdraw_fee",
- &withdraw_purpose.withdraw_fee),
+ TALER_JSON_spec_amount ("withdraw_fee",
+ &withdraw_fee),
GNUNET_JSON_spec_fixed_auto ("h_denom_pub",
&withdraw_purpose.h_denomination_pub),
GNUNET_JSON_spec_fixed_auto ("h_coin_envelope",
@@ -189,26 +190,23 @@ TALER_EXCHANGE_parse_reserve_history (
{
const struct TALER_EXCHANGE_Keys *key_state;
const struct TALER_EXCHANGE_DenomPublicKey *dki;
- struct TALER_Amount fee;
key_state = TALER_EXCHANGE_get_keys (exchange);
dki = TALER_EXCHANGE_get_denomination_key_by_hash (key_state,
&withdraw_purpose.
h_denomination_pub);
- TALER_amount_ntoh (&fee,
- &withdraw_purpose.withdraw_fee);
if ( (GNUNET_YES !=
- TALER_amount_cmp_currency (&fee,
+ TALER_amount_cmp_currency (&withdraw_fee,
&dki->fee_withdraw)) ||
(0 !=
- TALER_amount_cmp (&fee,
+ TALER_amount_cmp (&withdraw_fee,
&dki->fee_withdraw)) )
{
GNUNET_break_op (0);
GNUNET_JSON_parse_free (withdraw_spec);
return GNUNET_SYSERR;
}
- rh->details.withdraw.fee = fee;
+ rh->details.withdraw.fee = withdraw_fee;
}
rh->details.withdraw.out_authorization_sig
= json_object_get (transaction,
@@ -526,7 +524,7 @@ TALER_EXCHANGE_verify_coin_history (
GNUNET_JSON_spec_fixed_auto ("h_wire",
&dr.h_wire),
GNUNET_JSON_spec_absolute_time_nbo ("timestamp",
- &dr.timestamp),
+ &dr.wallet_timestamp),
GNUNET_JSON_spec_absolute_time_nbo ("refund_deadline",
&dr.refund_deadline),
TALER_JSON_spec_amount_nbo ("deposit_fee",
@@ -634,9 +632,16 @@ TALER_EXCHANGE_verify_coin_history (
else if (0 == strcasecmp (type,
"REFUND"))
{
- struct TALER_RefundRequestPS rr;
struct TALER_MerchantSignatureP sig;
+ struct TALER_Amount refund_fee;
+ struct TALER_RefundRequestPS rr = {
+ .purpose.size = htonl (sizeof (rr)),
+ .purpose.purpose = htonl (TALER_SIGNATURE_MERCHANT_REFUND),
+ .coin_pub = *coin_pub
+ };
struct GNUNET_JSON_Specification spec[] = {
+ TALER_JSON_spec_amount ("refund_fee",
+ &refund_fee),
GNUNET_JSON_spec_fixed_auto ("merchant_sig",
&sig),
GNUNET_JSON_spec_fixed_auto ("h_contract_terms",
@@ -645,8 +650,6 @@ TALER_EXCHANGE_verify_coin_history (
&rr.merchant),
GNUNET_JSON_spec_uint64 ("rtransaction_id",
&rr.rtransaction_id),
- TALER_JSON_spec_amount_nbo ("refund_fee",
- &rr.refund_fee),
GNUNET_JSON_spec_end ()
};
@@ -658,9 +661,6 @@ TALER_EXCHANGE_verify_coin_history (
GNUNET_break_op (0);
return GNUNET_SYSERR;
}
- rr.purpose.size = htonl (sizeof (rr));
- rr.purpose.purpose = htonl (TALER_SIGNATURE_MERCHANT_REFUND);
- rr.coin_pub = *coin_pub;
TALER_amount_hton (&rr.refund_amount,
&amount);
if (GNUNET_OK !=
@@ -683,13 +683,11 @@ TALER_EXCHANGE_verify_coin_history (
/* check that refund fee matches our expectations from /keys! */
if (NULL != dk)
{
- TALER_amount_ntoh (&fee,
- &rr.refund_fee);
if ( (GNUNET_YES !=
- TALER_amount_cmp_currency (&fee,
+ TALER_amount_cmp_currency (&refund_fee,
&dk->fee_refund)) ||
(0 !=
- TALER_amount_cmp (&fee,
+ TALER_amount_cmp (&refund_fee,
&dk->fee_refund)) )
{
GNUNET_break_op (0);
diff --git a/src/lib/exchange_api_deposit.c b/src/lib/exchange_api_deposit.c
index 5f3749931..351fa7a10 100644
--- a/src/lib/exchange_api_deposit.c
+++ b/src/lib/exchange_api_deposit.c
@@ -160,7 +160,7 @@ auditor_cb (void *cls,
ah,
&dh->depconf.h_wire,
&dh->depconf.h_contract_terms,
- GNUNET_TIME_absolute_ntoh (dh->depconf.timestamp),
+ GNUNET_TIME_absolute_ntoh (dh->depconf.exchange_timestamp),
GNUNET_TIME_absolute_ntoh (dh->depconf.refund_deadline),
&amount_without_fee,
&dh->depconf.coin_pub,
@@ -196,8 +196,10 @@ verify_deposit_signature_ok (struct TALER_EXCHANGE_DepositHandle *dh,
{
const struct TALER_EXCHANGE_Keys *key_state;
struct GNUNET_JSON_Specification spec[] = {
- GNUNET_JSON_spec_fixed_auto ("sig", exchange_sig),
- GNUNET_JSON_spec_fixed_auto ("pub", exchange_pub),
+ GNUNET_JSON_spec_fixed_auto ("exchange_sig", exchange_sig),
+ GNUNET_JSON_spec_fixed_auto ("exchange_pub", exchange_pub),
+ GNUNET_JSON_spec_absolute_time_nbo ("exchange_timestamp",
+ &dh->depconf.exchange_timestamp),
GNUNET_JSON_spec_end ()
};
@@ -386,6 +388,7 @@ handle_deposit_finished (void *cls,
}
dh->cb (dh->cb_cls,
&hr,
+ GNUNET_TIME_absolute_ntoh (dh->depconf.exchange_timestamp),
es,
ep);
TALER_EXCHANGE_deposit_cancel (dh);
@@ -429,7 +432,7 @@ verify_signatures (const struct TALER_EXCHANGE_DenomPublicKey *dki,
.purpose.size = htonl (sizeof (dr)),
.h_contract_terms = *h_contract_terms,
.h_wire = *h_wire,
- .timestamp = GNUNET_TIME_absolute_hton (timestamp),
+ .wallet_timestamp = GNUNET_TIME_absolute_hton (timestamp),
.refund_deadline = GNUNET_TIME_absolute_hton (refund_deadline),
.merchant = *merchant_pub,
.coin_pub = *coin_pub
@@ -488,6 +491,59 @@ verify_signatures (const struct TALER_EXCHANGE_DenomPublicKey *dki,
/**
+ * Sign a deposit permission. Function for wallets.
+ *
+ * @param amount the amount to be deposited
+ * @param deposit_fee the deposit fee we expect to pay
+ * @param h_wire hash of the merchant’s account details
+ * @param h_contract_terms hash of the contact of the merchant with the customer (further details are never disclosed to the exchange)
+ * @param coin_priv coin’s private key
+ * @param wallet_timestamp timestamp when the contract was finalized, must not be too far in the future
+ * @param merchant_pub the public key of the merchant (used to identify the merchant for refund requests)
+ * @param refund_deadline date until which the merchant can issue a refund to the customer via the exchange (can be zero if refunds are not allowed); must not be after the @a wire_deadline
+ * @param[out] coin_sig set to the signature made with purpose #TALER_SIGNATURE_WALLET_COIN_DEPOSIT
+ */
+void
+TALER_EXCHANGE_deposit_permission_sign (
+ const struct TALER_Amount *amount,
+ const struct TALER_Amount *deposit_fee,
+ const struct GNUNET_HashCode *h_wire,
+ const struct GNUNET_HashCode *h_contract_terms,
+ const struct TALER_CoinSpendPrivateKeyP *coin_priv,
+ struct GNUNET_TIME_Absolute wallet_timestamp,
+ const struct TALER_MerchantPublicKeyP *merchant_pub,
+ struct GNUNET_TIME_Absolute refund_deadline,
+ struct TALER_CoinSpendSignatureP *coin_sig)
+{
+ struct TALER_DepositRequestPS dr = {
+ .purpose.size = htonl
+ (sizeof (dr)),
+ .purpose.purpose = htonl
+ (TALER_SIGNATURE_WALLET_COIN_DEPOSIT),
+ .h_contract_terms = *h_contract_terms,
+ .h_wire = *h_wire,
+ .wallet_timestamp = GNUNET_TIME_absolute_hton (wallet_timestamp),
+ .refund_deadline = GNUNET_TIME_absolute_hton (refund_deadline),
+ .merchant = *merchant_pub
+ };
+
+ GNUNET_assert (GNUNET_OK ==
+ GNUNET_TIME_round_abs (&wallet_timestamp));
+ GNUNET_assert (GNUNET_OK ==
+ GNUNET_TIME_round_abs (&refund_deadline));
+ GNUNET_CRYPTO_eddsa_key_get_public (&coin_priv->eddsa_priv,
+ &dr.coin_pub.eddsa_pub);
+ TALER_amount_hton (&dr.amount_with_fee,
+ amount);
+ TALER_amount_hton (&dr.deposit_fee,
+ deposit_fee);
+ GNUNET_CRYPTO_eddsa_sign (&coin_priv->eddsa_priv,
+ &dr,
+ &coin_sig->eddsa_signature);
+}
+
+
+/**
* Submit a deposit permission to the exchange and get the exchange's response.
* Note that while we return the response verbatim to the caller for
* further processing, we do already verify that the response is
@@ -658,7 +714,7 @@ TALER_EXCHANGE_deposit (struct TALER_EXCHANGE_Handle *exchange,
TALER_SIGNATURE_EXCHANGE_CONFIRM_DEPOSIT);
dh->depconf.h_contract_terms = *h_contract_terms;
dh->depconf.h_wire = h_wire;
- dh->depconf.timestamp = GNUNET_TIME_absolute_hton (timestamp);
+ /* dh->depconf.exchange_timestamp; -- initialized later from exchange reply! */
dh->depconf.refund_deadline = GNUNET_TIME_absolute_hton (refund_deadline);
TALER_amount_hton (&dh->depconf.amount_without_fee,
&amount_without_fee);
diff --git a/src/lib/exchange_api_deposits_get.c b/src/lib/exchange_api_deposits_get.c
index aecd88240..004a24d42 100644
--- a/src/lib/exchange_api_deposits_get.c
+++ b/src/lib/exchange_api_deposits_get.c
@@ -33,7 +33,7 @@
/**
- * @brief A Deposit Wtid Handle
+ * @brief A Deposit Get Handle
*/
struct TALER_EXCHANGE_DepositGetHandle
{
@@ -84,31 +84,19 @@ struct TALER_EXCHANGE_DepositGetHandle
*
* @param dwh deposit wtid handle
* @param json json reply with the signature
- * @param[out] exchange_pub set to the exchange's public key
+ * @param exchange_pub the exchange's public key
+ * @param exchange_sig the exchange's signature
* @return #GNUNET_OK if the signature is valid, #GNUNET_SYSERR if not
*/
static int
verify_deposit_wtid_signature_ok (
const struct TALER_EXCHANGE_DepositGetHandle *dwh,
const json_t *json,
- struct TALER_ExchangePublicKeyP *exchange_pub)
+ const struct TALER_ExchangePublicKeyP *exchange_pub,
+ const struct TALER_ExchangeSignatureP *exchange_sig)
{
- struct TALER_ExchangeSignatureP exchange_sig;
const struct TALER_EXCHANGE_Keys *key_state;
- struct GNUNET_JSON_Specification spec[] = {
- GNUNET_JSON_spec_fixed_auto ("exchange_sig", &exchange_sig),
- GNUNET_JSON_spec_fixed_auto ("exchange_pub", exchange_pub),
- GNUNET_JSON_spec_end ()
- };
- if (GNUNET_OK !=
- GNUNET_JSON_parse (json,
- spec,
- NULL, NULL))
- {
- GNUNET_break_op (0);
- return GNUNET_SYSERR;
- }
key_state = TALER_EXCHANGE_get_keys (dwh->exchange);
if (GNUNET_OK !=
TALER_EXCHANGE_test_signing_key (key_state,
@@ -120,7 +108,7 @@ verify_deposit_wtid_signature_ok (
if (GNUNET_OK !=
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE,
&dwh->depconf,
- &exchange_sig.eddsa_signature,
+ &exchange_sig->eddsa_signature,
&exchange_pub->eddsa_pub))
{
GNUNET_break_op (0);
@@ -144,12 +132,6 @@ handle_deposit_wtid_finished (void *cls,
const void *response)
{
struct TALER_EXCHANGE_DepositGetHandle *dwh = cls;
- const struct TALER_WireTransferIdentifierRawP *wtid = NULL;
- struct GNUNET_TIME_Absolute execution_time = GNUNET_TIME_UNIT_FOREVER_ABS;
- const struct TALER_Amount *coin_contribution = NULL;
- struct TALER_Amount coin_contribution_s;
- struct TALER_ExchangePublicKeyP exchange_pub;
- struct TALER_ExchangePublicKeyP *ep = NULL;
const json_t *j = response;
struct TALER_EXCHANGE_HttpResponse hr = {
.reply = j,
@@ -164,10 +146,13 @@ handle_deposit_wtid_finished (void *cls,
break;
case MHD_HTTP_OK:
{
+ struct TALER_EXCHANGE_DepositData dd;
struct GNUNET_JSON_Specification spec[] = {
GNUNET_JSON_spec_fixed_auto ("wtid", &dwh->depconf.wtid),
- GNUNET_JSON_spec_absolute_time ("execution_time", &execution_time),
- TALER_JSON_spec_amount ("coin_contribution", &coin_contribution_s),
+ GNUNET_JSON_spec_absolute_time ("execution_time", &dd.execution_time),
+ TALER_JSON_spec_amount ("coin_contribution", &dd.coin_contribution),
+ GNUNET_JSON_spec_fixed_auto ("exchange_sig", &dd.exchange_sig),
+ GNUNET_JSON_spec_fixed_auto ("exchange_pub", &dd.exchange_pub),
GNUNET_JSON_spec_end ()
};
@@ -181,15 +166,15 @@ handle_deposit_wtid_finished (void *cls,
hr.ec = TALER_EC_DEPOSITS_INVALID_BODY_BY_EXCHANGE;
break;
}
- wtid = &dwh->depconf.wtid;
- dwh->depconf.execution_time = GNUNET_TIME_absolute_hton (execution_time);
+ dwh->depconf.execution_time = GNUNET_TIME_absolute_hton (
+ dd.execution_time);
TALER_amount_hton (&dwh->depconf.coin_contribution,
- &coin_contribution_s);
- coin_contribution = &coin_contribution_s;
+ &dd.coin_contribution);
if (GNUNET_OK !=
verify_deposit_wtid_signature_ok (dwh,
j,
- &exchange_pub))
+ &dd.exchange_pub,
+ &dd.exchange_sig))
{
GNUNET_break_op (0);
hr.http_status = 0;
@@ -197,13 +182,19 @@ handle_deposit_wtid_finished (void *cls,
}
else
{
- ep = &exchange_pub;
+ dd.wtid = dwh->depconf.wtid;
+ dwh->cb (dwh->cb_cls,
+ &hr,
+ &dd);
+ TALER_EXCHANGE_deposits_get_cancel (dwh);
+ return;
}
}
break;
case MHD_HTTP_ACCEPTED:
{
/* Transaction known, but not executed yet */
+ struct GNUNET_TIME_Absolute execution_time;
struct GNUNET_JSON_Specification spec[] = {
GNUNET_JSON_spec_absolute_time ("execution_time", &execution_time),
GNUNET_JSON_spec_end ()
@@ -219,6 +210,18 @@ handle_deposit_wtid_finished (void *cls,
hr.ec = TALER_EC_DEPOSITS_INVALID_BODY_BY_EXCHANGE;
break;
}
+ else
+ {
+ struct TALER_EXCHANGE_DepositData dd = {
+ .execution_time = execution_time
+ };
+
+ dwh->cb (dwh->cb_cls,
+ &hr,
+ &dd);
+ TALER_EXCHANGE_deposits_get_cancel (dwh);
+ return;
+ }
}
break;
case MHD_HTTP_BAD_REQUEST:
@@ -259,10 +262,7 @@ handle_deposit_wtid_finished (void *cls,
}
dwh->cb (dwh->cb_cls,
&hr,
- ep,
- wtid,
- execution_time,
- coin_contribution);
+ NULL);
TALER_EXCHANGE_deposits_get_cancel (dwh);
}
diff --git a/src/lib/exchange_api_handle.c b/src/lib/exchange_api_handle.c
index 6fa8979d0..283f77043 100644
--- a/src/lib/exchange_api_handle.c
+++ b/src/lib/exchange_api_handle.c
@@ -39,7 +39,7 @@
* Which version of the Taler protocol is implemented
* by this library? Used to determine compatibility.
*/
-#define EXCHANGE_PROTOCOL_CURRENT 7
+#define EXCHANGE_PROTOCOL_CURRENT 8
/**
* How many versions are we backwards compatible with?
diff --git a/src/lib/exchange_api_melt.c b/src/lib/exchange_api_melt.c
index f89036e40..0695f997b 100644
--- a/src/lib/exchange_api_melt.c
+++ b/src/lib/exchange_api_melt.c
@@ -445,11 +445,11 @@ TALER_EXCHANGE_melt (struct TALER_EXCHANGE_Handle *exchange,
char pub_str[sizeof (struct TALER_CoinSpendPublicKeyP) * 2];
char *end;
- end = GNUNET_STRINGS_data_to_string (&melt.coin_pub,
- sizeof (struct
- TALER_CoinSpendPublicKeyP),
- pub_str,
- sizeof (pub_str));
+ end = GNUNET_STRINGS_data_to_string (
+ &melt.coin_pub,
+ sizeof (struct TALER_CoinSpendPublicKeyP),
+ pub_str,
+ sizeof (pub_str));
*end = '\0';
GNUNET_snprintf (arg_str,
sizeof (arg_str),
diff --git a/src/lib/exchange_api_refund.c b/src/lib/exchange_api_refund.c
index c64dcc97a..1af1f14b9 100644
--- a/src/lib/exchange_api_refund.c
+++ b/src/lib/exchange_api_refund.c
@@ -81,23 +81,23 @@ struct TALER_EXCHANGE_RefundHandle
* Verify that the signature on the "200 OK" response
* from the exchange is valid.
*
- * @param rh refund handle
+ * @param[in,out] rh refund handle (refund fee added)
* @param json json reply with the signature
* @param[out] exchange_pub set to the exchange's public key
* @param[out] exchange_sig set to the exchange's signature
* @return #GNUNET_OK if the signature is valid, #GNUNET_SYSERR if not
*/
static int
-verify_refund_signature_ok (const struct TALER_EXCHANGE_RefundHandle *rh,
+verify_refund_signature_ok (struct TALER_EXCHANGE_RefundHandle *rh,
const json_t *json,
struct TALER_ExchangePublicKeyP *exchange_pub,
struct TALER_ExchangeSignatureP *exchange_sig)
-
{
const struct TALER_EXCHANGE_Keys *key_state;
struct GNUNET_JSON_Specification spec[] = {
- GNUNET_JSON_spec_fixed_auto ("sig", exchange_sig),
- GNUNET_JSON_spec_fixed_auto ("pub", exchange_pub),
+ GNUNET_JSON_spec_fixed_auto ("exchange_sig", exchange_sig),
+ GNUNET_JSON_spec_fixed_auto ("exchange_pub", exchange_pub),
+ TALER_JSON_spec_amount_nbo ("refund_fee", &rh->depconf.refund_fee),
GNUNET_JSON_spec_end ()
};
@@ -148,12 +148,15 @@ handle_refund_finished (void *cls,
struct TALER_ExchangeSignatureP exchange_sig;
struct TALER_ExchangePublicKeyP *ep = NULL;
struct TALER_ExchangeSignatureP *es = NULL;
+ struct TALER_Amount ra;
+ const struct TALER_Amount *rf = NULL;
const json_t *j = response;
struct TALER_EXCHANGE_HttpResponse hr = {
.reply = j,
.http_status = (unsigned int) response_code
};
+
rh->job = NULL;
switch (response_code)
{
@@ -175,6 +178,9 @@ handle_refund_finished (void *cls,
{
ep = &exchange_pub;
es = &exchange_sig;
+ TALER_amount_ntoh (&ra,
+ &rh->depconf.refund_fee);
+ rf = &ra;
}
break;
case MHD_HTTP_BAD_REQUEST:
@@ -233,6 +239,7 @@ handle_refund_finished (void *cls,
}
rh->cb (rh->cb_cls,
&hr,
+ rf,
ep,
es);
TALER_EXCHANGE_refund_cancel (rh);
@@ -256,7 +263,6 @@ handle_refund_finished (void *cls,
* @param amount the amount to be refunded; must be larger than the refund fee
* (as that fee is still being subtracted), and smaller than the amount
* (with deposit fee) of the original deposit contribution of this coin
- * @param refund_fee fee applicable to this coin for the refund
* @param h_contract_terms hash of the contact of the merchant with the customer that is being refunded
* @param coin_pub coin’s public key of the coin from the original deposit operation
* @param rtransaction_id transaction id for the transaction between merchant and customer (of refunding operation);
@@ -272,7 +278,6 @@ handle_refund_finished (void *cls,
struct TALER_EXCHANGE_RefundHandle *
TALER_EXCHANGE_refund (struct TALER_EXCHANGE_Handle *exchange,
const struct TALER_Amount *amount,
- const struct TALER_Amount *refund_fee,
const struct GNUNET_HashCode *h_contract_terms,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
uint64_t rtransaction_id,
@@ -294,14 +299,11 @@ TALER_EXCHANGE_refund (struct TALER_EXCHANGE_Handle *exchange,
rr.rtransaction_id = GNUNET_htonll (rtransaction_id);
TALER_amount_hton (&rr.refund_amount,
amount);
- TALER_amount_hton (&rr.refund_fee,
- refund_fee);
GNUNET_CRYPTO_eddsa_sign (&merchant_priv->eddsa_priv,
&rr,
&merchant_sig.eddsa_sig);
return TALER_EXCHANGE_refund2 (exchange,
amount,
- refund_fee,
h_contract_terms,
coin_pub,
rtransaction_id,
@@ -329,7 +331,6 @@ TALER_EXCHANGE_refund (struct TALER_EXCHANGE_Handle *exchange,
* @param amount the amount to be refunded; must be larger than the refund fee
* (as that fee is still being subtracted), and smaller than the amount
* (with deposit fee) of the original deposit contribution of this coin
- * @param refund_fee fee applicable to this coin for the refund
* @param h_contract_terms hash of the contact of the merchant with the customer that is being refunded
* @param coin_pub coin’s public key of the coin from the original deposit operation
* @param rtransaction_id transaction id for the transaction between merchant and customer (of refunding operation);
@@ -346,7 +347,6 @@ TALER_EXCHANGE_refund (struct TALER_EXCHANGE_Handle *exchange,
struct TALER_EXCHANGE_RefundHandle *
TALER_EXCHANGE_refund2 (struct TALER_EXCHANGE_Handle *exchange,
const struct TALER_Amount *amount,
- const struct TALER_Amount *refund_fee,
const struct GNUNET_HashCode *h_contract_terms,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
uint64_t rtransaction_id,
@@ -376,12 +376,11 @@ TALER_EXCHANGE_refund2 (struct TALER_EXCHANGE_Handle *exchange,
"/coins/%s/refund",
pub_str);
}
- refund_obj = json_pack ("{s:o, s:o," /* amount/fee */
+ refund_obj = json_pack ("{s:o," /* amount */
" s:o," /* h_contract_terms */
" s:I," /* rtransaction id */
" s:o, s:o}", /* merchant_pub, merchant_sig */
"refund_amount", TALER_JSON_from_amount (amount),
- "refund_fee", TALER_JSON_from_amount (refund_fee),
"h_contract_terms", GNUNET_JSON_from_data_auto (
h_contract_terms),
"rtransaction_id", (json_int_t) rtransaction_id,
@@ -410,8 +409,6 @@ TALER_EXCHANGE_refund2 (struct TALER_EXCHANGE_Handle *exchange,
rh->depconf.rtransaction_id = GNUNET_htonll (rtransaction_id);
TALER_amount_hton (&rh->depconf.refund_amount,
amount);
- TALER_amount_hton (&rh->depconf.refund_fee,
- refund_fee);
eh = TALER_EXCHANGE_curl_easy_get_ (rh->url);
if ( (NULL == eh) ||
diff --git a/src/lib/exchange_api_transfers_get.c b/src/lib/exchange_api_transfers_get.c
index 552536958..6b5bba8e8 100644
--- a/src/lib/exchange_api_transfers_get.c
+++ b/src/lib/exchange_api_transfers_get.c
@@ -85,24 +85,18 @@ check_transfers_get_response_ok (
const json_t *json)
{
json_t *details_j;
- struct GNUNET_HashCode h_wire;
- struct GNUNET_TIME_Absolute exec_time;
- struct TALER_Amount total_amount;
+ struct TALER_EXCHANGE_TransferData td;
struct TALER_Amount total_expected;
- struct TALER_Amount wire_fee;
struct TALER_MerchantPublicKeyP merchant_pub;
- unsigned int num_details;
- struct TALER_ExchangePublicKeyP exchange_pub;
- struct TALER_ExchangeSignatureP exchange_sig;
struct GNUNET_JSON_Specification spec[] = {
- TALER_JSON_spec_amount ("total", &total_amount),
- TALER_JSON_spec_amount ("wire_fee", &wire_fee),
+ TALER_JSON_spec_amount ("total", &td.total_amount),
+ TALER_JSON_spec_amount ("wire_fee", &td.wire_fee),
GNUNET_JSON_spec_fixed_auto ("merchant_pub", &merchant_pub),
- GNUNET_JSON_spec_fixed_auto ("h_wire", &h_wire),
- GNUNET_JSON_spec_absolute_time ("execution_time", &exec_time),
+ GNUNET_JSON_spec_fixed_auto ("h_wire", &td.h_wire),
+ GNUNET_JSON_spec_absolute_time ("execution_time", &td.execution_time),
GNUNET_JSON_spec_json ("deposits", &details_j),
- GNUNET_JSON_spec_fixed_auto ("exchange_sig", &exchange_sig),
- GNUNET_JSON_spec_fixed_auto ("exchange_pub", &exchange_pub),
+ GNUNET_JSON_spec_fixed_auto ("exchange_sig", &td.exchange_sig),
+ GNUNET_JSON_spec_fixed_auto ("exchange_pub", &td.exchange_pub),
GNUNET_JSON_spec_end ()
};
struct TALER_EXCHANGE_HttpResponse hr = {
@@ -119,22 +113,32 @@ check_transfers_get_response_ok (
return GNUNET_SYSERR;
}
if (GNUNET_OK !=
- TALER_amount_get_zero (total_amount.currency,
+ TALER_amount_get_zero (td.total_amount.currency,
&total_expected))
{
GNUNET_break_op (0);
+ GNUNET_JSON_parse_free (spec);
return GNUNET_SYSERR;
}
- num_details = json_array_size (details_j);
+ if (GNUNET_OK !=
+ TALER_EXCHANGE_test_signing_key (
+ TALER_EXCHANGE_get_keys (wdh->exchange),
+ &td.exchange_pub))
+ {
+ GNUNET_break_op (0);
+ GNUNET_JSON_parse_free (spec);
+ return GNUNET_SYSERR;
+ }
+ td.details_length = json_array_size (details_j);
{
- struct TALER_TrackTransferDetails details[num_details];
- unsigned int i;
struct GNUNET_HashContext *hash_context;
- struct TALER_WireDepositDetailP dd;
- struct TALER_WireDepositDataPS wdp;
+ struct TALER_TrackTransferDetails *details;
+ details = GNUNET_new_array (td.details_length,
+ struct TALER_TrackTransferDetails);
+ td.details = details;
hash_context = GNUNET_CRYPTO_hash_context_start ();
- for (i = 0; i<num_details; i++)
+ for (unsigned int i = 0; i<td.details_length; i++)
{
struct TALER_TrackTransferDetails *detail = &details[i];
struct json_t *detail_j = json_array_get (details_j, i);
@@ -147,25 +151,17 @@ check_transfers_get_response_ok (
GNUNET_JSON_spec_end ()
};
- if (GNUNET_OK !=
- GNUNET_JSON_parse (detail_j,
- spec_detail,
- NULL, NULL))
- {
- GNUNET_break_op (0);
- GNUNET_CRYPTO_hash_context_abort (hash_context);
- GNUNET_JSON_parse_free (spec);
- return GNUNET_SYSERR;
- }
- /* build up big hash for signature checking later */
- dd.h_contract_terms = detail->h_contract_terms;
- dd.execution_time = GNUNET_TIME_absolute_hton (exec_time);
- dd.coin_pub = detail->coin_pub;
- TALER_amount_hton (&dd.deposit_value,
- &detail->coin_value);
- TALER_amount_hton (&dd.deposit_fee,
- &detail->coin_fee);
- if ( (0 >
+ if ( (GNUNET_OK !=
+ GNUNET_JSON_parse (detail_j,
+ spec_detail,
+ NULL, NULL)) ||
+ (GNUNET_OK !=
+ TALER_amount_cmp_currency (&total_expected,
+ &detail->coin_value)) ||
+ (GNUNET_OK !=
+ TALER_amount_cmp_currency (&total_expected,
+ &detail->coin_fee)) ||
+ (0 >
TALER_amount_add (&total_expected,
&total_expected,
&detail->coin_value)) ||
@@ -177,71 +173,78 @@ check_transfers_get_response_ok (
GNUNET_break_op (0);
GNUNET_CRYPTO_hash_context_abort (hash_context);
GNUNET_JSON_parse_free (spec);
+ GNUNET_free (details);
return GNUNET_SYSERR;
}
- GNUNET_CRYPTO_hash_context_read (
- hash_context,
- &dd,
- sizeof (struct TALER_WireDepositDetailP));
+ /* build up big hash for signature checking later */
+ {
+ struct TALER_WireDepositDetailP dd;
+
+ dd.h_contract_terms = detail->h_contract_terms;
+ dd.execution_time = GNUNET_TIME_absolute_hton (td.execution_time);
+ dd.coin_pub = detail->coin_pub;
+ TALER_amount_hton (&dd.deposit_value,
+ &detail->coin_value);
+ TALER_amount_hton (&dd.deposit_fee,
+ &detail->coin_fee);
+ GNUNET_CRYPTO_hash_context_read (hash_context,
+ &dd,
+ sizeof (dd));
+ }
}
/* Check signature */
- wdp.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE_DEPOSIT);
- wdp.purpose.size = htonl (sizeof (struct TALER_WireDepositDataPS));
- TALER_amount_hton (&wdp.total,
- &total_amount);
- TALER_amount_hton (&wdp.wire_fee,
- &wire_fee);
- wdp.merchant_pub = merchant_pub;
- wdp.h_wire = h_wire;
- GNUNET_CRYPTO_hash_context_finish (hash_context,
- &wdp.h_details);
- if (GNUNET_OK !=
- TALER_EXCHANGE_test_signing_key (TALER_EXCHANGE_get_keys (
- wdh->exchange),
- &exchange_pub))
{
- GNUNET_break_op (0);
- GNUNET_JSON_parse_free (spec);
- return GNUNET_SYSERR;
- }
- if (GNUNET_OK !=
- GNUNET_CRYPTO_eddsa_verify (
- TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE_DEPOSIT,
- &wdp,
- &exchange_sig.eddsa_signature,
- &exchange_pub.eddsa_pub))
- {
- GNUNET_break_op (0);
- GNUNET_JSON_parse_free (spec);
- return GNUNET_SYSERR;
+ struct TALER_WireDepositDataPS wdp = {
+ .purpose.purpose = htonl (
+ TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE_DEPOSIT),
+ .purpose.size = htonl (sizeof (wdp)),
+ .merchant_pub = merchant_pub,
+ .h_wire = td.h_wire
+ };
+
+ TALER_amount_hton (&wdp.total,
+ &td.total_amount);
+ TALER_amount_hton (&wdp.wire_fee,
+ &td.wire_fee);
+ GNUNET_CRYPTO_hash_context_finish (hash_context,
+ &wdp.h_details);
+ if (GNUNET_OK !=
+ GNUNET_CRYPTO_eddsa_verify (
+ TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE_DEPOSIT,
+ &wdp,
+ &td.exchange_sig.eddsa_signature,
+ &td.exchange_pub.eddsa_pub))
+ {
+ GNUNET_break_op (0);
+ GNUNET_JSON_parse_free (spec);
+ GNUNET_free (details);
+ return GNUNET_SYSERR;
+ }
}
if (0 >
TALER_amount_subtract (&total_expected,
&total_expected,
- &wire_fee))
+ &td.wire_fee))
{
GNUNET_break_op (0);
GNUNET_JSON_parse_free (spec);
+ GNUNET_free (details);
return GNUNET_SYSERR;
}
if (0 !=
TALER_amount_cmp (&total_expected,
- &total_amount))
+ &td.total_amount))
{
GNUNET_break_op (0);
GNUNET_JSON_parse_free (spec);
+ GNUNET_free (details);
return GNUNET_SYSERR;
}
wdh->cb (wdh->cb_cls,
&hr,
- &exchange_pub,
- &h_wire,
- exec_time,
- &total_amount,
- &wire_fee,
- num_details,
- details);
+ &td);
+ GNUNET_free (details);
}
GNUNET_JSON_parse_free (spec);
TALER_EXCHANGE_transfers_get_cancel (wdh);
@@ -322,12 +325,7 @@ handle_transfers_get_finished (void *cls,
}
wdh->cb (wdh->cb_cls,
&hr,
- NULL,
- NULL,
- GNUNET_TIME_UNIT_ZERO_ABS,
- NULL,
- NULL,
- 0, NULL);
+ NULL);
TALER_EXCHANGE_transfers_get_cancel (wdh);
}
diff --git a/src/lib/exchange_api_withdraw2.c b/src/lib/exchange_api_withdraw2.c
index f9468927a..25f669143 100644
--- a/src/lib/exchange_api_withdraw2.c
+++ b/src/lib/exchange_api_withdraw2.c
@@ -429,8 +429,6 @@ TALER_EXCHANGE_withdraw2 (
TALER_amount_hton (&req.amount_with_fee,
&wh->requested_amount);
- TALER_amount_hton (&req.withdraw_fee,
- &dk->fee_withdraw);
GNUNET_CRYPTO_hash (pd->coin_ev,
pd->coin_ev_size,
&req.h_coin_envelope);