diff options
Diffstat (limited to 'src/mint/taler-mint-httpd_db.c')
-rw-r--r-- | src/mint/taler-mint-httpd_db.c | 881 |
1 files changed, 498 insertions, 383 deletions
diff --git a/src/mint/taler-mint-httpd_db.c b/src/mint/taler-mint-httpd_db.c index 63bca2ecc..17f44c9c9 100644 --- a/src/mint/taler-mint-httpd_db.c +++ b/src/mint/taler-mint-httpd_db.c @@ -17,41 +17,73 @@ * @file taler-mint-httpd_db.c * @brief High-level (transactional-layer) database operations for the mint. * @author Christian Grothoff - * - * TODO: - * - actually abstract DB implementation (i.e. via plugin logic) - * (this file should remain largely unchanged with the exception - * of the PQ-specific DB handle types) */ #include "platform.h" #include <pthread.h> #include <jansson.h> #include "taler-mint-httpd_db.h" #include "taler_signatures.h" -#include "taler-mint-httpd_keys.h" #include "taler-mint-httpd_responses.h" -#include "mint_db.h" #include "taler_util.h" #include "taler-mint-httpd_keystate.h" +#include "plugin.h" /** - * Get an amount in the mint's currency that is zero. + * Calculate the total value of all transactions performed. + * Stores @a off plus the cost of all transactions in @a tl + * in @a ret. * - * @return zero amount in the mint's currency + * @param pos transaction list to process + * @param off offset to use as the starting value + * @param ret where the resulting total is to be stored + * @return #GNUNET_OK on success, #GNUNET_SYSERR on errors */ -static struct TALER_Amount -mint_amount_native_zero () +static int +calculate_transaction_list_totals (struct TALER_MINT_DB_TransactionList *tl, + const struct TALER_Amount *off, + struct TALER_Amount *ret) { - struct TALER_Amount amount; - - memset (&amount, - 0, - sizeof (amount)); - memcpy (amount.currency, - MINT_CURRENCY, - strlen (MINT_CURRENCY) + 1); - return amount; + struct TALER_Amount spent = *off; + struct TALER_MINT_DB_TransactionList *pos; + + for (pos = tl; NULL != pos; pos = pos->next) + { + switch (pos->type) + { + case TALER_MINT_DB_TT_DEPOSIT: + if (GNUNET_OK != + TALER_amount_add (&spent, + &spent, + &pos->details.deposit->amount_with_fee)) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + break; + case TALER_MINT_DB_TT_REFRESH_MELT: + if (GNUNET_OK != + TALER_amount_add (&spent, + &spent, + &pos->details.melt->amount_with_fee)) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + break; + case TALER_MINT_DB_TT_LOCK: + /* should check if lock is still active, + and if it is for THIS operation; if + lock is inactive, delete it; if lock + is for THIS operation, ignore it; + if lock is for another operation, + count it! */ + GNUNET_assert (0); // FIXME: not implemented! (#3625) + return GNUNET_SYSERR; + } + } + *ret = spent; + return GNUNET_OK; } @@ -69,26 +101,24 @@ int TALER_MINT_db_execute_deposit (struct MHD_Connection *connection, const struct Deposit *deposit) { - PGconn *db_conn; + struct TALER_MINTDB_Session *session; struct TALER_MINT_DB_TransactionList *tl; - struct TALER_MINT_DB_TransactionList *pos; struct TALER_Amount spent; struct TALER_Amount value; - struct TALER_Amount fee_deposit; - struct TALER_Amount fee_withdraw; - struct TALER_Amount fee_refresh; struct MintKeyState *mks; struct TALER_MINT_DenomKeyIssuePriv *dki; int ret; - if (NULL == (db_conn = TALER_MINT_DB_get_connection (GNUNET_NO))) + if (NULL == (session = plugin->get_session (plugin->cls, + GNUNET_NO))) { GNUNET_break (0); return TALER_MINT_reply_internal_db_error (connection); } if (GNUNET_YES == - TALER_MINT_DB_have_deposit (db_conn, - deposit)) + plugin->have_deposit (plugin->cls, + session, + deposit)) { return TALER_MINT_reply_deposit_success (connection, &deposit->coin.coin_pub, @@ -96,79 +126,67 @@ TALER_MINT_db_execute_deposit (struct MHD_Connection *connection, &deposit->h_contract, deposit->transaction_id, &deposit->merchant_pub, - &deposit->amount); + &deposit->amount_with_fee); } mks = TALER_MINT_key_state_acquire (); dki = TALER_MINT_get_denom_key (mks, - deposit->coin.denom_pub); - value = TALER_amount_ntoh (dki->issue.value); - fee_deposit = TALER_amount_ntoh (dki->issue.fee_deposit); - fee_refresh = TALER_amount_ntoh (dki->issue.fee_refresh); + &deposit->coin.denom_pub); + TALER_amount_ntoh (&value, + &dki->issue.value); TALER_MINT_key_state_release (mks); if (GNUNET_OK != - TALER_MINT_DB_transaction (db_conn)) + plugin->start (plugin->cls, + session)) { GNUNET_break (0); return TALER_MINT_reply_internal_db_error (connection); } - tl = TALER_MINT_DB_get_coin_transactions (db_conn, - &deposit->coin.coin_pub); - spent = fee_withdraw; /* fee for THIS transaction */ - /* FIXME: need to deal better with integer overflows - in the logic that follows! (change amount.c API! -- #3637) */ - spent = TALER_amount_add (spent, - deposit->amount); - - for (pos = tl; NULL != pos; pos = pos->next) + /* fee for THIS transaction */ + spent = deposit->amount_with_fee; + /* add cost of all previous transactions */ + tl = plugin->get_coin_transactions (plugin->cls, + session, + &deposit->coin.coin_pub); + if (GNUNET_OK != + calculate_transaction_list_totals (tl, + &spent, + &spent)) { - switch (pos->type) - { - case TALER_MINT_DB_TT_DEPOSIT: - spent = TALER_amount_add (spent, - pos->details.deposit->amount); - spent = TALER_amount_add (spent, - fee_deposit); - break; - case TALER_MINT_DB_TT_REFRESH_MELT: - spent = TALER_amount_add (spent, - pos->details.melt->amount); - spent = TALER_amount_add (spent, - fee_refresh); - break; - case TALER_MINT_DB_TT_LOCK: - /* should check if lock is still active, - and if it is for THIS operation; if - lock is inactive, delete it; if lock - is for THIS operation, ignore it; - if lock is for another operation, - count it! */ - GNUNET_assert (0); // FIXME: not implemented! (#3625) - break; - } + plugin->free_coin_transaction_list (plugin->cls, + tl); + return TALER_MINT_reply_internal_db_error (connection); } - - if (0 < TALER_amount_cmp (spent, value)) + /* Check that cost of all transactions is smaller than + the value of the coin. */ + if (0 < TALER_amount_cmp (&spent, + &value)) { - TALER_MINT_DB_rollback (db_conn); + plugin->rollback (plugin->cls, + session); ret = TALER_MINT_reply_deposit_insufficient_funds (connection, - tl); - TALER_MINT_DB_free_coin_transaction_list (tl); + tl); + plugin->free_coin_transaction_list (plugin->cls, + tl); return ret; } - TALER_MINT_DB_free_coin_transaction_list (tl); + plugin->free_coin_transaction_list (plugin->cls, + tl); if (GNUNET_OK != - TALER_MINT_DB_insert_deposit (db_conn, - deposit)) + plugin->insert_deposit (plugin->cls, + session, + deposit)) { LOG_WARNING ("Failed to store /deposit information in database\n"); - TALER_MINT_DB_rollback (db_conn); + plugin->rollback (plugin->cls, + session); return TALER_MINT_reply_internal_db_error (connection); } if (GNUNET_OK != - TALER_MINT_DB_commit (db_conn)) + plugin->commit (plugin->cls, + session)) { LOG_WARNING ("/deposit transaction commit failed\n"); return TALER_MINT_reply_commit_error (connection); @@ -179,7 +197,7 @@ TALER_MINT_db_execute_deposit (struct MHD_Connection *connection, &deposit->h_contract, deposit->transaction_id, &deposit->merchant_pub, - &deposit->amount); + &deposit->amount_with_fee); } @@ -193,19 +211,21 @@ TALER_MINT_db_execute_deposit (struct MHD_Connection *connection, */ int TALER_MINT_db_execute_withdraw_status (struct MHD_Connection *connection, - const struct GNUNET_CRYPTO_EddsaPublicKey *reserve_pub) + const struct TALER_ReservePublicKey *reserve_pub) { - PGconn *db_conn; + struct TALER_MINTDB_Session *session; struct ReserveHistory *rh; int res; - if (NULL == (db_conn = TALER_MINT_DB_get_connection (GNUNET_NO))) + if (NULL == (session = plugin->get_session (plugin->cls, + GNUNET_NO))) { GNUNET_break (0); return TALER_MINT_reply_internal_db_error (connection); } - rh = TALER_MINT_DB_get_reserve_history (db_conn, - reserve_pub); + rh = plugin->get_reserve_history (plugin->cls, + session, + reserve_pub); if (NULL == rh) return TALER_MINT_reply_json_pack (connection, MHD_HTTP_NOT_FOUND, @@ -213,7 +233,8 @@ TALER_MINT_db_execute_withdraw_status (struct MHD_Connection *connection, "error", "Reserve not found"); res = TALER_MINT_reply_withdraw_status_success (connection, rh); - TALER_MINT_DB_free_reserve_history (rh); + plugin->free_reserve_history (plugin->cls, + rh); return res; } @@ -234,13 +255,13 @@ TALER_MINT_db_execute_withdraw_status (struct MHD_Connection *connection, */ int TALER_MINT_db_execute_withdraw_sign (struct MHD_Connection *connection, - const struct GNUNET_CRYPTO_EddsaPublicKey *reserve, - const struct GNUNET_CRYPTO_rsa_PublicKey *denomination_pub, + const struct TALER_ReservePublicKey *reserve, + const struct TALER_DenominationPublicKey *denomination_pub, const char *blinded_msg, size_t blinded_msg_len, - const struct GNUNET_CRYPTO_EddsaSignature *signature) + const struct TALER_ReserveSignature *signature) { - PGconn *db_conn; + struct TALER_MINTDB_Session *session; struct ReserveHistory *rh; const struct ReserveHistory *pos; struct MintKeyState *key_state; @@ -253,6 +274,7 @@ TALER_MINT_db_execute_withdraw_sign (struct MHD_Connection *connection, struct TALER_Amount withdraw_total; struct TALER_Amount balance; struct TALER_Amount value; + struct TALER_Amount fee_withdraw; struct GNUNET_HashCode h_blind; int res; @@ -260,14 +282,16 @@ TALER_MINT_db_execute_withdraw_sign (struct MHD_Connection *connection, blinded_msg_len, &h_blind); - if (NULL == (db_conn = TALER_MINT_DB_get_connection (GNUNET_NO))) + if (NULL == (session = plugin->get_session (plugin->cls, + GNUNET_NO))) { GNUNET_break (0); return TALER_MINT_reply_internal_db_error (connection); } - res = TALER_MINT_DB_get_collectable_blindcoin (db_conn, - &h_blind, - &collectable); + res = plugin->get_collectable_blindcoin (plugin->cls, + session, + &h_blind, + &collectable); if (GNUNET_SYSERR == res) { GNUNET_break (0); @@ -279,8 +303,8 @@ TALER_MINT_db_execute_withdraw_sign (struct MHD_Connection *connection, { res = TALER_MINT_reply_withdraw_sign_success (connection, &collectable); - GNUNET_CRYPTO_rsa_signature_free (collectable.sig); - GNUNET_CRYPTO_rsa_public_key_free (collectable.denom_pub); + GNUNET_CRYPTO_rsa_signature_free (collectable.sig.rsa_signature); + GNUNET_CRYPTO_rsa_public_key_free (collectable.denom_pub.rsa_public_key); return res; } GNUNET_assert (GNUNET_NO == res); @@ -299,18 +323,21 @@ TALER_MINT_db_execute_withdraw_sign (struct MHD_Connection *connection, "Denomination not found"); } if (GNUNET_OK != - TALER_MINT_DB_transaction (db_conn)) + plugin->start (plugin->cls, + session)) { GNUNET_break (0); TALER_MINT_key_state_release (key_state); return TALER_MINT_reply_internal_db_error (connection); } - rh = TALER_MINT_DB_get_reserve_history (db_conn, - reserve); + rh = plugin->get_reserve_history (plugin->cls, + session, + reserve); if (NULL == rh) { - TALER_MINT_DB_rollback (db_conn); + plugin->rollback (plugin->cls, + session); TALER_MINT_key_state_release (key_state); return TALER_MINT_reply_json_pack (connection, MHD_HTTP_NOT_FOUND, @@ -320,8 +347,21 @@ TALER_MINT_db_execute_withdraw_sign (struct MHD_Connection *connection, } /* calculate amount required including fees */ - amount_required = TALER_amount_add (TALER_amount_ntoh (dki->issue.value), - TALER_amount_ntoh (dki->issue.fee_withdraw)); + TALER_amount_ntoh (&value, + &dki->issue.value); + TALER_amount_ntoh (&fee_withdraw, + &dki->issue.fee_withdraw); + + if (GNUNET_OK != + TALER_amount_add (&amount_required, + &value, + &fee_withdraw)) + { + plugin->rollback (plugin->cls, + session); + TALER_MINT_key_state_release (key_state); + return TALER_MINT_reply_internal_db_error (connection); + } /* calculate balance of the reserve */ res = 0; @@ -333,70 +373,96 @@ TALER_MINT_db_execute_withdraw_sign (struct MHD_Connection *connection, if (0 == (res & 1)) deposit_total = pos->details.bank->amount; else - deposit_total = TALER_amount_add (deposit_total, - pos->details.bank->amount); + if (GNUNET_OK != + TALER_amount_add (&deposit_total, + &deposit_total, + &pos->details.bank->amount)) + { + plugin->rollback (plugin->cls, + session); + TALER_MINT_key_state_release (key_state); + return TALER_MINT_reply_internal_db_error (connection); + } res |= 1; break; case TALER_MINT_DB_RO_WITHDRAW_COIN: tdki = TALER_MINT_get_denom_key (key_state, - pos->details.withdraw->denom_pub); - value = TALER_amount_ntoh (tdki->issue.value); + &pos->details.withdraw->denom_pub); + TALER_amount_ntoh (&value, + &tdki->issue.value); if (0 == (res & 2)) withdraw_total = value; else - withdraw_total = TALER_amount_add (withdraw_total, - value); + if (GNUNET_OK != + TALER_amount_add (&withdraw_total, + &withdraw_total, + &value)) + { + plugin->rollback (plugin->cls, + session); + TALER_MINT_key_state_release (key_state); + return TALER_MINT_reply_internal_db_error (connection); + } res |= 2; break; } } - GNUNET_break (0 > TALER_amount_cmp (withdraw_total, - deposit_total)); - balance = TALER_amount_subtract (deposit_total, - withdraw_total); - if (0 < TALER_amount_cmp (amount_required, - balance)) + /* All reserve balances should be non-negative */ + GNUNET_break (GNUNET_SYSERR != + TALER_amount_subtract (&balance, + &deposit_total, + &withdraw_total)); + if (0 < TALER_amount_cmp (&amount_required, + &balance)) { TALER_MINT_key_state_release (key_state); - TALER_MINT_DB_rollback (db_conn); + plugin->rollback (plugin->cls, + session); res = TALER_MINT_reply_withdraw_sign_insufficient_funds (connection, rh); - TALER_MINT_DB_free_reserve_history (rh); + plugin->free_reserve_history (plugin->cls, + rh); return res; } - TALER_MINT_DB_free_reserve_history (rh); + plugin->free_reserve_history (plugin->cls, + rh); /* Balance is good, sign the coin! */ - sig = GNUNET_CRYPTO_rsa_sign (dki->denom_priv, + sig = GNUNET_CRYPTO_rsa_sign (dki->denom_priv.rsa_private_key, blinded_msg, blinded_msg_len); TALER_MINT_key_state_release (key_state); if (NULL == sig) { GNUNET_break (0); - TALER_MINT_DB_rollback (db_conn); + plugin->rollback (plugin->cls, + session); return TALER_MINT_reply_internal_error (connection, "Internal error"); } - collectable.sig = sig; - collectable.denom_pub = (struct GNUNET_CRYPTO_rsa_PublicKey *) denomination_pub; + collectable.sig.rsa_signature = sig; + collectable.denom_pub = *denomination_pub; collectable.reserve_pub = *reserve; GNUNET_CRYPTO_hash (blinded_msg, blinded_msg_len, &collectable.h_coin_envelope); collectable.reserve_sig = *signature; if (GNUNET_OK != - TALER_MINT_DB_insert_collectable_blindcoin (db_conn, - &h_blind, - &collectable)) + plugin->insert_collectable_blindcoin (plugin->cls, + session, + &h_blind, + amount_required, + &collectable)) { GNUNET_break (0); GNUNET_CRYPTO_rsa_signature_free (sig); - TALER_MINT_DB_rollback (db_conn); + plugin->rollback (plugin->cls, + session); return TALER_MINT_reply_internal_db_error (connection); } if (GNUNET_OK != - TALER_MINT_DB_commit (db_conn)) + plugin->commit (plugin->cls, + session)) { LOG_WARNING ("/withdraw/sign transaction commit failed\n"); return TALER_MINT_reply_commit_error (connection); @@ -413,9 +479,9 @@ TALER_MINT_db_execute_withdraw_sign (struct MHD_Connection *connection, * the database. * * @param connection the connection to send errors to - * @param db_conn the database connection + * @param session the database connection * @param key_state the mint's key state - * @param session_pub the refresh session's public key + * @param session_hash hash identifying the refresh session * @param coin_public_info the coin to melt * @param coin_details details about the coin being melted * @param oldcoin_index what is the number assigned to this coin @@ -425,10 +491,9 @@ TALER_MINT_db_execute_withdraw_sign (struct MHD_Connection *connection, */ static int refresh_accept_melts (struct MHD_Connection *connection, - PGconn *db_conn, + struct TALER_MINTDB_Session *session, const struct MintKeyState *key_state, - const struct GNUNET_HashCode *melt_hash, - const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub, + const struct GNUNET_HashCode *session_hash, const struct TALER_CoinPublicInfo *coin_public_info, const struct MeltDetails *coin_details, uint16_t oldcoin_index) @@ -437,11 +502,12 @@ refresh_accept_melts (struct MHD_Connection *connection, struct TALER_MINT_DB_TransactionList *tl; struct TALER_Amount coin_value; struct TALER_Amount coin_residual; + struct TALER_Amount spent; struct RefreshMelt melt; int res; dki = &TALER_MINT_get_denom_key (key_state, - coin_public_info->denom_pub)->issue; + &coin_public_info->denom_pub)->issue; if (NULL == dki) return (MHD_YES == @@ -452,40 +518,57 @@ refresh_accept_melts (struct MHD_Connection *connection, "denom not found")) ? GNUNET_NO : GNUNET_SYSERR; - coin_value = TALER_amount_ntoh (dki->value); - tl = TALER_MINT_DB_get_coin_transactions (db_conn, - &coin_public_info->coin_pub); - /* FIXME: #3636: compute how much value is left with this coin and - compare to `expected_value`! (subtract from "coin_value") */ - coin_residual = coin_value; - /* Refuse to refresh when the coin does not have enough money left to - * pay the refreshing fees of the coin. */ - - if (TALER_amount_cmp (coin_residual, - coin_details->melt_amount) < 0) + TALER_amount_ntoh (&coin_value, + &dki->value); + /* fee for THIS transaction; the melt amount includes the fee! */ + spent = coin_details->melt_amount_with_fee; + /* add historic transaction costs of this coin */ + tl = plugin->get_coin_transactions (plugin->cls, + session, + &coin_public_info->coin_pub); + if (GNUNET_OK != + calculate_transaction_list_totals (tl, + &spent, + &spent)) + { + GNUNET_break (0); + plugin->free_coin_transaction_list (plugin->cls, + tl); + return TALER_MINT_reply_internal_db_error (connection); + } + /* Refuse to refresh when the coin's value is insufficient + for the cost of all transactions. */ + if (TALER_amount_cmp (&coin_value, + &spent) < 0) { + GNUNET_assert (GNUNET_OK == + TALER_amount_subtract (&coin_residual, + &spent, + &coin_details->melt_amount_with_fee)); res = (MHD_YES == TALER_MINT_reply_refresh_melt_insufficient_funds (connection, &coin_public_info->coin_pub, coin_value, tl, - coin_details->melt_amount, + coin_details->melt_amount_with_fee, coin_residual)) ? GNUNET_NO : GNUNET_SYSERR; - TALER_MINT_DB_free_coin_transaction_list (tl); + plugin->free_coin_transaction_list (plugin->cls, + tl); return res; } - TALER_MINT_DB_free_coin_transaction_list (tl); + plugin->free_coin_transaction_list (plugin->cls, + tl); melt.coin = *coin_public_info; melt.coin_sig = coin_details->melt_sig; - melt.melt_hash = *melt_hash; - melt.amount = coin_details->melt_amount; + melt.session_hash = *session_hash; + melt.amount_with_fee = coin_details->melt_amount_with_fee; if (GNUNET_OK != - TALER_MINT_DB_insert_refresh_melt (db_conn, - session_pub, - oldcoin_index, - &melt)) + plugin->insert_refresh_melt (plugin->cls, + session, + oldcoin_index, + &melt)) { GNUNET_break (0); return GNUNET_SYSERR; @@ -502,69 +585,68 @@ refresh_accept_melts (struct MHD_Connection *connection, * melted and confirm the melting operation to the client. * * @param connection the MHD connection to handle - * @param melt_hash hash code of the session the coins are melted into - * @param refresh_session_pub public key of the refresh session - * @param client_signature signature of the client (matching @a refresh_session_pub) - * over the melting request + * @param session_hash hash code of the session the coins are melted into * @param num_new_denoms number of entries in @a denom_pubs, size of y-dimension of @commit_coin array * @param denum_pubs public keys of the coins we want to withdraw in the end * @param coin_count number of entries in @a coin_public_infos and @a coin_melt_details, size of y-dimension of @commit_link array * @param coin_public_infos information about the coins to melt * @param coin_melt_details signatures and (residual) value of the respective coin should be melted - * @param kappa size of x-dimension of @commit_coin and @commit_link arrays * @param commit_coin 2d array of coin commitments (what the mint is to sign - * once the "/refres/reveal" of cut and choose is done) + * once the "/refres/reveal" of cut and choose is done), + * x-dimension must be #KAPPA * @param commit_link 2d array of coin link commitments (what the mint is * to return via "/refresh/link" to enable linkage in the * future) + * x-dimension must be #KAPPA * @return MHD result code */ int TALER_MINT_db_execute_refresh_melt (struct MHD_Connection *connection, - const struct GNUNET_HashCode *melt_hash, - const struct GNUNET_CRYPTO_EddsaPublicKey *refresh_session_pub, - const struct GNUNET_CRYPTO_EddsaSignature *client_signature, + const struct GNUNET_HashCode *session_hash, unsigned int num_new_denoms, - struct GNUNET_CRYPTO_rsa_PublicKey *const*denom_pubs, + const struct TALER_DenominationPublicKey *denom_pubs, unsigned int coin_count, const struct TALER_CoinPublicInfo *coin_public_infos, const struct MeltDetails *coin_melt_details, - unsigned int kappa, struct RefreshCommitCoin *const* commit_coin, struct RefreshCommitLink *const* commit_link) { struct MintKeyState *key_state; - struct RefreshSession session; - PGconn *db_conn; + struct RefreshSession refresh_session; + struct TALER_MINTDB_Session *session; int res; unsigned int i; - unsigned int j; - if (NULL == (db_conn = TALER_MINT_DB_get_connection (GNUNET_NO))) + if (NULL == (session = plugin->get_session (plugin->cls, + GNUNET_NO))) { GNUNET_break (0); return TALER_MINT_reply_internal_db_error (connection); } if (GNUNET_OK != - TALER_MINT_DB_transaction (db_conn)) + plugin->start (plugin->cls, + session)) { GNUNET_break (0); return TALER_MINT_reply_internal_db_error (connection); } - res = TALER_MINT_DB_get_refresh_session (db_conn, - refresh_session_pub, - &session); + res = plugin->get_refresh_session (plugin->cls, + session, + session_hash, + &refresh_session); if (GNUNET_YES == res) { - TALER_MINT_DB_rollback (db_conn); + plugin->rollback (plugin->cls, + session); res = TALER_MINT_reply_refresh_melt_success (connection, - &session.session_hash, - session.noreveal_index); + session_hash, + refresh_session.noreveal_index); return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES; } if (GNUNET_SYSERR == res) { - TALER_MINT_DB_rollback (db_conn); + plugin->rollback (plugin->cls, + session); return TALER_MINT_reply_internal_db_error (connection); } @@ -574,98 +656,95 @@ TALER_MINT_db_execute_refresh_melt (struct MHD_Connection *connection, { if (GNUNET_OK != (res = refresh_accept_melts (connection, - db_conn, + session, key_state, - melt_hash, - refresh_session_pub, + session_hash, &coin_public_infos[i], &coin_melt_details[i], i))) { TALER_MINT_key_state_release (key_state); - TALER_MINT_DB_rollback (db_conn); + plugin->rollback (plugin->cls, + session); return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES; } } TALER_MINT_key_state_release (key_state); /* store requested new denominations */ - for (i=0;i<num_new_denoms;i++) + if (GNUNET_OK != + plugin->insert_refresh_order (plugin->cls, + session, + session_hash, + num_new_denoms, + denom_pubs)) { - if (GNUNET_OK != - TALER_MINT_DB_insert_refresh_order (db_conn, - refresh_session_pub, - i, - denom_pubs[i])) - { - TALER_MINT_DB_rollback (db_conn); - return TALER_MINT_reply_internal_db_error (connection); - } + plugin->rollback (plugin->cls, + session); + return TALER_MINT_reply_internal_db_error (connection); } - for (i = 0; i < kappa; i++) + for (i = 0; i < KAPPA; i++) { - for (j = 0; j < num_new_denoms; j++) + if (GNUNET_OK != + plugin->insert_refresh_commit_coins (plugin->cls, + session, + session_hash, + i, + num_new_denoms, + commit_coin[i])) { - if (GNUNET_OK != - TALER_MINT_DB_insert_refresh_commit_coin (db_conn, - refresh_session_pub, - i, - j, - &commit_coin[i][j])) - { - TALER_MINT_DB_rollback (db_conn); - return TALER_MINT_reply_internal_db_error (connection); - } + plugin->rollback (plugin->cls, + session); + return TALER_MINT_reply_internal_db_error (connection); } } - for (i = 0; i < kappa; i++) + for (i = 0; i < KAPPA; i++) { - for (j = 0; j < coin_count; j++) + if (GNUNET_OK != + plugin->insert_refresh_commit_links (plugin->cls, + session, + session_hash, + i, + coin_count, + commit_link[i])) { - if (GNUNET_OK != - TALER_MINT_DB_insert_refresh_commit_link (db_conn, - refresh_session_pub, - i, - j, - &commit_link[i][j])) - { - TALER_MINT_DB_rollback (db_conn); - return TALER_MINT_reply_internal_db_error (connection); - } + plugin->rollback (plugin->cls, + session); + return TALER_MINT_reply_internal_db_error (connection); } } /* store 'global' session data */ - session.melt_sig = *client_signature; - session.session_hash = *melt_hash; - session.num_oldcoins = coin_count; - session.num_newcoins = num_new_denoms; - session.kappa = KAPPA; // FIXME... - session.noreveal_index + refresh_session.num_oldcoins = coin_count; + refresh_session.num_newcoins = num_new_denoms; + refresh_session.noreveal_index = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_STRONG, - session.kappa); + KAPPA); if (GNUNET_OK != - (res = TALER_MINT_DB_create_refresh_session (db_conn, - refresh_session_pub, - &session))) + (res = plugin->create_refresh_session (plugin->cls, + session, + session_hash, + &refresh_session))) { - TALER_MINT_DB_rollback (db_conn); + plugin->rollback (plugin->cls, + session); return TALER_MINT_reply_internal_db_error (connection); } if (GNUNET_OK != - TALER_MINT_DB_commit (db_conn)) + plugin->commit (plugin->cls, + session)) { LOG_WARNING ("/refresh/melt transaction commit failed\n"); return TALER_MINT_reply_commit_error (connection); } return TALER_MINT_reply_refresh_melt_success (connection, - &session.session_hash, - session.noreveal_index); + session_hash, + refresh_session.noreveal_index); } @@ -673,67 +752,74 @@ TALER_MINT_db_execute_refresh_melt (struct MHD_Connection *connection, * Check if the given @a transfer_privs correspond to an honest * commitment for the given session. * Checks that the transfer private keys match their commitments. - * Then derives the shared secret for each kappa, and check that they match. + * Then derives the shared secret for each #KAPPA, and check that they match. * * @param connection the MHD connection to handle - * @param db_conn database connection to use - * @param refresh_session session to query + * @param session database connection to use + * @param session_hash hash of session to query * @param off commitment offset to check * @param num_oldcoins size of the @a transfer_privs and @a melts arrays * @param transfer_privs private transfer keys * @param melts array of melted coins * @param num_newcoins number of newcoins being generated - * @param denom_pub array of @a num_newcoins keys for the new coins + * @param denom_pubs array of @a num_newcoins keys for the new coins * @return #GNUNET_OK if the committment was honest, * #GNUNET_NO if there was a problem and we generated an error message * #GNUNET_SYSERR if we could not even generate an error message */ static int check_commitment (struct MHD_Connection *connection, - PGconn *db_conn, - const struct GNUNET_CRYPTO_EddsaPublicKey *refresh_session, + struct TALER_MINTDB_Session *session, + const struct GNUNET_HashCode *session_hash, unsigned int off, unsigned int num_oldcoins, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *transfer_privs, + const struct TALER_TransferPrivateKey *transfer_privs, const struct RefreshMelt *melts, unsigned int num_newcoins, - struct GNUNET_CRYPTO_rsa_PublicKey *const*denom_pubs) + const struct TALER_DenominationPublicKey *denom_pubs) { unsigned int j; - int res; struct TALER_LinkSecret last_shared_secret; int secret_initialized = GNUNET_NO; + struct GNUNET_CRYPTO_EcdhePublicKey coin_ecdhe; + struct GNUNET_CRYPTO_EcdhePrivateKey transfer_ecdhe; + struct RefreshCommitLink *commit_links; + struct RefreshCommitCoin *commit_coins; + + commit_links = GNUNET_malloc (num_oldcoins * + sizeof (struct RefreshCommitLink)); + if (GNUNET_OK != + plugin->get_refresh_commit_links (plugin->cls, + session, + session_hash, + off, + num_oldcoins, + commit_links)) + { + GNUNET_break (0); + GNUNET_free (commit_links); + return (MHD_YES == TALER_MINT_reply_internal_db_error (connection)) + ? GNUNET_NO : GNUNET_SYSERR; + } for (j = 0; j < num_oldcoins; j++) { - struct RefreshCommitLink commit_link; struct TALER_TransferSecret transfer_secret; struct TALER_LinkSecret shared_secret; - struct GNUNET_CRYPTO_EcdsaPublicKey transfer_pub_check; - - res = TALER_MINT_DB_get_refresh_commit_link (db_conn, - refresh_session, - off, - j, - &commit_link); - if (GNUNET_OK != res) - { - GNUNET_break (0); - return (MHD_YES == TALER_MINT_reply_internal_db_error (connection)) - ? GNUNET_NO : GNUNET_SYSERR; - } + struct TALER_TransferPublicKey transfer_pub_check; - GNUNET_CRYPTO_ecdsa_key_get_public (&transfer_privs[j], - &transfer_pub_check); + GNUNET_CRYPTO_ecdsa_key_get_public (&transfer_privs[j].ecdsa_priv, + &transfer_pub_check.ecdsa_pub); if (0 != memcmp (&transfer_pub_check, - &commit_link.transfer_pub, - sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey))) + &commit_links[j].transfer_pub, + sizeof (struct TALER_TransferPublicKey))) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "transfer keys do not match\n"); + GNUNET_free (commit_links); /* FIXME: return more specific error with original signature (#3712) */ - return (MHD_YES == + return (MHD_YES == TALER_MINT_reply_refresh_reveal_missmatch (connection, off, j, @@ -743,25 +829,31 @@ check_commitment (struct MHD_Connection *connection, /* We're converting key types here, which is not very nice * but necessary and harmless (keys will be thrown away later). */ - /* FIXME: ECDHE/ECDSA-key type confusion! Can we reduce/avoid this? */ + GNUNET_CRYPTO_ecdsa_public_to_ecdhe (&melts[j].coin.coin_pub.ecdsa_pub, + &coin_ecdhe); + GNUNET_CRYPTO_ecdsa_private_to_ecdhe (&transfer_privs[j].ecdsa_priv, + &transfer_ecdhe); if (GNUNET_OK != - GNUNET_CRYPTO_ecc_ecdh ((const struct GNUNET_CRYPTO_EcdhePrivateKey *) &transfer_privs[j], - (const struct GNUNET_CRYPTO_EcdhePublicKey *) &melts[j].coin.coin_pub, + GNUNET_CRYPTO_ecc_ecdh (&transfer_ecdhe, + &coin_ecdhe, &transfer_secret.key)) { GNUNET_break (0); + GNUNET_CRYPTO_ecdhe_key_clear (&transfer_ecdhe); + GNUNET_free (commit_links); return (MHD_YES == TALER_MINT_reply_internal_error (connection, "ECDH error")) ? GNUNET_NO : GNUNET_SYSERR; } - + GNUNET_CRYPTO_ecdhe_key_clear (&transfer_ecdhe); if (GNUNET_OK != - TALER_transfer_decrypt (&commit_link.shared_secret_enc, + TALER_transfer_decrypt (&commit_links[j].shared_secret_enc, &transfer_secret, &shared_secret)) { GNUNET_break (0); - return (MHD_YES == + GNUNET_free (commit_links); + return (MHD_YES == TALER_MINT_reply_internal_error (connection, "Decryption error")) ? GNUNET_NO : GNUNET_SYSERR; @@ -778,6 +870,7 @@ check_commitment (struct MHD_Connection *connection, { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "shared secrets do not match\n"); + GNUNET_free (commit_links); /* FIXME: return more specific error with original signature (#3712) */ return (MHD_YES == TALER_MINT_reply_refresh_reveal_missmatch (connection, @@ -788,71 +881,75 @@ check_commitment (struct MHD_Connection *connection, } } GNUNET_break (GNUNET_YES == secret_initialized); - + GNUNET_free (commit_links); /* Check that the commitments for all new coins were correct */ + commit_coins = GNUNET_malloc (num_newcoins * + sizeof (struct RefreshCommitCoin)); + + if (GNUNET_OK != + plugin->get_refresh_commit_coins (plugin->cls, + session, + session_hash, + off, + num_newcoins, + commit_coins)) + { + GNUNET_break (0); + GNUNET_free (commit_coins); + return (MHD_YES == TALER_MINT_reply_internal_db_error (connection)) + ? GNUNET_NO : GNUNET_SYSERR; + } + for (j = 0; j < num_newcoins; j++) { - struct RefreshCommitCoin commit_coin; struct TALER_RefreshLinkDecrypted *link_data; - struct GNUNET_CRYPTO_EcdsaPublicKey coin_pub; + struct TALER_CoinSpendPublicKey coin_pub; struct GNUNET_HashCode h_msg; char *buf; size_t buf_len; - res = TALER_MINT_DB_get_refresh_commit_coin (db_conn, - refresh_session, - off, - j, - &commit_coin); - if (GNUNET_OK != res) - { - GNUNET_break (0); - return (MHD_YES == TALER_MINT_reply_internal_db_error (connection)) - ? GNUNET_NO : GNUNET_SYSERR; - } - - link_data = TALER_refresh_decrypt (commit_coin.refresh_link, + link_data = TALER_refresh_decrypt (commit_coins[j].refresh_link, &last_shared_secret); if (NULL == link_data) { GNUNET_break (0); + GNUNET_free (commit_coins); return (MHD_YES == TALER_MINT_reply_internal_error (connection, "Decryption error")) ? GNUNET_NO : GNUNET_SYSERR; } - GNUNET_CRYPTO_ecdsa_key_get_public (&link_data->coin_priv, - &coin_pub); - /* FIXME: we had envisioned a more complex scheme to derive - the message to sign for a blinded coin... - FIXME: we should have a function in util/ to do this! */ + GNUNET_CRYPTO_ecdsa_key_get_public (&link_data->coin_priv.ecdsa_priv, + &coin_pub.ecdsa_pub); GNUNET_CRYPTO_hash (&coin_pub, - sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey), + sizeof (struct TALER_CoinSpendPublicKey), &h_msg); if (0 == (buf_len = GNUNET_CRYPTO_rsa_blind (&h_msg, - link_data->blinding_key, - denom_pubs[j], + link_data->blinding_key.rsa_blinding_key, + denom_pubs[j].rsa_public_key, &buf))) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "blind failed\n"); + GNUNET_free (commit_coins); return (MHD_YES == TALER_MINT_reply_internal_error (connection, "Blinding error")) ? GNUNET_NO : GNUNET_SYSERR; } - if ( (buf_len != commit_coin.coin_ev_size) || + if ( (buf_len != commit_coins[j].coin_ev_size) || (0 != memcmp (buf, - commit_coin.coin_ev, + commit_coins[j].coin_ev, buf_len)) ) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "blind envelope does not match for kappa=%u, old=%d\n", + "blind envelope does not match for k=%u, old=%d\n", off, (int) j); /* FIXME: return more specific error with original signature (#3712) */ + GNUNET_free (commit_coins); return (MHD_YES == TALER_MINT_reply_refresh_reveal_missmatch (connection, off, @@ -862,6 +959,7 @@ check_commitment (struct MHD_Connection *connection, } GNUNET_free (buf); } + GNUNET_free (commit_coins); return GNUNET_OK; } @@ -872,62 +970,53 @@ check_commitment (struct MHD_Connection *connection, * envelope from the database and performs the signing operation. * * @param connection the MHD connection to handle - * @param db_conn database connection to use - * @param refresh_session session to query + * @param session database connection to use + * @param session_hash hash of session to query * @param key_state key state to lookup denomination pubs * @param denom_pub denomination key for the coin to create - * @param noreveal_index which index should we use to obtain the - * envelope for the coin, based on cut-and-choose + * @param commit_coin the coin that was committed * @param coin_off number of the coin * @return NULL on error, otherwise signature over the coin */ -static struct GNUNET_CRYPTO_rsa_Signature * +static struct TALER_DenominationSignature refresh_mint_coin (struct MHD_Connection *connection, - PGconn *db_conn, - const struct GNUNET_CRYPTO_EddsaPublicKey *refresh_session, + struct TALER_MINTDB_Session *session, + const struct GNUNET_HashCode *session_hash, struct MintKeyState *key_state, - const struct GNUNET_CRYPTO_rsa_PublicKey *denom_pub, - unsigned int noreveal_index, + const struct TALER_DenominationPublicKey *denom_pub, + const struct RefreshCommitCoin *commit_coin, unsigned int coin_off) { - struct RefreshCommitCoin commit_coin; struct TALER_MINT_DenomKeyIssuePriv *dki; - struct GNUNET_CRYPTO_rsa_Signature *ev_sig; - int res; + struct TALER_DenominationSignature ev_sig; - res = TALER_MINT_DB_get_refresh_commit_coin (db_conn, - refresh_session, - noreveal_index, - coin_off, - &commit_coin); - if (GNUNET_OK != res) - { - GNUNET_break (0); - return NULL; - } - dki = TALER_MINT_get_denom_key (key_state, denom_pub); + dki = TALER_MINT_get_denom_key (key_state, + denom_pub); if (NULL == dki) { GNUNET_break (0); - return NULL; + ev_sig.rsa_signature = NULL; + return ev_sig; } - ev_sig = GNUNET_CRYPTO_rsa_sign (dki->denom_priv, - commit_coin.coin_ev, - commit_coin.coin_ev_size); - if (NULL == ev_sig) + ev_sig.rsa_signature + = GNUNET_CRYPTO_rsa_sign (dki->denom_priv.rsa_private_key, + commit_coin->coin_ev, + commit_coin->coin_ev_size); + if (NULL == ev_sig.rsa_signature) { GNUNET_break (0); - return NULL; + return ev_sig; } if (GNUNET_OK != - TALER_MINT_DB_insert_refresh_collectable (db_conn, - refresh_session, - coin_off, - ev_sig)) + plugin->insert_refresh_collectable (plugin->cls, + session, + session_hash, + coin_off, + &ev_sig)) { GNUNET_break (0); - GNUNET_CRYPTO_rsa_signature_free (ev_sig); - return NULL; + GNUNET_CRYPTO_rsa_signature_free (ev_sig.rsa_signature); + ev_sig.rsa_signature = NULL; } return ev_sig; } @@ -935,48 +1024,50 @@ refresh_mint_coin (struct MHD_Connection *connection, /** * Execute a "/refresh/reveal". The client is revealing to us the - * transfer keys for @a kappa-1 sets of coins. Verify that the + * transfer keys for @a #KAPPA-1 sets of coins. Verify that the * revealed transfer keys would allow linkage to the blinded coins, * and if so, return the signed coins for corresponding to the set of * coins that was not chosen. * * @param connection the MHD connection to handle - * @param refresh_session_pub public key of the refresh session - * @param kappa size of x-dimension of @transfer_privs array plus one (!) + * @param session_hash hash identifying the refresh session * @param num_oldcoins size of y-dimension of @transfer_privs array - * @param transfer_pubs array with the revealed transfer keys + * @param transfer_pubs array with the revealed transfer keys, + * x-dimension must be #KAPPA - 1 * @return MHD result code */ int TALER_MINT_db_execute_refresh_reveal (struct MHD_Connection *connection, - const struct GNUNET_CRYPTO_EddsaPublicKey *refresh_session_pub, - unsigned int kappa, + const struct GNUNET_HashCode *session_hash, unsigned int num_oldcoins, - struct GNUNET_CRYPTO_EcdsaPrivateKey *const*transfer_privs) + struct TALER_TransferPrivateKey **transfer_privs) { int res; - PGconn *db_conn; + struct TALER_MINTDB_Session *session; struct RefreshSession refresh_session; struct MintKeyState *key_state; struct RefreshMelt *melts; - struct GNUNET_CRYPTO_rsa_PublicKey **denom_pubs; - struct GNUNET_CRYPTO_rsa_Signature **ev_sigs; + struct TALER_DenominationPublicKey *denom_pubs; + struct TALER_DenominationSignature *ev_sigs; + struct RefreshCommitCoin *commit_coins; unsigned int i; unsigned int j; unsigned int off; - if (NULL == (db_conn = TALER_MINT_DB_get_connection (GNUNET_NO))) + if (NULL == (session = plugin->get_session (plugin->cls, + GNUNET_NO))) { GNUNET_break (0); return TALER_MINT_reply_internal_db_error (connection); } - res = TALER_MINT_DB_get_refresh_session (db_conn, - refresh_session_pub, - &refresh_session); + res = plugin->get_refresh_session (plugin->cls, + session, + session_hash, + &refresh_session); if (GNUNET_NO == res) return TALER_MINT_reply_arg_invalid (connection, - "session_pub"); + "session_hash"); if (GNUNET_SYSERR == res) return TALER_MINT_reply_internal_db_error (connection); if (0 == refresh_session.num_oldcoins) @@ -990,10 +1081,11 @@ TALER_MINT_db_execute_refresh_reveal (struct MHD_Connection *connection, for (j=0;j<refresh_session.num_oldcoins;j++) { if (GNUNET_OK != - TALER_MINT_DB_get_refresh_melt (db_conn, - refresh_session_pub, - j, - &melts[j])) + plugin->get_refresh_melt (plugin->cls, + session, + session_hash, + j, + &melts[j])) { GNUNET_break (0); GNUNET_free (melts); @@ -1001,34 +1093,31 @@ TALER_MINT_db_execute_refresh_reveal (struct MHD_Connection *connection, } } denom_pubs = GNUNET_malloc (refresh_session.num_newcoins * - sizeof (struct GNUNET_CRYPTO_rsa_PublicKey *)); - for (j=0;j<refresh_session.num_newcoins;j++) + sizeof (struct TALER_DenominationPublicKey)); + if (GNUNET_OK != + plugin->get_refresh_order (plugin->cls, + session, + session_hash, + refresh_session.num_newcoins, + denom_pubs)) { - denom_pubs[j] = TALER_MINT_DB_get_refresh_order (db_conn, - refresh_session_pub, - j); - if (NULL == denom_pubs[j]) - { - GNUNET_break (0); - for (i=0;i<j;i++) - GNUNET_CRYPTO_rsa_public_key_free (denom_pubs[i]); - GNUNET_free (denom_pubs); - GNUNET_free (melts); - return (MHD_YES == TALER_MINT_reply_internal_db_error (connection)) - ? GNUNET_NO : GNUNET_SYSERR; - } + GNUNET_break (0); + GNUNET_free (denom_pubs); + GNUNET_free (melts); + return (MHD_YES == TALER_MINT_reply_internal_db_error (connection)) + ? GNUNET_NO : GNUNET_SYSERR; } off = 0; - for (i=0;i<refresh_session.kappa - 1;i++) + for (i=0;i<KAPPA - 1;i++) { if (i == refresh_session.noreveal_index) off = 1; if (GNUNET_OK != (res = check_commitment (connection, - db_conn, - refresh_session_pub, + session, + session_hash, i + off, refresh_session.num_oldcoins, transfer_privs[i + off], @@ -1037,7 +1126,7 @@ TALER_MINT_db_execute_refresh_reveal (struct MHD_Connection *connection, denom_pubs))) { for (j=0;j<refresh_session.num_newcoins;j++) - GNUNET_CRYPTO_rsa_public_key_free (denom_pubs[j]); + GNUNET_CRYPTO_rsa_public_key_free (denom_pubs[j].rsa_public_key); GNUNET_free (denom_pubs); GNUNET_free (melts); return (GNUNET_NO == res) ? MHD_YES : MHD_NO; @@ -1047,50 +1136,71 @@ TALER_MINT_db_execute_refresh_reveal (struct MHD_Connection *connection, /* Client request OK, start transaction */ if (GNUNET_OK != - TALER_MINT_DB_transaction (db_conn)) + plugin->start (plugin->cls, + session)) { GNUNET_break (0); for (j=0;j<refresh_session.num_newcoins;j++) - GNUNET_CRYPTO_rsa_public_key_free (denom_pubs[j]); + GNUNET_CRYPTO_rsa_public_key_free (denom_pubs[j].rsa_public_key); GNUNET_free (denom_pubs); return TALER_MINT_reply_internal_db_error (connection); } + commit_coins = GNUNET_malloc (refresh_session.num_newcoins * + sizeof (struct RefreshCommitCoin)); + if (GNUNET_OK != + plugin->get_refresh_commit_coins (plugin->cls, + session, + session_hash, + refresh_session.noreveal_index, + refresh_session.num_newcoins, + commit_coins)) + { + GNUNET_break (0); + GNUNET_free (commit_coins); + for (j=0;j<refresh_session.num_newcoins;j++) + GNUNET_CRYPTO_rsa_public_key_free (denom_pubs[j].rsa_public_key); + GNUNET_free (denom_pubs); + return TALER_MINT_reply_internal_db_error (connection); + } ev_sigs = GNUNET_malloc (refresh_session.num_newcoins * - sizeof (struct GNUNET_CRYPTO_rsa_Signature *)); + sizeof (struct TALER_DenominationSignature)); key_state = TALER_MINT_key_state_acquire (); for (j=0;j<refresh_session.num_newcoins;j++) { ev_sigs[j] = refresh_mint_coin (connection, - db_conn, - refresh_session_pub, + session, + session_hash, key_state, - denom_pubs[j], - refresh_session.noreveal_index, + &denom_pubs[j], + &commit_coins[j], j); - if (NULL == ev_sigs[j]) + if (NULL == ev_sigs[j].rsa_signature) { TALER_MINT_key_state_release (key_state); for (i=0;i<j;i++) - GNUNET_CRYPTO_rsa_signature_free (ev_sigs[i]); + GNUNET_CRYPTO_rsa_signature_free (ev_sigs[i].rsa_signature); GNUNET_free (ev_sigs); for (j=0;j<refresh_session.num_newcoins;j++) - GNUNET_CRYPTO_rsa_public_key_free (denom_pubs[j]); + GNUNET_CRYPTO_rsa_public_key_free (denom_pubs[j].rsa_public_key); GNUNET_free (denom_pubs); + GNUNET_free (commit_coins); return TALER_MINT_reply_internal_db_error (connection); } } TALER_MINT_key_state_release (key_state); for (j=0;j<refresh_session.num_newcoins;j++) - GNUNET_CRYPTO_rsa_public_key_free (denom_pubs[j]); + GNUNET_CRYPTO_rsa_public_key_free (denom_pubs[j].rsa_public_key); GNUNET_free (denom_pubs); + GNUNET_free (commit_coins); if (GNUNET_OK != - TALER_MINT_DB_commit (db_conn)) + plugin->commit (plugin->cls, + session)) { LOG_WARNING ("/refresh/reveal transaction commit failed\n"); for (i=0;i<refresh_session.num_newcoins;i++) - GNUNET_CRYPTO_rsa_signature_free (ev_sigs[i]); + GNUNET_CRYPTO_rsa_signature_free (ev_sigs[i].rsa_signature); GNUNET_free (ev_sigs); return TALER_MINT_reply_commit_error (connection); } @@ -1099,7 +1209,7 @@ TALER_MINT_db_execute_refresh_reveal (struct MHD_Connection *connection, refresh_session.num_newcoins, ev_sigs); for (i=0;i<refresh_session.num_newcoins;i++) - GNUNET_CRYPTO_rsa_signature_free (ev_sigs[i]); + GNUNET_CRYPTO_rsa_signature_free (ev_sigs[i].rsa_signature); GNUNET_free (ev_sigs); return res; } @@ -1116,23 +1226,25 @@ TALER_MINT_db_execute_refresh_reveal (struct MHD_Connection *connection, */ int TALER_MINT_db_execute_refresh_link (struct MHD_Connection *connection, - const struct GNUNET_CRYPTO_EcdsaPublicKey *coin_pub) + const struct TALER_CoinSpendPublicKey *coin_pub) { int res; - PGconn *db_conn; - struct GNUNET_CRYPTO_EcdsaPublicKey transfer_pub; + struct TALER_MINTDB_Session *session; + struct TALER_TransferPublicKey transfer_pub; struct TALER_EncryptedLinkSecret shared_secret_enc; struct LinkDataList *ldl; - if (NULL == (db_conn = TALER_MINT_DB_get_connection (GNUNET_NO))) + if (NULL == (session = plugin->get_session (plugin->cls, + GNUNET_NO))) { GNUNET_break (0); return TALER_MINT_reply_internal_db_error (connection); } - res = TALER_db_get_transfer (db_conn, - coin_pub, - &transfer_pub, - &shared_secret_enc); + res = plugin->get_transfer (plugin->cls, + session, + coin_pub, + &transfer_pub, + &shared_secret_enc); if (GNUNET_SYSERR == res) { GNUNET_break (0); @@ -1148,7 +1260,9 @@ TALER_MINT_db_execute_refresh_link (struct MHD_Connection *connection, } GNUNET_assert (GNUNET_OK == res); - ldl = TALER_db_get_link (db_conn, coin_pub); + ldl = plugin->get_link_data_list (plugin->cls, + session, + coin_pub); if (NULL == ldl) { return TALER_MINT_reply_json_pack (connection, @@ -1161,7 +1275,8 @@ TALER_MINT_db_execute_refresh_link (struct MHD_Connection *connection, &transfer_pub, &shared_secret_enc, ldl); - TALER_db_link_data_list_free (ldl); + plugin->free_link_data_list (plugin->cls, + ldl); return res; } |