implement signing of /wire/deposit replies (#4135)

This commit is contained in:
Christian Grothoff 2016-04-11 19:54:54 +02:00
parent 3a5902b590
commit ce9dd3365d
4 changed files with 117 additions and 8 deletions

View File

@ -101,8 +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_ExchangeSignatureP 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_sig", &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),
@ -148,6 +152,7 @@ handle_wire_deposits_finished (void *cls,
} }
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,
@ -208,9 +213,9 @@ handle_wire_deposits_finished (void *cls,
*/ */
struct TALER_EXCHANGE_WireDepositsHandle * struct TALER_EXCHANGE_WireDepositsHandle *
TALER_EXCHANGE_wire_deposits (struct TALER_EXCHANGE_Handle *exchange, TALER_EXCHANGE_wire_deposits (struct TALER_EXCHANGE_Handle *exchange,
const struct TALER_WireTransferIdentifierRawP *wtid, const struct TALER_WireTransferIdentifierRawP *wtid,
TALER_EXCHANGE_WireDepositsCallback cb, TALER_EXCHANGE_WireDepositsCallback cb,
void *cb_cls) void *cb_cls)
{ {
struct TALER_EXCHANGE_WireDepositsHandle *wdh; struct TALER_EXCHANGE_WireDepositsHandle *wdh;
struct TALER_EXCHANGE_Context *ctx; struct TALER_EXCHANGE_Context *ctx;

View File

@ -1718,6 +1718,8 @@ TMH_DB_execute_wire_deposits (struct MHD_Connection *connection,
return TMH_RESPONSE_reply_internal_db_error (connection); return TMH_RESPONSE_reply_internal_db_error (connection);
} }
ctx.is_valid = GNUNET_NO; ctx.is_valid = GNUNET_NO;
ctx.wdd_head = NULL;
ctx.wdd_tail = NULL;
ret = TMH_plugin->lookup_wire_transfer (TMH_plugin->cls, ret = TMH_plugin->lookup_wire_transfer (TMH_plugin->cls,
session, session,
wtid, wtid,

View File

@ -1163,13 +1163,26 @@ TMH_RESPONSE_reply_wire_deposit_details (struct MHD_Connection *connection,
{ {
const struct TMH_WireDepositDetail *wdd_pos; const struct TMH_WireDepositDetail *wdd_pos;
json_t *deposits; 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 (); deposits = json_array ();
hash_context = GNUNET_CRYPTO_hash_context_start ();
/* 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) */
for (wdd_pos = wdd_head; NULL != wdd_pos; wdd_pos = wdd_pos->next) 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_array_append (deposits,
json_pack ("{s:o, s:o, s:o, s:I, s:o}", json_pack ("{s:o, s:o, s:o, s:I, s:o}",
"deposit_value", TALER_JSON_from_amount (&wdd_pos->deposit_value), "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, "coin_pub", GNUNET_JSON_from_data (&wdd_pos->coin_pub,
sizeof (struct TALER_CoinSpendPublicKeyP)))); 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, return TMH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_OK, MHD_HTTP_OK,
"{s:o, s:o, s:o, s:o}", "{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)), sizeof (struct TALER_MerchantPublicKeyP)),
"h_wire", GNUNET_JSON_from_data (h_wire, "h_wire", GNUNET_JSON_from_data (h_wire,
sizeof (struct GNUNET_HashCode)), 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)));
} }

View File

@ -112,6 +112,11 @@
*/ */
#define TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE 1036 #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 */ /* 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. * The contract sent by the merchant to the wallet.
*/ */