adjust types to match latest GNUnet API

This commit is contained in:
Christian Grothoff 2020-03-17 01:09:16 +01:00
parent 98f96970d6
commit c597af8334
No known key found for this signature in database
GPG Key ID: 939E6BE1E29FC3CC
7 changed files with 206 additions and 170 deletions

View File

@ -108,23 +108,24 @@ enum TEH_KS_DenominationKeyUse
{ {
/** /**
* The key is to be used for a /reserve/withdraw or /refresh (exchange) * The denomination key is to be used for a withdraw or reveal (exchange)
* operation. * operation.
*/ */
TEH_KS_DKU_WITHDRAW, TEH_KS_DKU_WITHDRAW,
/** /**
* The key is to be used for a /deposit or /refresh (melt) operation. * The denomination key is to be used for a deposit or melt operation.
*/ */
TEH_KS_DKU_DEPOSIT, TEH_KS_DKU_DEPOSIT,
/** /**
* The key is to be used for a /recoup operation. * The denomination key is to be used for a recoup operation, or to
* melt a coin that was deposited (or melted) before the revocation.
*/ */
TEH_KS_DKU_RECOUP, TEH_KS_DKU_RECOUP,
/** /**
* The key is to be used for a /refresh/recoup operation, * The key is to be used for a refresh + recoup operation,
* i.e. it is an old coin that regained value from a * i.e. it is an old coin that regained value from a
* recoup on a new coin derived from the old coin. * recoup on a new coin derived from the old coin.
*/ */

View File

@ -1,6 +1,6 @@
/* /*
This file is part of TALER This file is part of TALER
Copyright (C) 2014-2019 Taler Systems SA Copyright (C) 2014-2020 Taler Systems SA
TALER is free software; you can redistribute it and/or modify it under the TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU Affero General Public License as published by the Free Software terms of the GNU Affero General Public License as published by the Free Software
@ -15,7 +15,7 @@
*/ */
/** /**
* @file taler-exchange-httpd_melt.c * @file taler-exchange-httpd_melt.c
* @brief Handle /refresh/melt requests * @brief Handle melt requests
* @author Florian Dold * @author Florian Dold
* @author Benedikt Mueller * @author Benedikt Mueller
* @author Christian Grothoff * @author Christian Grothoff
@ -33,7 +33,7 @@
/** /**
* Send a response for a failed "/refresh/melt" request. The * Send a response for a failed "melt" request. The
* transaction history of the given coin demonstrates that the * transaction history of the given coin demonstrates that the
* @a residual value of the coin is below the @a requested * @a residual value of the coin is below the @a requested
* contribution of the coin for the melt. Thus, the exchange * contribution of the coin for the melt. Thus, the exchange
@ -48,12 +48,11 @@
* @return a MHD result code * @return a MHD result code
*/ */
static int static int
reply_melt_insufficient_funds (struct MHD_Connection *connection, reply_melt_insufficient_funds (
const struct struct MHD_Connection *connection,
TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_CoinSpendPublicKeyP *coin_pub,
const struct TALER_Amount *coin_value, const struct TALER_Amount *coin_value,
struct TALER_EXCHANGEDB_TransactionList * struct TALER_EXCHANGEDB_TransactionList *tl,
tl,
const struct TALER_Amount *requested, const struct TALER_Amount *requested,
const struct TALER_Amount *residual) const struct TALER_Amount *residual)
{ {
@ -88,7 +87,7 @@ reply_melt_insufficient_funds (struct MHD_Connection *connection,
/** /**
* Send a response to a "/refresh/melt" request. * Send a response to a "melt" request.
* *
* @param connection the connection to send the response to * @param connection the connection to send the response to
* @param rc value the client commited to * @param rc value the client commited to
@ -100,15 +99,15 @@ reply_melt_success (struct MHD_Connection *connection,
const struct TALER_RefreshCommitmentP *rc, const struct TALER_RefreshCommitmentP *rc,
uint32_t noreveal_index) uint32_t noreveal_index)
{ {
struct TALER_RefreshMeltConfirmationPS body;
struct TALER_ExchangePublicKeyP pub; struct TALER_ExchangePublicKeyP pub;
struct TALER_ExchangeSignatureP sig; struct TALER_ExchangeSignatureP sig;
json_t *sig_json; struct TALER_RefreshMeltConfirmationPS body = {
.purpose.size = htonl (sizeof (body)),
.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_MELT),
.rc = *rc,
.noreveal_index = htonl (noreveal_index)
};
body.purpose.size = htonl (sizeof (struct TALER_RefreshMeltConfirmationPS));
body.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_MELT);
body.rc = *rc;
body.noreveal_index = htonl (noreveal_index);
if (GNUNET_OK != if (GNUNET_OK !=
TEH_KS_sign (&body.purpose, TEH_KS_sign (&body.purpose,
&pub, &pub,
@ -119,22 +118,20 @@ reply_melt_success (struct MHD_Connection *connection,
TALER_EC_EXCHANGE_BAD_CONFIGURATION, TALER_EC_EXCHANGE_BAD_CONFIGURATION,
"no keys"); "no keys");
} }
sig_json = GNUNET_JSON_from_data_auto (&sig); return TALER_MHD_reply_json_pack (
GNUNET_assert (NULL != sig_json); connection,
return TALER_MHD_reply_json_pack (connection,
MHD_HTTP_OK, MHD_HTTP_OK,
"{s:i, s:o, s:o}", "{s:i, s:o, s:o}",
"noreveal_index", (int) noreveal_index, "noreveal_index", (int) noreveal_index,
"exchange_sig", sig_json, "exchange_sig", GNUNET_JSON_from_data_auto (&sig),
"exchange_pub", "exchange_pub", GNUNET_JSON_from_data_auto (&pub));
GNUNET_JSON_from_data_auto (&pub));
} }
/** /**
* Context for the /refresh/melt operation. * Context for the melt operation.
*/ */
struct RefreshMeltContext struct MeltContext
{ {
/** /**
@ -176,7 +173,7 @@ struct RefreshMeltContext
static enum GNUNET_DB_QueryStatus static enum GNUNET_DB_QueryStatus
refresh_check_melt (struct MHD_Connection *connection, refresh_check_melt (struct MHD_Connection *connection,
struct TALER_EXCHANGEDB_Session *session, struct TALER_EXCHANGEDB_Session *session,
struct RefreshMeltContext *rmc, struct MeltContext *rmc,
int *mhd_ret) int *mhd_ret)
{ {
struct TALER_EXCHANGEDB_TransactionList *tl; struct TALER_EXCHANGEDB_TransactionList *tl;
@ -186,7 +183,7 @@ refresh_check_melt (struct MHD_Connection *connection,
/* Start with cost of this melt transaction */ /* Start with cost of this melt transaction */
spent = rmc->refresh_session.amount_with_fee; spent = rmc->refresh_session.amount_with_fee;
/* add historic transaction costs of this coin, including recoups as /* get historic transaction costs of this coin, including recoups as
we might be a zombie coin */ we might be a zombie coin */
qs = TEH_plugin->get_coin_transactions (TEH_plugin->cls, qs = TEH_plugin->get_coin_transactions (TEH_plugin->cls,
session, session,
@ -204,20 +201,23 @@ refresh_check_melt (struct MHD_Connection *connection,
} }
if (rmc->zombie_required) if (rmc->zombie_required)
{ {
/* The denomination key is only usable for a melt if this is a true
zombie coin, i.e. it was refreshed and the resulting fresh coin was
then recouped. Check that this is truly the case. */
for (struct TALER_EXCHANGEDB_TransactionList *tp = tl; for (struct TALER_EXCHANGEDB_TransactionList *tp = tl;
NULL != tp; NULL != tp;
tp = tp->next) tp = tp->next)
{ {
if (TALER_EXCHANGEDB_TT_OLD_COIN_RECOUP == tp->type) if (TALER_EXCHANGEDB_TT_OLD_COIN_RECOUP == tp->type)
{ {
rmc->zombie_required = GNUNET_NO; /* was satisfied! */ rmc->zombie_required = GNUNET_NO; /* clear flag: was satisfied! */
break; break;
} }
} }
if (rmc->zombie_required) if (GNUNET_YES == rmc->zombie_required)
{ {
/* zombie status not satisfied */ /* zombie status not satisfied */
GNUNET_break (0); GNUNET_break_op (0);
TEH_plugin->free_coin_transaction_list (TEH_plugin->cls, TEH_plugin->free_coin_transaction_list (TEH_plugin->cls,
tl); tl);
*mhd_ret = TALER_MHD_reply_with_error (connection, *mhd_ret = TALER_MHD_reply_with_error (connection,
@ -244,8 +244,8 @@ refresh_check_melt (struct MHD_Connection *connection,
/* Refuse to refresh when the coin's value is insufficient /* Refuse to refresh when the coin's value is insufficient
for the cost of all transactions. */ for the cost of all transactions. */
if (TALER_amount_cmp (&rmc->coin_value, if (0 > TALER_amount_cmp (&rmc->coin_value,
&spent) < 0) &spent))
{ {
struct TALER_Amount coin_residual; struct TALER_Amount coin_residual;
@ -253,13 +253,12 @@ refresh_check_melt (struct MHD_Connection *connection,
TALER_amount_subtract (&coin_residual, TALER_amount_subtract (&coin_residual,
&spent, &spent,
&rmc->refresh_session.amount_with_fee)); &rmc->refresh_session.amount_with_fee));
*mhd_ret = reply_melt_insufficient_funds (connection, *mhd_ret = reply_melt_insufficient_funds (
&rmc->refresh_session.coin connection,
.coin_pub, &rmc->refresh_session.coin.coin_pub,
&rmc->coin_value, &rmc->coin_value,
tl, tl,
&rmc->refresh_session. &rmc->refresh_session.amount_with_fee,
amount_with_fee,
&coin_residual); &coin_residual);
TEH_plugin->free_coin_transaction_list (TEH_plugin->cls, TEH_plugin->free_coin_transaction_list (TEH_plugin->cls,
tl); tl);
@ -274,7 +273,7 @@ refresh_check_melt (struct MHD_Connection *connection,
/** /**
* Execute a "/refresh/melt". We have been given a list of valid * Execute a "melt". We have been given a list of valid
* coins and a request to melt them into the given @a * coins and a request to melt them into the given @a
* refresh_session_pub. Check that the coins all have the required * refresh_session_pub. Check that the coins all have the required
* value left and if so, store that they have been melted and confirm * value left and if so, store that they have been melted and confirm
@ -286,7 +285,7 @@ refresh_check_melt (struct MHD_Connection *connection,
* the soft error code, the function MAY be called again to retry and * the soft error code, the function MAY be called again to retry and
* MUST not queue a MHD response. * MUST not queue a MHD response.
* *
* @param cls our `struct RefreshMeltContext` * @param cls our `struct MeltContext`
* @param connection MHD request which triggered the transaction * @param connection MHD request which triggered the transaction
* @param session database session to use * @param session database session to use
* @param[out] mhd_ret set to MHD response status for @a connection, * @param[out] mhd_ret set to MHD response status for @a connection,
@ -299,18 +298,18 @@ melt_transaction (void *cls,
struct TALER_EXCHANGEDB_Session *session, struct TALER_EXCHANGEDB_Session *session,
int *mhd_ret) int *mhd_ret)
{ {
struct RefreshMeltContext *rmc = cls; struct MeltContext *rmc = cls;
enum GNUNET_DB_QueryStatus qs; enum GNUNET_DB_QueryStatus qs;
uint32_t noreveal_index; uint32_t noreveal_index;
/* Check if we already created such a session */ /* Check if we already created a matching refresh_session */
qs = TEH_plugin->get_melt_index (TEH_plugin->cls, qs = TEH_plugin->get_melt_index (TEH_plugin->cls,
session, session,
&rmc->refresh_session.rc, &rmc->refresh_session.rc,
&noreveal_index); &noreveal_index);
if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs) if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs)
{ {
TALER_LOG_DEBUG ("Found already-melted coin\n"); TALER_LOG_DEBUG ("Coin was previously melted, returning old reply\n");
*mhd_ret = reply_melt_success (connection, *mhd_ret = reply_melt_success (connection,
&rmc->refresh_session.rc, &rmc->refresh_session.rc,
noreveal_index); noreveal_index);
@ -335,13 +334,12 @@ melt_transaction (void *cls,
rmc, rmc,
mhd_ret); mhd_ret);
if (0 > qs) if (0 > qs)
return qs; return qs; /* if we failed, tell caller */
/* pick challenge and persist it */ /* pick challenge and persist it */
rmc->refresh_session.noreveal_index rmc->refresh_session.noreveal_index
= GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_STRONG, = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_STRONG,
TALER_CNC_KAPPA); TALER_CNC_KAPPA);
if (0 >= if (0 >=
(qs = TEH_plugin->insert_melt (TEH_plugin->cls, (qs = TEH_plugin->insert_melt (TEH_plugin->cls,
session, session,
@ -362,7 +360,7 @@ melt_transaction (void *cls,
/** /**
* Handle a "/refresh/melt" request after the first parsing has * Handle a "melt" request after the first parsing has
* happened. We now need to validate the coins being melted and the * happened. We now need to validate the coins being melted and the
* session signature and then hand things of to execute the melt * session signature and then hand things of to execute the melt
* operation. This function parses the JSON arrays and then passes * operation. This function parses the JSON arrays and then passes
@ -374,9 +372,8 @@ melt_transaction (void *cls,
*/ */
static int static int
handle_melt (struct MHD_Connection *connection, handle_melt (struct MHD_Connection *connection,
struct RefreshMeltContext *rmc) struct MeltContext *rmc)
{ {
/* verify signature of coin for melt operation */ /* verify signature of coin for melt operation */
{ {
struct TALER_RefreshMeltCoinAffirmationPS body; struct TALER_RefreshMeltCoinAffirmationPS body;
@ -392,12 +389,11 @@ handle_melt (struct MHD_Connection *connection,
body.coin_pub = rmc->refresh_session.coin.coin_pub; body.coin_pub = rmc->refresh_session.coin.coin_pub;
if (GNUNET_OK != if (GNUNET_OK !=
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_MELT, GNUNET_CRYPTO_eddsa_verify (
TALER_SIGNATURE_WALLET_COIN_MELT,
&body.purpose, &body.purpose,
&rmc->refresh_session.coin_sig. &rmc->refresh_session.coin_sig.eddsa_signature,
eddsa_signature, &rmc->refresh_session.coin.coin_pub.eddsa_pub))
&rmc->refresh_session.coin.coin_pub.
eddsa_pub))
{ {
GNUNET_break_op (0); GNUNET_break_op (0);
return TALER_MHD_reply_with_error (connection, return TALER_MHD_reply_with_error (connection,
@ -407,7 +403,7 @@ handle_melt (struct MHD_Connection *connection,
} }
} }
/* run transaction */ /* run database transaction */
{ {
int mhd_ret; int mhd_ret;
@ -420,7 +416,7 @@ handle_melt (struct MHD_Connection *connection,
return mhd_ret; return mhd_ret;
} }
/* generate ordinary response */ /* Success. Generate ordinary response. */
return reply_melt_success (connection, return reply_melt_success (connection,
&rmc->refresh_session.rc, &rmc->refresh_session.rc,
rmc->refresh_session.noreveal_index); rmc->refresh_session.noreveal_index);
@ -437,9 +433,10 @@ handle_melt (struct MHD_Connection *connection,
*/ */
static int static int
check_for_denomination_key (struct MHD_Connection *connection, check_for_denomination_key (struct MHD_Connection *connection,
struct RefreshMeltContext *rmc) struct MeltContext *rmc)
{ {
struct TEH_KS_StateHandle *key_state; struct TEH_KS_StateHandle *key_state;
int coin_is_dirty = GNUNET_NO;
key_state = TEH_KS_acquire (GNUNET_TIME_absolute_get ()); key_state = TEH_KS_acquire (GNUNET_TIME_absolute_get ());
if (NULL == key_state) if (NULL == key_state)
@ -458,9 +455,9 @@ check_for_denomination_key (struct MHD_Connection *connection,
unsigned int hc; unsigned int hc;
enum TALER_ErrorCode ec; enum TALER_ErrorCode ec;
dki = TEH_KS_denomination_key_lookup_by_hash (key_state, dki = TEH_KS_denomination_key_lookup_by_hash (
&rmc->refresh_session.coin. key_state,
denom_pub_hash, &rmc->refresh_session.coin.denom_pub_hash,
TEH_KS_DKU_DEPOSIT, TEH_KS_DKU_DEPOSIT,
&ec, &ec,
&hc); &hc);
@ -468,9 +465,9 @@ check_for_denomination_key (struct MHD_Connection *connection,
this coin was already seen and thus refresh is OK. */ this coin was already seen and thus refresh is OK. */
if (NULL == dki) if (NULL == dki)
{ {
dki = TEH_KS_denomination_key_lookup_by_hash (key_state, dki = TEH_KS_denomination_key_lookup_by_hash (
&rmc->refresh_session.coin. key_state,
denom_pub_hash, &rmc->refresh_session.coin.denom_pub_hash,
TEH_KS_DKU_RECOUP, TEH_KS_DKU_RECOUP,
&ec, &ec,
&hc); &hc);
@ -479,19 +476,25 @@ check_for_denomination_key (struct MHD_Connection *connection,
struct GNUNET_HashCode denom_hash; struct GNUNET_HashCode denom_hash;
enum GNUNET_DB_QueryStatus qs; enum GNUNET_DB_QueryStatus qs;
qs = TEH_plugin->get_coin_denomination (TEH_plugin->cls, /* Check that the coin is dirty (we have seen it before), as we will
not just allow melting of a *fresh* coin where the denomination was
revoked (those must be recouped) */
qs = TEH_plugin->get_coin_denomination (
TEH_plugin->cls,
NULL, NULL,
&rmc->refresh_session.coin. &rmc->refresh_session.coin.coin_pub,
coin_pub,
&denom_hash); &denom_hash);
if (0 > qs) if (0 > qs)
{ {
TEH_KS_release (key_state); TEH_KS_release (key_state);
/* There is no good reason for a serialization failure here: */
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR != qs);
return TALER_MHD_reply_with_error (connection, return TALER_MHD_reply_with_error (connection,
MHD_HTTP_INTERNAL_SERVER_ERROR, MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_REFRESH_MELT_DB_FETCH_ERROR, TALER_EC_REFRESH_MELT_DB_FETCH_ERROR,
"failed to find information about old coin"); "failed to find information about old coin");
} }
/* sanity check */
GNUNET_break (0 == GNUNET_break (0 ==
GNUNET_memcmp (&denom_hash, GNUNET_memcmp (&denom_hash,
&rmc->refresh_session.coin.denom_pub_hash)); &rmc->refresh_session.coin.denom_pub_hash));
@ -500,11 +503,17 @@ check_for_denomination_key (struct MHD_Connection *connection,
/* We never saw this coin before, so _this_ justification is not OK */ /* We never saw this coin before, so _this_ justification is not OK */
dki = NULL; dki = NULL;
} }
else
{
/* Minor optimization: no need to run the
#TEH_DB_know_coin_transaction below */
coin_is_dirty = GNUNET_YES;
}
} }
} }
/* Consider the case that the denomination expired for deposits, /* Consider the case that the denomination expired for deposits, but
but /refresh/recoup refilled the balance of the 'zombie' coin recoup of a refreshed coin refilled the balance of the 'zombie' coin
and we should thus allow the refresh during the legal period. */ and we should thus allow the refresh during the legal period. */
if (NULL == dki) if (NULL == dki)
{ {
@ -515,21 +524,35 @@ check_for_denomination_key (struct MHD_Connection *connection,
&ec, &ec,
&hc); &hc);
if (NULL != dki) if (NULL != dki)
rmc->zombie_required = GNUNET_YES; rmc->zombie_required = GNUNET_YES; /* check later that zombie is satisfied */
} }
if (NULL == dki) if (NULL == dki)
{ {
TEH_KS_release (key_state); TEH_KS_release (key_state);
TALER_LOG_WARNING ("Unknown denomination key in /refresh/melt request\n");
return TALER_MHD_reply_with_error (connection, return TALER_MHD_reply_with_error (connection,
hc, hc,
ec, ec,
"unknown denomination"); "unknown denomination");
} }
TALER_amount_ntoh (&rmc->coin_refresh_fee, TALER_amount_ntoh (&rmc->coin_refresh_fee,
&dki->issue.properties.fee_refresh); &dki->issue.properties.fee_refresh);
TALER_amount_ntoh (&rmc->coin_value, TALER_amount_ntoh (&rmc->coin_value,
&dki->issue.properties.value); &dki->issue.properties.value);
/* check client used sane currency */
if (GNUNET_YES !=
TALER_amount_cmp_currency (&rmc->refresh_session.amount_with_fee,
&rmc->coin_value) )
{
GNUNET_break_op (0);
TEH_KS_release (key_state);
return TALER_MHD_reply_with_error (connection,
MHD_HTTP_BAD_REQUEST,
TALER_EC_MELT_CURRENCY_MISSMATCH,
"value_with_fee");
}
/* check coin is actually properly signed */
if (GNUNET_OK != if (GNUNET_OK !=
TALER_test_coin_valid (&rmc->refresh_session.coin, TALER_test_coin_valid (&rmc->refresh_session.coin,
&dki->denom_pub)) &dki->denom_pub))
@ -545,7 +568,8 @@ check_for_denomination_key (struct MHD_Connection *connection,
TEH_KS_release (key_state); TEH_KS_release (key_state);
/* run actual logic, now that the request was parsed */ /* run actual logic, now that the request was parsed */
/* make sure coin is 'known' in database */ /* First, make sure coin is 'known' in database */
if (GNUNET_NO == coin_is_dirty)
{ {
struct TEH_DB_KnowCoinContext kcc; struct TEH_DB_KnowCoinContext kcc;
int mhd_ret; int mhd_ret;
@ -554,7 +578,7 @@ check_for_denomination_key (struct MHD_Connection *connection,
kcc.connection = connection; kcc.connection = connection;
if (GNUNET_OK != if (GNUNET_OK !=
TEH_DB_run_transaction (connection, TEH_DB_run_transaction (connection,
"know coin for refresh-melt", "know coin for melt",
&mhd_ret, &mhd_ret,
&TEH_DB_know_coin_transaction, &TEH_DB_know_coin_transaction,
&kcc)) &kcc))
@ -562,8 +586,9 @@ check_for_denomination_key (struct MHD_Connection *connection,
} }
/* sanity-check that "total melt amount > melt fee" */ /* sanity-check that "total melt amount > melt fee" */
if (TALER_amount_cmp (&rmc->coin_refresh_fee, if (0 <
&rmc->refresh_session.amount_with_fee) > 0) TALER_amount_cmp (&rmc->coin_refresh_fee,
&rmc->refresh_session.amount_with_fee))
{ {
GNUNET_break_op (0); GNUNET_break_op (0);
return TALER_MHD_reply_with_error (connection, return TALER_MHD_reply_with_error (connection,
@ -592,7 +617,7 @@ TEH_handler_melt (struct MHD_Connection *connection,
const struct TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_CoinSpendPublicKeyP *coin_pub,
const json_t *root) const json_t *root)
{ {
struct RefreshMeltContext rmc; struct MeltContext rmc;
int res; int res;
struct GNUNET_JSON_Specification spec[] = { struct GNUNET_JSON_Specification spec[] = {
TALER_JSON_spec_denomination_signature ("denom_sig", TALER_JSON_spec_denomination_signature ("denom_sig",

View File

@ -422,7 +422,7 @@ verify_and_execute_recoup (struct MHD_Connection *connection,
const struct TALER_EXCHANGEDB_DenominationKey *dki; const struct TALER_EXCHANGEDB_DenominationKey *dki;
struct TALER_RecoupRequestPS pr; struct TALER_RecoupRequestPS pr;
struct GNUNET_HashCode c_hash; struct GNUNET_HashCode c_hash;
char *coin_ev; void *coin_ev;
size_t coin_ev_size; size_t coin_ev_size;
enum TALER_ErrorCode ec; enum TALER_ErrorCode ec;
unsigned int hc; unsigned int hc;

View File

@ -45,7 +45,7 @@
/** /**
* Send a response for "/refresh/reveal". * Send a response for "/refreshes/$RCH/reveal".
* *
* @param connection the connection to send the response to * @param connection the connection to send the response to
* @param num_freshcoins number of new coins for which we reveal data * @param num_freshcoins number of new coins for which we reveal data
@ -53,7 +53,7 @@
* @return a MHD result code * @return a MHD result code
*/ */
static int static int
reply_refresh_reveal_success (struct MHD_Connection *connection, reply_refreshes_reveal_success (struct MHD_Connection *connection,
unsigned int num_freshcoins, unsigned int num_freshcoins,
const struct TALER_DenominationSignature *sigs) const struct TALER_DenominationSignature *sigs)
{ {
@ -102,7 +102,7 @@ reply_refresh_reveal_success (struct MHD_Connection *connection,
* @return a MHD result code * @return a MHD result code
*/ */
static int static int
reply_refresh_reveal_mismatch (struct MHD_Connection *connection, reply_refreshes_reveal_mismatch (struct MHD_Connection *connection,
const struct TALER_RefreshCommitmentP *rc) const struct TALER_RefreshCommitmentP *rc)
{ {
return TALER_MHD_reply_json_pack (connection, return TALER_MHD_reply_json_pack (connection,
@ -236,7 +236,7 @@ check_exists_cb (void *cls,
* @return transaction status * @return transaction status
*/ */
static enum GNUNET_DB_QueryStatus static enum GNUNET_DB_QueryStatus
refresh_reveal_preflight (void *cls, refreshes_reveal_preflight (void *cls,
struct MHD_Connection *connection, struct MHD_Connection *connection,
struct TALER_EXCHANGEDB_Session *session, struct TALER_EXCHANGEDB_Session *session,
int *mhd_ret) int *mhd_ret)
@ -293,7 +293,7 @@ refresh_reveal_preflight (void *cls,
* @return transaction status * @return transaction status
*/ */
static enum GNUNET_DB_QueryStatus static enum GNUNET_DB_QueryStatus
refresh_reveal_transaction (void *cls, refreshes_reveal_transaction (void *cls,
struct MHD_Connection *connection, struct MHD_Connection *connection,
struct TALER_EXCHANGEDB_Session *session, struct TALER_EXCHANGEDB_Session *session,
int *mhd_ret) int *mhd_ret)
@ -411,7 +411,7 @@ refresh_reveal_transaction (void *cls,
&rc_expected)) &rc_expected))
{ {
GNUNET_break_op (0); GNUNET_break_op (0);
*mhd_ret = reply_refresh_reveal_mismatch (connection, *mhd_ret = reply_refreshes_reveal_mismatch (connection,
&rc_expected); &rc_expected);
return GNUNET_DB_STATUS_HARD_ERROR; return GNUNET_DB_STATUS_HARD_ERROR;
} }
@ -475,7 +475,7 @@ refresh_reveal_transaction (void *cls,
* @return transaction status * @return transaction status
*/ */
static enum GNUNET_DB_QueryStatus static enum GNUNET_DB_QueryStatus
refresh_reveal_persist (void *cls, refreshes_reveal_persist (void *cls,
struct MHD_Connection *connection, struct MHD_Connection *connection,
struct TALER_EXCHANGEDB_Session *session, struct TALER_EXCHANGEDB_Session *session,
int *mhd_ret) int *mhd_ret)
@ -529,7 +529,7 @@ refresh_reveal_persist (void *cls,
* @return MHD result code * @return MHD result code
*/ */
static int static int
resolve_refresh_reveal_denominations (struct TEH_KS_StateHandle *key_state, resolve_refreshes_reveal_denominations (struct TEH_KS_StateHandle *key_state,
struct MHD_Connection *connection, struct MHD_Connection *connection,
struct RevealContext *rctx, struct RevealContext *rctx,
const json_t *link_sigs_json, const json_t *link_sigs_json,
@ -537,8 +537,8 @@ resolve_refresh_reveal_denominations (struct TEH_KS_StateHandle *key_state,
const json_t *coin_evs) const json_t *coin_evs)
{ {
unsigned int num_fresh_coins = json_array_size (new_denoms_h_json); unsigned int num_fresh_coins = json_array_size (new_denoms_h_json);
const struct /* We know num_fresh_coins is bounded by #MAX_FRESH_COINS, so this is safe */
TALER_EXCHANGEDB_DenominationKey *dkis[num_fresh_coins]; const struct TALER_EXCHANGEDB_DenominationKey *dkis[num_fresh_coins];
struct GNUNET_HashCode dki_h[num_fresh_coins]; struct GNUNET_HashCode dki_h[num_fresh_coins];
struct TALER_RefreshCoinData rcds[num_fresh_coins]; struct TALER_RefreshCoinData rcds[num_fresh_coins];
struct TALER_CoinSpendSignatureP link_sigs[num_fresh_coins]; struct TALER_CoinSpendSignatureP link_sigs[num_fresh_coins];
@ -577,6 +577,8 @@ resolve_refresh_reveal_denominations (struct TEH_KS_StateHandle *key_state,
ec, ec,
"failed to find denomination key"); "failed to find denomination key");
} }
/* #TEH_KS_DKU_WITHDRAW should warrant that we only get denomination
keys where we did not yet forget the private key */
GNUNET_assert (NULL != dkis[i]->denom_priv.rsa_private_key); GNUNET_assert (NULL != dkis[i]->denom_priv.rsa_private_key);
} }
@ -586,7 +588,7 @@ resolve_refresh_reveal_denominations (struct TEH_KS_StateHandle *key_state,
struct TALER_RefreshCoinData *rcd = &rcds[i]; struct TALER_RefreshCoinData *rcd = &rcds[i];
struct GNUNET_JSON_Specification spec[] = { struct GNUNET_JSON_Specification spec[] = {
GNUNET_JSON_spec_varsize (NULL, GNUNET_JSON_spec_varsize (NULL,
(void **) &rcd->coin_ev, &rcd->coin_ev,
&rcd->coin_ev_size), &rcd->coin_ev_size),
GNUNET_JSON_spec_end () GNUNET_JSON_spec_end ()
}; };
@ -723,13 +725,13 @@ resolve_refresh_reveal_denominations (struct TEH_KS_StateHandle *key_state,
TEH_DB_run_transaction (connection, TEH_DB_run_transaction (connection,
"reveal pre-check", "reveal pre-check",
&res, &res,
&refresh_reveal_preflight, &refreshes_reveal_preflight,
rctx)) && rctx)) &&
(GNUNET_YES == rctx->preflight_ok) ) (GNUNET_YES == rctx->preflight_ok) )
{ {
/* Generate final (positive) response */ /* Generate final (positive) response */
GNUNET_assert (NULL != rctx->ev_sigs); GNUNET_assert (NULL != rctx->ev_sigs);
res = reply_refresh_reveal_success (connection, res = reply_refreshes_reveal_success (connection,
num_fresh_coins, num_fresh_coins,
rctx->ev_sigs); rctx->ev_sigs);
GNUNET_break (MHD_NO != res); GNUNET_break (MHD_NO != res);
@ -744,7 +746,7 @@ resolve_refresh_reveal_denominations (struct TEH_KS_StateHandle *key_state,
TEH_DB_run_transaction (connection, TEH_DB_run_transaction (connection,
"run reveal", "run reveal",
&res, &res,
&refresh_reveal_transaction, &refreshes_reveal_transaction,
rctx)) rctx))
{ {
/* reveal failed, too bad */ /* reveal failed, too bad */
@ -755,12 +757,12 @@ resolve_refresh_reveal_denominations (struct TEH_KS_StateHandle *key_state,
TEH_DB_run_transaction (connection, TEH_DB_run_transaction (connection,
"persist reveal", "persist reveal",
&res, &res,
&refresh_reveal_persist, &refreshes_reveal_persist,
rctx)) rctx))
{ {
/* Generate final (positive) response */ /* Generate final (positive) response */
GNUNET_assert (NULL != rctx->ev_sigs); GNUNET_assert (NULL != rctx->ev_sigs);
res = reply_refresh_reveal_success (connection, res = reply_refreshes_reveal_success (connection,
num_fresh_coins, num_fresh_coins,
rctx->ev_sigs); rctx->ev_sigs);
break; break;
@ -785,9 +787,9 @@ cleanup:
/** /**
* Handle a "/refresh/reveal" request. Parses the given JSON * Handle a "/refreshes/$RCH/reveal" request. Parses the given JSON
* transfer private keys and if successful, passes everything to * transfer private keys and if successful, passes everything to
* #resolve_refresh_reveal_denominations() which will verify that the * #resolve_refreshes_reveal_denominations() which will verify that the
* revealed information is valid then returns the signed refreshed * revealed information is valid then returns the signed refreshed
* coins. * coins.
* *
@ -800,7 +802,7 @@ cleanup:
* @return MHD result code * @return MHD result code
*/ */
static int static int
handle_refresh_reveal_json (struct MHD_Connection *connection, handle_refreshes_reveal_json (struct MHD_Connection *connection,
struct RevealContext *rctx, struct RevealContext *rctx,
const json_t *tp_json, const json_t *tp_json,
const json_t *link_sigs_json, const json_t *link_sigs_json,
@ -810,7 +812,7 @@ handle_refresh_reveal_json (struct MHD_Connection *connection,
unsigned int num_fresh_coins = json_array_size (new_denoms_h_json); unsigned int num_fresh_coins = json_array_size (new_denoms_h_json);
unsigned int num_tprivs = json_array_size (tp_json); unsigned int num_tprivs = json_array_size (tp_json);
GNUNET_assert (num_tprivs == TALER_CNC_KAPPA - 1); GNUNET_assert (num_tprivs == TALER_CNC_KAPPA - 1); /* checked just earlier */
if ( (num_fresh_coins >= MAX_FRESH_COINS) || if ( (num_fresh_coins >= MAX_FRESH_COINS) ||
(0 == num_fresh_coins) ) (0 == num_fresh_coins) )
{ {
@ -871,7 +873,7 @@ handle_refresh_reveal_json (struct MHD_Connection *connection,
TALER_EC_REFRESH_REVEAL_KEYS_MISSING, TALER_EC_REFRESH_REVEAL_KEYS_MISSING,
"exchange lacks keys"); "exchange lacks keys");
} }
ret = resolve_refresh_reveal_denominations (key_state, ret = resolve_refreshes_reveal_denominations (key_state,
connection, connection,
rctx, rctx,
link_sigs_json, link_sigs_json,
@ -887,9 +889,9 @@ handle_refresh_reveal_json (struct MHD_Connection *connection,
* Handle a "/refreshes/$RCH/reveal" request. This time, the client reveals the * Handle a "/refreshes/$RCH/reveal" request. This time, the client reveals the
* private transfer keys except for the cut-and-choose value returned from * private transfer keys except for the cut-and-choose value returned from
* "/coins/$COIN_PUB/melt". This function parses the revealed keys and secrets and * "/coins/$COIN_PUB/melt". This function parses the revealed keys and secrets and
* ultimately passes everything to #resolve_refresh_reveal_denominations() * ultimately passes everything to #resolve_refreshes_reveal_denominations()
* which will verify that the revealed information is valid then runs the * which will verify that the revealed information is valid then runs the
* transaction in #refresh_reveal_transaction() and finally returns the signed * transaction in #refreshes_reveal_transaction() and finally returns the signed
* refreshed coins. * refreshed coins.
* *
* @param rh context of the handler * @param rh context of the handler
@ -904,7 +906,6 @@ TEH_handler_reveal (const struct TEH_RequestHandler *rh,
const json_t *root, const json_t *root,
const char *const args[2]) const char *const args[2])
{ {
int res;
json_t *coin_evs; json_t *coin_evs;
json_t *transfer_privs; json_t *transfer_privs;
json_t *link_sigs; json_t *link_sigs;
@ -923,7 +924,6 @@ TEH_handler_reveal (const struct TEH_RequestHandler *rh,
memset (&rctx, memset (&rctx,
0, 0,
sizeof (rctx)); sizeof (rctx));
if (GNUNET_OK != if (GNUNET_OK !=
GNUNET_STRINGS_string_to_data (args[0], GNUNET_STRINGS_string_to_data (args[0],
strlen (args[0]), strlen (args[0]),
@ -945,6 +945,10 @@ TEH_handler_reveal (const struct TEH_RequestHandler *rh,
TALER_EC_OPERATION_INVALID, TALER_EC_OPERATION_INVALID,
"expected 'reveal' operation"); "expected 'reveal' operation");
} }
{
int res;
res = TALER_MHD_parse_json_data (connection, res = TALER_MHD_parse_json_data (connection,
root, root,
spec); spec);
@ -953,6 +957,7 @@ TEH_handler_reveal (const struct TEH_RequestHandler *rh,
GNUNET_break_op (0); GNUNET_break_op (0);
return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES; return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES;
} }
}
/* Check we got enough transfer private keys */ /* Check we got enough transfer private keys */
/* Note we do +1 as 1 row (cut-and-choose!) is missing! */ /* Note we do +1 as 1 row (cut-and-choose!) is missing! */
@ -965,7 +970,11 @@ TEH_handler_reveal (const struct TEH_RequestHandler *rh,
TALER_EC_REFRESH_REVEAL_CNC_TRANSFER_ARRAY_SIZE_INVALID, TALER_EC_REFRESH_REVEAL_CNC_TRANSFER_ARRAY_SIZE_INVALID,
"transfer_privs"); "transfer_privs");
} }
res = handle_refresh_reveal_json (connection,
{
int res;
res = handle_refreshes_reveal_json (connection,
&rctx, &rctx,
transfer_privs, transfer_privs,
link_sigs, link_sigs,
@ -974,6 +983,7 @@ TEH_handler_reveal (const struct TEH_RequestHandler *rh,
GNUNET_JSON_parse_free (spec); GNUNET_JSON_parse_free (spec);
return res; return res;
} }
}
/* end of taler-exchange-httpd_refresh_reveal.c */ /* end of taler-exchange-httpd_refreshes_reveal.c */

View File

@ -241,7 +241,7 @@ TALER_EXCHANGEDB_denomination_key_write (
(wrote != (ssize_t) wsize) ) (wrote != (ssize_t) wsize) )
goto cleanup; goto cleanup;
{ {
char *priv_enc; void *priv_enc;
size_t priv_enc_size; size_t priv_enc_size;
priv_enc_size priv_enc_size

View File

@ -455,7 +455,7 @@ struct TALER_PlanchetDetail
/** /**
* Blinded coin (see GNUNET_CRYPTO_rsa_blind()). Note: is malloc()'ed! * Blinded coin (see GNUNET_CRYPTO_rsa_blind()). Note: is malloc()'ed!
*/ */
char *coin_ev; void *coin_ev;
/** /**
* Number of bytes in @a coin_ev. * Number of bytes in @a coin_ev.
@ -683,7 +683,7 @@ struct TALER_RefreshCoinData
/** /**
* The envelope with the blinded coin. * The envelope with the blinded coin.
*/ */
char *coin_ev; void *coin_ev;
/** /**
* Number of bytes in @a coin_ev * Number of bytes in @a coin_ev

View File

@ -329,7 +329,7 @@ TALER_refresh_get_commitment (struct TALER_RefreshCommitmentP *rc,
hash_context */ hash_context */
for (unsigned int i = 0; i<num_new_coins; i++) for (unsigned int i = 0; i<num_new_coins; i++)
{ {
char *buf; void *buf;
size_t buf_size; size_t buf_size;
/* The denomination keys should / must all be identical regardless /* The denomination keys should / must all be identical regardless