diff options
Diffstat (limited to 'src/exchange/taler-exchange-httpd_keys.c')
| -rw-r--r-- | src/exchange/taler-exchange-httpd_keys.c | 161 |
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", |
