implementing private key deletion (#5536)
This commit is contained in:
parent
82ce84fe67
commit
a9268421d7
@ -1,3 +1,7 @@
|
||||
Mon Mar 11 03:24:07 CET 2019
|
||||
Completed implementation of #5536 (delete private keys once we
|
||||
no longer need them). -CG
|
||||
|
||||
Sat Mar 2 19:09:43 CET 2019
|
||||
Changing denomination key revocation file format and moving them
|
||||
to their own directory (preparations for #5536 resolution). -CG
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
This file is part of TALER
|
||||
Copyright (C) 2014-2017 GNUnet e.V.
|
||||
Copyright (C) 2014--2019 GNUnet e.V.
|
||||
|
||||
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
|
||||
@ -629,7 +629,19 @@ add_revocations_transaction (void *cls,
|
||||
int *mhd_ret)
|
||||
{
|
||||
struct AddRevocationContext *arc = cls;
|
||||
enum GNUNET_DB_QueryStatus qs;
|
||||
struct TALER_MasterSignatureP master_sig;
|
||||
uint64_t rowid;
|
||||
|
||||
qs = TEH_plugin->get_denomination_revocation (TEH_plugin->cls,
|
||||
session,
|
||||
&arc->dki->issue.properties.denom_hash,
|
||||
&master_sig,
|
||||
&rowid);
|
||||
if (0 > qs)
|
||||
return qs; /* failure */
|
||||
if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs)
|
||||
return qs; /* already exists == success */
|
||||
return TEH_plugin->insert_denomination_revocation (TEH_plugin->cls,
|
||||
session,
|
||||
&arc->dki->issue.properties.denom_hash,
|
||||
@ -692,7 +704,6 @@ reload_keys_denom_iter (void *cls,
|
||||
struct GNUNET_TIME_Absolute start;
|
||||
struct GNUNET_TIME_Absolute horizon;
|
||||
struct GNUNET_TIME_Absolute expire_deposit;
|
||||
int res;
|
||||
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
|
||||
"Loading denomination key `%s' (%s)\n",
|
||||
@ -747,10 +758,10 @@ reload_keys_denom_iter (void *cls,
|
||||
"Adding denomination key `%s' (%s) to active set\n",
|
||||
alias,
|
||||
GNUNET_h2s (&dki->issue.properties.denom_hash));
|
||||
res = store_in_map (key_state->denomkey_map,
|
||||
dki);
|
||||
if (GNUNET_NO == res)
|
||||
return GNUNET_OK;
|
||||
if (GNUNET_NO /* entry already exists */ ==
|
||||
store_in_map (key_state->denomkey_map,
|
||||
dki))
|
||||
return GNUNET_OK; /* do not update expiration if entry exists */
|
||||
key_state->min_dk_expire = GNUNET_TIME_absolute_min (key_state->min_dk_expire,
|
||||
expire_deposit);
|
||||
return GNUNET_OK;
|
||||
@ -774,51 +785,43 @@ revocations_iter (void *cls,
|
||||
{
|
||||
struct ResponseFactoryContext *rfc = cls;
|
||||
struct TEH_KS_StateHandle *key_state = rfc->key_state;
|
||||
int res;
|
||||
struct AddRevocationContext arc;
|
||||
const struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki;
|
||||
struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki;
|
||||
|
||||
dki = GNUNET_CONTAINER_multihashmap_get (key_state->denomkey_map,
|
||||
denom_hash);
|
||||
if (NULL == dki)
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
|
||||
"Revoked denomination `%s' unknown (or duplicate file), ignoring revocation\n",
|
||||
GNUNET_h2s (denom_hash));
|
||||
return GNUNET_OK;
|
||||
|
||||
}
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||
"Adding denomination key `%s' to revocation set\n",
|
||||
GNUNET_h2s (denom_hash));
|
||||
dki = GNUNET_CONTAINER_multihashmap_get (key_state->denomkey_map,
|
||||
denom_hash);
|
||||
// FIXME: what do we do if dki is not known?
|
||||
// especially what if we have neither private key NOR
|
||||
// DB entry? (maybe ancient revocation? should we ignore it?)
|
||||
if (NULL != dki)
|
||||
{
|
||||
GNUNET_assert (GNUNET_YES ==
|
||||
GNUNET_CONTAINER_multihashmap_remove (key_state->denomkey_map,
|
||||
denom_hash,
|
||||
dki));
|
||||
if (GNUNET_NO ==
|
||||
GNUNET_assert (GNUNET_YES ==
|
||||
GNUNET_CONTAINER_multihashmap_put (key_state->revoked_map,
|
||||
&dki->issue.properties.denom_hash,
|
||||
dki,
|
||||
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
|
||||
{
|
||||
/* revocation file must exist twice, keep only one of the dkis */
|
||||
GNUNET_CRYPTO_rsa_private_key_free (dki->denom_priv.rsa_private_key);
|
||||
GNUNET_CRYPTO_rsa_public_key_free (dki->denom_pub.rsa_public_key);
|
||||
GNUNET_free (dki);
|
||||
return GNUNET_OK;
|
||||
}
|
||||
}
|
||||
/* Try to insert DKI into DB until we succeed; note that if the DB
|
||||
failure is persistent, we need to die, as we cannot continue
|
||||
without the DKI being in the DB). */
|
||||
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
|
||||
/* Try to insert revocation into DB */
|
||||
arc.dki = dki;
|
||||
arc.revocation_master_sig = revocation_master_sig;
|
||||
if (GNUNET_OK !=
|
||||
TEH_DB_run_transaction (NULL,
|
||||
"add denomination key revocations",
|
||||
"add denomination key revocation",
|
||||
NULL,
|
||||
&add_revocations_transaction,
|
||||
&arc))
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Giving up, this is fatal. Committing suicide via SIGTERM.\n");
|
||||
"Failed to add revocation to database. This is fatal. Committing suicide via SIGTERM.\n");
|
||||
handle_signal (SIGTERM);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
@ -1576,6 +1579,16 @@ make_fresh_key_state ()
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* We do not get expired DKIs from
|
||||
TALER_EXCHANGEDB_denomination_keys_iterate(), so we must fetch
|
||||
the old keys (where we only have the public keys) from the
|
||||
database! */
|
||||
qs = TEH_plugin->iterate_denomination_info (TEH_plugin->cls,
|
||||
&reload_public_denoms_cb,
|
||||
&rfc);
|
||||
GNUNET_break (0 <= qs); /* warn, but continue, fingers crossed */
|
||||
|
||||
/* process revocations */
|
||||
if (-1 ==
|
||||
TALER_EXCHANGEDB_revocations_iterate (TEH_revocation_directory,
|
||||
&TEH_master_public_key,
|
||||
@ -1591,22 +1604,7 @@ make_fresh_key_state ()
|
||||
json_decref (rfc.sign_keys_array);
|
||||
return NULL;
|
||||
}
|
||||
if (0 == GNUNET_CONTAINER_multihashmap_size (key_state->denomkey_map))
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Have no denomination keys. Bad configuration.\n");
|
||||
key_state->refcnt = 1;
|
||||
ks_release (key_state);
|
||||
destroy_response_factory (&rfc);
|
||||
return NULL;
|
||||
}
|
||||
/* Once we no longer get expired DKIs from
|
||||
TALER_EXCHANGEDB_denomination_keys_iterate(),
|
||||
we must fetch the information from the database! */
|
||||
qs = TEH_plugin->iterate_denomination_info (TEH_plugin->cls,
|
||||
&reload_public_denoms_cb,
|
||||
&rfc);
|
||||
GNUNET_break (0 <= qs); /* warn, but continue, fingers crossed */
|
||||
|
||||
/* Initialize `current_sign_key_issue` and `rfc.sign_keys_array` */
|
||||
TALER_EXCHANGEDB_signing_keys_iterate (TEH_exchange_directory,
|
||||
&reload_keys_sign_iter,
|
||||
@ -1624,6 +1622,17 @@ make_fresh_key_state ()
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* sanity check */
|
||||
if (0 == GNUNET_CONTAINER_multihashmap_size (key_state->denomkey_map))
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Have no denomination keys. Bad configuration.\n");
|
||||
key_state->refcnt = 1;
|
||||
ks_release (key_state);
|
||||
destroy_response_factory (&rfc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Initialize and sort the `denomkey_array` */
|
||||
rfc.denomkey_array
|
||||
= GNUNET_new_array (GNUNET_CONTAINER_multihashmap_size (key_state->denomkey_map),
|
||||
|
@ -158,8 +158,14 @@ TALER_EXCHANGEDB_denomination_key_read (const char *filename,
|
||||
if (0 == GNUNET_TIME_absolute_get_remaining
|
||||
(GNUNET_TIME_absolute_ntoh (dki->issue.properties.expire_withdraw)).rel_value_us)
|
||||
{
|
||||
/* FIXME: #5536: we should delete this file, the
|
||||
private key is no longer needed (and return SYSERR!) */
|
||||
if (0 != UNLINK (filename))
|
||||
{
|
||||
GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
|
||||
"unlink",
|
||||
filename);
|
||||
return GNUNET_OK; /* yes, we had an error, but the file content
|
||||
was fine and is being returned */
|
||||
}
|
||||
}
|
||||
return GNUNET_OK;
|
||||
}
|
||||
|
@ -76,8 +76,16 @@ signkeys_iterate_dir_iter (void *cls,
|
||||
if (0 == GNUNET_TIME_absolute_get_remaining
|
||||
(GNUNET_TIME_absolute_ntoh (issue.issue.expire)).rel_value_us)
|
||||
{
|
||||
/* FIXME: #5536: we should delete this file, the
|
||||
private key is no longer needed (and return SYSERR!) */
|
||||
if (0 != UNLINK (filename))
|
||||
{
|
||||
GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
|
||||
"unlink",
|
||||
filename);
|
||||
return GNUNET_OK; /* yes, we had an error, but continue to iterate anyway */
|
||||
}
|
||||
/* Expired file deleted, continue to iterate -without- calling iterator
|
||||
as this key is expired */
|
||||
return GNUNET_OK;
|
||||
}
|
||||
return skc->it (skc->it_cls,
|
||||
filename,
|
||||
|
Loading…
Reference in New Issue
Block a user