[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:
parent
a55fc45126
commit
a6544069f9
@ -2068,23 +2068,26 @@ finish_keys_response (struct TEH_KeyStateHandle *ksh)
|
|||||||
|
|
||||||
last_cpd = GNUNET_TIME_UNIT_ZERO_TS;
|
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 TEH_DenominationKey *dk;
|
||||||
struct GNUNET_CONTAINER_MultiHashMap *denominations_by_group;
|
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 =
|
denominations_by_group =
|
||||||
GNUNET_CONTAINER_multihashmap_create (1024,
|
GNUNET_CONTAINER_multihashmap_create (1024,
|
||||||
GNUNET_NO /* NO, because keys are only on the stack */);
|
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 */
|
/* heap = min heap, sorted by start time */
|
||||||
while (NULL != (dk = GNUNET_CONTAINER_heap_remove_root (heap)))
|
while (NULL != (dk = GNUNET_CONTAINER_heap_remove_root (heap)))
|
||||||
@ -2113,7 +2116,6 @@ finish_keys_response (struct TEH_KeyStateHandle *ksh)
|
|||||||
recoup,
|
recoup,
|
||||||
denoms,
|
denoms,
|
||||||
grouped_denominations,
|
grouped_denominations,
|
||||||
|
|
||||||
&grouped_hash_xor))
|
&grouped_hash_xor))
|
||||||
{
|
{
|
||||||
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
|
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
|
||||||
@ -2318,24 +2320,26 @@ finish_keys_response (struct TEH_KeyStateHandle *ksh)
|
|||||||
(const
|
(const
|
||||||
void **) &group))
|
void **) &group))
|
||||||
{
|
{
|
||||||
struct GNUNET_HashCode hc;
|
// Add the XOR over all hashes of denominations in this group to the group
|
||||||
|
|
||||||
GNUNET_CRYPTO_hash_xor (&group->hash_xor,
|
|
||||||
&grouped_hash_xor,
|
|
||||||
&grouped_hash_xor);
|
|
||||||
|
|
||||||
GNUNET_assert (0 ==
|
GNUNET_assert (0 ==
|
||||||
json_object_set (
|
json_object_set (
|
||||||
group->json,
|
group->json,
|
||||||
"hash",
|
"hash",
|
||||||
GNUNET_JSON_PACK (
|
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 ==
|
GNUNET_assert (0 ==
|
||||||
json_array_append_new (
|
json_array_append_new (
|
||||||
grouped_denominations,
|
grouped_denominations,
|
||||||
group->json));
|
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);
|
GNUNET_free (group);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -370,12 +370,17 @@ TALER_JSON_spec_amount_any_nbo (const char *name,
|
|||||||
**/
|
**/
|
||||||
struct TALER_DenominationGroup
|
struct TALER_DenominationGroup
|
||||||
{
|
{
|
||||||
/* currency must be set prior to calling TALER_JSON_spec_denomination_group */
|
|
||||||
const char *currency;
|
|
||||||
enum TALER_DenominationCipher cipher;
|
enum TALER_DenominationCipher cipher;
|
||||||
struct TALER_Amount value;
|
struct TALER_Amount value;
|
||||||
struct TALER_DenomFeeSet fees;
|
struct TALER_DenomFeeSet fees;
|
||||||
struct TALER_AgeMask age_mask;
|
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;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -265,6 +265,8 @@ parse_denomination_group (void *cls,
|
|||||||
GNUNET_JSON_spec_uint32 ("age_mask",
|
GNUNET_JSON_spec_uint32 ("age_mask",
|
||||||
&group->age_mask.bits),
|
&group->age_mask.bits),
|
||||||
&age_mask_missing),
|
&age_mask_missing),
|
||||||
|
GNUNET_JSON_spec_fixed_auto ("hash",
|
||||||
|
&group->hash),
|
||||||
GNUNET_JSON_spec_end ()
|
GNUNET_JSON_spec_end ()
|
||||||
};
|
};
|
||||||
const char *emsg;
|
const char *emsg;
|
||||||
|
@ -924,8 +924,13 @@ decode_keys_json (const json_t *resp_obj,
|
|||||||
key_data->age_mask = TALER_extensions_age_restriction_ageMask ();
|
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 *denominations_by_group;
|
||||||
json_t *group_obj;
|
json_t *group_obj;
|
||||||
@ -940,23 +945,25 @@ decode_keys_json (const json_t *resp_obj,
|
|||||||
json_typeof (denominations_by_group));
|
json_typeof (denominations_by_group));
|
||||||
|
|
||||||
json_array_foreach (denominations_by_group, group_idx, group_obj) {
|
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 = {
|
// First, parse { cipher, fees, value, age_mask, hash } of the current
|
||||||
.currency = currency
|
// group.
|
||||||
};
|
struct TALER_DenominationGroup group = { .currency = currency };
|
||||||
struct GNUNET_JSON_Specification group_spec[] = {
|
struct GNUNET_JSON_Specification group_spec[] = {
|
||||||
TALER_JSON_spec_denomination_group (NULL, &group),
|
TALER_JSON_spec_denomination_group (NULL, &group),
|
||||||
GNUNET_JSON_spec_end ()
|
GNUNET_JSON_spec_end ()
|
||||||
};
|
};
|
||||||
|
|
||||||
EXITIF (GNUNET_SYSERR ==
|
EXITIF (GNUNET_SYSERR ==
|
||||||
GNUNET_JSON_parse (group_obj,
|
GNUNET_JSON_parse (group_obj,
|
||||||
group_spec,
|
group_spec,
|
||||||
NULL,
|
NULL,
|
||||||
NULL));
|
NULL));
|
||||||
|
|
||||||
/* Now, parse the individual denominations */
|
// Now, parse the individual denominations
|
||||||
{
|
{
|
||||||
json_t *denom_keys_array;
|
json_t *denom_keys_array;
|
||||||
json_t *denom_key_obj;
|
json_t *denom_key_obj;
|
||||||
@ -970,9 +977,9 @@ decode_keys_json (const json_t *resp_obj,
|
|||||||
|
|
||||||
memset (&dk, 0, sizeof (dk));
|
memset (&dk, 0, sizeof (dk));
|
||||||
|
|
||||||
/* Set the common fields from the group for this particular
|
// Set the common fields from the group for this particular
|
||||||
* denomination. Required to make the validity check inside
|
// denomination. Required to make the validity check inside
|
||||||
* parse_json_denomkey_partially pass */
|
// parse_json_denomkey_partially pass
|
||||||
dk.key.cipher = group.cipher;
|
dk.key.cipher = group.cipher;
|
||||||
dk.value = group.value;
|
dk.value = group.value;
|
||||||
dk.fees = group.fees;
|
dk.fees = group.fees;
|
||||||
@ -987,6 +994,15 @@ decode_keys_json (const json_t *resp_obj,
|
|||||||
&key_data->master_pub,
|
&key_data->master_pub,
|
||||||
check_sig ? &hash_xor: NULL));
|
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;
|
for (unsigned int j = 0;
|
||||||
j<key_data->num_denom_keys;
|
j<key_data->num_denom_keys;
|
||||||
j++)
|
j++)
|
||||||
@ -1019,9 +1035,15 @@ decode_keys_json (const json_t *resp_obj,
|
|||||||
key_data->last_denom_issue_date
|
key_data->last_denom_issue_date
|
||||||
= GNUNET_TIME_timestamp_max (key_data->last_denom_issue_date,
|
= GNUNET_TIME_timestamp_max (key_data->last_denom_issue_date,
|
||||||
dk.valid_from);
|
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 */
|
/* parse the auditor information */
|
||||||
|
Loading…
Reference in New Issue
Block a user