fix #3825
This commit is contained in:
parent
95f4cdc6df
commit
babeff1968
@ -744,9 +744,9 @@ struct TALER_MINTDB_Plugin
|
||||
*/
|
||||
int
|
||||
(*get_withdraw_info) (void *cls,
|
||||
struct TALER_MINTDB_Session *sesssion,
|
||||
const struct GNUNET_HashCode *h_blind,
|
||||
struct TALER_MINTDB_CollectableBlindcoin *collectable);
|
||||
struct TALER_MINTDB_Session *sesssion,
|
||||
const struct GNUNET_HashCode *h_blind,
|
||||
struct TALER_MINTDB_CollectableBlindcoin *collectable);
|
||||
|
||||
|
||||
/**
|
||||
@ -755,11 +755,6 @@ struct TALER_MINTDB_Plugin
|
||||
*
|
||||
* @param cls the @e cls of this struct with the plugin-specific state
|
||||
* @param sesssion database connection to use
|
||||
* @param h_blind hash of the blinded message which is (blindly) signed by the
|
||||
* signature in @a collectable
|
||||
* @param withdraw amount by which the reserve will be withdrawn with this
|
||||
* transaction (based on the value of the denomination key
|
||||
* used for the signature); coin value plus fee.
|
||||
* @param collectable corresponding collectable coin (blind signature)
|
||||
* if a coin is found
|
||||
* @return #GNUNET_SYSERR on internal error
|
||||
@ -768,10 +763,8 @@ struct TALER_MINTDB_Plugin
|
||||
*/
|
||||
int
|
||||
(*insert_withdraw_info) (void *cls,
|
||||
struct TALER_MINTDB_Session *sesssion,
|
||||
const struct GNUNET_HashCode *h_blind,
|
||||
struct TALER_Amount withdraw,
|
||||
const struct TALER_MINTDB_CollectableBlindcoin *collectable);
|
||||
struct TALER_MINTDB_Session *sesssion,
|
||||
const struct TALER_MINTDB_CollectableBlindcoin *collectable);
|
||||
|
||||
|
||||
/**
|
||||
|
@ -294,9 +294,9 @@ TMH_DB_execute_withdraw_sign (struct MHD_Connection *connection,
|
||||
return TMH_RESPONSE_reply_internal_db_error (connection);
|
||||
}
|
||||
res = TMH_plugin->get_withdraw_info (TMH_plugin->cls,
|
||||
session,
|
||||
&h_blind,
|
||||
&collectable);
|
||||
session,
|
||||
&h_blind,
|
||||
&collectable);
|
||||
if (GNUNET_SYSERR == res)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
@ -446,17 +446,15 @@ TMH_DB_execute_withdraw_sign (struct MHD_Connection *connection,
|
||||
}
|
||||
collectable.sig.rsa_signature = sig;
|
||||
collectable.denom_pub = *denomination_pub;
|
||||
collectable.amount_with_fee = amount_required;
|
||||
collectable.withdraw_fee = fee_withdraw;
|
||||
collectable.reserve_pub = *reserve;
|
||||
GNUNET_CRYPTO_hash (blinded_msg,
|
||||
blinded_msg_len,
|
||||
&collectable.h_coin_envelope);
|
||||
collectable.h_coin_envelope = h_blind;
|
||||
collectable.reserve_sig = *signature;
|
||||
if (GNUNET_OK !=
|
||||
TMH_plugin->insert_withdraw_info (TMH_plugin->cls,
|
||||
session,
|
||||
&h_blind,
|
||||
amount_required,
|
||||
&collectable))
|
||||
session,
|
||||
&collectable))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
GNUNET_CRYPTO_rsa_signature_free (sig);
|
||||
@ -871,7 +869,7 @@ check_commitment (struct MHD_Connection *connection,
|
||||
&transfer_privs[j],
|
||||
&melts[j].coin.coin_pub,
|
||||
&shared_secret))
|
||||
{
|
||||
{
|
||||
GNUNET_free (commit_links);
|
||||
return (MHD_YES ==
|
||||
TMH_RESPONSE_reply_internal_error (connection,
|
||||
|
@ -266,19 +266,21 @@ postgres_create_tables (void *cls,
|
||||
key, as (broken) clients that use a non-random coin and blinding factor
|
||||
should fail to even withdraw, as otherwise the coins will fail to deposit
|
||||
(as they really must be unique). */
|
||||
/* TODO: maybe add withdraw fee and amount_with_fee explicitly to table,
|
||||
so we can init those fields on select? #3825
|
||||
TODO: maybe add timestamp of when the operation was performed, so we
|
||||
can influence the reserves' expiration_date not just based on
|
||||
incoming but also based on outgoing transactions? */
|
||||
SQLEXEC ("CREATE TABLE IF NOT EXISTS reserves_out"
|
||||
SQLEXEC ("CREATE TABLE IF NOT EXISTS reserves_out"
|
||||
"(h_blind_ev BYTEA PRIMARY KEY"
|
||||
",denom_pub BYTEA NOT NULL REFERENCES denominations (pub)"
|
||||
",denom_sig BYTEA NOT NULL"
|
||||
",reserve_pub BYTEA NOT NULL CHECK (LENGTH(reserve_pub)=32) REFERENCES reserves (reserve_pub) ON DELETE CASCADE"
|
||||
",reserve_sig BYTEA NOT NULL CHECK (LENGTH(reserve_sig)=64)"
|
||||
",execution_date INT8 NOT NULL"
|
||||
",amount_with_fee_val INT8 NOT NULL"
|
||||
",amount_with_fee_frac INT4 NOT NULL"
|
||||
",amount_with_fee_curr VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL"
|
||||
",withdraw_fee_val INT8 NOT NULL"
|
||||
",withdraw_fee_frac INT4 NOT NULL"
|
||||
",withdraw_fee_curr VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL"
|
||||
");");
|
||||
/* Index blindcoins(reserve_pub) for get_reserves_blindcoins statement */
|
||||
/* Index blindcoins(reserve_pub) for get_reserves_out statement */
|
||||
SQLEXEC_INDEX ("CREATE INDEX reserves_out_reserve_pub_index ON"
|
||||
" reserves_out (reserve_pub)");
|
||||
/* Table with coins that have been (partially) spent, used to track
|
||||
@ -529,9 +531,16 @@ postgres_prepare (PGconn *db_conn)
|
||||
",denom_sig"
|
||||
",reserve_pub"
|
||||
",reserve_sig"
|
||||
",execution_date"
|
||||
",amount_with_fee_val"
|
||||
",amount_with_fee_frac"
|
||||
",amount_with_fee_curr"
|
||||
",withdraw_fee_val"
|
||||
",withdraw_fee_frac"
|
||||
",withdraw_fee_curr"
|
||||
") VALUES "
|
||||
"($1, $2, $3, $4, $5);",
|
||||
5, NULL);
|
||||
"($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12);",
|
||||
12, NULL);
|
||||
/* Used in #postgres_get_withdraw_info() to
|
||||
locate the response for a /withdraw/sign request
|
||||
using the hash of the blinded message. Used to
|
||||
@ -542,6 +551,13 @@ postgres_prepare (PGconn *db_conn)
|
||||
",denom_sig"
|
||||
",reserve_sig"
|
||||
",reserve_pub"
|
||||
",execution_date"
|
||||
",amount_with_fee_val"
|
||||
",amount_with_fee_frac"
|
||||
",amount_with_fee_curr"
|
||||
",withdraw_fee_val"
|
||||
",withdraw_fee_frac"
|
||||
",withdraw_fee_curr"
|
||||
" FROM reserves_out"
|
||||
" WHERE h_blind_ev=$1",
|
||||
1, NULL);
|
||||
@ -549,12 +565,19 @@ postgres_prepare (PGconn *db_conn)
|
||||
obtain all of the /withdraw/sign operations that
|
||||
have been performed on a given reserve. (i.e. to
|
||||
demonstrate double-spending) */
|
||||
PREPARE ("get_reserves_blindcoins",
|
||||
PREPARE ("get_reserves_out",
|
||||
"SELECT"
|
||||
" h_blind_ev"
|
||||
",denom_pub"
|
||||
",denom_sig"
|
||||
",reserve_sig"
|
||||
",execution_date"
|
||||
",amount_with_fee_val"
|
||||
",amount_with_fee_frac"
|
||||
",amount_with_fee_curr"
|
||||
",withdraw_fee_val"
|
||||
",withdraw_fee_frac"
|
||||
",withdraw_fee_curr"
|
||||
" FROM reserves_out"
|
||||
" WHERE reserve_pub=$1;",
|
||||
1, NULL);
|
||||
@ -1273,17 +1296,15 @@ postgres_reserves_in_insert (void *cls,
|
||||
*/
|
||||
static int
|
||||
postgres_get_withdraw_info (void *cls,
|
||||
struct TALER_MINTDB_Session *session,
|
||||
const struct GNUNET_HashCode *h_blind,
|
||||
struct TALER_MINTDB_CollectableBlindcoin *collectable)
|
||||
struct TALER_MINTDB_Session *session,
|
||||
const struct GNUNET_HashCode *h_blind,
|
||||
struct TALER_MINTDB_CollectableBlindcoin *collectable)
|
||||
{
|
||||
PGresult *result;
|
||||
struct TALER_PQ_QueryParam params[] = {
|
||||
TALER_PQ_query_param_auto_from_type (h_blind),
|
||||
TALER_PQ_query_param_end
|
||||
};
|
||||
struct GNUNET_CRYPTO_rsa_PublicKey *denom_pub;
|
||||
struct GNUNET_CRYPTO_rsa_Signature *denom_sig;
|
||||
int ret;
|
||||
|
||||
ret = GNUNET_SYSERR;
|
||||
@ -1301,31 +1322,35 @@ postgres_get_withdraw_info (void *cls,
|
||||
ret = GNUNET_NO;
|
||||
goto cleanup;
|
||||
}
|
||||
struct TALER_PQ_ResultSpec rs[] = {
|
||||
TALER_PQ_result_spec_rsa_public_key("denom_pub", &denom_pub),
|
||||
TALER_PQ_result_spec_rsa_signature("denom_sig", &denom_sig),
|
||||
TALER_PQ_result_spec_auto_from_type("reserve_sig", &collectable->reserve_sig),
|
||||
TALER_PQ_result_spec_auto_from_type("reserve_pub", &collectable->reserve_pub),
|
||||
/* FIXME: collectable->amount_with_fee and
|
||||
collectable->withdraw_fee not initialized! (#3825) */
|
||||
TALER_PQ_result_spec_end
|
||||
};
|
||||
|
||||
if (GNUNET_OK != TALER_PQ_extract_result (result, rs, 0))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
goto cleanup;
|
||||
struct TALER_PQ_ResultSpec rs[] = {
|
||||
TALER_PQ_result_spec_rsa_public_key ("denom_pub",
|
||||
&collectable->denom_pub.rsa_public_key),
|
||||
TALER_PQ_result_spec_rsa_signature ("denom_sig",
|
||||
&collectable->sig.rsa_signature),
|
||||
TALER_PQ_result_spec_auto_from_type ("reserve_sig",
|
||||
&collectable->reserve_sig),
|
||||
TALER_PQ_result_spec_auto_from_type ("reserve_pub",
|
||||
&collectable->reserve_pub),
|
||||
TALER_PQ_result_spec_amount ("amount_with_fee",
|
||||
&collectable->amount_with_fee),
|
||||
TALER_PQ_result_spec_amount ("withdraw_fee",
|
||||
&collectable->withdraw_fee),
|
||||
TALER_PQ_result_spec_end
|
||||
};
|
||||
|
||||
if (GNUNET_OK !=
|
||||
TALER_PQ_extract_result (result, rs, 0))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
/* FIXME: why do we bother with the temporary variables? */
|
||||
collectable->denom_pub.rsa_public_key = denom_pub;
|
||||
collectable->sig.rsa_signature = denom_sig;
|
||||
collectable->h_coin_envelope = *h_blind;
|
||||
ret = GNUNET_YES;
|
||||
|
||||
cleanup:
|
||||
PQclear (result);
|
||||
if (GNUNET_YES != ret)
|
||||
TALER_PQ_cleanup_result (rs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1336,11 +1361,6 @@ postgres_get_withdraw_info (void *cls,
|
||||
*
|
||||
* @param cls the `struct PostgresClosure` with the plugin-specific state
|
||||
* @param session database connection to use
|
||||
* @param h_blind hash of the blinded message. FIXME:
|
||||
* redundant information given @a collectable's h_coin_envelope, right? #3825
|
||||
* @param withdraw amount by which the reserve will be reduced with this
|
||||
* transaction (coin value plus fee). FIXME:
|
||||
* redundant information given @a collectable's amount_with_fee! #3825
|
||||
* @param collectable corresponding collectable coin (blind signature)
|
||||
* if a coin is found
|
||||
* @return #GNUNET_SYSERR on internal error
|
||||
@ -1349,21 +1369,22 @@ postgres_get_withdraw_info (void *cls,
|
||||
*/
|
||||
static int
|
||||
postgres_insert_withdraw_info (void *cls,
|
||||
struct TALER_MINTDB_Session *session,
|
||||
const struct GNUNET_HashCode *h_blind,
|
||||
struct TALER_Amount withdraw,
|
||||
const struct TALER_MINTDB_CollectableBlindcoin *collectable)
|
||||
struct TALER_MINTDB_Session *session,
|
||||
const struct TALER_MINTDB_CollectableBlindcoin *collectable)
|
||||
{
|
||||
PGresult *result;
|
||||
struct TALER_MINTDB_Reserve reserve;
|
||||
int ret = GNUNET_SYSERR;
|
||||
struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ();
|
||||
struct TALER_PQ_QueryParam params[] = {
|
||||
TALER_PQ_query_param_auto_from_type (h_blind),
|
||||
TALER_PQ_query_param_auto_from_type (&collectable->h_coin_envelope),
|
||||
TALER_PQ_query_param_rsa_public_key (collectable->denom_pub.rsa_public_key),
|
||||
TALER_PQ_query_param_rsa_signature (collectable->sig.rsa_signature),
|
||||
TALER_PQ_query_param_auto_from_type (&collectable->reserve_pub),
|
||||
TALER_PQ_query_param_auto_from_type (&collectable->reserve_sig),
|
||||
/* FIXME: store fees? #3825 */
|
||||
TALER_PQ_query_param_absolute_time (&now),
|
||||
TALER_PQ_query_param_amount (&collectable->amount_with_fee),
|
||||
TALER_PQ_query_param_amount (&collectable->withdraw_fee),
|
||||
TALER_PQ_query_param_end
|
||||
};
|
||||
|
||||
@ -1392,7 +1413,7 @@ postgres_insert_withdraw_info (void *cls,
|
||||
if (GNUNET_SYSERR ==
|
||||
TALER_amount_subtract (&reserve.balance,
|
||||
&reserve.balance,
|
||||
&withdraw))
|
||||
&collectable->amount_with_fee))
|
||||
{
|
||||
/* Should have been checked before we got here... */
|
||||
GNUNET_break (0);
|
||||
@ -1501,11 +1522,6 @@ postgres_get_reserve_history (void *cls,
|
||||
PQclear (result);
|
||||
}
|
||||
{
|
||||
struct GNUNET_HashCode h_blind_ev;
|
||||
struct TALER_ReserveSignatureP reserve_sig;
|
||||
struct TALER_MINTDB_CollectableBlindcoin *cbc;
|
||||
struct GNUNET_CRYPTO_rsa_PublicKey *denom_pub;
|
||||
struct GNUNET_CRYPTO_rsa_Signature *denom_sig;
|
||||
struct TALER_PQ_QueryParam params[] = {
|
||||
TALER_PQ_query_param_auto_from_type (reserve_pub),
|
||||
TALER_PQ_query_param_end
|
||||
@ -1515,7 +1531,7 @@ postgres_get_reserve_history (void *cls,
|
||||
GNUNET_assert (NULL != rh_tail);
|
||||
GNUNET_assert (NULL == rh_tail->next);
|
||||
result = TALER_PQ_exec_prepared (session->conn,
|
||||
"get_reserves_blindcoins",
|
||||
"get_reserves_out",
|
||||
params);
|
||||
if (PGRES_TUPLES_OK != PQresultStatus (result))
|
||||
{
|
||||
@ -1526,28 +1542,35 @@ postgres_get_reserve_history (void *cls,
|
||||
rows = PQntuples (result);
|
||||
while (0 < rows)
|
||||
{
|
||||
struct TALER_PQ_ResultSpec rs[] = {
|
||||
TALER_PQ_result_spec_auto_from_type ("h_blind_ev", &h_blind_ev),
|
||||
TALER_PQ_result_spec_rsa_public_key ("denom_pub", &denom_pub),
|
||||
TALER_PQ_result_spec_rsa_signature ("denom_sig", &denom_sig),
|
||||
TALER_PQ_result_spec_auto_from_type ("reserve_sig", &reserve_sig),
|
||||
TALER_PQ_result_spec_end
|
||||
};
|
||||
struct TALER_MINTDB_CollectableBlindcoin *cbc;
|
||||
|
||||
if (GNUNET_YES !=
|
||||
TALER_PQ_extract_result (result, rs, --rows))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
PQclear (result);
|
||||
goto cleanup;
|
||||
}
|
||||
cbc = GNUNET_new (struct TALER_MINTDB_CollectableBlindcoin);
|
||||
cbc->sig.rsa_signature = denom_sig;
|
||||
cbc->denom_pub.rsa_public_key = denom_pub;
|
||||
/* FIXME: amount_with_fee and withdraw_fee not initialized! #3825 */
|
||||
cbc->h_coin_envelope = h_blind_ev;
|
||||
cbc->reserve_pub = *reserve_pub;
|
||||
cbc->reserve_sig = reserve_sig;
|
||||
{
|
||||
struct TALER_PQ_ResultSpec rs[] = {
|
||||
TALER_PQ_result_spec_auto_from_type ("h_blind_ev",
|
||||
&cbc->h_coin_envelope),
|
||||
TALER_PQ_result_spec_rsa_public_key ("denom_pub",
|
||||
&cbc->denom_pub.rsa_public_key),
|
||||
TALER_PQ_result_spec_rsa_signature ("denom_sig",
|
||||
&cbc->sig.rsa_signature),
|
||||
TALER_PQ_result_spec_auto_from_type ("reserve_sig",
|
||||
&cbc->reserve_sig),
|
||||
TALER_PQ_result_spec_amount ("amount_with_fee",
|
||||
&cbc->amount_with_fee),
|
||||
TALER_PQ_result_spec_amount ("withdraw_fee",
|
||||
&cbc->withdraw_fee),
|
||||
TALER_PQ_result_spec_end
|
||||
};
|
||||
if (GNUNET_YES !=
|
||||
TALER_PQ_extract_result (result, rs, --rows))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
GNUNET_free (cbc);
|
||||
PQclear (result);
|
||||
goto cleanup;
|
||||
}
|
||||
cbc->reserve_pub = *reserve_pub;
|
||||
}
|
||||
rh_tail->next = GNUNET_new (struct TALER_MINTDB_ReserveHistory);
|
||||
rh_tail = rh_tail->next;
|
||||
rh_tail->type = TALER_MINTDB_RO_WITHDRAW_COIN;
|
||||
|
@ -14,7 +14,7 @@
|
||||
TALER; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
/**
|
||||
* @file mint/test_mint_db.c
|
||||
* @file mint/test_mintdb.c
|
||||
* @brief test cases for DB interaction functions
|
||||
* @author Sree Harsha Totakura <sreeharsha@totakura.in>
|
||||
*/
|
||||
@ -239,7 +239,6 @@ run (void *cls,
|
||||
struct GNUNET_TIME_Absolute expiry;
|
||||
struct TALER_Amount amount;
|
||||
struct DenomKeyPair *dkp;
|
||||
struct GNUNET_HashCode h_blind;
|
||||
struct TALER_MINTDB_CollectableBlindcoin cbc;
|
||||
struct TALER_MINTDB_CollectableBlindcoin cbc2;
|
||||
struct TALER_MINTDB_ReserveHistory *rh;
|
||||
@ -321,24 +320,25 @@ run (void *cls,
|
||||
amount.currency,
|
||||
expiry.abs_value_us));
|
||||
dkp = create_denom_key_pair (1024, session);
|
||||
RND_BLK(&h_blind);
|
||||
RND_BLK(&cbc.h_coin_envelope);
|
||||
RND_BLK(&cbc.reserve_sig);
|
||||
cbc.denom_pub = dkp->pub;
|
||||
cbc.sig.rsa_signature
|
||||
= GNUNET_CRYPTO_rsa_sign (dkp->priv.rsa_private_key,
|
||||
&h_blind,
|
||||
sizeof (h_blind));
|
||||
&cbc.h_coin_envelope,
|
||||
sizeof (cbc.h_coin_envelope));
|
||||
(void) memcpy (&cbc.reserve_pub,
|
||||
&reserve_pub,
|
||||
sizeof (reserve_pub));
|
||||
amount.value--;
|
||||
amount.fraction--;
|
||||
cbc.amount_with_fee = amount;
|
||||
GNUNET_assert (GNUNET_OK ==
|
||||
TALER_amount_get_zero (CURRENCY, &cbc.withdraw_fee));
|
||||
FAILIF (GNUNET_OK !=
|
||||
plugin->insert_withdraw_info (plugin->cls,
|
||||
session,
|
||||
&h_blind,
|
||||
amount,
|
||||
&cbc));
|
||||
session,
|
||||
&cbc));
|
||||
FAILIF (GNUNET_OK !=
|
||||
check_reserve (session,
|
||||
&reserve_pub,
|
||||
@ -348,9 +348,9 @@ run (void *cls,
|
||||
expiry.abs_value_us));
|
||||
FAILIF (GNUNET_YES !=
|
||||
plugin->get_withdraw_info (plugin->cls,
|
||||
session,
|
||||
&h_blind,
|
||||
&cbc2));
|
||||
session,
|
||||
&cbc.h_coin_envelope,
|
||||
&cbc2));
|
||||
FAILIF (NULL == cbc2.denom_pub.rsa_public_key);
|
||||
FAILIF (0 != memcmp (&cbc2.reserve_sig,
|
||||
&cbc.reserve_sig,
|
||||
@ -359,7 +359,7 @@ run (void *cls,
|
||||
&cbc.reserve_pub,
|
||||
sizeof (cbc2.reserve_pub)));
|
||||
FAILIF (GNUNET_OK !=
|
||||
GNUNET_CRYPTO_rsa_verify (&h_blind,
|
||||
GNUNET_CRYPTO_rsa_verify (&cbc.h_coin_envelope,
|
||||
cbc2.sig.rsa_signature,
|
||||
dkp->pub.rsa_public_key));
|
||||
rh = plugin->get_reserve_history (plugin->cls,
|
||||
@ -387,7 +387,8 @@ run (void *cls,
|
||||
&reserve_pub,
|
||||
sizeof (reserve_pub)));
|
||||
FAILIF (0 != memcmp (&withdraw->h_coin_envelope,
|
||||
&h_blind, sizeof (h_blind)));
|
||||
&cbc.h_coin_envelope,
|
||||
sizeof (cbc.h_coin_envelope)));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user