[new /keys response] added proper hash verification

- Running XOR of all SHA-512 hashes of each denomination's public key is
  compared against the "hash" value in the JSON blob.

- Fixed a bug during creation of the running XOR.
This commit is contained in:
Özgür Kesim 2022-06-27 10:10:51 +02:00
parent a55fc45126
commit a6544069f9
Signed by: oec
GPG Key ID: 3D76A56D79EDD9D7
4 changed files with 66 additions and 33 deletions

View File

@ -2068,23 +2068,26 @@ finish_keys_response (struct TEH_KeyStateHandle *ksh)
last_cpd = GNUNET_TIME_UNIT_ZERO_TS;
// FIXME: This block contains the implementation of the DEPRICATED
// "denom_pubs" array along with the new grouped "denominations".
// "denom_pubs" Will be removed sooner or later.
{
struct TEH_DenominationKey *dk;
struct GNUNET_CONTAINER_MultiHashMap *denominations_by_group;
// groupData is the value we store for each group meta-data
struct groupData
{
// 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;
};
denominations_by_group =
GNUNET_CONTAINER_multihashmap_create (1024,
GNUNET_NO /* NO, because keys are only on the stack */);
/* groupData is the value we store for each group meta-data */
struct groupData
{
/* 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 */
while (NULL != (dk = GNUNET_CONTAINER_heap_remove_root (heap)))
@ -2113,7 +2116,6 @@ finish_keys_response (struct TEH_KeyStateHandle *ksh)
recoup,
denoms,
grouped_denominations,
&grouped_hash_xor))
{
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
@ -2318,24 +2320,26 @@ finish_keys_response (struct TEH_KeyStateHandle *ksh)
(const
void **) &group))
{
struct GNUNET_HashCode hc;
GNUNET_CRYPTO_hash_xor (&group->hash_xor,
&grouped_hash_xor,
&grouped_hash_xor);
// Add the XOR over all hashes of denominations in this group to the group
GNUNET_assert (0 ==
json_object_set (
group->json,
"hash",
GNUNET_JSON_PACK (
GNUNET_JSON_pack_data_auto (NULL, &hc))));
GNUNET_JSON_pack_data_auto (NULL,
&group->hash_xor))));
// Add this group to the array
GNUNET_assert (0 ==
json_array_append_new (
grouped_denominations,
group->json));
// Build the running XOR over all hash(_xor)
GNUNET_CRYPTO_hash_xor (&group->hash_xor,
&grouped_hash_xor,
&grouped_hash_xor);
GNUNET_free (group);
}

View File

@ -370,12 +370,17 @@ TALER_JSON_spec_amount_any_nbo (const char *name,
**/
struct TALER_DenominationGroup
{
/* currency must be set prior to calling TALER_JSON_spec_denomination_group */
const char *currency;
enum TALER_DenominationCipher cipher;
struct TALER_Amount value;
struct TALER_DenomFeeSet fees;
struct TALER_AgeMask age_mask;
// currency must be set prior to calling TALER_JSON_spec_denomination_group
const char *currency;
// hash is/should be the XOR of all SHA-512 hashes of the public keys in this
// group
struct GNUNET_HashCode hash;
};
/**

View File

@ -265,6 +265,8 @@ parse_denomination_group (void *cls,
GNUNET_JSON_spec_uint32 ("age_mask",
&group->age_mask.bits),
&age_mask_missing),
GNUNET_JSON_spec_fixed_auto ("hash",
&group->hash),
GNUNET_JSON_spec_end ()
};
const char *emsg;

View File

@ -924,8 +924,13 @@ decode_keys_json (const json_t *resp_obj,
key_data->age_mask = TALER_extensions_age_restriction_ageMask ();
}
/* parse the denomination keys, merging with the
possibly EXISTING array as required (/keys cherry picking) */
/**
* Parse the denomination keys, merging with the
* possibly EXISTING array as required (/keys cherry picking).
*
* The denominations are grouped by common values of
* {cipher, value, fee, age_mask}.
**/
{
json_t *denominations_by_group;
json_t *group_obj;
@ -940,23 +945,25 @@ decode_keys_json (const json_t *resp_obj,
json_typeof (denominations_by_group));
json_array_foreach (denominations_by_group, group_idx, group_obj) {
/* First, parse { cipher, fees, value, age_mask } of the current group */
// Running XOR of each SHA512 hash of the denominations' public key in
// this group. Used to compare against group.hash after all keys have
// been parsed.
struct GNUNET_HashCode group_hash_xor = {0};
struct TALER_DenominationGroup group = {
.currency = currency
};
// First, parse { cipher, fees, value, age_mask, hash } of the current
// group.
struct TALER_DenominationGroup group = { .currency = currency };
struct GNUNET_JSON_Specification group_spec[] = {
TALER_JSON_spec_denomination_group (NULL, &group),
GNUNET_JSON_spec_end ()
};
EXITIF (GNUNET_SYSERR ==
GNUNET_JSON_parse (group_obj,
group_spec,
NULL,
NULL));
/* Now, parse the individual denominations */
// Now, parse the individual denominations
{
json_t *denom_keys_array;
json_t *denom_key_obj;
@ -970,9 +977,9 @@ decode_keys_json (const json_t *resp_obj,
memset (&dk, 0, sizeof (dk));
/* Set the common fields from the group for this particular
* denomination. Required to make the validity check inside
* parse_json_denomkey_partially pass */
// Set the common fields from the group for this particular
// denomination. Required to make the validity check inside
// parse_json_denomkey_partially pass
dk.key.cipher = group.cipher;
dk.value = group.value;
dk.fees = group.fees;
@ -987,6 +994,15 @@ decode_keys_json (const json_t *resp_obj,
&key_data->master_pub,
check_sig ? &hash_xor: NULL));
// Build the running xor of the SHA512-hash of the public keys
{
struct TALER_DenominationHashP hc = {0};
TALER_denom_pub_hash (&dk.key, &hc);
GNUNET_CRYPTO_hash_xor (&hc.hash,
&group_hash_xor,
&group_hash_xor);
}
for (unsigned int j = 0;
j<key_data->num_denom_keys;
j++)
@ -1019,9 +1035,15 @@ decode_keys_json (const json_t *resp_obj,
key_data->last_denom_issue_date
= GNUNET_TIME_timestamp_max (key_data->last_denom_issue_date,
dk.valid_from);
}
};
};
}; // json_array_foreach over denominations
// The calculated group_hash_xor must be the same as group.hash from
// the json.
EXITIF (0 !=
GNUNET_CRYPTO_hash_cmp (&group_hash_xor, &group.hash));
} // block for parsing individual denominations
}; // json_array_foreach over groups of denominations
}
/* parse the auditor information */