first steps on #5777

This commit is contained in:
Christian Grothoff 2019-06-26 23:58:48 +02:00
parent 9a69fd81ed
commit 19e0b66f87
No known key found for this signature in database
GPG Key ID: 939E6BE1E29FC3CC
4 changed files with 82 additions and 4 deletions

View File

@ -1907,6 +1907,9 @@ TEH_KS_denomination_key_lookup_by_hash (const struct TEH_KS_StateHandle *key_sta
map = (TEH_KS_DKU_PAYBACK == use) ? key_state->revoked_map : key_state->denomkey_map;
dki = GNUNET_CONTAINER_multihashmap_get (map,
denom_pub_hash);
if ( (NULL == dki) && (TEH_KS_DKU_ZOMBIE == use))
dki = GNUNET_CONTAINER_multihashmap_get (key_state->revoked_map,
denom_pub_hash);
if (NULL == dki)
return NULL;
now = GNUNET_TIME_absolute_get ();
@ -1958,6 +1961,16 @@ TEH_KS_denomination_key_lookup_by_hash (const struct TEH_KS_StateHandle *key_sta
return NULL;
}
break;
case TEH_KS_DKU_ZOMBIE:
if (now.abs_value_us >
GNUNET_TIME_absolute_ntoh (dki->issue.properties.expire_legal).abs_value_us)
{
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Not returning DKI for %s, as legal expiration of coin has passed\n",
GNUNET_h2s (denom_pub_hash));
return NULL;
}
break;
}
return dki;
}

View File

@ -109,7 +109,14 @@ enum TEH_KS_DenominationKeyUse {
/**
* The key is to be used for a /payback operation.
*/
TEH_KS_DKU_PAYBACK
TEH_KS_DKU_PAYBACK,
/**
* The key is to be used for a /refresh/payback operation,
* i.e. it is an old coin that regained value from a
* payback on a new coin derived from the old coin.
*/
TEH_KS_DKU_ZOMBIE
};

View File

@ -1,6 +1,6 @@
/*
This file is part of TALER
Copyright (C) 2014-2019 Inria & GNUnet e.V.
Copyright (C) 2014-2019 Taler Systems SA
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
@ -173,12 +173,12 @@ refresh_check_melt (struct MHD_Connection *connection,
session,
&rmc->refresh_session.coin.coin_pub,
GNUNET_NO,
&tl);
&tl);
if (0 > qs)
{
if (GNUNET_DB_STATUS_HARD_ERROR == qs)
*mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection,
TALER_EC_REFRESH_MELT_DB_FETCH_ERROR);
TALER_EC_REFRESH_MELT_DB_FETCH_ERROR);
return qs;
}
if (GNUNET_OK !=
@ -453,9 +453,64 @@ TEH_REFRESH_handler_refresh_melt (struct TEH_RequestHandler *rh,
"no keys");
goto cleanup;
}
/* Baseline: check if deposits/refreshs are generally
simply still allowed for this denomination */
rmc.dki = TEH_KS_denomination_key_lookup_by_hash (key_state,
&rmc.refresh_session.coin.denom_pub_hash,
TEH_KS_DKU_DEPOSIT);
/* Consider case that denomination was revoked but
this coin was already seen and thus refresh is OK. */
if (NULL == rmc.dki)
{
struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki;
dki = TEH_KS_denomination_key_lookup_by_hash (key_state,
&rmc.refresh_session.coin.denom_pub_hash,
TEH_KS_DKU_PAYBACK);
if (NULL != dki)
{
struct TALER_CoinPublicInfo coin_info;
enum GNUNET_DB_QueryStatus qs;
qs = TEH_plugin->get_known_coin (TEH_plugin->cls,
NULL,
&rmc.refresh_session.coin.coin_pub,
&coin_info);
if (0 > qs)
{
GNUNET_break (0);
res = TEH_RESPONSE_reply_internal_db_error (connection,
TALER_EC_REFRESH_MELT_DB_FETCH_ERROR);
goto cleanup;
}
if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs)
{
/* Coin was known beforehand, so we should allow the refresh */
rmc.dki = dki;
GNUNET_CRYPTO_rsa_signature_free (coin_info.denom_sig.rsa_signature);
}
}
}
/* Consider the case that the denomination expired for deposits,
but /refresh/payback refilled the balance of the 'zombie' coin
and we should thus allow the refresh during the legal period. */
if (NULL == rmc.dki)
{
struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki;
dki = TEH_KS_denomination_key_lookup_by_hash (key_state,
&rmc.refresh_session.coin.denom_pub_hash,
TEH_KS_DKU_ZOMBIE);
if (NULL != dki)
{
/* Test if zombie-condition is actually satisfied for the coin */
if (0 /* FIXME: test if zombie-satisfied */)
rmc.dki = dki;
}
}
if (NULL == rmc.dki)
{
TALER_LOG_WARNING ("Unknown denomination key in /refresh/melt request\n");

View File

@ -3304,6 +3304,7 @@ postgres_get_known_coin (void *cls,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
struct TALER_CoinPublicInfo *coin_info)
{
struct PostgresClosure *pc = cls;
struct GNUNET_PQ_QueryParam params[] = {
GNUNET_PQ_query_param_auto_from_type (coin_pub),
GNUNET_PQ_query_param_end
@ -3320,6 +3321,8 @@ postgres_get_known_coin (void *cls,
"Getting known coin data for coin %s\n",
TALER_B2S (coin_pub));
coin_info->coin_pub = *coin_pub;
if (NULL == session)
session = postgres_get_session (pc);
return GNUNET_PQ_eval_prepared_singleton_select (session->conn,
"get_known_coin",
params,