donau

Donation authority for GNU Taler (experimental)
Log | Files | Refs | Submodules | README | LICENSE

commit e5ba926767df04d48a08d57e9fb449fefb10296c
parent c02a91ecf5098342af10869465cb3e09b20d81d2
Author: Casaburi Johannes <johannes.casaburi@students.bfh.ch>
Date:   Wed, 20 Mar 2024 14:33:50 +0100

working on keys path

Diffstat:
Msrc/donau/donau-httpd_keys.c | 775+++++++++++++++++--------------------------------------------------------------
1 file changed, 162 insertions(+), 613 deletions(-)

diff --git a/src/donau/donau-httpd_keys.c b/src/donau/donau-httpd_keys.c @@ -116,85 +116,6 @@ static struct TALER_SecurityModulePublicKeyP donation_unit_cs_sm_pub; */ static struct TALER_SecurityModulePublicKeyP esign_sm_pub; -/** - * Function called to forcefully resume suspended keys requests. - * - * @param cls unused, NULL - */ -static void -keys_timeout_cb (void *cls) -{ - struct SuspendedKeysRequests *skr; - - (void) cls; - keys_tt = NULL; - while (NULL != (skr = skr_head)) - { - if (GNUNET_TIME_absolute_is_future (skr->timeout)) - break; - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Resuming /keys request due to timeout\n"); - GNUNET_CONTAINER_DLL_remove (skr_head, skr_tail, skr); - MHD_resume_connection (skr->connection); - TALER_MHD_daemon_trigger (); - GNUNET_free (skr); - } - if (NULL == skr) - return; - keys_tt = GNUNET_SCHEDULER_add_at (skr->timeout, &keys_timeout_cb, - NULL); -} - - -/** - * Suspend /keys request while we (hopefully) are waiting to be - * provisioned with key material. - * - * @param[in] connection to suspend - */ -static MHD_RESULT -suspend_request (struct MHD_Connection *connection) -{ - struct SuspendedKeysRequests *skr; - - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Suspending /keys request until key material changes\n"); - if (terminating) - { - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_EXCHANGE_GENERIC_KEYS_MISSING, - "Exchange terminating"); - } - skr = GNUNET_new (struct SuspendedKeysRequests); - skr->connection = connection; - MHD_suspend_connection (connection); - GNUNET_CONTAINER_DLL_insert (skr_head, - skr_tail, - skr); - skr->timeout = GNUNET_TIME_relative_to_absolute (KEYS_TIMEOUT); - if (NULL == keys_tt) - { - keys_tt = GNUNET_SCHEDULER_add_at (skr->timeout, - &keys_timeout_cb, - NULL); - } - skr_size++; - if (skr_size > SKR_LIMIT) - { - skr = skr_tail; - GNUNET_CONTAINER_DLL_remove (skr_head, - skr_tail, - skr); - skr_size--; - skr_connection = skr->connection; - MHD_resume_connection (skr->connection); - TALER_MHD_daemon_trigger (); - GNUNET_free (skr); - } - return MHD_YES; -} - /** * Information about a donation unit on offer by the donation unit helper. @@ -348,17 +269,6 @@ struct DH_KeyStateHandle struct GNUNET_CONTAINER_MultiPeerMap *signkey_map; /** - * Sorted array of responses to /keys (MUST be sorted by cherry-picking date) of - * length @e krd_array_length; - */ - struct KeysResponseData *krd_array; - - /** - * Length of the @e krd_array. - */ - unsigned int krd_array_length; - - /** * Information we track for thecrypto helpers. Preserved * when the @e key_generation changes, thus kept separate. */ @@ -387,19 +297,9 @@ struct DH_KeyStateHandle */ struct GNUNET_TIME_Timestamp signature_expires; -}; - -/** - * Entry in (sorted) array with possible pre-build responses for /keys. - * We keep pre-build responses for the various (valid) cherry-picking - * values around. - */ -struct KeysResponseData -{ - /** - * Response to return if the client supports (deflate) compression. - */ + * Response to return if the client supports (deflate) compression. + */ struct MHD_Response *response_compressed; /** @@ -412,14 +312,6 @@ struct KeysResponseData */ char *etag; - /** - * Cherry-picking timestamp the client must have set for this - * response to be valid. 0 if this is the "full" response. - * The client's request must include this date or a higher one - * for this response to be applicable. - */ - struct GNUNET_TIME_Timestamp cherry_pick_date; - }; /** @@ -470,36 +362,116 @@ struct HelperState }; /** - * Closure for #insert_donation_unit_cb. + * Closure for #add_sign_key_cb. */ -struct DonationUnitKeyCtx +struct SignKeyCtx { /** - * Heap for sorting active donation unit keys by start time. - */ - struct GNUNET_CONTAINER_Heap *heap; - - /** - * What is the minimum key rotation frequency of - * valid donation unit keys? + * JSON array of signing keys (being created). */ - struct GNUNET_TIME_Relative min_dk_frequency; + json_t *signkeys; }; /** - * Closure for #add_sign_key_cb. + * Function called to forcefully resume suspended keys requests. + * + * @param cls unused, NULL */ -struct SignKeyCtx +static void +keys_timeout_cb (void *cls) +{ + struct SuspendedKeysRequests *skr; + + (void) cls; + keys_tt = NULL; + while (NULL != (skr = skr_head)) + { + if (GNUNET_TIME_absolute_is_future (skr->timeout)) + break; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Resuming /keys request due to timeout\n"); + GNUNET_CONTAINER_DLL_remove (skr_head, skr_tail, skr); + MHD_resume_connection (skr->connection); + TALER_MHD_daemon_trigger (); + GNUNET_free (skr); + } + if (NULL == skr) + return; + keys_tt = GNUNET_SCHEDULER_add_at (skr->timeout, &keys_timeout_cb, + NULL); +} + + +/** + * Suspend /keys request while we (hopefully) are waiting to be + * provisioned with key material. + * + * @param[in] connection to suspend + */ +static MHD_RESULT +suspend_request (struct MHD_Connection *connection) +{ + struct SuspendedKeysRequests *skr; + + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Suspending /keys request until key material changes\n"); + if (terminating) + { + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_EXCHANGE_GENERIC_KEYS_MISSING, + "Exchange terminating"); + } + skr = GNUNET_new (struct SuspendedKeysRequests); + skr->connection = connection; + MHD_suspend_connection (connection); + GNUNET_CONTAINER_DLL_insert (skr_head, + skr_tail, + skr); + skr->timeout = GNUNET_TIME_relative_to_absolute (KEYS_TIMEOUT); + if (NULL == keys_tt) + { + keys_tt = GNUNET_SCHEDULER_add_at (skr->timeout, + &keys_timeout_cb, + NULL); + } + skr_size++; + if (skr_size > SKR_LIMIT) + { + skr = skr_tail; + GNUNET_CONTAINER_DLL_remove (skr_head, + skr_tail, + skr); + skr_size--; + skr_connection = skr->connection; + MHD_resume_connection (skr->connection); + TALER_MHD_daemon_trigger (); + GNUNET_free (skr); + } + return MHD_YES; +} + + +/** + * Closure for #insert_donation_unit_cb and #add_signkey_cb. + */ +struct KeysBuilderContext { /** - * What is the current rotation frequency for signing keys. Updated. + * Our key state. */ - struct GNUNET_TIME_Relative min_sk_frequency; + struct DH_KeyStateHandle *ksh; /** - * JSON array of signing keys (being created). + * Array of donation unit keys. + */ + json_t *donation_units; + + /** + * Array of signing keys. */ json_t *signkeys; + }; /** @@ -520,14 +492,7 @@ add_sign_key_cb (void *cls, struct SigningKey *sk = value; (void) pid; - if (GNUNET_TIME_absolute_is_future (sk->meta.expire_sign.abs_time)) - { - ctx->min_sk_frequency = - GNUNET_TIME_relative_min (ctx->min_sk_frequency, - GNUNET_TIME_absolute_get_difference ( - sk->meta.valid_from.abs_time, - sk->meta.expire_sign.abs_time)); - } + GNUNET_assert ( 0 == json_array_append_new ( @@ -578,29 +543,6 @@ setup_general_response_headers (void *cls, /** - * Closure for #insert_donation_unit_cb and #add_signkey_cb. - */ -struct KeysBuilderContext -{ - /** - * Our key state. - */ - struct DH_KeyStateHandle *ksh; - - /** - * Array of donation unit keys. - */ - json_t *donation_units; - - /** - * Array of signing keys. - */ - json_t *signkeys; - -}; - - -/** * Function called on all of our current and future donation unit keys * known to the helper process. Filters out those that are current * and adds the remaining donation unit keys (with their configuration @@ -627,16 +569,8 @@ insert_donation_unit_cb (void *cls, if (NULL != du) return GNUNET_OK; /* skip: this key is already active! */ - // if (GNUNET_TIME_relative_is_zero (hd->validity_duration)) - // return GNUNET_OK; /* this key already expired! */ - - // if (GNUNET_OK != - // load_extension_data (hd->section_name, - // &meta)) - // { - // /* Woops, couldn't determine fee structure!? */ - // return GNUNET_OK; - // } + if (GNUNET_TIME_relative_is_zero (hd->validity_duration)) + return GNUNET_OK; /* this key already expired! */ GNUNET_assert ( 0 == json_array_append_new ( @@ -644,12 +578,12 @@ insert_donation_unit_cb (void *cls, GNUNET_JSON_PACK ( GNUNET_JSON_pack_data_auto ("donation_unit_pub", &hd->donation_unit_pub), - // GNUNET_JSON_pack_uint64 ("validity_year", - // du->validity_year), - // TALER_JSON_pack_amount ("value", - // &du->value), - // GNUNET_JSON_pack_data_auto ("donation_unit_secmod_sig", - // &hd->sm_sig), + GNUNET_JSON_pack_uint64 ("validity_year", + du->validity_year), + TALER_JSON_pack_amount ("value", + &du->value), + GNUNET_JSON_pack_data_auto ("donation_unit_secmod_sig", + &hd->sm_sig), GNUNET_JSON_pack_string ("section_name", hd->section_name) ))); @@ -658,37 +592,29 @@ insert_donation_unit_cb (void *cls, /** - * Initialize @a krd using the given values for @a signkeys, + * Initialize @a ksh using the given values for @a signkeys, * and @a denoms. * - * @param[in,out] ksh key state handle we build @a krd for + * @param[in,out] ksh key state handle we build @a ksh for * @param[in] du_keys_hash hash over all the denomination keys in @a denoms - * @param last_cherry_pick_date timestamp to use * @param[in,out] signkeys list of sign keys to return * @param[in,out] grouped_donation_units list of grouped denominations to return * @return #GNUNET_OK on success */ static enum GNUNET_GenericReturnValue -create_krd (struct DH_KeyStateHandle *ksh, - const struct GNUNET_HashCode *du_keys_hash, - struct GNUNET_TIME_Timestamp last_cherry_pick_date, - json_t *signkeys, - json_t *grouped_donation_units) +create_keys_response (struct DH_KeyStateHandle *ksh, + const struct GNUNET_HashCode *du_keys_hash, + json_t *signkeys, + json_t *grouped_donation_units) { - struct KeysResponseData krd; struct DONAU_DonauPublicKeyP donau_pub; // struct DONAU_DonauSignatureP donau_sig; json_t *keys; - - // GNUNET_assert (! GNUNET_TIME_absolute_is_zero ( - // last_cherry_pick_date.abs_time)); GNUNET_assert (NULL != signkeys); GNUNET_assert (NULL != grouped_donation_units); GNUNET_assert (NULL != DH_currency); - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Creating /keys at cherry pick date %s\n", - GNUNET_TIME_timestamp2s (last_cherry_pick_date)); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Creating /keys response"); /* Sign hash over master signatures of all denomination keys until this time (in reverse order). */ @@ -700,7 +626,6 @@ create_krd (struct DH_KeyStateHandle *ksh, // DONAU_donau_online_key_set_sign ( // &TEH_keys_donau_sign2_, // ksh, - // last_cherry_pick_date, // du_keys_hash, // &donau_pub, // &donau_sig))) @@ -774,100 +699,51 @@ create_krd (struct DH_KeyStateHandle *ksh, } /* Create uncompressed response */ - krd.response_uncompressed + ksh->response_uncompressed = MHD_create_response_from_buffer (keys_jsonz_size, keys_json, MHD_RESPMEM_MUST_FREE); - GNUNET_assert (NULL != krd.response_uncompressed); + GNUNET_assert (NULL != ksh->response_uncompressed); setup_general_response_headers (ksh, - krd.response_uncompressed); + ksh->response_uncompressed); GNUNET_break (MHD_YES == - MHD_add_response_header (krd.response_uncompressed, + MHD_add_response_header (ksh->response_uncompressed, MHD_HTTP_HEADER_ETAG, etag)); /* Also compute compressed version of /keys response */ comp = TALER_MHD_body_compress (&keys_jsonz, &keys_jsonz_size); - krd.response_compressed + ksh->response_compressed = MHD_create_response_from_buffer (keys_jsonz_size, keys_jsonz, MHD_RESPMEM_MUST_FREE); - GNUNET_assert (NULL != krd.response_compressed); + GNUNET_assert (NULL != ksh->response_compressed); /* If the response is actually compressed, set the respective header. */ GNUNET_assert ( (MHD_YES != comp) || (MHD_YES == - MHD_add_response_header (krd.response_compressed, + MHD_add_response_header (ksh->response_compressed, MHD_HTTP_HEADER_CONTENT_ENCODING, "deflate")) ); setup_general_response_headers (ksh, - krd.response_compressed); + ksh->response_compressed); /* Set cache control headers: our response varies depending on these headers */ GNUNET_break (MHD_YES == - MHD_add_response_header (krd.response_compressed, + MHD_add_response_header (ksh->response_compressed, MHD_HTTP_HEADER_VARY, MHD_HTTP_HEADER_ACCEPT_ENCODING)); /* Information is always public, revalidate after 1 day */ GNUNET_break (MHD_YES == - MHD_add_response_header (krd.response_compressed, + MHD_add_response_header (ksh->response_compressed, MHD_HTTP_HEADER_CACHE_CONTROL, "public,max-age=86400")); GNUNET_break (MHD_YES == - MHD_add_response_header (krd.response_compressed, + MHD_add_response_header (ksh->response_compressed, MHD_HTTP_HEADER_ETAG, etag)); - krd.etag = GNUNET_strdup (etag); + ksh->etag = GNUNET_strdup (etag); } - krd.cherry_pick_date = last_cherry_pick_date; - GNUNET_array_append (ksh->krd_array, - ksh->krd_array_length, - krd); - return GNUNET_OK; -} - -/** - *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; - - /** - * List of denominations for the group, - * included in @e json, do not free separately! - */ - json_t *list; - - /** - * Offset of the group in the final array. - */ - unsigned int group_off; - -}; - - -/** - * Helper function called to clean up the group data - * in the denominations_by_group below. - * - * @param cls unused - * @param key unused - * @param value a `struct GroupData` to free - * @return #GNUNET_OK - */ -static int -free_group (void *cls, - const struct GNUNET_HashCode *key, - void *value) -{ - struct GroupData *gd = value; - - (void) cls; - (void) key; - GNUNET_free (gd); return GNUNET_OK; } @@ -887,13 +763,11 @@ finish_keys_response (struct DH_KeyStateHandle *ksh) enum GNUNET_GenericReturnValue ret = GNUNET_SYSERR; struct SignKeyCtx sctx; json_t *grouped_donation_units = NULL; - struct GNUNET_TIME_Timestamp last_cherry_pick_date; - struct GNUNET_CONTAINER_Heap *heap; struct GNUNET_HashContext *hash_context = NULL; + struct KeysBuilderContext kbc; sctx.signkeys = json_array (); GNUNET_assert (NULL != sctx.signkeys); - sctx.min_sk_frequency = GNUNET_TIME_UNIT_FOREVER_REL; GNUNET_CONTAINER_multipeermap_iterate (ksh->signkey_map, &add_sign_key_cb, @@ -907,241 +781,54 @@ finish_keys_response (struct DH_KeyStateHandle *ksh) goto CLEANUP; } - heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MAX); - { - struct DonationUnitKeyCtx dkc = { - .heap = heap, - .min_dk_frequency = GNUNET_TIME_UNIT_FOREVER_REL, - }; - - GNUNET_CONTAINER_multihashmap_iterate (ksh->donation_unit_map, - &insert_donation_unit_cb, - &dkc); - // ksh->rekey_frequency - // = GNUNET_TIME_relative_min (dkc.min_dk_frequency, - // sctx.min_sk_frequency); - } + GNUNET_CONTAINER_multihashmap_iterate (ksh->donation_unit_map, + &insert_donation_unit_cb, + &kbc); - hash_context = GNUNET_CRYPTO_hash_context_start (); grouped_donation_units = json_array (); GNUNET_assert (NULL != grouped_donation_units); - last_cherry_pick_date = GNUNET_TIME_UNIT_ZERO_TS; - { struct DH_DonationUnitKey *dk; - struct GNUNET_CONTAINER_MultiHashMap *donation_units_by_group; - - donation_units_by_group = - GNUNET_CONTAINER_multihashmap_create (1024, - GNUNET_NO /* NO, because keys are only on the stack */ - ); - /* heap = max heap, sorted by start time */ - while (NULL != (dk = GNUNET_CONTAINER_heap_remove_root (heap))) - { - if (! GNUNET_TIME_absolute_is_zero (last_cherry_pick_date.abs_time)) - { - /* - * This is not the first entry in the heap (because last_cherry_pick_date != - * GNUNET_TIME_UNIT_ZERO_TS) and the previous entry had a different - * start time. Therefore, we create a new entry in ksh. - */ - struct GNUNET_HashCode hc; - - // compute_msig_hash (&sig_ctx, - // &hc); - if (GNUNET_OK != - create_krd (ksh, - &hc, - last_cherry_pick_date, - sctx.signkeys, - grouped_donation_units)) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Failed to generate key response data for %s\n", - GNUNET_TIME_timestamp2s (last_cherry_pick_date)); - /* drain heap before destroying it */ - while (NULL != (dk = GNUNET_CONTAINER_heap_remove_root (heap))) - /* intentionally empty */; - GNUNET_CONTAINER_heap_destroy (heap); - goto CLEANUP; - } - } - - // last_cherry_pick_date = dk->meta.validity_year; - - /* - * Group the donation_units by {cipher, value, fees, age_mask}. - * - * For each group we save the group meta-data and the list of - * donation_units in this group as a json-blob in the multihashmap - * donation_units_by_group. - */ - { - struct GroupData *group; - json_t *entry; - struct GNUNET_HashCode key; - struct DONAU_DonationUnitGroup meta = { - .cipher = dk->donation_unit_pub.bsign_pub_key->cipher, - .value = dk->value, - }; - - /* Search the group/JSON-blob for the key */ - DONAU_donation_unit_group_get_key (&meta, - &key); - group = GNUNET_CONTAINER_multihashmap_get ( - donation_units_by_group, - &key); - if (NULL == group) - { - /* There is no group for this meta-data yet, so we create a new group */ - const char *cipher; - - switch (meta.cipher) - { - case GNUNET_CRYPTO_BSA_RSA: - cipher = "RSA"; - break; - case GNUNET_CRYPTO_BSA_CS: - cipher = "CS"; - break; - default: - GNUNET_assert (false); - } - - group = GNUNET_new (struct GroupData); - - /* Create a new array for the donation_units in this group */ - group->list = json_array (); - GNUNET_assert (NULL != group->list); - group->json = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_string ("cipher", - cipher), - GNUNET_JSON_pack_array_steal ("donation_units", - group->list), - TALER_JSON_pack_amount ("value", - &meta.value)); - GNUNET_assert (NULL != group->json); - - group->group_off - = json_array_size (grouped_donation_units); - GNUNET_assert (0 == - json_array_append_new ( - grouped_donation_units, - group->json)); - GNUNET_assert ( - GNUNET_OK == - GNUNET_CONTAINER_multihashmap_put (donation_units_by_group, - &key, - group, - GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY) - ); - } - - /* Now that we have found/created the right group, add the - denomination to the list */ - { - struct HelperDonationUnit *hd; - struct GNUNET_JSON_PackSpec key_spec; - bool private_key_lost; - - hd = GNUNET_CONTAINER_multihashmap_get (ksh->helpers->donation_unit, - &dk->h_donation_unit_pub.hash) - ; - private_key_lost - = (NULL == hd) || - GNUNET_TIME_absolute_is_past ( - GNUNET_TIME_absolute_add ( - hd->start_time.abs_time, - hd->validity_duration)); - switch (meta.cipher) - { - case GNUNET_CRYPTO_BSA_RSA: - key_spec = - GNUNET_JSON_pack_rsa_public_key ( - "rsa_pub", - dk->donation_unit_pub.bsign_pub_key->details.rsa_public_key); - break; - case GNUNET_CRYPTO_BSA_CS: - key_spec = - GNUNET_JSON_pack_data_varsize ( - "cs_pub", - &dk->donation_unit_pub.bsign_pub_key->details.cs_public_key, - sizeof (dk->donation_unit_pub.bsign_pub_key->details. - cs_public_key)); - break; - default: - GNUNET_assert (false); - } - - entry = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_allow_null ( - private_key_lost - ? GNUNET_JSON_pack_bool ("lost", - true) - : GNUNET_JSON_pack_string ("dummy", - NULL)), - key_spec - ); - GNUNET_assert (NULL != entry); - } - - /* Build up the running hash of all master signatures of the - donation_units */ - // append_signature (&sig_ctx, - // group->group_off, - // (unsigned int) json_array_size (group->list), - // &dk->master_sig); - - /* Finally, add the denomination to the list of donation_units in this - group */ - GNUNET_assert (json_is_array (group->list)); - GNUNET_assert (0 == - json_array_append_new (group->list, - entry)); - } - } /* loop over heap ends */ - - GNUNET_CONTAINER_multihashmap_iterate (donation_units_by_group, - &free_group, - NULL); - GNUNET_CONTAINER_multihashmap_destroy (donation_units_by_group); - } - GNUNET_CONTAINER_heap_destroy (heap); - // if (! GNUNET_TIME_absolute_is_zero (last_cherry_pick_date.abs_time)) - if (true) - { - struct GNUNET_HashCode hc; - - GNUNET_CRYPTO_hash_context_finish (hash_context, &hc); - if (GNUNET_OK != - create_krd (ksh, - &hc, - last_cherry_pick_date, - sctx.signkeys, - grouped_donation_units)) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Failed to generate key response data for %s\n", - GNUNET_TIME_timestamp2s (last_cherry_pick_date)); - goto CLEANUP; - } + // while (NULL != (dk = )) + // { +// + // struct GNUNET_HashCode hc; + // // compute_msig_hash (&sig_ctx, + // // &hc); + // if (GNUNET_OK != + // create_keys_response (ksh, + // &hc, + // sctx.signkeys, + // grouped_donation_units)) + // { + // GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + // "Failed to generate key response data\n"); + // goto CLEANUP; + // } +// + // } } - else + + struct GNUNET_HashCode hc; + GNUNET_CRYPTO_hash_context_finish (hash_context, &hc); + if (GNUNET_OK != + create_keys_response (ksh, + &hc, + sctx.signkeys, + kbc.donation_units)) { - GNUNET_log ( - GNUNET_ERROR_TYPE_WARNING, - "No donation unit keys available. Refusing to generate /keys response.\n") - ; - GNUNET_CRYPTO_hash_context_abort (hash_context); + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Failed to generate key response data\n"); + goto CLEANUP; } ret = GNUNET_OK; CLEANUP: - json_decref (grouped_donation_units); + // json_decref (grouped_donation_units); if (NULL != sctx.signkeys) json_decref (sctx.signkeys); return ret; @@ -1201,15 +888,8 @@ clear_signkey_cb (void *cls, static void clear_response_cache (struct DH_KeyStateHandle *ksh) { - for (unsigned int i = 0; i < ksh->krd_array_length; i++) - { - struct KeysResponseData *krd = &ksh->krd_array[i]; - - MHD_destroy_response (krd->response_compressed); - MHD_destroy_response (krd->response_uncompressed); - GNUNET_free (krd->etag); - } - GNUNET_array_grow (ksh->krd_array, ksh->krd_array_length, 0); + MHD_destroy_response (ksh->response_compressed); + MHD_destroy_response (ksh->response_uncompressed); } @@ -1940,6 +1620,7 @@ build_key_state (struct HelperState *hs) /* NOTE: fetches master-signed signkeys, but ALSO those that were revoked! */ GNUNET_break (GNUNET_OK == DH_plugin->preflight (DH_plugin->cls)); + qs = DH_plugin->iterate_donation_units (DH_plugin->cls, &donation_unit_info_cb, ksh); @@ -2182,29 +1863,6 @@ DH_handler_keys (struct DH_RequestContext *rc, /** - * Comparator used for a binary search by cherry_pick_date for @a key in the - * `struct KeysResponseData` array. See libc's qsort() and bsearch() functions. - * - * @param key pointer to a `struct GNUNET_TIME_Timestamp` - * @param value pointer to a `struct KeysResponseData` array entry - * @return 0 if time matches, -1 if key is smaller, 1 if key is larger - */ -static int -krd_search_comparator (const void *key, - const void *value) -{ - const struct GNUNET_TIME_Timestamp *kd = key; - const struct KeysResponseData *krd = value; - - if (GNUNET_TIME_timestamp_cmp (*kd, >, krd->cherry_pick_date)) - return -1; - if (GNUNET_TIME_timestamp_cmp (*kd, <, krd->cherry_pick_date)) - return 1; - return 0; -} - - -/** * Callback used to set headers in a response. * * @param cls closure @@ -2238,113 +1896,4 @@ DH_RESPONSE_reply_not_modified (struct MHD_Connection *connection, } -// MHD_RESULT -// DH_keys_get_handler (struct DH_RequestContext *rc, -// const char *const args[]) -// { -// struct GNUNET_TIME_Timestamp last_issue_date; -// const char *etag; -// -// etag = MHD_lookup_connection_value (rc->connection, -// MHD_HEADER_KIND, -// MHD_HTTP_HEADER_IF_NONE_MATCH); -// (void) args; -// { -// const char *have_cherrypick; -// -// have_cherrypick = MHD_lookup_connection_value (rc->connection, -// MHD_GET_ARGUMENT_KIND, -// "last_issue_date"); -// if (NULL != have_cherrypick) -// { -// unsigned long long cherrypickn; -// -// if (1 != -// sscanf (have_cherrypick, -// "%llu", -// &cherrypickn)) -// { -// GNUNET_break_op (0); -// return TALER_MHD_reply_with_error (rc->connection, -// MHD_HTTP_BAD_REQUEST, -// TALER_EC_GENERIC_PARAMETER_MALFORMED, -// have_cherrypick); -// } -// /* The following multiplication may overflow; but this should not really -// be a problem, as giving back 'older' data than what the client asks for -// (given that the client asks for data in the distant future) is not -// problematic */ -// last_issue_date = GNUNET_TIME_timestamp_from_s (cherrypickn); -// } -// else -// { -// last_issue_date = GNUNET_TIME_UNIT_ZERO_TS; -// } -// } -// -// { -// struct DH_KeyStateHandle *ksh; -// const struct KeysResponseData *krd; -// -// ksh = DH_keys_get_state (); -// if ( (NULL == ksh) || -// (0 == ksh->krd_array_length) ) -// { -// if ( ( (SKR_LIMIT == skr_size) && -// (rc->connection == skr_connection) ) || -// DH_suicide) -// { -// return TALER_MHD_reply_with_error ( -// rc->connection, -// MHD_HTTP_SERVICE_UNAVAILABLE, -// TALER_EC_EXCHANGE_GENERIC_KEYS_MISSING, -// DH_suicide -// ? "server terminating" -// : "too many connections suspended waiting on /keys"); -// } -// return suspend_request (rc->connection); -// } -// krd = bsearch (&last_issue_date, -// ksh->krd_array, -// ksh->krd_array_length, -// sizeof (struct KeysResponseData), -// &krd_search_comparator); -// GNUNET_log (GNUNET_ERROR_TYPE_INFO, -// "Filtering /keys by cherry pick date %s found entry %u/%u\n", -// GNUNET_TIME_timestamp2s (last_issue_date), -// (unsigned int) (krd - ksh->krd_array), -// ksh->krd_array_length); -// if ( (NULL == krd) && -// (ksh->krd_array_length > 0) ) -// { -// if (! GNUNET_TIME_absolute_is_zero (last_issue_date.abs_time)) -// GNUNET_log (GNUNET_ERROR_TYPE_WARNING, -// "Client provided invalid cherry picking timestamp %s, returning full response\n", -// GNUNET_TIME_timestamp2s (last_issue_date)); -// krd = &ksh->krd_array[ksh->krd_array_length - 1]; -// } -// if (NULL == krd) -// { -// /* Likely keys not ready *yet*. -// Wait until they are. */ -// return suspend_request (rc->connection); -// } -// if ( (NULL != etag) && -// (0 == strcmp (etag, -// krd->etag)) ) -// return DH_RESPONSE_reply_not_modified (rc->connection, -// krd->etag, -// &setup_general_response_headers, -// ksh); -// -// return MHD_queue_response (rc->connection, -// MHD_HTTP_OK, -// (MHD_YES == -// TALER_MHD_can_compress (rc->connection)) -// ? krd->response_compressed -// : krd->response_uncompressed); -// } -// } - - /* end of donau-httpd_keys.c */