implement checking of denomination revocation status in auditor

This commit is contained in:
Christian Grothoff 2017-04-08 22:52:32 +02:00
parent 8e9d6c6fd1
commit 11b8710a5c
No known key found for this signature in database
GPG Key ID: 939E6BE1E29FC3CC
8 changed files with 106 additions and 26 deletions

View File

@ -831,6 +831,8 @@ handle_payback_by_reserve (void *cls,
struct ReserveSummary *rs; struct ReserveSummary *rs;
struct GNUNET_TIME_Absolute expiry; struct GNUNET_TIME_Absolute expiry;
struct TALER_PaybackRequestPS pr; struct TALER_PaybackRequestPS pr;
struct TALER_MasterSignatureP msig;
int ret;
/* should be monotonically increasing */ /* should be monotonically increasing */
GNUNET_assert (rowid >= pp.last_reserve_payback_serial_id); GNUNET_assert (rowid >= pp.last_reserve_payback_serial_id);
@ -859,7 +861,44 @@ handle_payback_by_reserve (void *cls,
rowid, rowid,
"coin payback signature invalid"); "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, GNUNET_CRYPTO_hash (reserve_pub,
sizeof (*reserve_pub), sizeof (*reserve_pub),

View File

@ -122,7 +122,7 @@ exchange_signkeys_check ()
* @param cls closure (NULL) * @param cls closure (NULL)
* @param dki the denomination key * @param dki the denomination key
* @param alias coin alias * @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, * @return #GNUNET_OK to continue to iterate,
* #GNUNET_NO to stop iteration with no error, * #GNUNET_NO to stop iteration with no error,
* #GNUNET_SYSERR to abort iteration with error! * #GNUNET_SYSERR to abort iteration with error!
@ -131,7 +131,7 @@ static int
denomkeys_iter (void *cls, denomkeys_iter (void *cls,
const char *alias, const char *alias,
const struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki, const struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki,
int was_revoked) const struct TALER_MasterSignatureP *revocation_master_sig)
{ {
struct GNUNET_HashCode hc; struct GNUNET_HashCode hc;

View File

@ -1054,7 +1054,7 @@ struct RevokeClosure
* @param cls a `struct RevokeClosure` with information about what to revoke * @param cls a `struct RevokeClosure` with information about what to revoke
* @param dki the denomination key * @param dki the denomination key
* @param alias coin alias * @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, * @return #GNUNET_OK to continue to iterate,
* #GNUNET_NO to stop iteration with no error, * #GNUNET_NO to stop iteration with no error,
* #GNUNET_SYSERR to abort iteration with error! * #GNUNET_SYSERR to abort iteration with error!
@ -1063,11 +1063,11 @@ static int
exchange_keys_revoke_by_dki (void *cls, exchange_keys_revoke_by_dki (void *cls,
const char *alias, const char *alias,
const struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki, const struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki,
int was_revoked) const struct TALER_MasterSignatureP *revocation_master_sig)
{ {
struct RevokeClosure *rc = cls; struct RevokeClosure *rc = cls;
if (GNUNET_YES == was_revoked) if (NULL != revocation_master_sig)
return GNUNET_OK; /* refuse to do it twice */ return GNUNET_OK; /* refuse to do it twice */
if (0 != memcmp (rc->hc, if (0 != memcmp (rc->hc,
&dki->issue.properties.denom_hash, &dki->issue.properties.denom_hash,

View File

@ -261,7 +261,7 @@ store_in_map (struct GNUNET_CONTAINER_MultiHashMap *map,
* @param cls closure * @param cls closure
* @param dki the denomination key issue * @param dki the denomination key issue
* @param alias coin alias * @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, * @return #GNUNET_OK to continue to iterate,
* #GNUNET_NO to stop iteration with no error, * #GNUNET_NO to stop iteration with no error,
* #GNUNET_SYSERR to abort iteration with error! * #GNUNET_SYSERR to abort iteration with error!
@ -270,7 +270,7 @@ static int
reload_keys_denom_iter (void *cls, reload_keys_denom_iter (void *cls,
const char *alias, const char *alias,
const struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki, const struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki,
int was_revoked) const struct TALER_MasterSignatureP *revocation_master_sig)
{ {
struct TEH_KS_StateHandle *ctx = cls; struct TEH_KS_StateHandle *ctx = cls;
struct GNUNET_TIME_Absolute now; struct GNUNET_TIME_Absolute now;
@ -292,12 +292,61 @@ reload_keys_denom_iter (void *cls,
alias); alias);
return GNUNET_OK; 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, res = store_in_map (ctx->revoked_map,
dki); dki);
if (GNUNET_NO == res) if (GNUNET_NO == res)
return GNUNET_OK; 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 == GNUNET_assert (0 ==
json_array_append_new (ctx->payback_array, json_array_append_new (ctx->payback_array,
GNUNET_JSON_from_data_auto (&dki->issue.properties.denom_hash))); GNUNET_JSON_from_data_auto (&dki->issue.properties.denom_hash)));
@ -319,15 +368,6 @@ reload_keys_denom_iter (void *cls,
&denom_key_hash, &denom_key_hash,
sizeof (struct GNUNET_HashCode)); 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); session = TEH_plugin->get_session (TEH_plugin->cls);

View File

@ -257,7 +257,7 @@ denomkeys_iterate_keydir_iter (void *cls,
char *rev; char *rev;
struct TALER_MasterSignatureP msig; struct TALER_MasterSignatureP msig;
struct TALER_MasterDenominationKeyRevocation rm; struct TALER_MasterDenominationKeyRevocation rm;
int revoked; const struct TALER_MasterSignatureP *revoked;
if ( (strlen(filename) > strlen (".rev")) && if ( (strlen(filename) > strlen (".rev")) &&
(0 == strcmp (&filename[strlen(filename) - strlen (".rev")], (0 == strcmp (&filename[strlen(filename) - strlen (".rev")],
@ -278,7 +278,7 @@ denomkeys_iterate_keydir_iter (void *cls,
GNUNET_asprintf (&rev, GNUNET_asprintf (&rev,
"%s.rev", "%s.rev",
filename); filename);
revoked = GNUNET_NO; revoked = NULL;
if (GNUNET_YES == GNUNET_DISK_file_test (rev)) if (GNUNET_YES == GNUNET_DISK_file_test (rev))
{ {
/* Check if revocation is valid... */ /* Check if revocation is valid... */
@ -311,10 +311,9 @@ denomkeys_iterate_keydir_iter (void *cls,
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Denomination key `%s' was revoked!\n", "Denomination key `%s' was revoked!\n",
filename); filename);
revoked = GNUNET_YES; revoked = &msig;
} }
} }
} }
GNUNET_free (rev); GNUNET_free (rev);
ret = dic->it (dic->it_cls, ret = dic->it (dic->it_cls,

View File

@ -38,7 +38,7 @@
* @param cls closure with expected DKI * @param cls closure with expected DKI
* @param dki the denomination key * @param dki the denomination key
* @param alias coin alias * @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, * @return #GNUNET_OK to continue to iterate,
* #GNUNET_NO to stop iteration with no error, * #GNUNET_NO to stop iteration with no error,
* #GNUNET_SYSERR to abort iteration with error! * #GNUNET_SYSERR to abort iteration with error!
@ -47,7 +47,7 @@ static int
dki_iter (void *cls, dki_iter (void *cls,
const char *alias, const char *alias,
const struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki, const struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki,
int was_revoked) const struct TALER_MasterSignatureP *revocation_master_sig)
{ {
const struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *exp = cls; const struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *exp = cls;

View File

@ -162,7 +162,7 @@ TALER_EXCHANGEDB_signing_key_write (const char *exchange_base_dir,
* @param cls closure * @param cls closure
* @param alias coin alias * @param alias coin alias
* @param dki the denomination key * @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, * @return #GNUNET_OK to continue to iterate,
* #GNUNET_NO to stop iteration with no error, * #GNUNET_NO to stop iteration with no error,
* #GNUNET_SYSERR to abort iteration with error! * #GNUNET_SYSERR to abort iteration with error!
@ -171,7 +171,7 @@ typedef int
(*TALER_EXCHANGEDB_DenominationKeyIterator)(void *cls, (*TALER_EXCHANGEDB_DenominationKeyIterator)(void *cls,
const char *alias, const char *alias,
const struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki, const struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki,
int was_revoked); const struct TALER_MasterSignatureP *revocation_master_sig);
/** /**

View File

@ -2030,6 +2030,8 @@ struct TALER_EXCHANGEDB_Plugin
struct TALER_EXCHANGEDB_Session *session, struct TALER_EXCHANGEDB_Session *session,
const struct GNUNET_HashCode *denom_pub_hash, const struct GNUNET_HashCode *denom_pub_hash,
const struct TALER_MasterSignatureP *master_sig); const struct TALER_MasterSignatureP *master_sig);
/** /**
* Obtain information about a denomination key's revocation from * Obtain information about a denomination key's revocation from
* the database. * the database.