check exchange signature on /wire/deposit response (#4135)

This commit is contained in:
Christian Grothoff 2016-04-11 20:16:58 +02:00
parent ce9dd3365d
commit cb987575c1
4 changed files with 55 additions and 17 deletions

View File

@ -38,9 +38,9 @@
*/ */
int int
TALER_EXCHANGE_verify_coin_history_ (const char *currency, TALER_EXCHANGE_verify_coin_history_ (const char *currency,
const struct TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_CoinSpendPublicKeyP *coin_pub,
json_t *history, json_t *history,
struct TALER_Amount *total) struct TALER_Amount *total)
{ {
size_t len; size_t len;
size_t off; size_t off;
@ -119,7 +119,6 @@ TALER_EXCHANGE_verify_coin_history_ (const char *currency,
return GNUNET_SYSERR; return GNUNET_SYSERR;
} }
// FIXME: check sig!
TALER_amount_ntoh (&dr_amount, TALER_amount_ntoh (&dr_amount,
&dr->amount_with_fee); &dr->amount_with_fee);
if (0 != TALER_amount_cmp (&dr_amount, if (0 != TALER_amount_cmp (&dr_amount,

View File

@ -34,8 +34,8 @@
*/ */
int int
TALER_EXCHANGE_verify_coin_history_ (const char *currency, TALER_EXCHANGE_verify_coin_history_ (const char *currency,
const struct TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_CoinSpendPublicKeyP *coin_pub,
json_t *history, json_t *history,
struct TALER_Amount *total); struct TALER_Amount *total);
/* end of exchange_api_common.h */ /* end of exchange_api_common.h */

View File

@ -327,11 +327,11 @@ TALER_EXCHANGE_perform (struct TALER_EXCHANGE_Context *ctx)
*/ */
void void
TALER_EXCHANGE_get_select_info (struct TALER_EXCHANGE_Context *ctx, TALER_EXCHANGE_get_select_info (struct TALER_EXCHANGE_Context *ctx,
fd_set *read_fd_set, fd_set *read_fd_set,
fd_set *write_fd_set, fd_set *write_fd_set,
fd_set *except_fd_set, fd_set *except_fd_set,
int *max_fd, int *max_fd,
long *timeout) long *timeout)
{ {
long to; long to;
int m; int m;

View File

@ -101,12 +101,12 @@ handle_wire_deposits_finished (void *cls,
struct TALER_Amount total_amount; struct TALER_Amount total_amount;
struct TALER_MerchantPublicKeyP merchant_pub; struct TALER_MerchantPublicKeyP merchant_pub;
unsigned int num_details; unsigned int num_details;
struct TALER_ExchangePublicKeyP pub; struct TALER_ExchangePublicKeyP exchange_pub;
struct TALER_ExchangeSignatureP sig; struct TALER_ExchangeSignatureP exchange_sig;
struct GNUNET_JSON_Specification spec[] = { struct GNUNET_JSON_Specification spec[] = {
GNUNET_JSON_spec_fixed_auto ("H_wire", &h_wire), GNUNET_JSON_spec_fixed_auto ("H_wire", &h_wire),
GNUNET_JSON_spec_fixed_auto ("exchange_pub", &pub), GNUNET_JSON_spec_fixed_auto ("exchange_pub", &exchange_pub),
GNUNET_JSON_spec_fixed_auto ("exchange_sig", &sig), GNUNET_JSON_spec_fixed_auto ("exchange_sig", &exchange_sig),
GNUNET_JSON_spec_fixed_auto ("merchant_pub", &merchant_pub), GNUNET_JSON_spec_fixed_auto ("merchant_pub", &merchant_pub),
TALER_JSON_spec_amount ("total_amount", &total_amount), TALER_JSON_spec_amount ("total_amount", &total_amount),
GNUNET_JSON_spec_json ("details", &details_j), GNUNET_JSON_spec_json ("details", &details_j),
@ -126,7 +126,11 @@ handle_wire_deposits_finished (void *cls,
{ {
struct TALER_WireDepositDetails details[num_details]; struct TALER_WireDepositDetails details[num_details];
unsigned int i; unsigned int i;
struct GNUNET_HashContext *hash_context;
struct TALER_WireDepositDetailP dd;
struct TALER_WireDepositDataPS wdp;
hash_context = GNUNET_CRYPTO_hash_context_start ();
for (i=0;i<num_details;i++) for (i=0;i<num_details;i++)
{ {
struct TALER_WireDepositDetails *detail = &details[i]; struct TALER_WireDepositDetails *detail = &details[i];
@ -149,10 +153,45 @@ handle_wire_deposits_finished (void *cls,
response_code = 0; response_code = 0;
break; break;
} }
/* build up big hash for signature checking later */
dd.h_contract = detail->h_contract;
dd.transaction_id = GNUNET_htonll (detail->transaction_id);
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 (struct TALER_WireDepositDetailP));
}
/* 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);
wdp.merchant_pub = merchant_pub;
wdp.h_wire = h_wire;
GNUNET_CRYPTO_hash_context_finish (hash_context,
&wdp.h_details);
if ( (0 == response_code /* avoid crypto if things are already wrong */) &&
(GNUNET_OK !=
TALER_EXCHANGE_test_signing_key (TALER_EXCHANGE_get_keys (wdh->exchange),
&exchange_pub)) )
{
GNUNET_break_op (0);
response_code = 0;
}
if ( (0 == response_code /* avoid crypto if things are already wrong */) &&
(GNUNET_OK !=
TALER_EXCHANGE_test_signing_key (TALER_EXCHANGE_get_keys (wdh->exchange),
&exchange_pub)) )
{
GNUNET_break_op (0);
response_code = 0;
} }
if (0 == response_code) if (0 == response_code)
break; break;
/* FIXME: check signature (#4135) */
wdh->cb (wdh->cb_cls, wdh->cb (wdh->cb_cls,
response_code, response_code,
json, json,