aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/include/taler_mintdb_plugin.h26
-rw-r--r--src/mint/taler-mint-httpd_responses.c4
-rw-r--r--src/mint/taler-mint-httpd_withdraw.c87
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,13 +87,33 @@ 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.
*/
struct TALER_ReservePublicKeyP reserve_pub;
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;