return revoked denom hashes under payback array in /keys

This commit is contained in:
Christian Grothoff 2017-04-08 20:08:44 +02:00
parent 47d03e227a
commit d2f970c964
No known key found for this signature in database
GPG Key ID: 939E6BE1E29FC3CC

View File

@ -1,6 +1,6 @@
/* /*
This file is part of TALER This file is part of TALER
Copyright (C) 2014, 2015 GNUnet e.V. Copyright (C) 2014-2017 GNUnet e.V.
TALER is free software; you can redistribute it and/or modify it under the 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 terms of the GNU Affero General Public License as published by the Free Software
@ -58,6 +58,12 @@ struct TEH_KS_StateHandle
*/ */
json_t *auditors_array; json_t *auditors_array;
/**
* JSON array with revoked denomination keys. (Currently not really used
* after initialization).
*/
json_t *payback_array;
/** /**
* Cached JSON text that the exchange will send for a "/keys" request. * Cached JSON text that the exchange will send for a "/keys" request.
* Includes our @e TEH_master_public_key public key, the signing and * Includes our @e TEH_master_public_key public key, the signing and
@ -71,6 +77,12 @@ struct TEH_KS_StateHandle
*/ */
struct GNUNET_CONTAINER_MultiHashMap *denomkey_map; struct GNUNET_CONTAINER_MultiHashMap *denomkey_map;
/**
* Mapping from revoked denomination keys to denomination key issue struct.
* Used to lookup the key by hash.
*/
struct GNUNET_CONTAINER_MultiHashMap *revoked_map;
/** /**
* Hash context we used to combine the hashes of all denomination * Hash context we used to combine the hashes of all denomination
* keys into one big hash. * keys into one big hash.
@ -204,6 +216,45 @@ TALER_EXCHANGE_conf_duration_provide ()
} }
/**
* Store a copy of @a dki in @a map.
*
* @param map hash map to store @a dki in
* @param dki information to store in @a map
* @return #GNUNET_OK on success,
* #GNUNET_NO if such an entry already exists
*/
static int
store_in_map (struct GNUNET_CONTAINER_MultiHashMap *map,
const struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki)
{
struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *d2;
int res;
d2 = GNUNET_new (struct TALER_EXCHANGEDB_DenominationKeyIssueInformation);
d2->issue = dki->issue;
d2->denom_priv.rsa_private_key
= GNUNET_CRYPTO_rsa_private_key_dup (dki->denom_priv.rsa_private_key);
d2->denom_pub.rsa_public_key
= GNUNET_CRYPTO_rsa_public_key_dup (dki->denom_pub.rsa_public_key);
res = GNUNET_CONTAINER_multihashmap_put (map,
&d2->issue.properties.denom_hash,
d2,
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
if (GNUNET_OK != res)
{
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"Duplicate denomination key `%s'\n",
GNUNET_h2s (&d2->issue.properties.denom_hash));
GNUNET_CRYPTO_rsa_private_key_free (d2->denom_priv.rsa_private_key);
GNUNET_CRYPTO_rsa_public_key_free (d2->denom_pub.rsa_public_key);
GNUNET_free (d2);
return GNUNET_NO;
}
return GNUNET_OK;
}
/** /**
* Iterator for (re)loading/initializing denomination keys. * Iterator for (re)loading/initializing denomination keys.
* *
@ -226,22 +277,12 @@ reload_keys_denom_iter (void *cls,
struct GNUNET_TIME_Absolute horizon; struct GNUNET_TIME_Absolute horizon;
struct GNUNET_TIME_Absolute expire_deposit; struct GNUNET_TIME_Absolute expire_deposit;
struct GNUNET_HashCode denom_key_hash; struct GNUNET_HashCode denom_key_hash;
struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *d2;
struct TALER_EXCHANGEDB_Session *session; struct TALER_EXCHANGEDB_Session *session;
int res; int res;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Loading denomination key `%s'\n", "Loading denomination key `%s'\n",
alias); alias);
horizon = GNUNET_TIME_relative_to_absolute (TALER_EXCHANGE_conf_duration_provide ());
if (GNUNET_TIME_absolute_ntoh (dki->issue.properties.start).abs_value_us >
horizon.abs_value_us)
{
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Skipping future denomination key `%s'\n",
alias);
return GNUNET_OK;
}
now = GNUNET_TIME_absolute_get (); now = GNUNET_TIME_absolute_get ();
expire_deposit = GNUNET_TIME_absolute_ntoh (dki->issue.properties.expire_deposit); expire_deposit = GNUNET_TIME_absolute_ntoh (dki->issue.properties.expire_deposit);
if (expire_deposit.abs_value_us < now.abs_value_us) if (expire_deposit.abs_value_us < now.abs_value_us)
@ -251,6 +292,26 @@ reload_keys_denom_iter (void *cls,
alias); alias);
return GNUNET_OK; return GNUNET_OK;
} }
if (GNUNET_YES == was_revoked)
{
res = store_in_map (ctx->revoked_map,
dki);
if (GNUNET_NO == res)
return GNUNET_OK;
GNUNET_assert (0 ==
json_array_append_new (ctx->payback_array,
GNUNET_JSON_from_data_auto (&dki->issue.properties.denom_hash)));
return GNUNET_OK;
}
horizon = GNUNET_TIME_relative_to_absolute (TALER_EXCHANGE_conf_duration_provide ());
if (GNUNET_TIME_absolute_ntoh (dki->issue.properties.start).abs_value_us >
horizon.abs_value_us)
{
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Skipping future denomination key `%s'\n",
alias);
return GNUNET_OK;
}
GNUNET_CRYPTO_rsa_public_key_hash (dki->denom_pub.rsa_public_key, GNUNET_CRYPTO_rsa_public_key_hash (dki->denom_pub.rsa_public_key,
&denom_key_hash); &denom_key_hash);
@ -327,26 +388,10 @@ reload_keys_denom_iter (void *cls,
as it is possible we just retry until we succeed. */ as it is possible we just retry until we succeed. */
} }
d2 = GNUNET_new (struct TALER_EXCHANGEDB_DenominationKeyIssueInformation); res = store_in_map (ctx->denomkey_map,
d2->issue = dki->issue; dki);
d2->denom_priv.rsa_private_key if (GNUNET_NO == res)
= GNUNET_CRYPTO_rsa_private_key_dup (dki->denom_priv.rsa_private_key);
d2->denom_pub.rsa_public_key
= GNUNET_CRYPTO_rsa_public_key_dup (dki->denom_pub.rsa_public_key);
res = GNUNET_CONTAINER_multihashmap_put (ctx->denomkey_map,
&denom_key_hash,
d2,
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
if (GNUNET_OK != res)
{
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"Duplicate denomination key `%s'\n",
alias);
GNUNET_CRYPTO_rsa_private_key_free (d2->denom_priv.rsa_private_key);
GNUNET_CRYPTO_rsa_public_key_free (d2->denom_pub.rsa_public_key);
GNUNET_free (d2);
return GNUNET_OK; return GNUNET_OK;
}
ctx->min_dk_expire = GNUNET_TIME_absolute_min (ctx->min_dk_expire, ctx->min_dk_expire = GNUNET_TIME_absolute_min (ctx->min_dk_expire,
expire_deposit); expire_deposit);
GNUNET_assert (0 == GNUNET_assert (0 ==
@ -594,6 +639,11 @@ ks_release_ (struct TEH_KS_StateHandle *key_state)
json_decref (key_state->denom_keys_array); json_decref (key_state->denom_keys_array);
key_state->denom_keys_array = NULL; key_state->denom_keys_array = NULL;
} }
if (NULL != key_state->payback_array)
{
json_decref (key_state->payback_array);
key_state->payback_array = NULL;
}
if (NULL != key_state->sign_keys_array) if (NULL != key_state->sign_keys_array)
{ {
json_decref (key_state->sign_keys_array); json_decref (key_state->sign_keys_array);
@ -607,6 +657,14 @@ ks_release_ (struct TEH_KS_StateHandle *key_state)
GNUNET_CONTAINER_multihashmap_destroy (key_state->denomkey_map); GNUNET_CONTAINER_multihashmap_destroy (key_state->denomkey_map);
key_state->denomkey_map = NULL; key_state->denomkey_map = NULL;
} }
if (NULL != key_state->revoked_map)
{
GNUNET_CONTAINER_multihashmap_iterate (key_state->revoked_map,
&free_denom_key,
key_state);
GNUNET_CONTAINER_multihashmap_destroy (key_state->revoked_map);
key_state->revoked_map = NULL;
}
GNUNET_free_non_null (key_state->keys_json); GNUNET_free_non_null (key_state->keys_json);
GNUNET_free (key_state); GNUNET_free (key_state);
} }
@ -662,6 +720,9 @@ TEH_KS_acquire_ (const char *location)
key_state->denom_keys_array = json_array (); key_state->denom_keys_array = json_array ();
GNUNET_assert (NULL != key_state->denom_keys_array); GNUNET_assert (NULL != key_state->denom_keys_array);
key_state->payback_array = json_array ();
GNUNET_assert (NULL != key_state->payback_array);
key_state->sign_keys_array = json_array (); key_state->sign_keys_array = json_array ();
GNUNET_assert (NULL != key_state->sign_keys_array); GNUNET_assert (NULL != key_state->sign_keys_array);
@ -670,6 +731,8 @@ TEH_KS_acquire_ (const char *location)
key_state->denomkey_map = GNUNET_CONTAINER_multihashmap_create (32, key_state->denomkey_map = GNUNET_CONTAINER_multihashmap_create (32,
GNUNET_NO); GNUNET_NO);
key_state->revoked_map = GNUNET_CONTAINER_multihashmap_create (4,
GNUNET_NO);
key_state->reload_time = GNUNET_TIME_absolute_get (); key_state->reload_time = GNUNET_TIME_absolute_get ();
GNUNET_TIME_round_abs (&key_state->reload_time); GNUNET_TIME_round_abs (&key_state->reload_time);
GNUNET_log (GNUNET_ERROR_TYPE_INFO, GNUNET_log (GNUNET_ERROR_TYPE_INFO,
@ -731,6 +794,7 @@ TEH_KS_acquire_ (const char *location)
GNUNET_JSON_from_data_auto (&TEH_master_public_key), GNUNET_JSON_from_data_auto (&TEH_master_public_key),
"signkeys", key_state->sign_keys_array, "signkeys", key_state->sign_keys_array,
"denoms", key_state->denom_keys_array, "denoms", key_state->denom_keys_array,
"payback", key_state->payback_array,
"auditors", key_state->auditors_array, "auditors", key_state->auditors_array,
"list_issue_date", GNUNET_JSON_from_time_abs (key_state->reload_time), "list_issue_date", GNUNET_JSON_from_time_abs (key_state->reload_time),
"eddsa_pub", GNUNET_JSON_from_data_auto (&key_state->current_sign_key_issue.issue.signkey_pub), "eddsa_pub", GNUNET_JSON_from_data_auto (&key_state->current_sign_key_issue.issue.signkey_pub),
@ -739,6 +803,7 @@ TEH_KS_acquire_ (const char *location)
key_state->auditors_array = NULL; key_state->auditors_array = NULL;
key_state->sign_keys_array = NULL; key_state->sign_keys_array = NULL;
key_state->denom_keys_array = NULL; key_state->denom_keys_array = NULL;
key_state->payback_array = NULL;
key_state->keys_json = json_dumps (keys, key_state->keys_json = json_dumps (keys,
JSON_INDENT (2)); JSON_INDENT (2));
GNUNET_assert (NULL != key_state->keys_json); GNUNET_assert (NULL != key_state->keys_json);
@ -770,10 +835,12 @@ TEH_KS_denomination_key_lookup (const struct TEH_KS_StateHandle *key_state,
struct GNUNET_HashCode hc; struct GNUNET_HashCode hc;
struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki; struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki;
struct GNUNET_TIME_Absolute now; struct GNUNET_TIME_Absolute now;
const struct GNUNET_CONTAINER_MultiHashMap *map;
GNUNET_CRYPTO_rsa_public_key_hash (denom_pub->rsa_public_key, GNUNET_CRYPTO_rsa_public_key_hash (denom_pub->rsa_public_key,
&hc); &hc);
dki = GNUNET_CONTAINER_multihashmap_get (key_state->denomkey_map, map = (TEH_KS_DKU_PAYBACK == use) ? key_state->revoked_map : key_state->denomkey_map;
dki = GNUNET_CONTAINER_multihashmap_get (map,
&hc); &hc);
if (NULL == dki) if (NULL == dki)
return NULL; return NULL;
@ -810,9 +877,16 @@ TEH_KS_denomination_key_lookup (const struct TEH_KS_StateHandle *key_state,
} }
break; break;
case TEH_KS_DKU_PAYBACK: case TEH_KS_DKU_PAYBACK:
GNUNET_break (0); /* not implemented (#3887) */ if (now.abs_value_us >
GNUNET_TIME_absolute_ntoh (dki->issue.properties.expire_deposit).abs_value_us)
{
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Not returning DKI for %s, as time to payback coin has passed\n",
GNUNET_h2s (&hc));
return NULL; return NULL;
} }
break;
}
return dki; return dki;
} }