fix recoup-refresh audit logic

This commit is contained in:
Christian Grothoff 2020-03-26 20:54:41 +01:00
parent 394765a1e6
commit f052527ea5
No known key found for this signature in database
GPG Key ID: 939E6BE1E29FC3CC
4 changed files with 148 additions and 78 deletions

View File

@ -190,6 +190,10 @@ report_emergency_by_amount (
const struct TALER_Amount *risk,
const struct TALER_Amount *loss)
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Reporting emergency on denomination `%s' over loss of %s\n",
GNUNET_h2s (&issue->denom_hash),
TALER_amount2s (loss));
TALER_ARL_report (report_emergencies,
json_pack ("{s:o, s:o, s:o, s:o, s:o, s:o}",
"denompub_hash",
@ -808,14 +812,14 @@ withdraw_cb (void *cls,
GNUNET_h2s (&dh),
TALER_amount2s (&value));
ds->num_issued++;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"New balance of denomination `%s' is %s\n",
GNUNET_h2s (&dh),
TALER_amount2s (&ds->denom_balance));
GNUNET_assert (GNUNET_OK ==
TALER_amount_add (&ds->denom_balance,
&ds->denom_balance,
&value));
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"New balance of denomination `%s' is %s\n",
GNUNET_h2s (&dh),
TALER_amount2s (&ds->denom_balance));
GNUNET_assert (GNUNET_OK ==
TALER_amount_add (&total_escrow_balance,
&total_escrow_balance,
@ -1349,7 +1353,6 @@ deposit_cb (void *cls,
struct CoinContext *cc = cls;
const struct TALER_DenominationKeyValidityPS *issue;
struct DenominationSummary *ds;
struct TALER_Amount tmp;
enum GNUNET_DB_QueryStatus qs;
(void) wire_deadline;
@ -1459,6 +1462,8 @@ deposit_cb (void *cls,
}
else
{
struct TALER_Amount tmp;
if (GNUNET_SYSERR ==
TALER_amount_subtract (&tmp,
&ds->denom_balance,
@ -1696,7 +1701,6 @@ check_recoup (struct CoinContext *cc,
const struct TALER_CoinSpendSignatureP *coin_sig,
const struct TALER_DenominationBlindingKeyP *coin_blind)
{
struct TALER_RecoupRequestPS pr;
struct DenominationSummary *ds;
enum GNUNET_DB_QueryStatus qs;
const struct TALER_DenominationKeyValidityPS *issue;
@ -1711,15 +1715,14 @@ check_recoup (struct CoinContext *cc,
"row", (json_int_t) rowid,
"loss", TALER_JSON_from_amount (amount),
"key_pub", GNUNET_JSON_from_data_auto (
&pr.h_denom_pub)));
&coin->denom_pub_hash)));
GNUNET_assert (GNUNET_OK ==
TALER_amount_add (&total_bad_sig_loss,
&total_bad_sig_loss,
amount));
}
qs = TALER_ARL_get_denomination_info (denom_pub,
&issue,
&pr.h_denom_pub);
qs = TALER_ARL_get_denomination_info_by_hash (&coin->denom_pub_hash,
&issue);
if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
{
report_row_inconsistency ("recoup",
@ -1735,28 +1738,34 @@ check_recoup (struct CoinContext *cc,
cc->qs = qs;
return GNUNET_SYSERR;
}
pr.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_RECOUP);
pr.purpose.size = htonl (sizeof (pr));
pr.coin_pub = coin->coin_pub;
pr.coin_blind = *coin_blind;
if (GNUNET_OK !=
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_RECOUP,
&pr.purpose,
&coin_sig->eddsa_signature,
&coin->coin_pub.eddsa_pub))
{
TALER_ARL_report (report_bad_sig_losses,
json_pack ("{s:s, s:I, s:o, s:o}",
"operation", "recoup",
"row", (json_int_t) rowid,
"loss", TALER_JSON_from_amount (amount),
"coin_pub", GNUNET_JSON_from_data_auto (
&coin->coin_pub)));
GNUNET_assert (GNUNET_OK ==
TALER_amount_add (&total_bad_sig_loss,
&total_bad_sig_loss,
amount));
return GNUNET_OK;
struct TALER_RecoupRequestPS pr = {
.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_RECOUP),
.purpose.size = htonl (sizeof (pr)),
.coin_pub = coin->coin_pub,
.coin_blind = *coin_blind,
.h_denom_pub = coin->denom_pub_hash
};
if (GNUNET_OK !=
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_RECOUP,
&pr.purpose,
&coin_sig->eddsa_signature,
&coin->coin_pub.eddsa_pub))
{
TALER_ARL_report (report_bad_sig_losses,
json_pack ("{s:s, s:I, s:o, s:o}",
"operation", "recoup",
"row", (json_int_t) rowid,
"loss", TALER_JSON_from_amount (amount),
"coin_pub", GNUNET_JSON_from_data_auto (
&coin->coin_pub)));
GNUNET_assert (GNUNET_OK ==
TALER_amount_add (&total_bad_sig_loss,
&total_bad_sig_loss,
amount));
return GNUNET_OK;
}
}
ds = get_denomination_summary (cc,
issue,
@ -1803,7 +1812,7 @@ check_recoup (struct CoinContext *cc,
* @param amount how much should be added back to the reserve
* @param reserve_pub public key of the reserve
* @param coin public information about the coin
* @param denom_pub denomination public key of @a coin
* @param denom_pub_hash hash of denomination public key of @a coin
* @param coin_sig signature with @e coin_pub of type #TALER_SIGNATURE_WALLET_COIN_RECOUP
* @param coin_blind blinding factor used to blind the coin
* @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop
@ -1844,6 +1853,7 @@ recoup_cb (void *cls,
* @param timestamp when did we receive the recoup request
* @param amount how much should be added back to the reserve
* @param old_coin_pub original coin that was refreshed to create @a coin
* @param old_denom_pub public key of @a old_coin_pub
* @param coin public information about the coin
* @param denom_pub denomination public key of @a coin
* @param coin_sig signature with @e coin_pub of type #TALER_SIGNATURE_WALLET_COIN_RECOUP
@ -1856,17 +1866,65 @@ recoup_refresh_cb (void *cls,
struct GNUNET_TIME_Absolute timestamp,
const struct TALER_Amount *amount,
const struct TALER_CoinSpendPublicKeyP *old_coin_pub,
const struct GNUNET_HashCode *old_denom_pub_hash,
const struct TALER_CoinPublicInfo *coin,
const struct TALER_DenominationPublicKey *denom_pub,
const struct TALER_CoinSpendSignatureP *coin_sig,
const struct TALER_DenominationBlindingKeyP *coin_blind)
{
struct CoinContext *cc = cls;
const struct TALER_DenominationKeyValidityPS *issue;
enum GNUNET_DB_QueryStatus qs;
GNUNET_assert (rowid >= ppc.last_recoup_refresh_serial_id); /* should be monotonically increasing */
ppc.last_recoup_refresh_serial_id = rowid + 1;
(void) timestamp;
(void) old_coin_pub;
GNUNET_assert (rowid >= ppc.last_recoup_refresh_serial_id); /* should be monotonically increasing */
ppc.last_recoup_refresh_serial_id = rowid + 1;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Recoup-refresh amount is %s\n",
TALER_amount2s (amount));
/* Update old coin's denomination balance summary */
qs = TALER_ARL_get_denomination_info_by_hash (old_denom_pub_hash,
&issue);
if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS >= qs)
{
if (qs < 0)
{
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
cc->qs = qs;
return GNUNET_SYSERR;
}
report_row_inconsistency ("refresh-recoup",
rowid,
"denomination key of old coin not found");
}
else
{
struct DenominationSummary *dso;
dso = get_denomination_summary (cc,
issue,
old_denom_pub_hash);
if (NULL == dso)
{
report_row_inconsistency ("refresh_reveal",
rowid,
"denomination key for old coin unknown to auditor");
}
else
{
GNUNET_assert (GNUNET_OK ==
TALER_amount_add (&dso->denom_balance,
&dso->denom_balance,
amount));
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"New balance of denomination `%s' after refresh-recoup is %s\n",
GNUNET_h2s (&issue->denom_hash),
TALER_amount2s (&dso->denom_balance));
}
}
return check_recoup (cc,
rowid,
amount,
@ -1970,6 +2028,34 @@ analyze_coins (void *cls)
if (0 > cc.qs)
return cc.qs;
/* process recoups */
if (0 >
(qs = TALER_ARL_edb->select_recoup_refresh_above_serial_id (
TALER_ARL_edb->cls,
TALER_ARL_esession,
ppc.last_recoup_refresh_serial_id,
&recoup_refresh_cb,
&cc)))
{
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
return qs;
}
if (0 > cc.qs)
return cc.qs;
if (0 >
(qs = TALER_ARL_edb->select_recoup_above_serial_id (
TALER_ARL_edb->cls,
TALER_ARL_esession,
ppc.last_recoup_serial_id,
&recoup_cb,
&cc)))
{
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
return qs;
}
if (0 > cc.qs)
return cc.qs;
/* process refreshs */
if (0 >
(qs = TALER_ARL_edb->select_refreshes_above_serial_id (
@ -2000,34 +2086,6 @@ analyze_coins (void *cls)
if (0 > cc.qs)
return cc.qs;
/* process recoups */
if (0 >
(qs = TALER_ARL_edb->select_recoup_above_serial_id (
TALER_ARL_edb->cls,
TALER_ARL_esession,
ppc.last_recoup_serial_id,
&recoup_cb,
&cc)))
{
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
return qs;
}
if (0 > cc.qs)
return cc.qs;
if (0 >
(qs = TALER_ARL_edb->select_recoup_refresh_above_serial_id (
TALER_ARL_edb->cls,
TALER_ARL_esession,
ppc.last_recoup_refresh_serial_id,
&recoup_refresh_cb,
&cc)))
{
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
return qs;
}
if (0 > cc.qs)
return cc.qs;
/* sync 'cc' back to disk */
cc.qs = GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
GNUNET_CONTAINER_multihashmap_iterate (cc.denom_summaries,

View File

@ -1192,8 +1192,8 @@ postgres_get_session (void *cls)
",coin_blind"
",h_blind_ev"
",coins.denom_pub_hash"
",denoms.denom_pub"
",coins.denom_sig"
",denoms.denom_pub"
",amount_val"
",amount_frac"
" FROM recoup"
@ -1213,24 +1213,27 @@ postgres_get_session (void *cls)
" recoup_refresh_uuid"
",timestamp"
",rc.old_coin_pub"
",coin_pub"
",old_coins.denom_pub_hash AS old_denom_pub_hash"
",recoup_refresh.coin_pub"
",coin_sig"
",coin_blind"
",h_blind_ev"
",coins.denom_pub_hash"
",denoms.denom_pub"
",coins.denom_sig"
",h_blind_ev"
",new_coins.denom_pub_hash"
",new_coins.denom_sig"
",amount_val"
",amount_frac"
" FROM recoup_refresh"
" JOIN refresh_revealed_coins rrc"
" INNER JOIN refresh_revealed_coins rrc"
" ON (rrc.h_coin_ev = h_blind_ev)"
" JOIN refresh_commitments rc"
" INNER JOIN refresh_commitments rc"
" ON (rrc.rc = rc.rc)"
" JOIN known_coins coins"
" USING (coin_pub)"
" JOIN denominations denoms"
" ON (coins.denom_pub_hash = denoms.denom_pub_hash)"
" INNER JOIN known_coins old_coins"
" ON (rc.old_coin_pub = old_coins.coin_pub)"
" INNER JOIN known_coins new_coins"
" ON (new_coins.coin_pub = recoup_refresh.coin_pub)"
" INNER JOIN denominations denoms"
" ON (new_coins.denom_pub_hash = denoms.denom_pub_hash)"
" WHERE recoup_refresh_uuid>=$1"
" ORDER BY recoup_refresh_uuid ASC;",
1),
@ -6381,8 +6384,8 @@ recoup_serial_helper_cb (void *cls,
struct TALER_CoinPublicInfo coin;
struct TALER_CoinSpendSignatureP coin_sig;
struct TALER_DenominationBlindingKeyP coin_blind;
struct TALER_DenominationPublicKey denom_pub;
struct TALER_Amount amount;
struct TALER_DenominationPublicKey denom_pub;
struct GNUNET_HashCode h_blind_ev;
struct GNUNET_TIME_Absolute timestamp;
struct GNUNET_PQ_ResultSpec rs[] = {
@ -6394,6 +6397,8 @@ recoup_serial_helper_cb (void *cls,
&reserve_pub),
GNUNET_PQ_result_spec_auto_from_type ("coin_pub",
&coin.coin_pub),
GNUNET_PQ_result_spec_rsa_public_key ("denom_pub",
&denom_pub.rsa_public_key),
GNUNET_PQ_result_spec_auto_from_type ("coin_sig",
&coin_sig),
GNUNET_PQ_result_spec_auto_from_type ("coin_blind",
@ -6402,8 +6407,6 @@ recoup_serial_helper_cb (void *cls,
&h_blind_ev),
GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash",
&coin.denom_pub_hash),
GNUNET_PQ_result_spec_rsa_public_key ("denom_pub",
&denom_pub.rsa_public_key),
GNUNET_PQ_result_spec_rsa_signature ("denom_sig",
&coin.denom_sig.rsa_signature),
TALER_PQ_RESULT_SPEC_AMOUNT ("amount",
@ -6532,6 +6535,7 @@ recoup_refresh_serial_helper_cb (void *cls,
struct TALER_CoinSpendSignatureP coin_sig;
struct TALER_DenominationBlindingKeyP coin_blind;
struct TALER_DenominationPublicKey denom_pub;
struct GNUNET_HashCode old_denom_pub_hash;
struct TALER_Amount amount;
struct GNUNET_HashCode h_blind_ev;
struct GNUNET_TIME_Absolute timestamp;
@ -6542,18 +6546,20 @@ recoup_refresh_serial_helper_cb (void *cls,
&timestamp),
GNUNET_PQ_result_spec_auto_from_type ("old_coin_pub",
&old_coin_pub),
GNUNET_PQ_result_spec_auto_from_type ("old_denom_pub_hash",
&old_denom_pub_hash),
GNUNET_PQ_result_spec_auto_from_type ("coin_pub",
&coin.coin_pub),
GNUNET_PQ_result_spec_auto_from_type ("coin_sig",
&coin_sig),
GNUNET_PQ_result_spec_auto_from_type ("coin_blind",
&coin_blind),
GNUNET_PQ_result_spec_rsa_public_key ("denom_pub",
&denom_pub.rsa_public_key),
GNUNET_PQ_result_spec_auto_from_type ("h_blind_ev",
&h_blind_ev),
GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash",
&coin.denom_pub_hash),
GNUNET_PQ_result_spec_rsa_public_key ("denom_pub",
&denom_pub.rsa_public_key),
GNUNET_PQ_result_spec_rsa_signature ("denom_sig",
&coin.denom_sig.rsa_signature),
TALER_PQ_RESULT_SPEC_AMOUNT ("amount",
@ -6576,6 +6582,7 @@ recoup_refresh_serial_helper_cb (void *cls,
timestamp,
&amount,
&old_coin_pub,
&old_denom_pub_hash,
&coin,
&denom_pub,
&coin_sig,

View File

@ -1317,6 +1317,7 @@ drop:
* @param amount how much should be added back to the reserve
* @param reserve_pub public key of the reserve
* @param coin public information about the coin
* @param denom_pub denomination key of @a coin
* @param coin_sig signature with @e coin_pub of type #TALER_SIGNATURE_WALLET_COIN_RECOUP
* @param coin_blind blinding factor used to blind the coin
* @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop

View File

@ -1346,6 +1346,7 @@ typedef int
* @param amount how much should be added back to the reserve
* @param reserve_pub public key of the reserve
* @param coin public information about the coin
* @param denom_pub denomination key of @a coin
* @param coin_sig signature with @e coin_pub of type #TALER_SIGNATURE_WALLET_COIN_RECOUP
* @param coin_blind blinding factor used to blind the coin
* @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop
@ -1372,7 +1373,9 @@ typedef int
* @param timestamp when did we receive the recoup request
* @param amount how much should be added back to the reserve
* @param old_coin_pub original coin that was refreshed to create @a coin
* @param old_denom_pub_hash hash of public key of @a old_coin_pub
* @param coin public information about the coin
* @param denom_pub denomination key of @a coin
* @param coin_sig signature with @e coin_pub of type #TALER_SIGNATURE_WALLET_COIN_RECOUP
* @param coin_blind blinding factor used to blind the coin
* @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop
@ -1384,6 +1387,7 @@ typedef int
struct GNUNET_TIME_Absolute timestamp,
const struct TALER_Amount *amount,
const struct TALER_CoinSpendPublicKeyP *old_coin_pub,
const struct GNUNET_HashCode *old_denom_pub_hash,
const struct TALER_CoinPublicInfo *coin,
const struct TALER_DenominationPublicKey *denom_pub,
const struct TALER_CoinSpendSignatureP *coin_sig,