more work on future /keys

This commit is contained in:
Christian Grothoff 2020-12-06 17:51:44 +01:00
parent d9ac8e7975
commit fd96e34c78
No known key found for this signature in database
GPG Key ID: 939E6BE1E29FC3CC
2 changed files with 223 additions and 51 deletions

View File

@ -177,6 +177,32 @@ struct KeysResponseData
};
/**
* @brief All information about an exchange online signing key (which is used to
* sign messages from the exchange).
*/
struct SigningKey
{
/**
* The exchange's (online signing) public key.
*/
struct TALER_ExchangePublicKeyP exchange_pub;
/**
* Meta data about the signing key, such as validity periods.
*/
struct TALER_EXCHANGEDB_SignkeyMetaData meta;
/**
* The long-term offline master key's signature for this signing key.
* Signs over @e exchange_pub and @e meta.
*/
struct TALER_MasterSignatureP master_sig;
};
/**
* Snapshot of the (coin and signing) keys (including private keys) of
* the exchange. There can be multiple instances of this struct, as it is
@ -197,11 +223,10 @@ struct TEH_KeyStateHandle
struct GNUNET_CONTAINER_MultiHashMap *denomkey_map;
/**
* Map from `struct TALER_ExchangePublicKey` to `TBD`
* Map from `struct TALER_ExchangePublicKey` to `struct SigningKey`
* entries. Based on the fact that a `struct GNUNET_PeerIdentity` is also
* an EdDSA public key.
*/
// FIXME: never initialized, never cleaned up!
struct GNUNET_CONTAINER_MultiPeerMap *signkey_map;
/**
@ -373,11 +398,11 @@ free_esign_cb (void *cls,
const struct GNUNET_PeerIdentity *pid,
void *value)
{
struct HelperSignkey *sk = value;
struct HelperSignkey *hsk = value;
(void) cls;
(void) pid;
GNUNET_free (sk);
GNUNET_free (hsk);
return GNUNET_OK;
}
@ -507,36 +532,36 @@ helper_esign_cb (
const struct TALER_SecurityModuleSignatureP *sm_sig)
{
struct HelperState *hs = cls;
struct HelperSignkey *sk;
struct HelperSignkey *hsk;
struct GNUNET_PeerIdentity pid;
check_esign_sm_pub (sm_pub);
pid.public_key = exchange_pub->eddsa_pub;
sk = GNUNET_CONTAINER_multipeermap_get (hs->denom_keys,
&pid);
if (NULL != sk)
hsk = GNUNET_CONTAINER_multipeermap_get (hs->denom_keys,
&pid);
if (NULL != hsk)
{
/* should be just an update (revocation!), so update existing entry */
sk->validity_duration = validity_duration;
GNUNET_break (0 ==
GNUNET_memcmp (sm_sig,
&sk->sm_sig));
&hsk->sm_sig));
GNUNET_break (start_time.abs_value_us ==
sk->start_time.abs_value_us);
hsk->start_time.abs_value_us);
return;
}
sk = GNUNET_new (struct HelperSignkey);
sk->start_time = start_time;
sk->validity_duration = validity_duration;
sk->exchange_pub = *exchange_pub;
sk->sm_sig = *sm_sig;
hsk = GNUNET_new (struct HelperSignkey);
hsk->start_time = start_time;
hsk->validity_duration = validity_duration;
hsk->exchange_pub = *exchange_pub;
hsk->sm_sig = *sm_sig;
GNUNET_assert (
GNUNET_OK ==
GNUNET_CONTAINER_multihashmap_put (
hs->esign_keys,
&pid,
sk,
hsk,
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
}
@ -612,6 +637,28 @@ clear_denomination_cb (void *cls,
}
/**
* Free denomination key data.
*
* @param cls a `struct TEH_KeyStateHandle`, unused
* @param h_denom_pub hash of the denomination public key, unused
* @param value a `struct SigningKey` to free
* @return #GNUNET_OK (continue to iterate)
*/
static int
clear_signkey_cb (void *cls,
const struct GNUNET_PeerIdentity *pid,
void *value)
{
struct SigningKey *sk = value;
(void) cls;
(void) pid;
GNUNET_free (sk);
return GNUNET_OK;
}
/**
* Free resources associated with @a cls, possibly excluding
* the helper data.
@ -628,6 +675,10 @@ destroy_key_state (struct TEH_KeyStateHandle *ksh,
&clear_denomination_cb,
ksh);
GNUNET_CONTAINER_multihashmap_destroy (ksh->denomkey_map);
GNUNET_CONTAINER_multihashmap_iterate (ksh->signkey_map,
&clear_signkey_cb,
ksh);
GNUNET_CONTAINER_multihashmap_destroy (ksh->denomkey_map);
if (free_helper)
destroy_key_helpers (&ksh->helpers);
GNUNET_free (ksh);
@ -655,21 +706,93 @@ destroy_key_state_cb (void *cls)
*
* @param cls closure with a `struct TEH_KeyStateHandle *`
* @param denom_pub public key of the denomination
* @param issue detailed information about the denomination (value, expiration times, fees)
* @param h_denom_pub hash of @a denom_pub
* @param meta meta data information about the denomination type (value, expirations, fees)
* @param master_sig master signature affirming the validity of this denomination
* @param recoup_possible true if the key was revoked and clients can currently recoup
* coins of this denomination
*/
// FIXME: want a different function with
// + revocation data
// - private key data
static void
denomination_info_cb (
void *cls,
const struct TALER_DenominationPublicKey *denom_pub,
const struct TALER_EXCHANGEDB_DenominationKeyInformationP *issue)
const struct GNUNET_HashCode *h_denom_pub,
const struct TALER_EXCHANGEDB_DenominationKeyMetaData *meta,
const struct TALER_MasterSignatureP *master_sig,
bool recoup_possible)
{
struct TEH_KeyStateHandle *ksh = cls;
struct TEH_DenominationKey *dk;
dk = GNUNET_new (struct TEH_DenominationKey);
dk->denom_pub.rsa_public_key
= GNUNET_CRYPTO_rsa_public_key_dup (denom_pub->rsa_public_key);
dk->h_denom_pub = *h_denom_pub;
dk->meta = meta;
dk->master_sig = *master_sig;
dk->recoup_possible = recoup_possible;
GNUNET_assert (
GNUNET_OK ==
GNUNET_CONTAINER_multihashmap_insert (ksh->denom_map,
&dk->h_denom_pub,
dk,
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
}
/**
* Function called with information about the exchange's online signing keys.
*
* @param cls closure with a `struct TEH_KeyStateHandle *`
* @param exchange_pub the public key
* @param meta meta data information about the denomination type (expirations)
* @param master_sig master signature affirming the validity of this denomination
*/
static void
signkey_info_cb (
void *cls,
const struct TALER_ExchangePublicKeyP *exchange_pub,
const struct TALER_EXCHANGEDB_SignkeyMetaData *meta,
const struct TALER_MasterSignatureP *master_sig)
{
struct TEH_KeyStateHandle *ksh = cls;
struct SigningKey *sk;
struct GNUNET_PeerIdentity pid;
sk = GNUNET_new (struct SigningKey);
sk->exchnage_pub = *exchange_pub;
sk->meta = *meta;
sk->master_sig = *master_sig;
pid.public_key = exchange_pub->eddsa_pub;
GNUNET_assert (
GNUNET_OK ==
GNUNET_CONTAINER_multihashmap_insert (ksh->signkey_map,
&pid,
sk,
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
}
/**
* Function called with information about the exchange's auditors.
*
* @param cls closure with a `struct TEH_KeyStateHandle *`
* @param auditor_pub the public key of the auditor
* @param auditor_url URL of the REST API of the auditor
* @param auditor_name human readable official name of the auditor
* @param ... MORE
*/
static void
auditor_info_cb (
void *cls,
const struct TALER_AuditorPublicKeyP *auditor_pub,
const char *auditor_url,
const char *auditor_name,
...)
{
struct TEH_KeyStateHandle *ksh = cls;
// FIXME: check with helper to see if denomination is OK
// for use with signing!
// FIXME: remember...
}
@ -703,33 +826,46 @@ build_key_state (struct HelperState *hs)
}
ksh->denomkey_map = GNUNET_CONTAINER_multihashmap_create (1024,
GNUNET_YES);
// FIXME: should _also_ fetch revocation status here!
qs = TEH_plugin->iterate_denomination_info (TEH_plugin->cls,
&denomination_info_cb,
ksh);
ksh->signkey_map = GNUNET_CONTAINER_multihashmap_create (32,
GNUNET_NO /* MUST be NO! */);
#if TBD
// NOTE: should ONLY fetch master-signed signkeys, but ALSO those that were revoked!
qs = TEH_plugin->iterate_denominations (TEH_plugin->cls,
&denomination_info_cb,
ksh);
if (qs < 0)
{
// now what!?
GNUNET_break (0);
destroy_key_state (ksh,
true);
return NULL;
}
#endif
#if TBD
// NOTE: should ONLY fetch non-revoked AND master-signed signkeys!
qs = TEH_plugin->iterate_signkeys (TEH_plugin->cls,
&signkey_info_cb,
ksh);
if (qs < 0)
{
GNUNET_break (0);
destroy_key_state (ksh,
true);
return NULL;
}
#endif
#if TBD
qs = TEH_plugin->iterate_auditor_info (TEH_plugin->cls,
&auditor_info_cb,
ksh);
if (qs < 0)
{
// now what!?
GNUNET_break (0);
destroy_key_state (ksh,
true);
return NULL;
}
#endif
// FIXME: initialize more: fetch everything we care about from DB/CFG!
// STILL NEEDED:
// - revocation signatures (if any)
// - auditor signatures
// - master signatures???
// FIXME: should _also_ fetch master signatures and revocation status on signing keys!
return ksh;
}
@ -737,6 +873,10 @@ build_key_state (struct HelperState *hs)
/**
* Update the "/keys" responses in @a ksh up to @a now into the future.
*
* This function is to recompute all (including cherry-picked) responses we
* might want to return, based on the state already in @a ksh.
*
*
* @param[in,out] ksh state handle to update
* @param now timestamp for when to compute the replies.
*/
@ -745,6 +885,8 @@ update_keys_response (struct TEH_KeyStateHandle *ksh,
struct GNUNET_TIME_Absolute now)
{
// FIXME: update 'krd_array' here!
// FIXME: this relates to a good design for cherry-picking,
// which we currently don't have for new /keys!
}
@ -910,11 +1052,28 @@ TEH_keys_exchange_sign_ (const struct
sig);
if (TALER_EC_NONE != ec)
return ec;
/* FIXME: check here that 'pub' is set to an exchange public
key that is actually signed by the master key! Otherwise, we
happily continue to use key material even if the offline
signatures have not been made yet! */
{
/* Here we check here that 'pub' is set to an exchange public key that is
actually signed by the master key! Otherwise, we happily continue to
use key material even if the offline signatures have not been made
yet! */
struct GNUNET_PeerIdentity pid;
struct SigningKey *sk;
pid.public_key = pub->eddsa_pub;
sk = GNUNET_CONTAINER_multipeermap_get (ksh->signkey_map,
&pid);
if (NULL == sk)
{
GNUNET_break (0);
/* just to be safe, zero out the (valid) signature, as the key
should no longer be used */
memset (sig,
0,
sizeof (*sig));
return TALER_EC_EXCHANGE_KEYS_SIGNKEY_HELPER_BUG;
}
}
return ec;
}

View File

@ -34,12 +34,6 @@
*/
struct TEH_DenominationKey
{
/**
* The helper to sign with this denomination key. Will be NULL if the
* private key is not available (this is the case after the key has expired
* for signing coins, if it is too early, or if the key has been revoked).
*/
struct TALER_CRYPTO_DenominationHelper *dh;
/**
* Decoded denomination public key (the hash of it is in
@ -48,9 +42,28 @@ struct TEH_DenominationKey
struct TALER_DenominationPublicKey denom_pub;
/**
* Signed public information about a denomination key.
* Hash code of the denomination public key.
*/
struct TALER_EXCHANGEDB_DenominationKeyInformationP issue;
struct GNUNET_HashCode h_denom_pub;
/**
* Meta data about the type of the denomination, such as fees and validity
* periods.
*/
struct TALER_EXCHANGEDB_DenominationKeyMetaData meta;
/**
* The long-term offline master key's signature for this denomination.
* Signs over @e h_denom_pub and @e meta.
*/
struct TALER_MasterSignatureP master_sig_validity;
/**
* The master key's signature to revoke this denomination, or all zero
* if the denomination has NOT yet been revoked.
*/
struct TALER_MasterSignatureP master_sig_revocation;
};