aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2017-04-08 22:52:32 +0200
committerChristian Grothoff <christian@grothoff.org>2017-04-08 22:52:32 +0200
commit11b8710a5caac9c81cb0eb6094b363fa46a74809 (patch)
treea83464349867a655c157e4aab5a4ed9e0bdc3471
parent8e9d6c6fd1dce2dc04258e91673baa083b291600 (diff)
implement checking of denomination revocation status in auditor
-rw-r--r--src/auditor/taler-auditor.c41
-rw-r--r--src/exchange-tools/taler-exchange-keycheck.c4
-rw-r--r--src/exchange-tools/taler-exchange-keyup.c6
-rw-r--r--src/exchange/taler-exchange-httpd_keystate.c64
-rw-r--r--src/exchangedb/exchangedb_denomkeys.c7
-rw-r--r--src/exchangedb/test_exchangedb_denomkeys.c4
-rw-r--r--src/include/taler_exchangedb_lib.h4
-rw-r--r--src/include/taler_exchangedb_plugin.h2
8 files changed, 106 insertions, 26 deletions
diff --git a/src/auditor/taler-auditor.c b/src/auditor/taler-auditor.c
index 5576bd6a2..c4fb025d2 100644
--- a/src/auditor/taler-auditor.c
+++ b/src/auditor/taler-auditor.c
@@ -831,6 +831,8 @@ handle_payback_by_reserve (void *cls,
struct ReserveSummary *rs;
struct GNUNET_TIME_Absolute expiry;
struct TALER_PaybackRequestPS pr;
+ struct TALER_MasterSignatureP msig;
+ int ret;
/* should be monotonically increasing */
GNUNET_assert (rowid >= pp.last_reserve_payback_serial_id);
@@ -859,7 +861,44 @@ handle_payback_by_reserve (void *cls,
rowid,
"coin payback signature invalid");
}
- /* TODO: check that the coin was eligible for payback! #3887!*/
+
+ /* check that the coin was eligible for payback!*/
+ ret = edb->get_denomination_revocation (edb->cls,
+ esession,
+ &pr.h_denom_pub,
+ &msig);
+ if (GNUNET_SYSERR == ret)
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ if (GNUNET_NO == ret)
+ {
+ report_row_inconsistency ("payback",
+ rowid,
+ "denomination key not in revocation set");
+ }
+ else
+ {
+ /* verify msig */
+ struct TALER_MasterDenominationKeyRevocation kr;
+
+ kr.purpose.purpose = htonl (TALER_SIGNATURE_MASTER_DENOMINATION_KEY_REVOKED);
+ kr.purpose.size = htonl (sizeof (kr));
+ kr.h_denom_pub = pr.h_denom_pub;
+ if (GNUNET_OK !=
+ GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MASTER_DENOMINATION_KEY_REVOKED,
+ &kr.purpose,
+ &msig.eddsa_signature,
+ &master_pub.eddsa_pub))
+ {
+ report_row_inconsistency ("denomination_revocations",
+ 0, /* FIXME: modify DB API to return rowid! (#4984) */
+ "master signature invalid");
+ }
+ /* TODO: cache result so we don't do this every time! (#4983) */
+ }
+
GNUNET_CRYPTO_hash (reserve_pub,
sizeof (*reserve_pub),
diff --git a/src/exchange-tools/taler-exchange-keycheck.c b/src/exchange-tools/taler-exchange-keycheck.c
index 3286cff4c..8018e3521 100644
--- a/src/exchange-tools/taler-exchange-keycheck.c
+++ b/src/exchange-tools/taler-exchange-keycheck.c
@@ -122,7 +122,7 @@ exchange_signkeys_check ()
* @param cls closure (NULL)
* @param dki the denomination key
* @param alias coin alias
- * @param was_revoked #GNUNET_YES if the @a dki was revoked and wallets should trigger /payback
+ * @param revocation_master_sig non-NULL if @a dki was revoked
* @return #GNUNET_OK to continue to iterate,
* #GNUNET_NO to stop iteration with no error,
* #GNUNET_SYSERR to abort iteration with error!
@@ -131,7 +131,7 @@ static int
denomkeys_iter (void *cls,
const char *alias,
const struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki,
- int was_revoked)
+ const struct TALER_MasterSignatureP *revocation_master_sig)
{
struct GNUNET_HashCode hc;
diff --git a/src/exchange-tools/taler-exchange-keyup.c b/src/exchange-tools/taler-exchange-keyup.c
index abf8793c7..f5e5961f0 100644
--- a/src/exchange-tools/taler-exchange-keyup.c
+++ b/src/exchange-tools/taler-exchange-keyup.c
@@ -1054,7 +1054,7 @@ struct RevokeClosure
* @param cls a `struct RevokeClosure` with information about what to revoke
* @param dki the denomination key
* @param alias coin alias
- * @param was_revoked #GNUNET_YES if the @a dki was revoked and wallets should trigger /payback
+ * @param revocation_master_sig non-NULL if @a dki was revoked
* @return #GNUNET_OK to continue to iterate,
* #GNUNET_NO to stop iteration with no error,
* #GNUNET_SYSERR to abort iteration with error!
@@ -1063,11 +1063,11 @@ static int
exchange_keys_revoke_by_dki (void *cls,
const char *alias,
const struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki,
- int was_revoked)
+ const struct TALER_MasterSignatureP *revocation_master_sig)
{
struct RevokeClosure *rc = cls;
- if (GNUNET_YES == was_revoked)
+ if (NULL != revocation_master_sig)
return GNUNET_OK; /* refuse to do it twice */
if (0 != memcmp (rc->hc,
&dki->issue.properties.denom_hash,
diff --git a/src/exchange/taler-exchange-httpd_keystate.c b/src/exchange/taler-exchange-httpd_keystate.c
index a2025c9d5..2b7019594 100644
--- a/src/exchange/taler-exchange-httpd_keystate.c
+++ b/src/exchange/taler-exchange-httpd_keystate.c
@@ -261,7 +261,7 @@ store_in_map (struct GNUNET_CONTAINER_MultiHashMap *map,
* @param cls closure
* @param dki the denomination key issue
* @param alias coin alias
- * @param was_revoked #GNUNET_YES if @a dki has been revoked
+ * @param revocation_master_sig non-NULL if @a dki was revoked
* @return #GNUNET_OK to continue to iterate,
* #GNUNET_NO to stop iteration with no error,
* #GNUNET_SYSERR to abort iteration with error!
@@ -270,7 +270,7 @@ static int
reload_keys_denom_iter (void *cls,
const char *alias,
const struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki,
- int was_revoked)
+ const struct TALER_MasterSignatureP *revocation_master_sig)
{
struct TEH_KS_StateHandle *ctx = cls;
struct GNUNET_TIME_Absolute now;
@@ -292,12 +292,61 @@ reload_keys_denom_iter (void *cls,
alias);
return GNUNET_OK;
}
- if (GNUNET_YES == was_revoked)
+ if (0 != memcmp (&dki->issue.properties.master,
+ &TEH_master_public_key,
+ sizeof (struct TALER_MasterPublicKeyP)))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Master key in denomination key file `%s' does not match! Skipping it.\n",
+ alias);
+ return GNUNET_OK;
+ }
+
+ session = TEH_plugin->get_session (TEH_plugin->cls);
+ if (NULL == session)
+ return GNUNET_SYSERR;
+
+ if (NULL != revocation_master_sig)
{
res = store_in_map (ctx->revoked_map,
dki);
if (GNUNET_NO == res)
return GNUNET_OK;
+ /* Try to insert DKI into DB until we succeed; note that if the DB
+ failure is persistent, this code may loop forever (as there is no
+ sane alternative, we cannot continue without the DKI being in the
+ DB). */
+ res = GNUNET_SYSERR;
+ while (GNUNET_OK != res)
+ {
+ res = TEH_plugin->start (TEH_plugin->cls,
+ session);
+ if (GNUNET_OK != res)
+ {
+ /* Transaction start failed!? Very bad error, log and retry */
+ GNUNET_break (0);
+ continue;
+ }
+ res = TEH_plugin->insert_denomination_revocation (TEH_plugin->cls,
+ session,
+ &dki->issue.properties.denom_hash,
+ revocation_master_sig);
+ if (GNUNET_SYSERR == res)
+ {
+ GNUNET_break (0);
+ TEH_plugin->rollback (TEH_plugin->cls,
+ session);
+ continue;
+ }
+ if (GNUNET_NO == res)
+ {
+ TEH_plugin->rollback (TEH_plugin->cls,
+ session);
+ break; /* already in is also OK! */
+ }
+ res = TEH_plugin->commit (TEH_plugin->cls,
+ session);
+ }
GNUNET_assert (0 ==
json_array_append_new (ctx->payback_array,
GNUNET_JSON_from_data_auto (&dki->issue.properties.denom_hash)));
@@ -319,15 +368,6 @@ reload_keys_denom_iter (void *cls,
&denom_key_hash,
sizeof (struct GNUNET_HashCode));
- if (0 != memcmp (&dki->issue.properties.master,
- &TEH_master_public_key,
- sizeof (struct TALER_MasterPublicKeyP)))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Master key in denomination key file `%s' does not match! Skipping it.\n",
- alias);
- return GNUNET_OK;
- }
session = TEH_plugin->get_session (TEH_plugin->cls);
diff --git a/src/exchangedb/exchangedb_denomkeys.c b/src/exchangedb/exchangedb_denomkeys.c
index bfc3ab8eb..017960277 100644
--- a/src/exchangedb/exchangedb_denomkeys.c
+++ b/src/exchangedb/exchangedb_denomkeys.c
@@ -257,7 +257,7 @@ denomkeys_iterate_keydir_iter (void *cls,
char *rev;
struct TALER_MasterSignatureP msig;
struct TALER_MasterDenominationKeyRevocation rm;
- int revoked;
+ const struct TALER_MasterSignatureP *revoked;
if ( (strlen(filename) > strlen (".rev")) &&
(0 == strcmp (&filename[strlen(filename) - strlen (".rev")],
@@ -278,7 +278,7 @@ denomkeys_iterate_keydir_iter (void *cls,
GNUNET_asprintf (&rev,
"%s.rev",
filename);
- revoked = GNUNET_NO;
+ revoked = NULL;
if (GNUNET_YES == GNUNET_DISK_file_test (rev))
{
/* Check if revocation is valid... */
@@ -311,10 +311,9 @@ denomkeys_iterate_keydir_iter (void *cls,
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Denomination key `%s' was revoked!\n",
filename);
- revoked = GNUNET_YES;
+ revoked = &msig;
}
}
-
}
GNUNET_free (rev);
ret = dic->it (dic->it_cls,
diff --git a/src/exchangedb/test_exchangedb_denomkeys.c b/src/exchangedb/test_exchangedb_denomkeys.c
index e7803c2ef..fb728115a 100644
--- a/src/exchangedb/test_exchangedb_denomkeys.c
+++ b/src/exchangedb/test_exchangedb_denomkeys.c
@@ -38,7 +38,7 @@
* @param cls closure with expected DKI
* @param dki the denomination key
* @param alias coin alias
- * @param was_revoked #GNUNET_YES if revoked
+ * @param revocation_master_sig non-NULL if @a dki was revoked
* @return #GNUNET_OK to continue to iterate,
* #GNUNET_NO to stop iteration with no error,
* #GNUNET_SYSERR to abort iteration with error!
@@ -47,7 +47,7 @@ static int
dki_iter (void *cls,
const char *alias,
const struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki,
- int was_revoked)
+ const struct TALER_MasterSignatureP *revocation_master_sig)
{
const struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *exp = cls;
diff --git a/src/include/taler_exchangedb_lib.h b/src/include/taler_exchangedb_lib.h
index d70270e8e..70ae3634a 100644
--- a/src/include/taler_exchangedb_lib.h
+++ b/src/include/taler_exchangedb_lib.h
@@ -162,7 +162,7 @@ TALER_EXCHANGEDB_signing_key_write (const char *exchange_base_dir,
* @param cls closure
* @param alias coin alias
* @param dki the denomination key
- * @param was_revoked #GNUNET_YES if the @a dki was revoked and wallets should trigger /payback
+ * @param revocation_master_sig non-NULL if @a dki was revoked
* @return #GNUNET_OK to continue to iterate,
* #GNUNET_NO to stop iteration with no error,
* #GNUNET_SYSERR to abort iteration with error!
@@ -171,7 +171,7 @@ typedef int
(*TALER_EXCHANGEDB_DenominationKeyIterator)(void *cls,
const char *alias,
const struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki,
- int was_revoked);
+ const struct TALER_MasterSignatureP *revocation_master_sig);
/**
diff --git a/src/include/taler_exchangedb_plugin.h b/src/include/taler_exchangedb_plugin.h
index 40499b2b2..a5295378b 100644
--- a/src/include/taler_exchangedb_plugin.h
+++ b/src/include/taler_exchangedb_plugin.h
@@ -2030,6 +2030,8 @@ struct TALER_EXCHANGEDB_Plugin
struct TALER_EXCHANGEDB_Session *session,
const struct GNUNET_HashCode *denom_pub_hash,
const struct TALER_MasterSignatureP *master_sig);
+
+
/**
* Obtain information about a denomination key's revocation from
* the database.