donau

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

commit 24c840c27efbf3ce6c4bd321e26de1d11efcc96a
parent 71f9e391a3d2a3137bdd8c6d2362a9e502914175
Author: Casaburi Johannes <johannes.casaburi@students.bfh.ch>
Date:   Thu,  4 Jan 2024 16:29:40 +0100

Working on key path

Diffstat:
Msrc/donau/donau-httpd.c | 4+++-
Msrc/donau/donau-httpd_keys.c | 869+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------
Msrc/donau/donau-httpd_keys.h | 6+++---
3 files changed, 766 insertions(+), 113 deletions(-)

diff --git a/src/donau/donau-httpd.c b/src/donau/donau-httpd.c @@ -199,6 +199,7 @@ r404 (struct MHD_Connection *connection, details); } + /** * Function called whenever MHD is done with a request. If the * request was a POST, we may have stored a `struct Buffer *` in the @@ -397,6 +398,7 @@ proceed_with_handler (struct DH_RequestContext *rc, return ret; } + /** * Handle a GET "/management" request. * @@ -414,7 +416,7 @@ handle_get_management (struct DH_RequestContext *rc, (NULL == args[1]) ) { return DH_keys_management_get_keys_handler (rc->rh, - rc->connection); + rc->connection); } GNUNET_break_op (0); return r404 (rc->connection, diff --git a/src/donau/donau-httpd_keys.c b/src/donau/donau-httpd_keys.c @@ -24,8 +24,8 @@ #include "taler/taler_mhd_lib.h" #include "donau-httpd.h" #include "donau-httpd_keys.h" -//#include "donau-httpd_config.h" -//#include "donau-httpd_responses.h" +// #include "donau-httpd_config.h" +// #include "donau-httpd_responses.h" #include "donaudb_plugin.h" @@ -35,6 +35,28 @@ */ #define SKR_LIMIT 32 +/** + * Counter incremented whenever we have a reason to re-build the keys because + * something external changed. See #DH_keys_get_state() and + * #DH_keys_update_states() for uses of this variable. + */ +static uint64_t key_generation; + +/** + * RSA security module public key, all zero if not known. + */ +static struct TALER_SecurityModulePublicKeyP donation_unit_rsa_sm_pub; + +/** + * CS security module public key, all zero if not known. + */ +static struct TALER_SecurityModulePublicKeyP donation_unit_cs_sm_pub; + +/** + * EdDSA security module public key, all zero if not known. + */ +static struct TALER_SecurityModulePublicKeyP esign_sm_pub; + /** * When do we forcefully timeout a /keys request? @@ -72,10 +94,107 @@ struct SigningKey }; +struct DH_KeyStateHandle +{ + + /** + * Mapping from denomination keys to denomination key issue struct. + * Used to lookup the key by hash. + */ + struct GNUNET_CONTAINER_MultiHashMap *denomkey_map; + + /** + * Map from `struct TALER_ExchangePublicKey` to `struct SigningKey` + * entries. Based on the fact that a `struct GNUNET_PeerIdentity` is also + * an EdDSA public key. + */ + 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. + */ + struct HelperState *helpers; + + /** + * Cached reply for a GET /management/keys request. Used so we do not + * re-create the reply every time. + */ + json_t *management_keys_reply; + + /** + * For which (global) key_generation was this data structure created? + * Used to check when we are outdated and need to be re-generated. + */ + uint64_t key_generation; + + /** + * When did we initiate the key reloading? + */ + struct GNUNET_TIME_Timestamp reload_time; + + /** + * When does our online signing key expire and we + * thus need to re-generate this response? + */ + struct GNUNET_TIME_Timestamp signature_expires; + + /** + * True if #finish_keys_response() was not yet run and this key state + * is only suitable for the /management/keys API. + */ + bool management_only; + +}; + +/** + * 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. + */ + struct MHD_Response *response_compressed; + + /** + * Response to return if the client does not support compression. + */ + struct MHD_Response *response_uncompressed; + + /** + * ETag for these responses. + */ + 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; + +}; + /** * State associated with the crypto helpers / security modules. NOT updated * when the #key_generation is updated (instead constantly kept in sync - * whenever #TEH_keys_get_state() is called). + * whenever #DH_keys_get_state() is called). */ struct HelperState { @@ -86,19 +205,19 @@ struct HelperState struct TALER_CRYPTO_ExchangeSignHelper *esh; /** - * Handle for the denom/RSA helper. + * Handle for the donation_unit/RSA helper. */ struct TALER_CRYPTO_RsaDenominationHelper *rsadh; /** - * Handle for the denom/CS helper. + * Handle for the donation_unit/CS helper. */ struct TALER_CRYPTO_CsDenominationHelper *csdh; /** - * Map from H(denom_pub) to `struct HelperDenomination` entries. + * Map from H(donation_unit_pub) to `struct HelperDenomination` entries. */ - struct GNUNET_CONTAINER_MultiHashMap *denom_keys; + struct GNUNET_CONTAINER_MultiHashMap *donation_unit_keys; /** * Map from H(rsa_pub) to `struct HelperDenomination` entries. @@ -119,56 +238,589 @@ struct HelperState }; -//static struct TEH_KeyStateHandle * -//keys_get_state (bool management_only) -//{ -// struct TEH_KeyStateHandle *old_ksh; -// struct TEH_KeyStateHandle *ksh; -// -// old_ksh = key_state; -// if (NULL == old_ksh) -// { -// ksh = build_key_state (NULL, -// management_only); -// if (NULL == ksh) -// return NULL; -// key_state = ksh; -// return ksh; -// } -// if ( (old_ksh->key_generation < key_generation) || -// (GNUNET_TIME_absolute_is_past (old_ksh->signature_expires.abs_time)) ) -// { -// GNUNET_log (GNUNET_ERROR_TYPE_INFO, -// "Rebuilding /keys, generation upgrade from %llu to %llu\n", -// (unsigned long long) old_ksh->key_generation, -// (unsigned long long) key_generation); -// ksh = build_key_state (old_ksh->helpers, -// management_only); -// key_state = ksh; -// old_ksh->helpers = NULL; -// destroy_key_state (old_ksh, -// false); -// return ksh; -// } -// sync_key_helpers (old_ksh->helpers); -// return old_ksh; -//} - -//struct DH_KeyStateHandle * -//DH_keys_get_state_for_management_only (void) -//{ -// return keys_get_state (true); -//} +/** + * Closure for #add_denom_key_cb. + */ +struct DenomKeyCtx +{ + /** + * Heap for sorting active denomination keys by start time. + */ + struct GNUNET_CONTAINER_Heap *heap; + + /** + * JSON array of revoked denomination keys. + */ + json_t *recoup; + + /** + * What is the minimum key rotation frequency of + * valid denomination keys? + */ + struct GNUNET_TIME_Relative min_dk_frequency; +}; + +/** + * Closure for #add_sign_key_cb. + */ +struct SignKeyCtx +{ + /** + * What is the current rotation frequency for signing keys. Updated. + */ + struct GNUNET_TIME_Relative min_sk_frequency; + + /** + * JSON array of signing keys (being created). + */ + json_t *signkeys; +}; + +/** + * Function called for all signing keys, used to build up the + * respective JSON response. + * + * @param cls a `struct SignKeyCtx *` with the array to append keys to + * @param pid the exchange public key (in type disguise) + * @param value a `struct SigningKey` + * @return #GNUNET_OK (continue to iterate) + */ +static enum GNUNET_GenericReturnValue +add_sign_key_cb (void *cls, + const struct GNUNET_PeerIdentity *pid, + void *value) +{ + struct SignKeyCtx *ctx = 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.start.abs_time, + // sk->meta.expire_sign.abs_time)); + //} + GNUNET_assert ( + 0 == + json_array_append_new ( + ctx->signkeys, + GNUNET_JSON_PACK ( + //GNUNET_JSON_pack_timestamp ("stamp_start", + // sk->meta.start), + //GNUNET_JSON_pack_timestamp ("stamp_expire", + // sk->meta.expire_sign), + //GNUNET_JSON_pack_timestamp ("stamp_end", + // sk->meta.expire_legal), + //GNUNET_JSON_pack_data_auto ("master_sig", + // &sk->master_sig), + GNUNET_JSON_pack_data_auto ("key", + &sk->donau_pub)))); + return GNUNET_OK; +} + + + +/** + * Add the headers we want to set for every /keys response. + * + * @param cls the key state to use + * @param[in,out] response the response to modify + */ +static void +setup_general_response_headers (void *cls, + struct MHD_Response *response) +{ + struct DH_KeyStateHandle *ksh = cls; + char dat[128]; + + TALER_MHD_add_global_headers (response); + GNUNET_break (MHD_YES == + MHD_add_response_header (response, + MHD_HTTP_HEADER_CONTENT_TYPE, + "application/json")); + TALER_MHD_get_date_string (ksh->reload_time.abs_time, + dat); + GNUNET_break (MHD_YES == + MHD_add_response_header (response, + MHD_HTTP_HEADER_LAST_MODIFIED, + dat)); + /* Set cache control headers: our response varies depending on these headers */ + GNUNET_break (MHD_YES == + MHD_add_response_header (response, + MHD_HTTP_HEADER_VARY, + MHD_HTTP_HEADER_ACCEPT_ENCODING)); + /* Information is always public, revalidate after 1 hour */ + GNUNET_break (MHD_YES == + MHD_add_response_header (response, + MHD_HTTP_HEADER_CACHE_CONTROL, + "public,max-age=3600")); +} + +/** + * Update the "/keys" responses in @a ksh, computing the detailed replies. + * + * This function is to recompute all (including cherry-picked) responses we + * might want to return, based on the state already in @a ksh. + * + * @param[in,out] ksh state handle to update + * @return #GNUNET_OK on success + */ +static enum GNUNET_GenericReturnValue +finish_keys_response (struct DH_KeyStateHandle *ksh) +{ + enum GNUNET_GenericReturnValue ret = GNUNET_SYSERR; + json_t *recoup; + struct SignKeyCtx sctx; + json_t *grouped_denominations = NULL; + struct GNUNET_TIME_Timestamp last_cherry_pick_date; + 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); + sctx.min_sk_frequency = GNUNET_TIME_UNIT_FOREVER_REL; + GNUNET_CONTAINER_multipeermap_iterate (ksh->signkey_map, + &add_sign_key_cb, + &sctx); + recoup = json_array (); + GNUNET_assert (NULL != recoup); + heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MAX); + { + struct DenomKeyCtx dkc = { + .recoup = recoup, + .heap = heap, + .min_dk_frequency = GNUNET_TIME_UNIT_FOREVER_REL, + }; + + //GNUNET_CONTAINER_multihashmap_iterate (ksh->denomkey_map, + // &add_denom_key_cb, + // &dkc); + //ksh->rekey_frequency + // = GNUNET_TIME_relative_min (dkc.min_dk_frequency, + // sctx.min_sk_frequency); + } + + hash_context = GNUNET_CRYPTO_hash_context_start (); + + grouped_denominations = json_array (); + GNUNET_assert (NULL != grouped_denominations); + + last_cherry_pick_date = GNUNET_TIME_UNIT_ZERO_TS; + + GNUNET_CONTAINER_heap_destroy (heap); + if (! GNUNET_TIME_absolute_is_zero (last_cherry_pick_date.abs_time)) + { + 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, + // recoup, + // grouped_denominations, + // &grouped_hash_xor)) + //{ + // GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + // "Failed to generate key response data for %s\n", + // GNUNET_TIME_timestamp2s (last_cherry_pick_date)); + // goto CLEANUP; + //} + ksh->management_only = false; + } + else + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "No denomination keys available. Refusing to generate /keys response.\n"); + GNUNET_CRYPTO_hash_context_abort (hash_context); + } + + ret = GNUNET_OK; + +CLEANUP: + json_decref (grouped_denominations); + json_decref (sctx.signkeys); + json_decref (recoup); + return ret; +} + +/** + * Free denomination key data. + * + * @param cls a `struct DH_KeyStateHandle`, unused + * @param h_donation_unit_pub hash of the denomination public key, unused + * @param value a `struct DH_DonationUnitKey` to free + * @return #GNUNET_OK (continue to iterate) + */ +static enum GNUNET_GenericReturnValue +clear_denomination_cb (void *cls, + const struct GNUNET_HashCode *h_donation_unit_pub, + void *value) +{ + struct DH_DonationUnitKey *dk = value; + + (void) cls; + (void) h_donation_unit_pub; + //TALER_denom_pub_free (&dk->denom_pub); + GNUNET_free (dk); + return GNUNET_OK; +} + + +/** + * Free denomination key data. + * + * @param cls a `struct DH_KeyStateHandle`, unused + * @param pid the online signing key (type-disguised), unused + * @param value a `struct SigningKey` to free + * @return #GNUNET_OK (continue to iterate) + */ +static enum GNUNET_GenericReturnValue +clear_signkey_cb (void *cls, + const struct GNUNET_PeerIdentity *pid, + void *value) +{ + struct SigningKey *sk = value; + + (void) cls; + (void) pid; + GNUNET_free (sk); + return GNUNET_OK; +} + +/** + * Clear memory for responses to "/keys" in @a ksh. + * + * @param[in,out] ksh key state to update + */ +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); +} + +/** + * Synchronize helper state. Polls the key helper for updates. + * + * @param[in,out] hs helper state to synchronize + */ +static void +sync_key_helpers (struct HelperState *hs) +{ + TALER_CRYPTO_helper_rsa_poll (hs->rsadh); + TALER_CRYPTO_helper_cs_poll (hs->csdh); + TALER_CRYPTO_helper_esign_poll (hs->esh); +} + +/** + * Destroy helper state. Does NOT call free() on @a hs, as that + * state is not separately allocated! Dual to #setup_key_helpers(). + * + * @param[in] hs helper state to free, but NOT the @a hs pointer itself! + */ +static void +destroy_key_helpers (struct HelperState *hs) +{ + //GNUNET_CONTAINER_multihashmap_iterate (hs->denom_keys, + // &free_denom_cb, + // hs); + //GNUNET_CONTAINER_multihashmap_destroy (hs->rsa_keys); + //hs->rsa_keys = NULL; + //GNUNET_CONTAINER_multihashmap_destroy (hs->cs_keys); + //hs->cs_keys = NULL; + //GNUNET_CONTAINER_multihashmap_destroy (hs->denom_keys); + //hs->denom_keys = NULL; + //GNUNET_CONTAINER_multipeermap_iterate (hs->esign_keys, + // &free_esign_cb, + // hs); + //GNUNET_CONTAINER_multipeermap_destroy (hs->esign_keys); + hs->esign_keys = NULL; + if (NULL != hs->rsadh) + { + TALER_CRYPTO_helper_rsa_disconnect (hs->rsadh); + hs->rsadh = NULL; + } + if (NULL != hs->csdh) + { + TALER_CRYPTO_helper_cs_disconnect (hs->csdh); + hs->csdh = NULL; + } + if (NULL != hs->esh) + { + TALER_CRYPTO_helper_esign_disconnect (hs->esh); + hs->esh = NULL; + } +} + +/** + * Free resources associated with @a cls, possibly excluding + * the helper data. + * + * @param[in] ksh key state to release + * @param free_helper true to also release the helper state + */ +static void +destroy_key_state (struct DH_KeyStateHandle *ksh, + bool free_helper) +{ + struct DH_GlobalFee *gf; + + clear_response_cache (ksh); + //while (NULL != (gf = ksh->gf_head)) + //{ + // GNUNET_CONTAINER_DLL_remove (ksh->gf_head, + // ksh->gf_tail, + // gf); + // GNUNET_free (gf); + //} + GNUNET_CONTAINER_multihashmap_iterate (ksh->denomkey_map, + &clear_denomination_cb, + ksh); + GNUNET_CONTAINER_multihashmap_destroy (ksh->denomkey_map); + GNUNET_CONTAINER_multipeermap_iterate (ksh->signkey_map, + &clear_signkey_cb, + ksh); + GNUNET_CONTAINER_multipeermap_destroy (ksh->signkey_map); + //json_decref (ksh->auditors); + //ksh->auditors = NULL; + //json_decref (ksh->global_fees); + //ksh->global_fees = NULL; + if (free_helper) + { + destroy_key_helpers (ksh->helpers); + GNUNET_free (ksh->helpers); + } + if (NULL != ksh->management_keys_reply) + { + json_decref (ksh->management_keys_reply); + ksh->management_keys_reply = NULL; + } + GNUNET_free (ksh); +} + +/** + * Setup helper state. + * + * @param[out] hs helper state to initialize + * @return #GNUNET_OK on success + */ +static enum GNUNET_GenericReturnValue +setup_key_helpers (struct HelperState *hs) +{ + //hs->denom_keys + // = GNUNET_CONTAINER_multihashmap_create (1024, + // GNUNET_YES); + hs->rsa_keys + = GNUNET_CONTAINER_multihashmap_create (1024, + GNUNET_YES); + hs->cs_keys + = GNUNET_CONTAINER_multihashmap_create (1024, + GNUNET_YES); + hs->esign_keys + = GNUNET_CONTAINER_multipeermap_create (32, + GNUNET_NO /* MUST BE NO! */); + //hs->rsadh = TALER_CRYPTO_helper_rsa_connect (DH_cfg, + // &helper_rsa_cb, + // hs); + //if (NULL == hs->rsadh) + //{ + // destroy_key_helpers (hs); + // return GNUNET_SYSERR; + //} + //hs->csdh = TALER_CRYPTO_helper_cs_connect (DH_cfg, + // &helper_cs_cb, + // hs); + //if (NULL == hs->csdh) + //{ + // destroy_key_helpers (hs); + // return GNUNET_SYSERR; + //} + //hs->esh = TALER_CRYPTO_helper_esign_connect (DH_cfg, + // &helper_esign_cb, + // hs); + //if (NULL == hs->esh) + //{ + // destroy_key_helpers (hs); + // return GNUNET_SYSERR; + //} + return GNUNET_OK; +} + +/** + * Create a key state. + * + * @param[in] hs helper state to (re)use, NULL if not available + * @param management_only if we should NOT run 'finish_keys_response()' + * because we only need the state for the /management/keys API + * @return NULL on error (i.e. failed to access database) + */ +static struct DH_KeyStateHandle * +build_key_state (struct HelperState *hs, + bool management_only) +{ + struct DH_KeyStateHandle *ksh; + enum GNUNET_DB_QueryStatus qs; + + ksh = GNUNET_new (struct DH_KeyStateHandle); + ksh->signature_expires = GNUNET_TIME_UNIT_FOREVER_TS; + ksh->reload_time = GNUNET_TIME_timestamp_get (); + /* We must use the key_generation from when we STARTED the process! */ + ksh->key_generation = key_generation; + if (NULL == hs) + { + ksh->helpers = GNUNET_new (struct HelperState); + if (GNUNET_OK != + setup_key_helpers (ksh->helpers)) + { + GNUNET_free (ksh->helpers); + GNUNET_assert (NULL == ksh->management_keys_reply); + GNUNET_free (ksh); + return NULL; + } + } + else + { + ksh->helpers = hs; + } + ksh->denomkey_map = GNUNET_CONTAINER_multihashmap_create (1024, + true); + ksh->signkey_map = GNUNET_CONTAINER_multipeermap_create (32, + false /* MUST be false! */ + ); + /* NOTE: fetches master-signed signkeys, but ALSO those that were revoked! */ + GNUNET_break (GNUNET_OK == + DH_plugin->preflight (DH_plugin->cls)); + if (qs < 0) + { + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR != qs); + GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR != qs); + destroy_key_state (ksh, + true); + return NULL; + } + //qs = DH_plugin->iterate_denominations (DH_plugin->cls, + // &denomination_info_cb, + // ksh); + //if (qs < 0) + //{ + // GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR != qs); + // GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR != qs); + // destroy_key_state (ksh, + // true); + // return NULL; + //} + /* NOTE: ONLY fetches non-revoked AND master-signed signkeys! */ + //qs = DH_plugin->iterate_active_signkeys (DH_plugin->cls, + // &signkey_info_cb, + // ksh); + //if (qs < 0) + //{ + // GNUNET_break (0); + // destroy_key_state (ksh, + // true); + // return NULL; + //} + + if (management_only) + { + ksh->management_only = true; + return ksh; + } + + if (GNUNET_OK != + finish_keys_response (ksh)) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Could not finish /keys response (likely no signing keys available yet)\n"); + destroy_key_state (ksh, + true); + return NULL; + } + + return ksh; +} + + +void +DH_keys_update_states () +{ + struct GNUNET_DB_EventHeaderP es = { + .size = htons (sizeof (es)), + //.type = htons (TALER_DBEVENT_DONAU_KEYS_UPDATED), + }; + + DH_plugin->event_notify (DH_plugin->cls, + &es, + NULL, + 0); + key_generation++; + //DH_resume_keys_requests (false); +} + +static struct DH_KeyStateHandle * +keys_get_state (bool management_only) +{ + struct DH_KeyStateHandle *old_ksh; + struct DH_KeyStateHandle *ksh; + old_ksh = key_state; + if (NULL == old_ksh) + { + //ksh = build_key_state (NULL, management_only); + ksh = NULL; + if (NULL == ksh) + return NULL; + key_state = ksh; + return ksh; + } + if ( (old_ksh->key_generation < key_generation) || + (GNUNET_TIME_absolute_is_past (old_ksh->signature_expires.abs_time)) ) + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Rebuilding /keys, generation upgrade from %llu to %llu\n", + (unsigned long long) old_ksh->key_generation, + (unsigned long long) key_generation); + ksh = build_key_state (old_ksh->helpers, + management_only); + key_state = ksh; + old_ksh->helpers = NULL; + destroy_key_state (old_ksh, + false); + return ksh; + } + sync_key_helpers (old_ksh->helpers); + return old_ksh; +} + +struct DH_KeyStateHandle * +DH_keys_get_state_for_management_only (void) +{ + return keys_get_state (true); +} MHD_RESULT DH_keys_management_get_keys_handler (const struct DH_RequestHandler *rh, - struct MHD_Connection *connection) + struct MHD_Connection *connection) { struct DH_KeyStateHandle *ksh; json_t *reply; (void) rh; - //ksh = DH_keys_get_state_for_management_only (); + // ksh = DH_keys_get_state_for_management_only (); ksh = NULL; if (NULL == ksh) { @@ -177,66 +829,65 @@ DH_keys_management_get_keys_handler (const struct DH_RequestHandler *rh, TALER_EC_EXCHANGE_GENERIC_KEYS_MISSING, "no key state"); } - //sync_key_helpers (ksh->helpers); - //if (NULL == ksh->management_keys_reply) - //{ - // struct FutureBuilderContext fbc = { - // .ksh = ksh, - // .denoms = json_array (), - // .signkeys = json_array () - // }; -// - // if ( (GNUNET_is_zero (&denom_rsa_sm_pub)) && - // (GNUNET_is_zero (&denom_cs_sm_pub)) ) - // { - // /* Either IPC failed, or neither helper had any denominations configured. */ - // return TALER_MHD_reply_with_error (connection, - // MHD_HTTP_BAD_GATEWAY, - // TALER_EC_EXCHANGE_DENOMINATION_HELPER_UNAVAILABLE, - // NULL); - // } - // if (GNUNET_is_zero (&esign_sm_pub)) - // { - // return TALER_MHD_reply_with_error (connection, - // MHD_HTTP_BAD_GATEWAY, - // TALER_EC_EXCHANGE_SIGNKEY_HELPER_UNAVAILABLE, - // NULL); - // } - // //GNUNET_assert (NULL != fbc.denoms); - // //GNUNET_assert (NULL != fbc.signkeys); - // GNUNET_CONTAINER_multihashmap_iterate (ksh->helpers->denom_keys, - // &add_future_denomkey_cb, - // &fbc); - // GNUNET_CONTAINER_multipeermap_iterate (ksh->helpers->esign_keys, - // &add_future_signkey_cb, - // &fbc); - // reply = GNUNET_JSON_PACK ( - // //GNUNET_JSON_pack_array_steal ("future_denoms", - // // fbc.denoms), - // //GNUNET_JSON_pack_array_steal ("future_signkeys", - // // fbc.signkeys), - // //GNUNET_JSON_pack_data_auto ("master_pub", - // // &DH_master_public_key), - // GNUNET_JSON_pack_data_auto ("denom_secmod_public_key", - // &denom_rsa_sm_pub), - // GNUNET_JSON_pack_data_auto ("denom_secmod_cs_public_key", - // &denom_cs_sm_pub), - // GNUNET_JSON_pack_data_auto ("signkey_secmod_public_key", - // &esign_sm_pub)); - // GNUNET_log (GNUNET_ERROR_TYPE_INFO, - // "Returning GET /management/keys response:\n"); - // if (NULL == reply) - // return TALER_MHD_reply_with_error (connection, - // MHD_HTTP_INTERNAL_SERVER_ERROR, - // TALER_EC_GENERIC_JSON_ALLOCATION_FAILURE, - // NULL); - // GNUNET_assert (NULL == ksh->management_keys_reply); - // ksh->management_keys_reply = reply; - //} - //else - //{ - // reply = ksh->management_keys_reply; - //} + sync_key_helpers (ksh->helpers); + if (NULL == ksh->management_keys_reply) + { + //struct FutureBuilderContext fbc = { + // .ksh = ksh, + // .donation_units = json_array (), + // .signkeys = json_array () + //}; + if ( (GNUNET_is_zero (&donation_unit_rsa_sm_pub)) && + (GNUNET_is_zero (&donation_unit_cs_sm_pub)) ) + { + /* Either IPC failed, or neither helper had any donation_unitinations configured. */ + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_BAD_GATEWAY, + TALER_EC_EXCHANGE_DENOMINATION_HELPER_UNAVAILABLE, + NULL); + } + if (GNUNET_is_zero (&esign_sm_pub)) + { + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_BAD_GATEWAY, + TALER_EC_EXCHANGE_SIGNKEY_HELPER_UNAVAILABLE, + NULL); + } + //GNUNET_assert (NULL != fbc.donation_units); + //GNUNET_assert (NULL != fbc.signkeys); + //GNUNET_CONTAINER_multihashmap_iterate (ksh->helpers->donation_unit_keys, + // &add_future_donation_unitkey_cb, + // &fbc); + //GNUNET_CONTAINER_multipeermap_iterate (ksh->helpers->esign_keys, + // &add_future_signkey_cb, + // &fbc); + reply = GNUNET_JSON_PACK ( + //GNUNET_JSON_pack_array_steal ("future_donation_units", + // fbc.donation_units), + //GNUNET_JSON_pack_array_steal ("future_signkeys", + // fbc.signkeys), + //GNUNET_JSON_pack_data_auto ("master_pub", + // &DH_master_public_key), + GNUNET_JSON_pack_data_auto ("donation_unit_secmod_public_key", + &donation_unit_rsa_sm_pub), + GNUNET_JSON_pack_data_auto ("donation_unit_secmod_cs_public_key", + &donation_unit_cs_sm_pub), + GNUNET_JSON_pack_data_auto ("signkey_secmod_public_key", + &esign_sm_pub)); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Returning GET /management/keys response:\n"); + if (NULL == reply) + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_GENERIC_JSON_ALLOCATION_FAILURE, + NULL); + GNUNET_assert (NULL == ksh->management_keys_reply); + ksh->management_keys_reply = reply; + } + else + { + reply = ksh->management_keys_reply; + } return TALER_MHD_reply_json (connection, reply, MHD_HTTP_OK); diff --git a/src/donau/donau-httpd_keys.h b/src/donau/donau-httpd_keys.h @@ -21,7 +21,7 @@ #include "taler/platform.h" #include "taler/taler_json_lib.h" #include "taler/taler_mhd_lib.h" -//#include "donau-httpd_responses.h" +// #include "donau-httpd_responses.h" #include "donau_util.h" @@ -51,7 +51,7 @@ struct DH_DonationUnitKey * Meta data about the type of the donation unit, containing the validity * year and the value of the donation unit. */ - //struct DONAUDB_DonationUnitKeyMetaData meta; + // struct DONAUDB_DonationUnitKeyMetaData meta; }; @@ -65,7 +65,7 @@ struct DH_DonationUnitKey */ MHD_RESULT DH_keys_management_get_keys_handler (const struct DH_RequestHandler *rh, - struct MHD_Connection *connection); + struct MHD_Connection *connection); #endif