summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2020-12-06 17:51:44 +0100
committerChristian Grothoff <christian@grothoff.org>2020-12-06 17:51:44 +0100
commitfd96e34c785e86423f739036506c9e860e683677 (patch)
tree4afe3ed8855545f850f8b5c0be50a351c49bd477
parentd9ac8e7975d813f1a868ab4d0cd062408f5aaf00 (diff)
downloadexchange-fd96e34c785e86423f739036506c9e860e683677.tar.gz
exchange-fd96e34c785e86423f739036506c9e860e683677.tar.bz2
exchange-fd96e34c785e86423f739036506c9e860e683677.zip
more work on future /keys
-rw-r--r--src/exchange/taler-exchange-httpd_keys.c247
-rw-r--r--src/exchange/taler-exchange-httpd_keys.h29
2 files changed, 224 insertions, 52 deletions
diff --git a/src/exchange/taler-exchange-httpd_keys.c b/src/exchange/taler-exchange-httpd_keys.c
index 7aade68f4..2bc23de16 100644
--- a/src/exchange/taler-exchange-httpd_keys.c
+++ b/src/exchange/taler-exchange-httpd_keys.c
@@ -178,6 +178,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
* reference counted and only destroyed once the last user is done
@@ -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));
}
@@ -613,6 +638,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;
}
diff --git a/src/exchange/taler-exchange-httpd_keys.h b/src/exchange/taler-exchange-httpd_keys.h
index 7b4d565f9..078838615 100644
--- a/src/exchange/taler-exchange-httpd_keys.h
+++ b/src/exchange/taler-exchange-httpd_keys.h
@@ -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 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_EXCHANGEDB_DenominationKeyInformationP issue;
+ struct TALER_MasterSignatureP master_sig_revocation;
+
};