From ce9dd3365dd70fb360f192dfead552aae539ca3e Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Mon, 11 Apr 2016 19:54:54 +0200 Subject: implement signing of /wire/deposit replies (#4135) --- src/exchange-lib/exchange_api_wire_deposits.c | 11 ++-- src/exchange/taler-exchange-httpd_db.c | 2 + src/exchange/taler-exchange-httpd_responses.c | 37 +++++++++++-- src/include/taler_signatures.h | 75 +++++++++++++++++++++++++++ 4 files changed, 117 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/exchange-lib/exchange_api_wire_deposits.c b/src/exchange-lib/exchange_api_wire_deposits.c index 0112f8565..5b661920d 100644 --- a/src/exchange-lib/exchange_api_wire_deposits.c +++ b/src/exchange-lib/exchange_api_wire_deposits.c @@ -101,8 +101,12 @@ handle_wire_deposits_finished (void *cls, struct TALER_Amount total_amount; struct TALER_MerchantPublicKeyP merchant_pub; unsigned int num_details; + struct TALER_ExchangePublicKeyP pub; + struct TALER_ExchangeSignatureP sig; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_fixed_auto ("H_wire", &h_wire), + GNUNET_JSON_spec_fixed_auto ("exchange_pub", &pub), + GNUNET_JSON_spec_fixed_auto ("exchange_sig", &sig), GNUNET_JSON_spec_fixed_auto ("merchant_pub", &merchant_pub), TALER_JSON_spec_amount ("total_amount", &total_amount), GNUNET_JSON_spec_json ("details", &details_j), @@ -148,6 +152,7 @@ handle_wire_deposits_finished (void *cls, } if (0 == response_code) break; + /* FIXME: check signature (#4135) */ wdh->cb (wdh->cb_cls, response_code, json, @@ -208,9 +213,9 @@ handle_wire_deposits_finished (void *cls, */ struct TALER_EXCHANGE_WireDepositsHandle * TALER_EXCHANGE_wire_deposits (struct TALER_EXCHANGE_Handle *exchange, - const struct TALER_WireTransferIdentifierRawP *wtid, - TALER_EXCHANGE_WireDepositsCallback cb, - void *cb_cls) + const struct TALER_WireTransferIdentifierRawP *wtid, + TALER_EXCHANGE_WireDepositsCallback cb, + void *cb_cls) { struct TALER_EXCHANGE_WireDepositsHandle *wdh; struct TALER_EXCHANGE_Context *ctx; diff --git a/src/exchange/taler-exchange-httpd_db.c b/src/exchange/taler-exchange-httpd_db.c index 1d9e79daa..f63334bfd 100644 --- a/src/exchange/taler-exchange-httpd_db.c +++ b/src/exchange/taler-exchange-httpd_db.c @@ -1718,6 +1718,8 @@ TMH_DB_execute_wire_deposits (struct MHD_Connection *connection, return TMH_RESPONSE_reply_internal_db_error (connection); } ctx.is_valid = GNUNET_NO; + ctx.wdd_head = NULL; + ctx.wdd_tail = NULL; ret = TMH_plugin->lookup_wire_transfer (TMH_plugin->cls, session, wtid, diff --git a/src/exchange/taler-exchange-httpd_responses.c b/src/exchange/taler-exchange-httpd_responses.c index 6c839b382..f8ff67228 100644 --- a/src/exchange/taler-exchange-httpd_responses.c +++ b/src/exchange/taler-exchange-httpd_responses.c @@ -1163,13 +1163,26 @@ TMH_RESPONSE_reply_wire_deposit_details (struct MHD_Connection *connection, { const struct TMH_WireDepositDetail *wdd_pos; json_t *deposits; + struct TALER_WireDepositDetailP dd; + struct GNUNET_HashContext *hash_context; + struct TALER_WireDepositDataPS wdp; + struct TALER_ExchangePublicKeyP pub; + struct TALER_ExchangeSignatureP sig; deposits = json_array (); - - /* NOTE: We usually keep JSON stuff out of the _DB file, and this - is also ugly if we ever add signatures over this data. (#4135) */ + hash_context = GNUNET_CRYPTO_hash_context_start (); for (wdd_pos = wdd_head; NULL != wdd_pos; wdd_pos = wdd_pos->next) { + dd.h_contract = wdd_pos->h_contract; + dd.transaction_id = GNUNET_htonll (wdd_pos->transaction_id); + dd.coin_pub = wdd_pos->coin_pub; + TALER_amount_hton (&dd.deposit_value, + &wdd_pos->deposit_value); + TALER_amount_hton (&dd.deposit_fee, + &wdd_pos->deposit_fee); + GNUNET_CRYPTO_hash_context_read (hash_context, + &dd, + sizeof (struct TALER_WireDepositDetailP)); json_array_append (deposits, json_pack ("{s:o, s:o, s:o, s:I, s:o}", "deposit_value", TALER_JSON_from_amount (&wdd_pos->deposit_value), @@ -1180,7 +1193,17 @@ TMH_RESPONSE_reply_wire_deposit_details (struct MHD_Connection *connection, "coin_pub", GNUNET_JSON_from_data (&wdd_pos->coin_pub, sizeof (struct TALER_CoinSpendPublicKeyP)))); } - /* FIXME: #4135: signing not implemented here */ + wdp.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE_DEPOSIT); + wdp.purpose.size = htonl (sizeof (struct TALER_WireDepositDataPS)); + TALER_amount_hton (&wdp.total, + total); + wdp.merchant_pub = *merchant_pub; + wdp.h_wire = *h_wire; + GNUNET_CRYPTO_hash_context_finish (hash_context, + &wdp.h_details); + TMH_KS_sign (&wdp.purpose, + &pub, + &sig); return TMH_RESPONSE_reply_json_pack (connection, MHD_HTTP_OK, "{s:o, s:o, s:o, s:o}", @@ -1189,7 +1212,11 @@ TMH_RESPONSE_reply_wire_deposit_details (struct MHD_Connection *connection, sizeof (struct TALER_MerchantPublicKeyP)), "h_wire", GNUNET_JSON_from_data (h_wire, sizeof (struct GNUNET_HashCode)), - "deposits", deposits); + "deposits", deposits, + "exchange_sig", GNUNET_JSON_from_data (&sig, + sizeof (sig)), + "exchange_pub", GNUNET_JSON_from_data (&pub, + sizeof (pub))); } diff --git a/src/include/taler_signatures.h b/src/include/taler_signatures.h index 587cdcee5..bd892e793 100644 --- a/src/include/taler_signatures.h +++ b/src/include/taler_signatures.h @@ -112,6 +112,11 @@ */ #define TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE 1036 +/** + * Signature where the Exchange confirms the /wire/deposit response. + */ +#define TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE_DEPOSIT 1037 + /*********************/ /* Wallet signatures */ @@ -834,6 +839,76 @@ struct TALER_DepositTrackPS }; +/** + * @brief Format internally used for packing the detailed information + * to generate the signature for /wire/deposit signatures. + */ +struct TALER_WireDepositDetailP +{ + + /** + * Hash of the contract + */ + struct GNUNET_HashCode h_contract; + + /** + * Merchant's transaction ID in NBO. + */ + uint64_t transaction_id GNUNET_PACKED; + + /** + * Coin's public key. + */ + struct TALER_CoinSpendPublicKeyP coin_pub; + + /** + * Total value of the coin. + */ + struct TALER_AmountNBO deposit_value; + + /** + * Fees charged by the exchange for the deposit. + */ + struct TALER_AmountNBO deposit_fee; + +}; + + +/** + * @brief Format used to generate the signature for /wire/deposit + * replies. + */ +struct TALER_WireDepositDataPS +{ + /** + * Purpose header for the signature over the contract with + * purpose #TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE_DEPOSIT. + */ + struct GNUNET_CRYPTO_EccSignaturePurpose purpose; + + /** + * Total amount that was transferred. + */ + struct TALER_AmountNBO total; + + /** + * Public key of the merchant (for all aggregated transactions). + */ + struct TALER_MerchantPublicKeyP merchant_pub; + + /** + * Hash of wire details of the merchant. + */ + struct GNUNET_HashCode h_wire; + + /** + * Hash of the individual deposits that were aggregated, + * each in the format of a `struct TALER_WireDepositDetailP`. + */ + struct GNUNET_HashCode h_details; + +}; + /** * The contract sent by the merchant to the wallet. */ -- cgit v1.2.3