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
|
Sat Mar 2 19:09:43 CET 2019
|
||||||
Changing denomination key revocation file format and moving them
|
Changing denomination key revocation file format and moving them
|
||||||
to their own directory (preparations for #5536 resolution). -CG
|
to their own directory (preparations for #5536 resolution). -CG
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
This file is part of TALER
|
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
|
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
|
||||||
@ -629,7 +629,19 @@ add_revocations_transaction (void *cls,
|
|||||||
int *mhd_ret)
|
int *mhd_ret)
|
||||||
{
|
{
|
||||||
struct AddRevocationContext *arc = cls;
|
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,
|
return TEH_plugin->insert_denomination_revocation (TEH_plugin->cls,
|
||||||
session,
|
session,
|
||||||
&arc->dki->issue.properties.denom_hash,
|
&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 start;
|
||||||
struct GNUNET_TIME_Absolute horizon;
|
struct GNUNET_TIME_Absolute horizon;
|
||||||
struct GNUNET_TIME_Absolute expire_deposit;
|
struct GNUNET_TIME_Absolute expire_deposit;
|
||||||
int res;
|
|
||||||
|
|
||||||
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
|
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
|
||||||
"Loading denomination key `%s' (%s)\n",
|
"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",
|
"Adding denomination key `%s' (%s) to active set\n",
|
||||||
alias,
|
alias,
|
||||||
GNUNET_h2s (&dki->issue.properties.denom_hash));
|
GNUNET_h2s (&dki->issue.properties.denom_hash));
|
||||||
res = store_in_map (key_state->denomkey_map,
|
if (GNUNET_NO /* entry already exists */ ==
|
||||||
dki);
|
store_in_map (key_state->denomkey_map,
|
||||||
if (GNUNET_NO == res)
|
dki))
|
||||||
return GNUNET_OK;
|
return GNUNET_OK; /* do not update expiration if entry exists */
|
||||||
key_state->min_dk_expire = GNUNET_TIME_absolute_min (key_state->min_dk_expire,
|
key_state->min_dk_expire = GNUNET_TIME_absolute_min (key_state->min_dk_expire,
|
||||||
expire_deposit);
|
expire_deposit);
|
||||||
return GNUNET_OK;
|
return GNUNET_OK;
|
||||||
@ -774,51 +785,43 @@ revocations_iter (void *cls,
|
|||||||
{
|
{
|
||||||
struct ResponseFactoryContext *rfc = cls;
|
struct ResponseFactoryContext *rfc = cls;
|
||||||
struct TEH_KS_StateHandle *key_state = rfc->key_state;
|
struct TEH_KS_StateHandle *key_state = rfc->key_state;
|
||||||
int res;
|
|
||||||
struct AddRevocationContext arc;
|
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,
|
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||||
"Adding denomination key `%s' to revocation set\n",
|
"Adding denomination key `%s' to revocation set\n",
|
||||||
GNUNET_h2s (denom_hash));
|
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_assert (GNUNET_YES ==
|
||||||
GNUNET_CONTAINER_multihashmap_remove (key_state->denomkey_map,
|
GNUNET_CONTAINER_multihashmap_remove (key_state->denomkey_map,
|
||||||
denom_hash,
|
denom_hash,
|
||||||
dki));
|
dki));
|
||||||
if (GNUNET_NO ==
|
GNUNET_assert (GNUNET_YES ==
|
||||||
GNUNET_CONTAINER_multihashmap_put (key_state->revoked_map,
|
GNUNET_CONTAINER_multihashmap_put (key_state->revoked_map,
|
||||||
&dki->issue.properties.denom_hash,
|
&dki->issue.properties.denom_hash,
|
||||||
dki,
|
dki,
|
||||||
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
|
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
|
||||||
{
|
/* Try to insert revocation into DB */
|
||||||
/* 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). */
|
|
||||||
arc.dki = dki;
|
arc.dki = dki;
|
||||||
arc.revocation_master_sig = revocation_master_sig;
|
arc.revocation_master_sig = revocation_master_sig;
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
TEH_DB_run_transaction (NULL,
|
TEH_DB_run_transaction (NULL,
|
||||||
"add denomination key revocations",
|
"add denomination key revocation",
|
||||||
NULL,
|
NULL,
|
||||||
&add_revocations_transaction,
|
&add_revocations_transaction,
|
||||||
&arc))
|
&arc))
|
||||||
{
|
{
|
||||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
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);
|
handle_signal (SIGTERM);
|
||||||
return GNUNET_SYSERR;
|
return GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
@ -1576,6 +1579,16 @@ make_fresh_key_state ()
|
|||||||
return NULL;
|
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 ==
|
if (-1 ==
|
||||||
TALER_EXCHANGEDB_revocations_iterate (TEH_revocation_directory,
|
TALER_EXCHANGEDB_revocations_iterate (TEH_revocation_directory,
|
||||||
&TEH_master_public_key,
|
&TEH_master_public_key,
|
||||||
@ -1591,22 +1604,7 @@ make_fresh_key_state ()
|
|||||||
json_decref (rfc.sign_keys_array);
|
json_decref (rfc.sign_keys_array);
|
||||||
return NULL;
|
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` */
|
/* Initialize `current_sign_key_issue` and `rfc.sign_keys_array` */
|
||||||
TALER_EXCHANGEDB_signing_keys_iterate (TEH_exchange_directory,
|
TALER_EXCHANGEDB_signing_keys_iterate (TEH_exchange_directory,
|
||||||
&reload_keys_sign_iter,
|
&reload_keys_sign_iter,
|
||||||
@ -1624,6 +1622,17 @@ make_fresh_key_state ()
|
|||||||
return NULL;
|
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` */
|
/* Initialize and sort the `denomkey_array` */
|
||||||
rfc.denomkey_array
|
rfc.denomkey_array
|
||||||
= GNUNET_new_array (GNUNET_CONTAINER_multihashmap_size (key_state->denomkey_map),
|
= 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
|
if (0 == GNUNET_TIME_absolute_get_remaining
|
||||||
(GNUNET_TIME_absolute_ntoh (dki->issue.properties.expire_withdraw)).rel_value_us)
|
(GNUNET_TIME_absolute_ntoh (dki->issue.properties.expire_withdraw)).rel_value_us)
|
||||||
{
|
{
|
||||||
/* FIXME: #5536: we should delete this file, the
|
if (0 != UNLINK (filename))
|
||||||
private key is no longer needed (and return SYSERR!) */
|
{
|
||||||
|
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;
|
return GNUNET_OK;
|
||||||
}
|
}
|
||||||
|
@ -76,8 +76,16 @@ signkeys_iterate_dir_iter (void *cls,
|
|||||||
if (0 == GNUNET_TIME_absolute_get_remaining
|
if (0 == GNUNET_TIME_absolute_get_remaining
|
||||||
(GNUNET_TIME_absolute_ntoh (issue.issue.expire)).rel_value_us)
|
(GNUNET_TIME_absolute_ntoh (issue.issue.expire)).rel_value_us)
|
||||||
{
|
{
|
||||||
/* FIXME: #5536: we should delete this file, the
|
if (0 != UNLINK (filename))
|
||||||
private key is no longer needed (and return SYSERR!) */
|
{
|
||||||
|
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,
|
return skc->it (skc->it_cls,
|
||||||
filename,
|
filename,
|
||||||
|
Loading…
Reference in New Issue
Block a user