aboutsummaryrefslogtreecommitdiff
path: root/src/exchange/taler-exchange-httpd_keys.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/exchange/taler-exchange-httpd_keys.c')
-rw-r--r--src/exchange/taler-exchange-httpd_keys.c161
1 files changed, 86 insertions, 75 deletions
diff --git a/src/exchange/taler-exchange-httpd_keys.c b/src/exchange/taler-exchange-httpd_keys.c
index 6eadb0d7..de5f1fbc 100644
--- a/src/exchange/taler-exchange-httpd_keys.c
+++ b/src/exchange/taler-exchange-httpd_keys.c
@@ -1351,7 +1351,7 @@ denomination_info_cb (
dk->meta = *meta;
dk->master_sig = *master_sig;
dk->recoup_possible = recoup_possible;
- dk->denom_pub.age_mask = meta->age_mask; /* FIXME-oec: age_mask -> reserved_field */
+ dk->denom_pub.age_mask = meta->age_mask;
GNUNET_assert (
GNUNET_OK ==
@@ -1726,12 +1726,13 @@ setup_general_response_headers (struct TEH_KeyStateHandle *ksh,
* @a recoup and @a denoms.
*
* @param[in,out] ksh key state handle we build @a krd for
- * @param[in] denom_keys_hash hash over all the denominatoin keys in @a denoms
+ * @param[in] denom_keys_hash hash over all the denomination keys in @a denoms
* @param last_cpd timestamp to use
* @param signkeys list of sign keys to return
* @param recoup list of revoked keys to return
* @param denoms list of denominations to return
* @param grouped_denominations list of grouped denominations to return
+ * @param[in] h_grouped XOR of all hashes in @a grouped_demoninations
* @return #GNUNET_OK on success
*/
static enum GNUNET_GenericReturnValue
@@ -1741,11 +1742,14 @@ create_krd (struct TEH_KeyStateHandle *ksh,
json_t *signkeys,
json_t *recoup,
json_t *denoms,
- json_t *grouped_denominations)
+ json_t *grouped_denominations,
+ const struct GNUNET_HashCode *h_grouped)
{
struct KeysResponseData krd;
struct TALER_ExchangePublicKeyP exchange_pub;
struct TALER_ExchangeSignatureP exchange_sig;
+ struct TALER_ExchangePublicKeyP grouped_exchange_pub;
+ struct TALER_ExchangeSignatureP grouped_exchange_sig;
json_t *keys;
GNUNET_assert (! GNUNET_TIME_absolute_is_zero (last_cpd.abs_time));
@@ -1753,11 +1757,13 @@ create_krd (struct TEH_KeyStateHandle *ksh,
GNUNET_assert (NULL != recoup);
GNUNET_assert (NULL != denoms);
GNUNET_assert (NULL != grouped_denominations);
+ GNUNET_assert (NULL != h_grouped);
GNUNET_assert (NULL != ksh->auditors);
GNUNET_assert (NULL != TEH_currency);
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Creating /keys at cherry pick date %s\n",
GNUNET_TIME_timestamp2s (last_cpd));
+
/* Sign hash over denomination keys */
{
enum TALER_ErrorCode ec;
@@ -1779,6 +1785,33 @@ create_krd (struct TEH_KeyStateHandle *ksh,
}
}
+ /* Sign grouped hash */
+ {
+ enum TALER_ErrorCode ec;
+
+ if (TALER_EC_NONE !=
+ (ec =
+ TALER_exchange_online_key_set_sign (
+ &TEH_keys_exchange_sign2_,
+ ksh,
+ last_cpd,
+ h_grouped,
+ &grouped_exchange_pub,
+ &grouped_exchange_sig)))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ "Could not create key response data: cannot sign grouped hash (%s)\n",
+ TALER_ErrorCode_get_hint (ec));
+ return GNUNET_SYSERR;
+ }
+ }
+
+ /* both public keys really must be the same */
+ GNUNET_assert (0 ==
+ memcmp (&grouped_exchange_pub,
+ &exchange_pub,
+ sizeof(exchange_pub)));
+
{
const struct SigningKey *sk;
@@ -1815,7 +1848,9 @@ create_krd (struct TEH_KeyStateHandle *ksh,
GNUNET_JSON_pack_data_auto ("eddsa_pub",
&exchange_pub),
GNUNET_JSON_pack_data_auto ("eddsa_sig",
- &exchange_sig));
+ &exchange_sig),
+ GNUNET_JSON_pack_data_auto ("denominations_sig",
+ &grouped_exchange_sig));
GNUNET_assert (NULL != keys);
/* Set wallet limit if KYC is configured */
@@ -1876,7 +1911,7 @@ create_krd (struct TEH_KeyStateHandle *ksh,
GNUNET_assert (0 == r);
}
- /* Update the keys object with the extensions */
+ /* Update the keys object with the extensions and its signature */
if (has_extensions)
{
json_t *sig;
@@ -1888,12 +1923,10 @@ create_krd (struct TEH_KeyStateHandle *ksh,
extensions);
GNUNET_assert (0 == r);
- /* add extensions_sig */
sig = GNUNET_JSON_PACK (
GNUNET_JSON_pack_data_auto ("extensions_sig",
&TEH_extensions_sig));
- /* update the keys object with extensions_sig */
r = json_object_update (keys, sig);
GNUNET_assert (0 == r);
}
@@ -2000,6 +2033,7 @@ finish_keys_response (struct TEH_KeyStateHandle *ksh)
struct GNUNET_TIME_Timestamp last_cpd;
struct GNUNET_CONTAINER_Heap *heap;
struct GNUNET_HashContext *hash_context = NULL;
+ struct GNUNET_HashCode grouped_hash_xor = {0};
sctx.signkeys = json_array ();
GNUNET_assert (NULL != sctx.signkeys);
@@ -2045,8 +2079,11 @@ finish_keys_response (struct TEH_KeyStateHandle *ksh)
/* groupData is the value we store for each group meta-data */
struct groupData
{
- json_t *json; /* The json blob with the group meta-data and list of denominations */
- struct GNUNET_HashContext *hash_context; /* hash over all denominations in that group */
+ /* The json blob with the group meta-data and list of denominations */
+ json_t *json;
+
+ /* xor of all hashes of denominations in that group */
+ struct GNUNET_HashCode hash_xor;
};
/* heap = min heap, sorted by start time */
@@ -2060,13 +2097,14 @@ finish_keys_response (struct TEH_KeyStateHandle *ksh)
/*
* This is not the first entry in the heap (because last_cpd !=
* GNUNET_TIME_UNIT_ZERO_TS) and the previous entry had a different
- * start time. Therefore, we create an entry in the ksh.
+ * start time. Therefore, we create a new entry in ksh.
*/
struct GNUNET_HashCode hc;
GNUNET_CRYPTO_hash_context_finish (
GNUNET_CRYPTO_hash_context_copy (hash_context),
&hc);
+
if (GNUNET_OK !=
create_krd (ksh,
&hc,
@@ -2074,7 +2112,9 @@ finish_keys_response (struct TEH_KeyStateHandle *ksh)
sctx.signkeys,
recoup,
denoms,
- grouped_denominations))
+ grouped_denominations,
+
+ &grouped_hash_xor))
{
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"Failed to generate key response data for %s\n",
@@ -2135,54 +2175,43 @@ finish_keys_response (struct TEH_KeyStateHandle *ksh)
* denominations in this group as a json-blob in the multihashmap
* denominations_by_group.
**/
-
{
static const char *denoms_key = "denoms";
struct groupData *group;
json_t *list;
json_t *entry;
struct GNUNET_HashCode key;
-
- /* Find the group/JSON-blob for the key */
- struct
- {
- enum TALER_DenominationCipher cipher;
- struct TALER_AgeMask age_mask;
- struct TALER_Amount value;
- struct TALER_DenomFeeSet fees;
- } meta = {
+ struct TALER_DenominationGroup meta = {
.cipher = dk->denom_pub.cipher,
.value = dk->meta.value,
.fees = dk->meta.fees,
.age_mask = dk->meta.age_mask,
};
+ /* Search the group/JSON-blob for the key */
GNUNET_CRYPTO_hash (&meta, sizeof(meta), &key);
- group = (struct groupData *) GNUNET_CONTAINER_multihashmap_get (
- denominations_by_group,
- &key);
+ group =
+ (struct groupData *) GNUNET_CONTAINER_multihashmap_get (
+ denominations_by_group,
+ &key);
if (NULL == group)
{
- /*
- * There is no group for this meta-data yet, so let's create a new
- * group entry.
- */
-
+ // There is no group for this meta-data yet, so we create a new group
bool age_restricted = meta.age_mask.bits != 0;
char *cipher;
group = GNUNET_new (struct groupData);
- group->hash_context = GNUNET_CRYPTO_hash_context_start ();
+ memset (group, 0, sizeof(*group));
switch (meta.cipher)
{
case TALER_DENOMINATION_RSA:
- cipher = age_restricted ? "RSA+age_restriction": "RSA";
+ cipher = age_restricted ? "RSA+age_restricted": "RSA";
break;
case TALER_DENOMINATION_CS:
- cipher = age_restricted ? "CS+age_restriction": "CS";
+ cipher = age_restricted ? "CS+age_restricted": "CS";
break;
default:
GNUNET_assert (false);
@@ -2196,13 +2225,13 @@ finish_keys_response (struct TEH_KeyStateHandle *ksh)
if (age_restricted)
{
- GNUNET_assert (0 ==
- json_object_set (group->json,
- "age_mask",
- json_integer (meta.age_mask.bits)));
+ int r = json_object_set (group->json,
+ "age_mask",
+ json_integer (meta.age_mask.bits));
+ GNUNET_assert (0 == r);
}
- /* Create a new array for the denominations in this group */
+ // Create a new array for the denominations in this group
list = json_array ();
GNUNET_assert (NULL != list);
GNUNET_assert (0 ==
@@ -2216,10 +2245,8 @@ finish_keys_response (struct TEH_KeyStateHandle *ksh)
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
}
- /*
- * Now that we have found/created the right group, add the denomination
- * to the list
- */
+ // Now that we have found/created the right group, add the
+ // denomination to the list
{
struct GNUNET_JSON_PackSpec key_spec;
@@ -2259,53 +2286,43 @@ finish_keys_response (struct TEH_KeyStateHandle *ksh)
GNUNET_assert (NULL != entry);
}
- /*
- * Build up the running hash of all denominations in this group
- * TODO: FIXME-oec: this is cipher and age_restriction dependent?!
- */
- GNUNET_CRYPTO_hash_context_read (group->hash_context,
- &dk->h_denom_pub,
- sizeof (struct GNUNET_HashCode));
+ // Build up the running xor of all hashes of the denominations in this
+ // group
+ GNUNET_CRYPTO_hash_xor (&dk->h_denom_pub.hash,
+ &group->hash_xor,
+ &group->hash_xor);
- /* Finally, add the denomination to the list of denominations in this
- * group */
+ // Finally, add the denomination to the list of denominations in this
+ // group
list = json_object_get (group->json, denoms_key);
GNUNET_assert (NULL != list);
GNUNET_assert (true == json_is_array (list));
GNUNET_assert (0 ==
json_array_append_new (list, entry));
}
- }
+ } /* loop over heap ends */
- /* Create the JSON-array of grouped denominations */
+ // Create the JSON-array of grouped denominations
if (0 <
GNUNET_CONTAINER_multihashmap_size (denominations_by_group))
{
struct GNUNET_CONTAINER_MultiHashMapIterator *iter;
- struct GNUNET_HashCode all_hashcode;
- struct GNUNET_HashContext *all_hash_ctx;
struct groupData *group = NULL;
- all_hash_ctx =
- GNUNET_CRYPTO_hash_context_start ();
-
iter =
GNUNET_CONTAINER_multihashmap_iterator_create (denominations_by_group);
while (GNUNET_OK ==
- GNUNET_CONTAINER_multihashmap_iterator_next (iter, NULL, (const
- void **)
- &group))
+ GNUNET_CONTAINER_multihashmap_iterator_next (iter,
+ NULL,
+ (const
+ void **) &group))
{
struct GNUNET_HashCode hc;
- GNUNET_CRYPTO_hash_context_finish (
- group->hash_context,
- &hc);
-
- GNUNET_CRYPTO_hash_context_read (all_hash_ctx,
- &hc,
- sizeof (struct GNUNET_HashCode));
+ GNUNET_CRYPTO_hash_xor (&group->hash_xor,
+ &grouped_hash_xor,
+ &grouped_hash_xor);
GNUNET_assert (0 ==
json_object_set (
@@ -2325,12 +2342,6 @@ finish_keys_response (struct TEH_KeyStateHandle *ksh)
GNUNET_CONTAINER_multihashmap_iterator_destroy (iter);
GNUNET_CONTAINER_multihashmap_destroy (denominations_by_group);
- GNUNET_CRYPTO_hash_context_finish (
- all_hash_ctx,
- &all_hashcode);
-
- /* FIXME-oec: TODO:
- * sign all_hashcode and add the signature to the /keys response */
}
}
@@ -2341,7 +2352,6 @@ finish_keys_response (struct TEH_KeyStateHandle *ksh)
GNUNET_CRYPTO_hash_context_finish (hash_context,
&hc);
-
if (GNUNET_OK !=
create_krd (ksh,
&hc,
@@ -2349,7 +2359,8 @@ finish_keys_response (struct TEH_KeyStateHandle *ksh)
sctx.signkeys,
recoup,
denoms,
- grouped_denominations))
+ grouped_denominations,
+ &grouped_hash_xor))
{
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"Failed to generate key response data for %s\n",