From d61dbb310995476ff977bb5da30d8f87dd161b6f Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sat, 28 Mar 2015 16:51:54 +0100 Subject: fix use of struct TALER_WithdrawRequestPS --- src/include/taler_mintdb_plugin.h | 26 +++++++++-- src/mint/taler-mint-httpd_responses.c | 4 ++ src/mint/taler-mint-httpd_withdraw.c | 87 ++++++++++++++++++++++------------- 3 files changed, 81 insertions(+), 36 deletions(-) diff --git a/src/include/taler_mintdb_plugin.h b/src/include/taler_mintdb_plugin.h index 18f3499f3..0cf8ba848 100644 --- a/src/include/taler_mintdb_plugin.h +++ b/src/include/taler_mintdb_plugin.h @@ -87,12 +87,32 @@ struct TALER_MINTDB_CollectableBlindcoin /** * Denomination key (which coin was generated). - * FIXME: we should probably instead have the - * AMOUNT *including* fee in what is being signed - * as well! */ struct TALER_DenominationPublicKey denom_pub; + /** + * Value of the coin being minted (matching the denomination key) + * plus the transaction fee. We include this in what is being + * signed so that we can verify a reserve's remaining total balance + * without needing to access the respective denomination key + * information each time. + */ + struct TALER_Amount amount_with_fee; + + /** + * Withdrawl fee charged by the mint. This must match the Mint's + * denomination key's withdrawl fee. If the client puts in an + * invalid withdrawl fee (too high or too low) that does not match + * the Mint's denomination key, the withdraw operation is invalid + * and will be rejected by the mint. The @e amount_with_fee minus + * the @e withdraw_fee is must match the value of the generated + * coin. We include this in what is being signed so that we can + * verify a mint's accounting without needing to access the + * respective denomination key information each time. + */ + struct TALER_Amount withdraw_fee; + + /** * Public key of the reserve that was drained. */ diff --git a/src/mint/taler-mint-httpd_responses.c b/src/mint/taler-mint-httpd_responses.c index 3ba9fdb67..e2b982b9f 100644 --- a/src/mint/taler-mint-httpd_responses.c +++ b/src/mint/taler-mint-httpd_responses.c @@ -501,6 +501,10 @@ compile_reserve_history (const struct TALER_MINTDB_ReserveHistory *rh, wr.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW); wr.purpose.size = htonl (sizeof (struct TALER_WithdrawRequestPS)); wr.reserve_pub = pos->details.withdraw->reserve_pub; + TALER_amount_hton (&wr.amount_with_fee, + &pos->details.withdraw->amount_with_fee); + TALER_amount_hton (&wr.withdraw_fee, + &pos->details.withdraw->withdraw_fee); GNUNET_CRYPTO_rsa_public_key_hash (pos->details.withdraw->denom_pub.rsa_public_key, &wr.h_denomination_pub); wr.h_coin_envelope = pos->details.withdraw->h_coin_envelope; diff --git a/src/mint/taler-mint-httpd_withdraw.c b/src/mint/taler-mint-httpd_withdraw.c index 786ef8203..41f966639 100644 --- a/src/mint/taler-mint-httpd_withdraw.c +++ b/src/mint/taler-mint-httpd_withdraw.c @@ -44,18 +44,18 @@ */ int TMH_WITHDRAW_handler_withdraw_status (struct TMH_RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size) + struct MHD_Connection *connection, + void **connection_cls, + const char *upload_data, + size_t *upload_data_size) { struct TALER_ReservePublicKeyP reserve_pub; int res; res = TMH_PARSE_mhd_request_arg_data (connection, - "reserve_pub", - &reserve_pub, - sizeof (struct TALER_ReservePublicKeyP)); + "reserve_pub", + &reserve_pub, + sizeof (struct TALER_ReservePublicKeyP)); if (GNUNET_SYSERR == res) return MHD_NO; /* internal error */ if (GNUNET_NO == res) @@ -83,10 +83,10 @@ TMH_WITHDRAW_handler_withdraw_status (struct TMH_RequestHandler *rh, */ int TMH_WITHDRAW_handler_withdraw_sign (struct TMH_RequestHandler *rh, - struct MHD_Connection *connection, - void **connection_cls, - const char *upload_data, - size_t *upload_data_size) + struct MHD_Connection *connection, + void **connection_cls, + const char *upload_data, + size_t *upload_data_size) { struct TALER_WithdrawRequestPS wsrd; int res; @@ -95,36 +95,41 @@ TMH_WITHDRAW_handler_withdraw_sign (struct TMH_RequestHandler *rh, size_t denomination_pub_data_size; char *blinded_msg; size_t blinded_msg_len; + struct TALER_Amount amount; + struct TALER_Amount amount_with_fee; + struct TALER_Amount fee_withdraw; struct TALER_ReserveSignatureP signature; + struct TALER_MINTDB_DenominationKeyIssueInformation *dki; + struct TMH_KS_StateHandle *ks; res = TMH_PARSE_mhd_request_arg_data (connection, - "reserve_pub", - &wsrd.reserve_pub, - sizeof (struct TALER_ReservePublicKeyP)); + "reserve_pub", + &wsrd.reserve_pub, + sizeof (struct TALER_ReservePublicKeyP)); if (GNUNET_SYSERR == res) return MHD_NO; /* internal error */ if (GNUNET_NO == res) return MHD_YES; /* invalid request */ res = TMH_PARSE_mhd_request_arg_data (connection, - "reserve_sig", - &signature, - sizeof (struct TALER_ReserveSignatureP)); + "reserve_sig", + &signature, + sizeof (struct TALER_ReserveSignatureP)); if (GNUNET_SYSERR == res) return MHD_NO; /* internal error */ if (GNUNET_NO == res) return MHD_YES; /* invalid request */ res = TMH_PARSE_mhd_request_var_arg_data (connection, - "denom_pub", - (void **) &denomination_pub_data, - &denomination_pub_data_size); + "denom_pub", + (void **) &denomination_pub_data, + &denomination_pub_data_size); if (GNUNET_SYSERR == res) return MHD_NO; /* internal error */ if (GNUNET_NO == res) return MHD_YES; /* invalid request */ res = TMH_PARSE_mhd_request_var_arg_data (connection, - "coin_ev", - (void **) &blinded_msg, - &blinded_msg_len); + "coin_ev", + (void **) &blinded_msg, + &blinded_msg_len); if (GNUNET_SYSERR == res) { GNUNET_free (denomination_pub_data); @@ -135,7 +140,25 @@ TMH_WITHDRAW_handler_withdraw_sign (struct TMH_RequestHandler *rh, GNUNET_free (denomination_pub_data); return MHD_YES; /* invalid request */ } - + denomination_pub.rsa_public_key + = GNUNET_CRYPTO_rsa_public_key_decode (denomination_pub_data, + denomination_pub_data_size); + ks = TMH_KS_acquire (); + dki = TMH_KS_denomination_key_lookup (ks, + &denomination_pub); + TALER_amount_ntoh (&amount, + &dki->issue.value); + TALER_amount_ntoh (&fee_withdraw, + &dki->issue.fee_withdraw); + GNUNET_assert (GNUNET_OK == + TALER_amount_add (&amount_with_fee, + &amount, + &fee_withdraw)); + TALER_amount_hton (&wsrd.amount_with_fee, + &amount_with_fee); + TALER_amount_hton (&wsrd.withdraw_fee, + &fee_withdraw); + TMH_KS_release (ks); /* verify signature! */ wsrd.purpose.size = htonl (sizeof (struct TALER_WithdrawRequestPS)); wsrd.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW); @@ -154,26 +177,24 @@ TMH_WITHDRAW_handler_withdraw_sign (struct TMH_RequestHandler *rh, TALER_LOG_WARNING ("Client supplied invalid signature for /withdraw/sign request\n"); GNUNET_free (denomination_pub_data); GNUNET_free (blinded_msg); + GNUNET_CRYPTO_rsa_public_key_free (denomination_pub.rsa_public_key); return TMH_RESPONSE_reply_arg_invalid (connection, "reserve_sig"); } - denomination_pub.rsa_public_key - = GNUNET_CRYPTO_rsa_public_key_decode (denomination_pub_data, - denomination_pub_data_size); GNUNET_free (denomination_pub_data); if (NULL == denomination_pub.rsa_public_key) { TALER_LOG_WARNING ("Client supplied ill-formed denomination public key for /withdraw/sign request\n"); GNUNET_free (blinded_msg); return TMH_RESPONSE_reply_arg_invalid (connection, - "denom_pub"); + "denom_pub"); } res = TMH_DB_execute_withdraw_sign (connection, - &wsrd.reserve_pub, - &denomination_pub, - blinded_msg, - blinded_msg_len, - &signature); + &wsrd.reserve_pub, + &denomination_pub, + blinded_msg, + blinded_msg_len, + &signature); GNUNET_free (blinded_msg); GNUNET_CRYPTO_rsa_public_key_free (denomination_pub.rsa_public_key); return res; -- cgit v1.2.3