This commit is contained in:
Christian Grothoff 2015-06-11 13:02:57 +02:00
parent 95f4cdc6df
commit babeff1968
4 changed files with 123 additions and 108 deletions

View File

@ -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);
/**

View File

@ -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);

View File

@ -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;

View File

@ -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;
}
}