diff options
author | Christian Grothoff <christian@grothoff.org> | 2017-04-18 21:05:27 +0200 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2017-04-18 21:05:27 +0200 |
commit | 5e8ef386803c399c1b6d780181b0b8662c418db0 (patch) | |
tree | e1e0e7433be54c9f1904e73d3257b00b82320847 /src/exchange-lib | |
parent | 164c125528e4af078815c0156df54fa0120eed8a (diff) |
fixing #4980
Diffstat (limited to 'src/exchange-lib')
-rw-r--r-- | src/exchange-lib/exchange_api_common.c | 147 | ||||
-rw-r--r-- | src/exchange-lib/exchange_api_reserve.c | 68 |
2 files changed, 88 insertions, 127 deletions
diff --git a/src/exchange-lib/exchange_api_common.c b/src/exchange-lib/exchange_api_common.c index 29d0f6d1c..d9d0a6d56 100644 --- a/src/exchange-lib/exchange_api_common.c +++ b/src/exchange-lib/exchange_api_common.c @@ -89,13 +89,22 @@ TALER_EXCHANGE_verify_coin_history (const char *currency, "DEPOSIT")) { struct TALER_DepositRequestPS dr; - struct TALER_Amount dr_amount; struct TALER_CoinSpendSignatureP sig; struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_fixed_auto ("signature", + GNUNET_JSON_spec_fixed_auto ("coin_sig", &sig), - GNUNET_JSON_spec_fixed_auto ("details", - &dr), + GNUNET_JSON_spec_fixed_auto ("h_proposal_data", + &dr.h_proposal_data), + GNUNET_JSON_spec_fixed_auto ("h_wire", + &dr.h_wire), + GNUNET_JSON_spec_absolute_time_nbo ("timestamp", + &dr.timestamp), + GNUNET_JSON_spec_absolute_time_nbo ("refund_deadline", + &dr.refund_deadline), + TALER_JSON_spec_amount_nbo ("deposit_fee", + &dr.deposit_fee), + GNUNET_JSON_spec_fixed_auto ("merchant_pub", + &dr.merchant), GNUNET_JSON_spec_end() }; @@ -107,12 +116,11 @@ TALER_EXCHANGE_verify_coin_history (const char *currency, GNUNET_break_op (0); return GNUNET_SYSERR; } - /* TODO #4980 */ - if (sizeof (dr) != ntohl (dr.purpose.size)) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } + dr.purpose.size = htonl (sizeof (dr)); + dr.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_DEPOSIT); + TALER_amount_hton (&dr.amount_with_fee, + &amount); + dr.coin_pub = *coin_pub; if (GNUNET_OK != GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_DEPOSIT, &dr.purpose, @@ -122,28 +130,22 @@ TALER_EXCHANGE_verify_coin_history (const char *currency, GNUNET_break_op (0); return GNUNET_SYSERR; } - TALER_amount_ntoh (&dr_amount, - &dr.amount_with_fee); - /* TODO #4980 */ - if (0 != TALER_amount_cmp (&dr_amount, - &amount)) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } + /* TODO: check that deposit fee and coin value match + our expectations from /keys! */ add = GNUNET_YES; } else if (0 == strcasecmp (type, "MELT")) { struct TALER_RefreshMeltCoinAffirmationPS rm; - struct TALER_Amount rm_amount; struct TALER_CoinSpendSignatureP sig; struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_fixed_auto ("signature", + GNUNET_JSON_spec_fixed_auto ("coin_sig", &sig), - GNUNET_JSON_spec_fixed_auto ("details", - &rm), + GNUNET_JSON_spec_fixed_auto ("session_hash", + &rm.session_hash), + TALER_JSON_spec_amount_nbo ("melt_fee", + &rm.melt_fee), GNUNET_JSON_spec_end() }; @@ -155,12 +157,11 @@ TALER_EXCHANGE_verify_coin_history (const char *currency, GNUNET_break_op (0); return GNUNET_SYSERR; } - /* TODO #4980 */ - if (sizeof (rm) != ntohl (rm.purpose.size)) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } + rm.purpose.size = htonl (sizeof (rm)); + rm.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_MELT); + TALER_amount_hton (&rm.amount_with_fee, + &amount); + rm.coin_pub = *coin_pub; if (GNUNET_OK != GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_MELT, &rm.purpose, @@ -170,30 +171,26 @@ TALER_EXCHANGE_verify_coin_history (const char *currency, GNUNET_break_op (0); return GNUNET_SYSERR; } - TALER_amount_ntoh (&rm_amount, - &rm.amount_with_fee); - /* TODO #4980 */ - if (0 != TALER_amount_cmp (&rm_amount, - &amount)) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } + /* TODO: check that deposit fee and coin value match + our expectations from /keys! */ add = GNUNET_YES; } else if (0 == strcasecmp (type, "REFUND")) { struct TALER_RefundRequestPS rr; - struct TALER_Amount rr_amount; - struct TALER_Amount rr_fee; - struct TALER_Amount rr_delta; - struct TALER_CoinSpendSignatureP sig; + struct TALER_MerchantSignatureP sig; struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_fixed_auto ("signature", + GNUNET_JSON_spec_fixed_auto ("merchant_sig", &sig), - GNUNET_JSON_spec_fixed_auto ("details", - &rr), + GNUNET_JSON_spec_fixed_auto ("h_proposal_data", + &rr.h_proposal_data), + GNUNET_JSON_spec_fixed_auto ("merchant_pub", + &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() }; @@ -205,38 +202,20 @@ TALER_EXCHANGE_verify_coin_history (const char *currency, GNUNET_break_op (0); return GNUNET_SYSERR; } - /* TODO #4980 */ - if (sizeof (rr) != ntohl (rr.purpose.size)) - { - 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 != GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MERCHANT_REFUND, &rr.purpose, - &sig.eddsa_signature, + &sig.eddsa_sig, &rr.merchant.eddsa_pub)) { GNUNET_break_op (0); return GNUNET_SYSERR; } - TALER_amount_ntoh (&rr_amount, - &rr.refund_amount); - if (GNUNET_OK != - TALER_amount_subtract (&rr_delta, - &rr_amount, - &rr_fee)) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - /* TODO #4980 */ - if (0 != TALER_amount_cmp (&rr_delta, - &amount)) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } /* NOTE: theoretically, we could also check that the given merchant_pub and h_proposal_data appear in the history under deposits. However, there is really no benefit @@ -244,13 +223,14 @@ TALER_EXCHANGE_verify_coin_history (const char *currency, (an auditor ought to check, though). Then again, we similarly had no reason to check the merchant's signature (other than a well-formendess check). */ + /* TODO: check that deposit fee and coin value match + our expectations from /keys! */ add = GNUNET_NO; } else if (0 == strcasecmp (type, "PAYBACK")) { struct TALER_PaybackConfirmationPS pc; - struct TALER_Amount pc_amount; struct TALER_ExchangePublicKeyP exchange_pub; struct TALER_ExchangeSignatureP exchange_sig; struct GNUNET_JSON_Specification spec[] = { @@ -258,8 +238,10 @@ TALER_EXCHANGE_verify_coin_history (const char *currency, &exchange_sig), GNUNET_JSON_spec_fixed_auto ("exchange_pub", &exchange_pub), - GNUNET_JSON_spec_fixed_auto ("details", - &pc), + GNUNET_JSON_spec_fixed_auto ("reserve_pub", + &pc.reserve_pub), + GNUNET_JSON_spec_absolute_time_nbo ("timestamp", + &pc.timestamp), GNUNET_JSON_spec_end() }; @@ -271,13 +253,11 @@ TALER_EXCHANGE_verify_coin_history (const char *currency, GNUNET_break_op (0); return GNUNET_SYSERR; } - - /* TODO #4980 */ - if (sizeof (pc) != ntohl (pc.purpose.size)) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } + pc.purpose.size = htonl (sizeof (pc)); + pc.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_PAYBACK); + pc.coin_pub = *coin_pub; + TALER_amount_hton (&pc.payback_amount, + &amount); if (GNUNET_OK != GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_CONFIRM_PAYBACK, &pc.purpose, @@ -287,15 +267,6 @@ TALER_EXCHANGE_verify_coin_history (const char *currency, GNUNET_break_op (0); return GNUNET_SYSERR; } - TALER_amount_ntoh (&pc_amount, - &pc.payback_amount); - /* TODO #4980 */ - if (0 != TALER_amount_cmp (&pc_amount, - &amount)) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } add = GNUNET_YES; } else diff --git a/src/exchange-lib/exchange_api_reserve.c b/src/exchange-lib/exchange_api_reserve.c index 0ed8cca00..98f15dcda 100644 --- a/src/exchange-lib/exchange_api_reserve.c +++ b/src/exchange-lib/exchange_api_reserve.c @@ -184,12 +184,15 @@ parse_reserve_history (struct TALER_EXCHANGE_Handle *exchange, { struct TALER_ReserveSignatureP sig; struct TALER_WithdrawRequestPS withdraw_purpose; - struct TALER_Amount amount_from_purpose; struct GNUNET_JSON_Specification withdraw_spec[] = { - GNUNET_JSON_spec_fixed_auto ("signature", + GNUNET_JSON_spec_fixed_auto ("reserve_sig", &sig), - GNUNET_JSON_spec_fixed_auto ("details", - &withdraw_purpose), + TALER_JSON_spec_amount_nbo ("withdraw_fee", + &withdraw_purpose.withdraw_fee), + GNUNET_JSON_spec_fixed_auto ("h_denom_pub", + &withdraw_purpose.h_denomination_pub), + GNUNET_JSON_spec_fixed_auto ("h_coin_envelope", + &withdraw_purpose.h_coin_envelope), GNUNET_JSON_spec_end() }; unsigned int i; @@ -203,6 +206,13 @@ parse_reserve_history (struct TALER_EXCHANGE_Handle *exchange, GNUNET_break_op (0); return GNUNET_SYSERR; } + withdraw_purpose.purpose.size + = htonl (sizeof (withdraw_purpose)); + withdraw_purpose.purpose.purpose + = htonl (TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW); + withdraw_purpose.reserve_pub = *reserve_pub; + TALER_amount_hton (&withdraw_purpose.amount_with_fee, + &amount); /* Check that the signature is a valid withdraw request */ if (GNUNET_OK != GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW, @@ -214,18 +224,10 @@ parse_reserve_history (struct TALER_EXCHANGE_Handle *exchange, GNUNET_JSON_parse_free (withdraw_spec); return GNUNET_SYSERR; } - TALER_amount_ntoh (&amount_from_purpose, - &withdraw_purpose.amount_with_fee); - /* TODO #4980 */ - if (0 != TALER_amount_cmp (&amount, - &amount_from_purpose)) - { - GNUNET_break_op (0); - GNUNET_JSON_parse_free (withdraw_spec); - return GNUNET_SYSERR; - } - rhistory[off].details.out_authorization_sig = json_object_get (transaction, - "signature"); + /* TODO: check that withdraw fee matches expectations! */ + rhistory[off].details.out_authorization_sig + = json_object_get (transaction, + "signature"); /* Check check that the same withdraw transaction isn't listed twice by the exchange. We use the "uuid" array to remember the hashes of all @@ -263,25 +265,22 @@ parse_reserve_history (struct TALER_EXCHANGE_Handle *exchange, "PAYBACK")) { struct TALER_PaybackConfirmationPS pc; - struct TALER_Amount amount_from_purpose; - struct GNUNET_TIME_Absolute timestamp_from_purpose; struct GNUNET_TIME_Absolute timestamp; const struct TALER_EXCHANGE_Keys *key_state; struct GNUNET_JSON_Specification payback_spec[] = { - GNUNET_JSON_spec_fixed_auto ("details", - &pc), + GNUNET_JSON_spec_fixed_auto ("coin_pub", + &pc.coin_pub), GNUNET_JSON_spec_fixed_auto ("exchange_sig", &rhistory[off].details.payback_details.exchange_sig), GNUNET_JSON_spec_fixed_auto ("exchange_pub", &rhistory[off].details.payback_details.exchange_pub), - GNUNET_JSON_spec_absolute_time ("timestamp", - ×tamp), - TALER_JSON_spec_amount ("amount", - &rhistory[off].amount), + GNUNET_JSON_spec_absolute_time_nbo ("timestamp", + &pc.timestamp), GNUNET_JSON_spec_end() }; rhistory[off].type = TALER_EXCHANGE_RTT_PAYBACK; + rhistory[off].amount = amount; if (GNUNET_OK != GNUNET_JSON_parse (transaction, payback_spec, @@ -291,22 +290,13 @@ parse_reserve_history (struct TALER_EXCHANGE_Handle *exchange, return GNUNET_SYSERR; } rhistory[off].details.payback_details.coin_pub = pc.coin_pub; - TALER_amount_ntoh (&amount_from_purpose, - &pc.payback_amount); + TALER_amount_hton (&pc.payback_amount, + &amount); + pc.purpose.size = htonl (sizeof (pc)); + pc.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_PAYBACK); + pc.reserve_pub = *reserve_pub; + timestamp = GNUNET_TIME_absolute_ntoh (pc.timestamp); rhistory[off].details.payback_details.timestamp = timestamp; - timestamp_from_purpose = GNUNET_TIME_absolute_ntoh (pc.timestamp); - /* TODO #4980 */ - if ( (0 != memcmp (&pc.reserve_pub, - reserve_pub, - sizeof (*reserve_pub))) || - (timestamp_from_purpose.abs_value_us != - timestamp.abs_value_us) || - (0 != TALER_amount_cmp (&amount_from_purpose, - &rhistory[off].amount)) ) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } key_state = TALER_EXCHANGE_get_keys (exchange); if (GNUNET_OK != |