aboutsummaryrefslogtreecommitdiff
path: root/src/auditor/taler-auditor.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2019-07-27 20:06:55 +0200
committerChristian Grothoff <christian@grothoff.org>2019-07-27 20:06:55 +0200
commit1057333666ad3aa17568255f0b7ffa1a2d9bcf40 (patch)
tree54a0f26b9cb3971e9bd1b6d33b2d7d654db86215 /src/auditor/taler-auditor.c
parent19c4feda562ca09ecef5c79d29fae36169ea9900 (diff)
add check that denomination was actually revoked if it is involved in /payback
Diffstat (limited to 'src/auditor/taler-auditor.c')
-rw-r--r--src/auditor/taler-auditor.c67
1 files changed, 57 insertions, 10 deletions
diff --git a/src/auditor/taler-auditor.c b/src/auditor/taler-auditor.c
index a63ac8bd0..c8becdaa5 100644
--- a/src/auditor/taler-auditor.c
+++ b/src/auditor/taler-auditor.c
@@ -30,8 +30,6 @@
* (While as the exchange could easily falsify those, we should
* probably check as otherwise insider *without* RSA private key
* access could still create false paybacks to drain exchange funds!)
- * - we don't check that for payback operations the denomination was actually
- * revoked (FIXME exists!)
* - error handling if denomination keys are used that are not known to the
* auditor is, eh, awful / non-existent. We just throw the DB's constraint
* violation back at the user. Great UX.
@@ -581,7 +579,7 @@ static struct GNUNET_CONTAINER_MultiHashMap *denominations;
*/
static enum GNUNET_DB_QueryStatus
get_denomination_info_by_hash (const struct GNUNET_HashCode *dh,
- const struct TALER_EXCHANGEDB_DenominationKeyInformationP **dki)
+ const struct TALER_EXCHANGEDB_DenominationKeyInformationP **dki)
{
struct TALER_EXCHANGEDB_DenominationKeyInformationP *dkip;
enum GNUNET_DB_QueryStatus qs;
@@ -964,8 +962,8 @@ handle_reserve_out (void *cls,
/* lookup denomination pub data (make sure denom_pub is valid, establish fees) */
qs = get_denomination_info (denom_pub,
- &dki,
- &wsrd.h_denomination_pub);
+ &dki,
+ &wsrd.h_denomination_pub);
if (0 > qs)
{
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
@@ -2897,6 +2895,11 @@ struct DenominationSummary
* #sync_denomination().
*/
int in_db;
+
+ /**
+ * #GNUNET_YES if this denomination was revoked.
+ */
+ int was_revoked;
};
@@ -2936,6 +2939,8 @@ init_denomination (const struct GNUNET_HashCode *denom_hash,
struct DenominationSummary *ds)
{
enum GNUNET_DB_QueryStatus qs;
+ struct TALER_MasterSignatureP msig;
+ uint64_t rowid;
qs = adb->get_denomination_balance (adb->cls,
asession,
@@ -2958,6 +2963,39 @@ init_denomination (const struct GNUNET_HashCode *denom_hash,
TALER_amount2s (&ds->denom_balance));
return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
}
+ qs = edb->get_denomination_revocation (edb->cls,
+ esession,
+ denom_hash,
+ &msig,
+ &rowid);
+ if (0 > qs)
+ {
+ GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
+ return qs;
+ }
+ if (0 < qs)
+ {
+ /* check revocation signature */
+ struct TALER_MasterDenominationKeyRevocationPS rm;
+
+ rm.purpose.purpose = htonl (TALER_SIGNATURE_MASTER_DENOMINATION_KEY_REVOKED);
+ rm.purpose.size = htonl (sizeof (rm));
+ rm.h_denom_pub = *denom_hash;
+ if (GNUNET_OK !=
+ GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MASTER_DENOMINATION_KEY_REVOKED,
+ &rm.purpose,
+ &msig.eddsa_signature,
+ &master_pub.eddsa_pub))
+ {
+ report_row_inconsistency ("denomination revocation table",
+ rowid,
+ "revocation signature invalid");
+ }
+ else
+ {
+ ds->was_revoked = GNUNET_YES;
+ }
+ }
GNUNET_assert (GNUNET_OK ==
TALER_amount_get_zero (currency,
&ds->denom_balance));
@@ -3351,8 +3389,8 @@ refresh_session_cb (void *cls,
ppc.last_melt_serial_id = rowid + 1;
qs = get_denomination_info (denom_pub,
- &dki,
- NULL);
+ &dki,
+ NULL);
if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs)
{
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
@@ -3686,8 +3724,8 @@ deposit_cb (void *cls,
ppc.last_deposit_serial_id = rowid + 1;
qs = get_denomination_info (denom_pub,
- &dki,
- NULL);
+ &dki,
+ NULL);
if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs)
{
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
@@ -4023,7 +4061,16 @@ check_payback (struct CoinContext *cc,
ds = get_denomination_summary (cc,
dki,
&dki->properties.denom_hash);
- /* FIXME: should check that denomination was actually revoked! */
+ if (GNUNET_NO == ds->was_revoked)
+ {
+ /* Woopsie, we allowed payback on non-revoked denomination!? */
+ report (report_bad_sig_losses,
+ json_pack ("{s:s, s:I, s:o, s:o}",
+ "operation", "payback (denomination not revoked)",
+ "row", (json_int_t) rowid,
+ "loss", TALER_JSON_from_amount (amount),
+ "coin_pub", GNUNET_JSON_from_data_auto (&coin->coin_pub)));
+ }
GNUNET_break (GNUNET_OK ==
TALER_amount_add (&ds->denom_payback,
&ds->denom_payback,