donau

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

commit 074814f88416e3637c0ea4770e8d1d32134f13d7
parent 7aa9f1928e285e28b1653db07d5b7a3bfafd423e
Author: Christian Grothoff <christian@grothoff.org>
Date:   Wed,  3 Apr 2024 14:01:55 +0200

get /keys response to work

Diffstat:
Msrc/donau/donau-httpd.c | 21++++++++++++++-------
Msrc/donau/donau-httpd.h | 5+++++
Msrc/donau/donau-httpd_keys.c | 1451+++++++++++++++++++++++++------------------------------------------------------
Msrc/donau/donau-httpd_keys.h | 50++++++++------------------------------------------
Msrc/donaudb/pg_iterate_donation_units.c | 13++++++++-----
Msrc/include/donau_crypto_lib.h | 28++++++++++++----------------
Msrc/pq/Makefile.am | 3++-
Msrc/pq/pq_result_helper.c | 10+++++-----
Msrc/pq/test_pq.c | 1+
Msrc/util/donau_crypto.c | 27++++++++++++---------------
10 files changed, 517 insertions(+), 1092 deletions(-)

diff --git a/src/donau/donau-httpd.c b/src/donau/donau-httpd.c @@ -54,7 +54,7 @@ * Above what request latency do we start to log? */ #define WARN_LATENCY GNUNET_TIME_relative_multiply ( \ - GNUNET_TIME_UNIT_MILLISECONDS, 500) + GNUNET_TIME_UNIT_MILLISECONDS, 500) /** * Are clients allowed to request /keys for times other than the @@ -129,7 +129,7 @@ bool DH_suicide; /** * Value to return from main() */ -static int global_ret; +int DH_global_ret; /** * Port to run the daemon on. @@ -940,7 +940,14 @@ run (void *cls, if (GNUNET_OK != donau_serve_process_config ()) { - global_ret = EXIT_NOTCONFIGURED; + DH_global_ret = EXIT_NOTCONFIGURED; + GNUNET_SCHEDULER_shutdown (); + return; + } + if (GNUNET_OK != + DH_keys_init ()) + { + DH_global_ret = EXIT_FAILURE; GNUNET_SCHEDULER_shutdown (); return; } @@ -954,7 +961,7 @@ run (void *cls, if (GNUNET_SYSERR == DH_plugin->preflight (DH_plugin->cls)) { - global_ret = EXIT_FAILURE; + DH_global_ret = EXIT_FAILURE; GNUNET_SCHEDULER_shutdown (); return; } @@ -966,7 +973,7 @@ run (void *cls, if (NULL == DH_curl_ctx) { GNUNET_break (0); - global_ret = EXIT_FAILURE; + DH_global_ret = EXIT_FAILURE; GNUNET_SCHEDULER_shutdown (); return; } @@ -1016,7 +1023,7 @@ run (void *cls, GNUNET_SCHEDULER_shutdown (); return; } - global_ret = EXIT_SUCCESS; + DH_global_ret = EXIT_SUCCESS; TALER_MHD_daemon_start (mhd); } @@ -1063,7 +1070,7 @@ main (int argc, return EXIT_INVALIDARGUMENT; if (GNUNET_NO == ret) return EXIT_SUCCESS; - return global_ret; + return DH_global_ret; } diff --git a/src/donau/donau-httpd.h b/src/donau/donau-httpd.h @@ -52,6 +52,11 @@ extern char *DH_donau_directory; extern bool DH_suicide; /** + * Value to return from main() + */ +extern int DH_global_ret; + +/** * Our DB plugin. */ extern struct DONAUDB_Plugin *DH_plugin; diff --git a/src/donau/donau-httpd_keys.c b/src/donau/donau-httpd_keys.c @@ -33,121 +33,6 @@ /** - * How many /keys request do we hold in suspension at - * most at any time? - */ -#define SKR_LIMIT 32 - -/** - * When do we forcefully timeout a /keys request? - */ -#define KEYS_TIMEOUT GNUNET_TIME_UNIT_MINUTES - -/** - * Number of entries in the @e skr_head DLL. - */ -static unsigned int skr_size; - -/** - * Handle to a connection that should be force-resumed - * with a hard error due to @a skr_size hitting - * #SKR_LIMIT. - */ -static struct MHD_Connection *skr_connection; - -/** - * Entry of /keys requests that are currently suspended because we are - * waiting for /keys to become ready. - */ -struct SuspendedKeysRequests -{ - /** - * Kept in a DLL. - */ - struct SuspendedKeysRequests *next; - - /** - * Kept in a DLL. - */ - struct SuspendedKeysRequests *prev; - - /** - * The suspended connection. - */ - struct MHD_Connection *connection; - - /** - * When does this request timeout? - */ - struct GNUNET_TIME_Absolute timeout; -}; - -/** - * Head of DLL of suspended /keys requests. - */ -static struct SuspendedKeysRequests *skr_head; - -/** - * Tail of DLL of suspended /keys requests. - */ -static struct SuspendedKeysRequests *skr_tail; - -/** - * Task to force timeouts on /keys requests. - */ -static struct GNUNET_SCHEDULER_Task *keys_tt; - -/** - * Are we shutting down? - */ -static bool terminating; - -/** - * 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; - -/** - * 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? - */ -#define KEYS_TIMEOUT GNUNET_TIME_UNIT_MINUTES - -/** - * Stores the latest generation of our key state. - */ -static struct DH_KeyStateHandle *key_state; - -/** * @brief All information about an donau online signing key (which is used to * sign messages from the donau). */ @@ -164,35 +49,25 @@ struct SigningKey */ struct DONAUDB_SignkeyMetaData meta; -}; - -struct DH_KeyStateHandle -{ - - /** - * Mapping from donation unit keys to donation unit key issue struct. - * Used to lookup the key by hash. - */ - struct GNUNET_CONTAINER_MultiHashMap *donation_unit_map; - /** - * Map from `struct DONAU_DonauPublicKey` to `struct SigningKey` - * entries. Based on the fact that a `struct GNUNET_PeerIdentity` is also - * an EdDSA public key. + * Did we lose the private keys? // NEEDED? */ - struct GNUNET_CONTAINER_MultiPeerMap *signkey_map; + bool lost; +}; - /** - * Information we track for the crypto helpers. Preserved - * when the @e key_generation changes, thus kept separate. - */ - struct HelperState *helpers; - /** - * Cached reply for a GET /keys request. Used so we do not - * re-create the reply every time. - */ - json_t *keys_reply; +/** + * Snapshot of the (coin and signing) keys (including private keys) of + * the exchange. There can be multiple instances of this struct, as it is + * reference counted and only destroyed once the last user is done + * with it. The current instance is acquired using + * #TEH_KS_acquire(). Using this function increases the + * reference count. The contents of this structure (except for the + * reference counter) should be considered READ-ONLY until it is + * ultimately destroyed (as there can be many concurrent users). + */ +struct DH_KeyStateHandle +{ /** * For which (global) key_generation was this data structure created? @@ -212,8 +87,8 @@ struct DH_KeyStateHandle struct GNUNET_TIME_Timestamp signature_expires; /** - * Response to return if the client supports (deflate) compression. - */ + * Response to return if the client supports (deflate) compression. + */ struct MHD_Response *response_compressed; /** @@ -228,184 +103,60 @@ struct DH_KeyStateHandle }; + /** - * State associated with the crypto helpers / security modules. NOT updated - * when the #key_generation is updated (instead constantly kept in sync - * whenever #DH_keys_get_state() is called). + * RSA security module public key, all zero if not known. */ -struct HelperState -{ - - /** - * Handle for the esign/EdDSA helper. - */ - struct TALER_CRYPTO_ExchangeSignHelper *esh; - - /** - * Handle for the donation_unit/RSA helper. - */ - struct TALER_CRYPTO_RsaDenominationHelper *rsadh; - - /** - * Handle for the donation_unit/CS helper. - */ - struct TALER_CRYPTO_CsDenominationHelper *csdh; - - /** - * Map from H(rsa_pub) to `struct DH_DonationUnitKey` entries. - */ - struct GNUNET_CONTAINER_MultiHashMap *rsa_keys; - - /** - * Map from H(cs_pub) to `struct DH_DonationUnitKey` entries. - */ - struct GNUNET_CONTAINER_MultiHashMap *cs_keys; - - /** - * 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 *esign_keys; - -}; +static struct TALER_SecurityModulePublicKeyP donation_unit_rsa_sm_pub; /** - * Function called to forcefully resume suspended keys requests. - * - * @param cls unused, NULL + * CS security module public key, all zero if not known. */ -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); -} - +static struct TALER_SecurityModulePublicKeyP donation_unit_cs_sm_pub; /** - * Suspend /keys request while we (hopefully) are waiting to be - * provisioned with key material. - * - * @param[in] connection to suspend + * EdDSA security module public key, all zero if not known. */ -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; -} - +static struct TALER_SecurityModulePublicKeyP esign_sm_pub; /** - * Closure for #insert_donation_unit_cb and #add_signkey_cb. + * 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. */ -struct KeysBuilderContext -{ - /** - * Our key state. - */ - struct DH_KeyStateHandle *ksh; +static uint64_t key_generation; - /** - * Array of donation unit keys. - */ - json_t *donation_units; +/** + * Handle for the esign/EdDSA helper. + */ +static struct TALER_CRYPTO_ExchangeSignHelper *esh; - /** - * Array of signing keys. - */ - json_t *signkeys; +/** + * Handle for the donation_unit/RSA helper. + */ +static struct TALER_CRYPTO_RsaDenominationHelper *rsadh; -}; +/** + * Handle for the donation_unit/CS helper. + */ +static struct TALER_CRYPTO_CsDenominationHelper *csdh; /** - * 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 donau public key (in type disguise) - * @param value a `struct SigningKey` - * @return #GNUNET_OK (continue to iterate) + * Map from H(rsa_pub) or H(cs_pub) to `struct DH_DonationUnitKey` entries. */ -static enum GNUNET_GenericReturnValue -add_sign_key_cb (void *cls, - const struct GNUNET_PeerIdentity *pid, - void *value) -{ - struct KeysBuilderContext *ctx = cls; - struct SigningKey *sk = value; +static struct GNUNET_CONTAINER_MultiHashMap *du_keys; - (void) pid; +/** + * Map from `struct TALER_ExchangePublicKey` to `struct SigningKey` + * entries. Based on the fact that a `struct GNUNET_PeerIdentity` is also + * an EdDSA public key. + */ +static struct GNUNET_CONTAINER_MultiPeerMap *esign_keys; - GNUNET_assert ( - 0 == - json_array_append_new ( - ctx->signkeys, - GNUNET_JSON_PACK ( - GNUNET_JSON_pack_timestamp ("stamp_start", - sk->meta.valid_from), - 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 ("key", - &sk->donau_pub)))); - return GNUNET_OK; -} +/** + * Stores the latest generation of our key state. + */ +static struct DH_KeyStateHandle *key_state; /** @@ -441,47 +192,10 @@ setup_general_response_headers (void *cls, /** - * 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 - * data) to the JSON array. - * - * @param cls the `struct FutureBuilderContext *` - * @param h_du_pub hash of the donation unit public key - * @param value a `struct DH_DonationUnitKey` - * @return #GNUNET_OK (continue to iterate) - */ -static enum GNUNET_GenericReturnValue -insert_donation_unit_cb (void *cls, - const struct GNUNET_HashCode *h_du_pub, - void *value) -{ - struct KeysBuilderContext *kbc = cls; - struct DH_DonationUnitKey *du = value; - - // if (GNUNET_TIME_relative_is_zero (hd->validity_duration)) - // return GNUNET_OK; /* this key already expired! */ - GNUNET_assert ( - 0 == json_array_append_new ( - kbc->donation_units, - GNUNET_JSON_PACK ( - DONAU_JSON_pack_donation_unit_pub ("donation_unit_pub", - &du->donation_unit_pub), - GNUNET_JSON_pack_uint64 ("year", - du->validity_year), - TALER_JSON_pack_amount ("value", // FIXME - &du->value) - ))); - return GNUNET_OK; -} - - -/** * Initialize @a ksh using the given values for @a signkeys, * and @a denoms. * * @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[in,out] signkeys list of sign keys to return * @param[in,out] donation_units list of grouped denominations to return * @return #GNUNET_OK on success @@ -491,46 +205,18 @@ create_keys_response (struct DH_KeyStateHandle *ksh, json_t *signkeys, json_t *donation_units) { - struct DONAU_DonauPublicKeyP donau_pub; - // struct DONAU_DonauSignatureP donau_sig; json_t *keys; + char *keys_json; + void *keys_jsonz; + size_t keys_jsonz_size; + int comp; + char etag[sizeof (struct GNUNET_HashCode) * 2]; GNUNET_assert (NULL != signkeys); GNUNET_assert (NULL != donation_units); GNUNET_assert (NULL != DH_currency); - GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Creating /keys response\n"); - - /* Sign hash over master signatures of all denomination keys until this time - (in reverse order). */ - // { - // enum TALER_ErrorCode ec; - // - // if (TALER_EC_NONE != - // (ec = - // DONAU_donau_online_key_set_sign ( - // &TEH_keys_donau_sign2_, - // ksh, - // du_keys_hash, - // &donau_pub, - // &donau_sig))) - // { - // GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - // "Could not create key response data: cannot sign (%s)\n", - // TALER_ErrorCode_get_hint (ec)); - // return GNUNET_SYSERR; - // } - // } - // - // { - // const struct SigningKey *sk; - // - // sk = GNUNET_CONTAINER_multipeermap_get (ksh->signkey_map, - // (const struct GNUNET_PeerIdentity *) - // &donau_pub); - // - // ksh->signature_expires = GNUNET_TIME_timestamp_min (sk->meta.expire_sign, - // ksh->signature_expires); - // } + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Creating /keys response\n"); keys = GNUNET_JSON_PACK ( GNUNET_JSON_pack_string ("version", @@ -542,92 +228,165 @@ create_keys_response (struct DH_KeyStateHandle *ksh, GNUNET_JSON_pack_array_incref ("signkeys", signkeys), GNUNET_JSON_pack_array_incref ("donation_units", - donation_units)); // , - // GNUNET_JSON_pack_data_auto ("donau_pub", - // &donau_pub)); // , - // GNUNET_JSON_pack_data_auto ("donau_sig", - // &donau_sig)); + donation_units)); GNUNET_assert (NULL != keys); + /* Convert /keys response to UTF8-String */ + keys_json = json_dumps (keys, + JSON_INDENT (2)); + json_decref (keys); + GNUNET_assert (NULL != keys_json); - { - char *keys_json; - void *keys_jsonz; - size_t keys_jsonz_size; - int comp; - char etag[sizeof (struct GNUNET_HashCode) * 2]; - - /* Convert /keys response to UTF8-String */ - keys_json = json_dumps (keys, - JSON_INDENT (2)); - json_decref (keys); - GNUNET_assert (NULL != keys_json); - - /* Keep copy for later compression... */ - keys_jsonz = GNUNET_strdup (keys_json); - keys_jsonz_size = strlen (keys_json); - - /* hash to compute etag */ - { - struct GNUNET_HashCode ehash; - char *end; - - GNUNET_CRYPTO_hash (keys_jsonz, - keys_jsonz_size, - &ehash); - end = GNUNET_STRINGS_data_to_string (&ehash, - sizeof (ehash), - etag, - sizeof (etag)); - *end = '\0'; - } + /* Keep copy for later compression... */ + keys_jsonz = GNUNET_strdup (keys_json); + keys_jsonz_size = strlen (keys_json); - /* Create uncompressed response */ - ksh->response_uncompressed - = MHD_create_response_from_buffer (keys_jsonz_size, - keys_json, - MHD_RESPMEM_MUST_FREE); - GNUNET_assert (NULL != ksh->response_uncompressed); - setup_general_response_headers (ksh, - ksh->response_uncompressed); - GNUNET_break (MHD_YES == - 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); - ksh->response_compressed - = MHD_create_response_from_buffer (keys_jsonz_size, - keys_jsonz, - MHD_RESPMEM_MUST_FREE); - 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 (ksh->response_compressed, - MHD_HTTP_HEADER_CONTENT_ENCODING, - "deflate")) ); - setup_general_response_headers (ksh, - ksh->response_compressed); - /* Set cache control headers: our response varies depending on these headers */ - GNUNET_break (MHD_YES == - 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 (ksh->response_compressed, - MHD_HTTP_HEADER_CACHE_CONTROL, - "public,max-age=86400")); - GNUNET_break (MHD_YES == - MHD_add_response_header (ksh->response_compressed, - MHD_HTTP_HEADER_ETAG, - etag)); - ksh->etag = GNUNET_strdup (etag); + /* hash to compute etag */ + { + struct GNUNET_HashCode ehash; + char *end; + + GNUNET_CRYPTO_hash (keys_jsonz, + keys_jsonz_size, + &ehash); + end = GNUNET_STRINGS_data_to_string (&ehash, + sizeof (ehash), + etag, + sizeof (etag)); + *end = '\0'; } + /* Create uncompressed response */ + ksh->response_uncompressed + = MHD_create_response_from_buffer (keys_jsonz_size, + keys_json, + MHD_RESPMEM_MUST_FREE); + GNUNET_assert (NULL != ksh->response_uncompressed); + setup_general_response_headers (ksh, + ksh->response_uncompressed); + GNUNET_break (MHD_YES == + 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); + ksh->response_compressed + = MHD_create_response_from_buffer (keys_jsonz_size, + keys_jsonz, + MHD_RESPMEM_MUST_FREE); + 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 (ksh->response_compressed, + MHD_HTTP_HEADER_CONTENT_ENCODING, + "deflate")) ); + setup_general_response_headers (ksh, + ksh->response_compressed); + /* Set cache control headers: our response varies depending on these headers */ + GNUNET_break (MHD_YES == + 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 (ksh->response_compressed, + MHD_HTTP_HEADER_CACHE_CONTROL, + "public,max-age=86400")); + GNUNET_break (MHD_YES == + MHD_add_response_header (ksh->response_compressed, + MHD_HTTP_HEADER_ETAG, + etag)); + ksh->etag = GNUNET_strdup (etag); + return GNUNET_OK; +} + + +/** + * Closure for #insert_donation_unit_cb and #add_signkey_cb. + */ +struct KeysBuilderContext +{ + + /** + * Array of donation unit keys. + */ + json_t *donation_units; + + /** + * Array of signing keys. + */ + 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 donau 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 KeysBuilderContext *ctx = cls; + struct SigningKey *sk = value; + + (void) pid; + GNUNET_assert ( + 0 == + json_array_append_new ( + ctx->signkeys, + GNUNET_JSON_PACK ( + GNUNET_JSON_pack_timestamp ("stamp_start", + sk->meta.valid_from), + GNUNET_JSON_pack_timestamp ("stamp_expire", + sk->meta.expire_sign), + GNUNET_JSON_pack_data_auto ("key", + &sk->donau_pub)))); + return GNUNET_OK; +} + + +/** + * 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 + * data) to the JSON array. + * + * @param cls the `struct FutureBuilderContext *` + * @param h_du_pub hash of the donation unit public key + * @param value a `struct DH_DonationUnitKey` + * @return #GNUNET_OK (continue to iterate) + */ +static enum GNUNET_GenericReturnValue +insert_donation_unit_cb (void *cls, + const struct GNUNET_HashCode *h_du_pub, + void *value) +{ + struct KeysBuilderContext *kbc = cls; + struct DH_DonationUnitKey *du = value; + + GNUNET_assert ( + 0 == json_array_append_new ( + kbc->donation_units, + GNUNET_JSON_PACK ( + DONAU_JSON_pack_donation_unit_pub ("donation_unit_pub", + &du->donation_unit_pub), + GNUNET_JSON_pack_uint64 ("year", + du->validity_year), + GNUNET_JSON_pack_bool ("lost", + du->lost), + TALER_JSON_pack_amount ("value", + &du->value) + ))); return GNUNET_OK; } @@ -648,11 +407,10 @@ finish_keys_response (struct DH_KeyStateHandle *ksh) struct KeysBuilderContext kbc; kbc.signkeys = json_array (); - kbc.donation_units = json_array (); GNUNET_assert (NULL != kbc.signkeys); + kbc.donation_units = json_array (); GNUNET_assert (NULL != kbc.donation_units); - - GNUNET_CONTAINER_multipeermap_iterate (ksh->signkey_map, + GNUNET_CONTAINER_multipeermap_iterate (esign_keys, &add_sign_key_cb, &kbc); @@ -663,8 +421,7 @@ finish_keys_response (struct DH_KeyStateHandle *ksh) ret = GNUNET_NO; goto CLEANUP; } - - GNUNET_CONTAINER_multihashmap_iterate (ksh->donation_unit_map, + GNUNET_CONTAINER_multihashmap_iterate (du_keys, &insert_donation_unit_cb, &kbc); @@ -676,29 +433,6 @@ finish_keys_response (struct DH_KeyStateHandle *ksh) goto CLEANUP; } - { - struct DH_DonationUnitKey *dk; - - // while (NULL != (dk = )) - // { -// - // struct GNUNET_HashCode hc; - // // compute_msig_hash (&sig_ctx, - // // &hc); - // if (GNUNET_OK != - // create_keys_response (ksh, - // &hc, - // kbc.signkeys, - // donation_units)) - // { - // GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - // "Failed to generate key response data\n"); - // goto CLEANUP; - // } -// - // } - } - if (GNUNET_OK != create_keys_response (ksh, kbc.signkeys, @@ -766,49 +500,14 @@ clear_signkey_cb (void *cls, /** - * 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) -{ - MHD_destroy_response (ksh->response_compressed); - MHD_destroy_response (ksh->response_uncompressed); -} - - -/** * 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); -} - - -void -DH_resume_keys_requests (bool do_shutdown) +sync_key_helpers (void) { - struct SuspendedKeysRequests *skr; - - if (do_shutdown) - terminating = true; - while (NULL != (skr = skr_head)) - { - GNUNET_CONTAINER_DLL_remove (skr_head, - skr_tail, - skr); - skr_size--; - MHD_resume_connection (skr->connection); - TALER_MHD_daemon_trigger (); - GNUNET_free (skr); - } + TALER_CRYPTO_helper_rsa_poll (rsadh); + TALER_CRYPTO_helper_cs_poll (csdh); + TALER_CRYPTO_helper_esign_poll (esh); } @@ -890,125 +589,53 @@ check_esign_sm_pub (const struct TALER_SecurityModulePublicKeyP *sm_pub) /** - * Helper function for #destroy_key_helpers to free all entries - * in the `donation_unit` map. - * - * @param cls the `struct DH_DonationUnitKey` - * @param h_donation_unit_pub hash of the donation unit public key - * @param value the `struct DH_DonationUnitKey` to release - * @return #GNUNET_OK (continue to iterate) - */ -static enum GNUNET_GenericReturnValue -free_donation_unit_cb (void *cls, - const struct GNUNET_HashCode *h_du_pub, - void *value) -{ - struct DH_DonationUnitKey *hd = value; - - (void) cls; - (void) h_du_pub; - DONAU_donation_unit_pub_free (&hd->donation_unit_pub); - GNUNET_free (hd); - return GNUNET_OK; -} - - -/** - * Helper function for #destroy_key_helpers to free all entries - * in the `esign_keys` map. - * - * @param cls the `struct SigningKey` - * @param pid unused, matches the donau public key - * @param value the `struct SigningKey` to release - * @return #GNUNET_OK (continue to iterate) - */ -static enum GNUNET_GenericReturnValue -free_esign_cb (void *cls, - const struct GNUNET_PeerIdentity *pid, - void *value) -{ - struct SigningKey *hsk = value; - - (void) cls; - (void) pid; - GNUNET_free (hsk); - return GNUNET_OK; -} - - -/** - * 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! + * Free resources of this module. */ -static void -destroy_key_helpers (struct HelperState *hs) +void +DH_keys_finished () { - // GNUNET_CONTAINER_multihashmap_iterate (hs->donation_unit, - // &free_donation_unit_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->donation_unit); - // hs->donation_unit = 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) + if (NULL != rsadh) + { + TALER_CRYPTO_helper_rsa_disconnect (rsadh); + rsadh = NULL; + } + if (NULL != csdh) + { + TALER_CRYPTO_helper_cs_disconnect (csdh); + csdh = NULL; + } + if (NULL != esh) { - TALER_CRYPTO_helper_rsa_disconnect (hs->rsadh); - hs->rsadh = NULL; + TALER_CRYPTO_helper_esign_disconnect (esh); + esh = NULL; } - if (NULL != hs->csdh) + if (NULL != du_keys) { - TALER_CRYPTO_helper_cs_disconnect (hs->csdh); - hs->csdh = NULL; + GNUNET_CONTAINER_multihashmap_iterate (du_keys, + &clear_donation_unit_cb, + NULL); + GNUNET_CONTAINER_multihashmap_destroy (du_keys); + du_keys = NULL; } - if (NULL != hs->esh) + if (NULL != esign_keys) { - TALER_CRYPTO_helper_esign_disconnect (hs->esh); - hs->esh = NULL; + GNUNET_CONTAINER_multipeermap_iterate (esign_keys, + &clear_signkey_cb, + NULL); + GNUNET_CONTAINER_multipeermap_destroy (esign_keys); + esign_keys = 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) +destroy_key_state (struct DH_KeyStateHandle *ksh) { - clear_response_cache (ksh); - - GNUNET_CONTAINER_multihashmap_iterate (ksh->donation_unit_map, - &clear_donation_unit_cb, - ksh); - GNUNET_CONTAINER_multihashmap_destroy (ksh->donation_unit_map); - GNUNET_CONTAINER_multipeermap_iterate (ksh->signkey_map, - &clear_signkey_cb, - ksh); - GNUNET_CONTAINER_multipeermap_destroy (ksh->signkey_map); - - if (free_helper) - { - destroy_key_helpers (ksh->helpers); - GNUNET_free (ksh->helpers); - } - if (NULL != ksh->keys_reply) - { - json_decref (ksh->keys_reply); - ksh->keys_reply = NULL; - } + if (NULL != ksh->response_compressed) + MHD_destroy_response (ksh->response_compressed); + if (NULL != ksh->response_uncompressed) + MHD_destroy_response (ksh->response_uncompressed); + GNUNET_free (ksh->etag); GNUNET_free (ksh); } @@ -1018,7 +645,7 @@ destroy_key_state (struct DH_KeyStateHandle *ksh, * only called once per key upon connect. Also called again in case a key is * being revoked, in that case with an @a end_time of zero. * - * @param cls closure with the `struct HelperState *` + * @param cls NULL * @param section_name name of the donation_unit type in the configuration; * NULL if the key has been revoked or purged * @param start_time when does the key become available for signing; @@ -1042,12 +669,11 @@ helper_rsa_cb ( const struct TALER_SecurityModulePublicKeyP *sm_pub, const struct TALER_SecurityModuleSignatureP *sm_sig) { - struct DH_KeyStateHandle *ksh = cls; - struct HelperState *hs = ksh->helpers; struct DH_DonationUnitKey *hd; struct TALER_Amount value; enum GNUNET_DB_QueryStatus qs; + GNUNET_assert (GNUNET_CRYPTO_BSA_RSA == bs_pub->cipher); if (GNUNET_OK != TALER_config_get_amount (DH_cfg, section_name, @@ -1067,31 +693,33 @@ helper_rsa_cb ( section_name, GNUNET_STRINGS_relative_time_to_string (validity_duration, false)); - hd = GNUNET_CONTAINER_multihashmap_get (hs->rsa_keys, + hd = GNUNET_CONTAINER_multihashmap_get (du_keys, &h_rsa->hash); if (NULL != hd) { - /* should be just an update (revocation!), so update existing entry */ - // hd->validity_duration = validity_duration; - hd->lost = false; + /* only update 'lost' status */ + hd->lost = GNUNET_TIME_relative_is_zero (validity_duration); return; } GNUNET_assert (NULL != sm_pub); check_donation_unit_rsa_sm_pub (sm_pub); hd = GNUNET_new (struct DH_DonationUnitKey); + hd->h_donation_unit_pub.hash = h_rsa->hash; + hd->donation_unit_pub.bsign_pub_key + = GNUNET_CRYPTO_bsign_pub_incref (bs_pub); hd->validity_year = GNUNET_TIME_time_to_year (start_time.abs_time); - hd->lost = false; hd->value = value; - // hd->start_time = start_time; - // hd->validity_duration = validity_duration; - // hd->h_details.h_rsa = *h_rsa; - // hd->sm_sig = *sm_sig; - GNUNET_assert (GNUNET_CRYPTO_BSA_RSA == bs_pub->cipher); - hd->donation_unit_pub.bsign_pub_key = - GNUNET_CRYPTO_bsign_pub_incref (bs_pub); - DONAU_donation_unit_pub_hash (&hd->donation_unit_pub, - &hd->h_donation_unit_pub); + hd->lost = GNUNET_TIME_relative_is_zero (validity_duration); + + GNUNET_assert ( + GNUNET_OK == + GNUNET_CONTAINER_multihashmap_put ( + du_keys, + &hd->h_donation_unit_pub.hash, + hd, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); + qs = DH_plugin->insert_donation_unit ( DH_plugin->cls, @@ -1101,31 +729,16 @@ helper_rsa_cb ( &hd->value); if (qs < 0) { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Failed to insert donation units\n"); - // FIXME: error, probably should not proceed... + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Failed to insert donation units\n"); + GNUNET_SCHEDULER_shutdown (); + DH_global_ret = EXIT_FAILURE; + return; } GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Inserted donation unit of %s\n", + "Inserted RSA donation unit of %s\n", TALER_amount2s (&value)); - - GNUNET_assert ( - GNUNET_OK == - GNUNET_CONTAINER_multihashmap_put ( - ksh->donation_unit_map, - &hd->h_donation_unit_pub.hash, - hd, - GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); - - // GNUNET_assert ( - // GNUNET_OK == - // GNUNET_CONTAINER_multihashmap_put ( - // hs->rsa_keys, - // &hd->h_donation_unit_pub.h_rsa.hash, - // hd, - // GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); - key_generation++; - DH_resume_keys_requests (false); } @@ -1134,7 +747,7 @@ helper_rsa_cb ( * only called once per key upon connect. Also called again in case a key is * being revoked, in that case with an @a end_time of zero. * - * @param cls closure with the `struct HelperState *` + * @param cls NULL * @param section_name name of the donation unit type in the configuration; * NULL if the key has been revoked or purged * @param start_time when does the key become available for signing; @@ -1155,12 +768,11 @@ helper_cs_cb ( const struct TALER_SecurityModulePublicKeyP *sm_pub, const struct TALER_SecurityModuleSignatureP *sm_sig) { - struct DH_KeyStateHandle *ksh = cls; - struct HelperState *hs = ksh->helpers; struct DH_DonationUnitKey *hd; struct TALER_Amount value; enum GNUNET_DB_QueryStatus qs; + GNUNET_assert (GNUNET_CRYPTO_BSA_CS == bs_pub->cipher); if (GNUNET_OK != TALER_config_get_amount (DH_cfg, section_name, @@ -1180,31 +792,32 @@ helper_cs_cb ( GNUNET_h2s (&h_cs->hash), section_name, GNUNET_STRINGS_relative_time_to_string (validity_duration, - GNUNET_NO)); - - hd = GNUNET_CONTAINER_multihashmap_get (hs->cs_keys, + false)); + hd = GNUNET_CONTAINER_multihashmap_get (du_keys, &h_cs->hash); if (NULL != hd) { /* should be just an update (revocation!), so update existing entry */ - hd->lost = false; + hd->lost = GNUNET_TIME_relative_is_zero (validity_duration); return; } GNUNET_assert (NULL != sm_pub); check_donation_unit_cs_sm_pub (sm_pub); hd = GNUNET_new (struct DH_DonationUnitKey); - hd->validity_year = GNUNET_TIME_time_to_year (start_time.abs_time); - hd->lost = false; - hd->value = value; - // hd->start_time = start_time; - // hd->validity_duration = validity_duration; - // hd->h_details.h_cs = *h_cs; - GNUNET_assert (GNUNET_CRYPTO_BSA_CS == bs_pub->cipher); + hd->h_donation_unit_pub.hash = h_cs->hash; hd->donation_unit_pub.bsign_pub_key = GNUNET_CRYPTO_bsign_pub_incref (bs_pub); - DONAU_donation_unit_pub_hash (&hd->donation_unit_pub, - &hd->h_donation_unit_pub); + hd->validity_year = GNUNET_TIME_time_to_year (start_time.abs_time); + hd->value = value; + hd->lost = GNUNET_TIME_relative_is_zero (validity_duration); + GNUNET_assert ( + GNUNET_OK == + GNUNET_CONTAINER_multihashmap_put ( + du_keys, + &hd->h_donation_unit_pub.hash, + hd, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); qs = DH_plugin->insert_donation_unit ( DH_plugin->cls, @@ -1214,31 +827,17 @@ helper_cs_cb ( &hd->value); if (qs < 0) { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Failed to insert donation units\n"); - // FIXME: error, probably should not proceed... + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Failed to insert donation units\n"); + GNUNET_SCHEDULER_shutdown (); + DH_global_ret = EXIT_FAILURE; + return; } GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Inserted donation unit of %s\n", + "Inserted CS donation unit of %s\n", TALER_amount2s (&value)); - GNUNET_assert ( - GNUNET_OK == - GNUNET_CONTAINER_multihashmap_put ( - ksh->donation_unit_map, - &hd->h_donation_unit_pub.hash, - hd, - GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); - - // GNUNET_assert ( - // GNUNET_OK == - // GNUNET_CONTAINER_multihashmap_put ( - // hs->cs_keys, - // &hd->h_donation_unit_pub.h_cs.hash, - // hd, - // GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); - key_generation++; - DH_resume_keys_requests (false); } @@ -1247,7 +846,7 @@ helper_cs_cb ( * only called once per key upon connect. Also called again in case a key is * being revoked, in that case with an @a end_time of zero. * - * @param cls closure with the `struct HelperState *` + * @param cls NULL * @param start_time when does the key become available for signing; * zero if the key has been revoked or purged * @param validity_duration how long does the key remain available for signing; @@ -1266,9 +865,7 @@ helper_esign_cb ( const struct TALER_SecurityModulePublicKeyP *sm_pub, const struct TALER_SecurityModuleSignatureP *sm_sig) { - struct DH_KeyStateHandle *ksh = cls; - struct HelperState *hs = ksh->helpers; - struct SigningKey *hsk; + struct SigningKey *sk; struct GNUNET_PeerIdentity pid; /* need to "cast" because secmod works with TALER_ExchangePublicKeyP */ struct DONAU_DonauPublicKeyP donau_pubkey = { @@ -1280,106 +877,101 @@ helper_esign_cb ( "EdDSA helper announces signing key %s with validity %s\n", TALER_B2S (donau_pub), GNUNET_STRINGS_relative_time_to_string (validity_duration, - GNUNET_NO)); + false)); pid.public_key = donau_pub->eddsa_pub; - hsk = GNUNET_CONTAINER_multipeermap_get (hs->esign_keys, - &pid); - // if (NULL != hsk) - // { - // GNUNET_break (0); // revocation not supported - // /* should be just an update (revocation!), so update existing entry */ - // // hsk->validity_duration = validity_duration; - // return; - // } - GNUNET_assert (NULL != sm_pub); - check_esign_sm_pub (sm_pub); - hsk = GNUNET_new (struct SigningKey); - // hsk->start_time = start_time; - // hsk->validity_duration = validity_duration; - hsk->donau_pub = donau_pubkey; - { - struct DONAUDB_SignkeyMetaData meta = { - .valid_from = start_time, - .expire_sign - = GNUNET_TIME_absolute_to_timestamp ( - GNUNET_TIME_absolute_add (start_time.abs_time, - validity_duration)), - .expire_legal - /* FIXME: make this configurable, not fixed to 10 years */ - = GNUNET_TIME_absolute_to_timestamp ( - GNUNET_TIME_absolute_add (start_time.abs_time, - GNUNET_TIME_relative_multiply ( - GNUNET_TIME_UNIT_YEARS, - 10))), - }; - - qs = DH_plugin->insert_signing_key ( - DH_plugin->cls, - &donau_pubkey, - &meta); - } - if (qs < 0) + sk = GNUNET_CONTAINER_multipeermap_get (esign_keys, + &pid); + if (NULL != sk) { - // FIXME + /* should be just an update (revocation!), so update existing entry */ + sk->lost = GNUNET_TIME_relative_is_zero (validity_duration); + return; } + GNUNET_assert (NULL != sm_pub); + check_esign_sm_pub (sm_pub); + + sk = GNUNET_new (struct SigningKey); + sk->donau_pub = donau_pubkey; + sk->meta.valid_from = start_time; + sk->meta.expire_sign + = GNUNET_TIME_absolute_to_timestamp ( + GNUNET_TIME_absolute_add (start_time.abs_time, + validity_duration)); + sk->meta.expire_legal + /* FIXME: make this configurable, not fixed to 10 years */ + = GNUNET_TIME_absolute_to_timestamp ( + GNUNET_TIME_absolute_add (start_time.abs_time, + GNUNET_TIME_relative_multiply ( + GNUNET_TIME_UNIT_YEARS, + 10))); GNUNET_assert ( GNUNET_OK == GNUNET_CONTAINER_multipeermap_put ( - hs->esign_keys, + esign_keys, &pid, - hsk, + sk, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); + + qs = DH_plugin->insert_signing_key ( + DH_plugin->cls, + &donau_pubkey, + &sk->meta); + if (qs < 0) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Failed to insert donation units\n"); + GNUNET_SCHEDULER_shutdown (); + DH_global_ret = EXIT_FAILURE; + return; + } + key_generation++; - DH_resume_keys_requests (false); } /** - * Setup helper state. + * Initialize keys subsystem. * - * @param[out] hs helper state to initialize * @return #GNUNET_OK on success */ -static enum GNUNET_GenericReturnValue -setup_key_helpers (struct DH_KeyStateHandle *ksh) +enum GNUNET_GenericReturnValue +DH_keys_init () { - struct HelperState *hs = ksh->helpers; - - hs->rsa_keys - = GNUNET_CONTAINER_multihashmap_create (1024, - GNUNET_YES); - hs->cs_keys + du_keys = GNUNET_CONTAINER_multihashmap_create (1024, GNUNET_YES); - hs->esign_keys + esign_keys = GNUNET_CONTAINER_multipeermap_create (32, GNUNET_NO /* MUST BE NO! */); - hs->rsadh = TALER_CRYPTO_helper_rsa_connect (DH_cfg, - "donau", - &helper_rsa_cb, - ksh); - if (NULL == hs->rsadh) + rsadh = TALER_CRYPTO_helper_rsa_connect (DH_cfg, + "donau", + &helper_rsa_cb, + NULL); + if (NULL == rsadh) { - destroy_key_helpers (hs); + GNUNET_break (0); + DH_keys_finished (); return GNUNET_SYSERR; } - hs->csdh = TALER_CRYPTO_helper_cs_connect (DH_cfg, - "donau", - &helper_cs_cb, - ksh); - if (NULL == hs->csdh) + csdh = TALER_CRYPTO_helper_cs_connect (DH_cfg, + "donau", + &helper_cs_cb, + NULL); + if (NULL == csdh) { - destroy_key_helpers (hs); + GNUNET_break (0); + DH_keys_finished (); return GNUNET_SYSERR; } - hs->esh = TALER_CRYPTO_helper_esign_connect (DH_cfg, - "donau", - &helper_esign_cb, - ksh); - if (NULL == hs->esh) + esh = TALER_CRYPTO_helper_esign_connect (DH_cfg, + "donau", + &helper_esign_cb, + NULL); + if (NULL == esh) { - destroy_key_helpers (hs); + GNUNET_break (0); + DH_keys_finished (); return GNUNET_SYSERR; } return GNUNET_OK; @@ -1389,9 +981,10 @@ setup_key_helpers (struct DH_KeyStateHandle *ksh) /** * Function called with information about the donau's donation_unit keys. * - * @param cls closure with a `struct TEH_KeyStateHandle *` + * @param cls NULL * @param donation_unit_pub public key of the donation_unit * @param h_donation_unit_pub hash of @a donation_unit_pub + * @param ... FIXME! */ static enum GNUNET_GenericReturnValue donation_unit_info_cb ( @@ -1401,24 +994,33 @@ donation_unit_info_cb ( uint64_t validity_year, struct TALER_Amount *value) { - struct DH_KeyStateHandle *ksh = cls; - struct DH_DonationUnitKey *dk; + struct DH_DonationUnitKey *hd; - // GNUNET_assert (GNUNET_CRYPTO_BSA_INVALID != - // donation_unit_pub->bsign_pub_key->cipher); + GNUNET_assert (GNUNET_CRYPTO_BSA_INVALID != + donation_unit_pub->bsign_pub_key->cipher); + hd = GNUNET_CONTAINER_multihashmap_get (du_keys, + &h_donation_unit_pub->hash); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Got %s key from database\n", + NULL == hd ? "unknown" : "known"); + if (NULL != hd) + { + /* we already know this, nothing to do */ + return GNUNET_OK; + } - dk = GNUNET_new (struct DH_DonationUnitKey); - DONAU_donation_unit_pub_deep_copy (&dk->donation_unit_pub, + hd = GNUNET_new (struct DH_DonationUnitKey); + hd->h_donation_unit_pub = *h_donation_unit_pub; + DONAU_donation_unit_pub_deep_copy (&hd->donation_unit_pub, donation_unit_pub); - dk->h_donation_unit_pub = *h_donation_unit_pub; - dk->validity_year = validity_year; - dk->value = *value; - + hd->validity_year = validity_year; + hd->value = *value; + hd->lost = true; /* no private key known, that can only come from the helper! */ GNUNET_assert ( GNUNET_OK == - GNUNET_CONTAINER_multihashmap_put (ksh->donation_unit_map, - &dk->h_donation_unit_pub.hash, - dk, + GNUNET_CONTAINER_multihashmap_put (du_keys, + &hd->h_donation_unit_pub.hash, + hd, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY) ); return GNUNET_OK; @@ -1428,7 +1030,7 @@ donation_unit_info_cb ( /** * Function called with information about the donau's online signing keys. * - * @param cls closure with a `struct DH_KeyStateHandle *` + * @param cls NULL * @param donau_pub the public key * @param meta meta data information about the denomination type (expirations) */ @@ -1438,17 +1040,26 @@ iterate_active_signing_keys_cb ( const struct DONAU_DonauPublicKeyP *donau_pub, struct DONAUDB_SignkeyMetaData *meta) { - struct DH_KeyStateHandle *ksh = cls; + /* The 'pid' is used as the key in the "peer" map... */ + struct GNUNET_PeerIdentity pid = { + .public_key = donau_pub->eddsa_pub + }; struct SigningKey *sk; - struct GNUNET_PeerIdentity pid; + sk = GNUNET_CONTAINER_multipeermap_get (esign_keys, + &pid); + if (NULL != sk) + { + /* should be just an update (revocation!), so update existing entry */ + return; + } sk = GNUNET_new (struct SigningKey); sk->donau_pub = *donau_pub; sk->meta = *meta; - pid.public_key = donau_pub->eddsa_pub; + sk->lost = true; /* no private key known, that can only come from the helper! */ GNUNET_assert ( GNUNET_OK == - GNUNET_CONTAINER_multipeermap_put (ksh->signkey_map, + GNUNET_CONTAINER_multipeermap_put (esign_keys, &pid, sk, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY) @@ -1459,82 +1070,61 @@ iterate_active_signing_keys_cb ( /** * Create a key state. * - * @param[in] hs helper state to (re)use, NULL if not available * @return NULL on error (i.e. failed to access database) */ -static struct DH_KeyStateHandle* -build_key_state (struct HelperState *hs) +static struct DH_KeyStateHandle * +build_key_state () { 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; - ksh->donation_unit_map = GNUNET_CONTAINER_multihashmap_create (1024, - true); - ksh->signkey_map = GNUNET_CONTAINER_multipeermap_create (32, - false /* MUST be false! */ - ); - if (NULL == hs) - { - ksh->helpers = GNUNET_new (struct HelperState); - if (GNUNET_OK != setup_key_helpers (ksh)) - { - GNUNET_free (ksh->helpers); - GNUNET_assert (NULL == ksh->keys_reply); - GNUNET_free (ksh); - return NULL; - } - } - else - { - ksh->helpers = 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); + NULL); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Fetched %d donation unit keys from DB\n", + (int) qs); if (qs < 0) { GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR != qs); GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR != qs); - destroy_key_state (ksh, - true); + destroy_key_state (ksh); return NULL; } + /* NOTE: ONLY fetches active signkeys! */ GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Fetching active signing keys from DB\n"); - qs = DH_plugin->iterate_active_signing_keys (DH_plugin->cls, &iterate_active_signing_keys_cb, - ksh); + NULL); GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Fetched %d active signing keys from DB\n", - qs); + (int) qs); if (qs < 0) { - GNUNET_break (0); - destroy_key_state (ksh, - true); + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR != qs); + GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR != qs); + destroy_key_state (ksh); return NULL; } - if (GNUNET_OK != finish_keys_response (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); + "Could not finish /keys response (likely no signing keys available yet)\n"); + destroy_key_state (ksh); return NULL; } @@ -1542,23 +1132,6 @@ build_key_state (struct HelperState *hs) } -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* DH_keys_get_state () { @@ -1568,115 +1141,40 @@ DH_keys_get_state () old_ksh = key_state; if (NULL == old_ksh) { - ksh = build_key_state (NULL); + ksh = build_key_state (); 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))) + 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); + ksh = build_key_state (); key_state = ksh; - old_ksh->helpers = NULL; - destroy_key_state (old_ksh, - false); + destroy_key_state (old_ksh); return ksh; } - sync_key_helpers (old_ksh->helpers); return old_ksh; } -/** - * Function called on all of our current and future donau signing keys - * known to the helper process. Filters out those that are current - * and adds the remaining signing keys (with their configuration - * data) to the JSON array. - * - * @param cls the `struct FutureBuilderContext *` - * @param pid actually the donau public key (type disguised) - * @param value a `struct DH_DonationUnitKey` - * @return #GNUNET_OK (continue to iterate) - */ -static enum GNUNET_GenericReturnValue -add_signkey_cb (void *cls, - const struct GNUNET_PeerIdentity *pid, - void *value) -{ - struct KeysBuilderContext *kbc = cls; - struct SigningKey *hsk = value; - struct SigningKey *sk; - - struct GNUNET_TIME_Timestamp stamp_expire; - // struct GNUNET_TIME_Timestamp legal_end; - - // sk = GNUNET_CONTAINER_multipeermap_get (kbc->ksh->signkey_map, pid); - // if (NULL != sk) - // return GNUNET_OK; /* skip: this key is already active */ - - // if (GNUNET_TIME_relative_is_zero (hsk->validity_duration)) - // return GNUNET_OK; /* this key already expired! */ - - // stamp_expire = GNUNET_TIME_absolute_to_timestamp ( - // GNUNET_TIME_absolute_add (hsk->start_time.abs_time, - // hsk->validity_duration)); - - // legal_end = GNUNET_TIME_absolute_to_timestamp ( - // GNUNET_TIME_absolute_add (stamp_expire.abs_time, - // signkey_legal_duration)); - - GNUNET_assert (0 == - json_array_append_new ( - kbc->signkeys, - GNUNET_JSON_PACK ( - GNUNET_JSON_pack_data_auto ("key", - &hsk->donau_pub) // , - // GNUNET_JSON_pack_timestamp ("stamp_start", - // hsk->start_time), - // GNUNET_JSON_pack_timestamp ("stamp_expire", - // stamp_expire), - // GNUNET_JSON_pack_timestamp ("stamp_end", - // legal_end), - // GNUNET_JSON_pack_data_auto ("signkey_secmod_sig", - // &hsk->sm_sig) - ))); - return GNUNET_OK; -} - - MHD_RESULT DH_handler_keys (struct DH_RequestContext *rc, const char *const args[]) { - struct DH_KeyStateHandle *ksh; - json_t *reply; - - // connection is always initialised struct MHD_Connection *connection = rc->connection; + struct DH_KeyStateHandle *ksh; + struct MHD_Response *resp; + sync_key_helpers (); ksh = DH_keys_get_state (); if (NULL == ksh) { - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_SERVICE_UNAVAILABLE, - TALER_EC_DONAU_GENERIC_KEYS_MISSING, - "no key state"); - } - sync_key_helpers (ksh->helpers); - if (NULL == ksh->keys_reply) - { - struct KeysBuilderContext kbc = { - .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)) ) { @@ -1693,54 +1191,26 @@ DH_handler_keys (struct DH_RequestContext *rc, TALER_EC_EXCHANGE_SIGNKEY_HELPER_UNAVAILABLE, NULL); } - GNUNET_assert (NULL != kbc.donation_units); - GNUNET_assert (NULL != kbc.signkeys); - GNUNET_assert (NULL != DH_currency); - GNUNET_CONTAINER_multihashmap_iterate (ksh->donation_unit_map, - &insert_donation_unit_cb, - &kbc); - GNUNET_CONTAINER_multipeermap_iterate (ksh->helpers->esign_keys, - &add_signkey_cb, - &kbc); - reply = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_string ("version", - DONAU_PROTOCOL_VERSION), - GNUNET_JSON_pack_string ("domain", - DH_domain), - GNUNET_JSON_pack_string ("base_url", - DH_base_url), - GNUNET_JSON_pack_string ("currency", - DH_currency), - GNUNET_JSON_pack_array_steal ("donation_units", - kbc.donation_units), - GNUNET_JSON_pack_array_steal ("signkeys", kbc.signkeys), - 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 /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->keys_reply); - ksh->keys_reply = reply; - } - else - { - reply = ksh->keys_reply; + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Failed to build /keys response?\n"); + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_SERVICE_UNAVAILABLE, + TALER_EC_DONAU_GENERIC_KEYS_MISSING, + "failed to create keys response"); } - return TALER_MHD_reply_json (connection, reply, - MHD_HTTP_OK); + /* FIXME: check client etag and reply not modified! */ + resp = TALER_MHD_can_compress (connection) + ? ksh->response_compressed + : ksh->response_uncompressed; + GNUNET_assert (NULL != resp); + return MHD_queue_response (connection, + MHD_HTTP_OK, + resp); } +#if DEAD /** * Callback used to set headers in a response. * @@ -1751,6 +1221,7 @@ typedef void (*DH_RESPONSE_SetHeaders) (void *cls, struct MHD_Response *resp); +// STATIC? needed? MHD_RESULT DH_RESPONSE_reply_not_modified (struct MHD_Connection *connection, const char *etags, @@ -1775,40 +1246,18 @@ DH_RESPONSE_reply_not_modified (struct MHD_Connection *connection, } -struct DH_DonationUnitKey * -DH_keys_donation_unit_by_hash ( - const struct DONAU_DonationUnitHashP *h_du_pub, - struct MHD_Connection *conn, - MHD_RESULT *mret) -{ - struct DH_KeyStateHandle *ksh; - - ksh = DH_keys_get_state (); - if (NULL == ksh) - { - *mret = TALER_MHD_reply_with_error (conn, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_EXCHANGE_GENERIC_KEYS_MISSING, - NULL); - return NULL; - } - return DH_keys_donation_unit_by_hash_from_state (ksh, - h_du_pub, - conn, - mret); -} +#endif struct DH_DonationUnitKey * -DH_keys_donation_unit_by_hash_from_state ( - const struct DH_KeyStateHandle *ksh, +DH_keys_donation_unit_by_hash ( const struct DONAU_DonationUnitHashP *h_du_pub, struct MHD_Connection *conn, MHD_RESULT *mret) { struct DH_DonationUnitKey *dk; - dk = GNUNET_CONTAINER_multihashmap_get (ksh->donation_unit_map, + dk = GNUNET_CONTAINER_multihashmap_get (du_keys, &h_du_pub->hash); if (NULL == dk) { diff --git a/src/donau/donau-httpd_keys.h b/src/donau/donau-httpd_keys.h @@ -26,24 +26,11 @@ #include "donaudb_plugin.h" #include "donau-httpd.h" - #ifndef DONAU_HTTPD_KEYS_H #define DONAU_HTTPD_KEYS_H /** - * Snapshot of the (coin and signing) keys (including private keys) of - * the exchange. There can be multiple instances of this struct, as it is - * reference counted and only destroyed once the last user is done - * with it. The current instance is acquired using - * #TEH_KS_acquire(). Using this function increases the - * reference count. The contents of this structure (except for the - * reference counter) should be considered READ-ONLY until it is - * ultimately destroyed (as there can be many concurrent users). - */ -struct DH_KeyStateHandle; - -/** * @brief All information about a donation unit key (which is used to * sign donation receipts into existence). */ @@ -78,12 +65,6 @@ struct DH_DonationUnitKey }; -/** - * Fully clean up keys subsystem. - */ -void -TEH_keys_finished (void); - /** * Resumes all suspended /keys requests, we may now have key material @@ -109,9 +90,7 @@ DH_handler_keys (struct DH_RequestContext *rc, /** - * Look up the issue for a donation unit public key. Note that the result - * must only be used in this thread and only until another key or - * key state is resolved. + * Look up the issue for a donation unit public key. * * @param h_du_pub hash of donation unit public key * @param[in,out] conn used to return status message if NULL is returned @@ -125,25 +104,6 @@ DH_keys_donation_unit_by_hash ( struct MHD_Connection *conn, MHD_RESULT *mret); -/** - * Look up the issue for a donation unit public key using a given @a ksh. This allows - * requesting multiple donation units with the same @a ksh which thus will - * remain valid until the next call to #TEH_keys_donation_unit_by_hash() or - * #DH_keys_get_state() or #DH_keys_donau_sign(). - * - * @param ksh key state state to look in - * @param h_du_pub hash of donation unit public key - * @param[in,out] conn connection used to return status message if NULL is returned - * @param[out] mret set to the MHD status if NULL is returned - * @return the donation unit key issue, - * or NULL if @a h_du_pub could not be found - */ -struct DH_DonationUnitKey * -DH_keys_donation_unit_by_hash_from_state ( - const struct DH_KeyStateHandle *ksh, - const struct DONAU_DonationUnitHashP *h_du_pub, - struct MHD_Connection *conn, - MHD_RESULT *mret); /** * Initialize keys subsystem. @@ -151,7 +111,13 @@ DH_keys_donation_unit_by_hash_from_state ( * @return #GNUNET_OK on success */ enum GNUNET_GenericReturnValue -TEH_keys_init (void); +DH_keys_init (void); + +/** + * Fully clean up keys subsystem. + */ +void +DH_keys_finished (void); #endif diff --git a/src/donaudb/pg_iterate_donation_units.c b/src/donaudb/pg_iterate_donation_units.c @@ -69,6 +69,7 @@ iterate_donation_units_cb (void *cls, struct DONAU_DonationUnitPublicKey donation_unit_pub; uint64_t validity_year; struct TALER_Amount value; + enum GNUNET_GenericReturnValue iret; struct GNUNET_PQ_ResultSpec rs[] = { GNUNET_PQ_result_spec_auto_from_type ("h_donation_unit_pub", @@ -91,12 +92,14 @@ iterate_donation_units_cb (void *cls, return; } - ctx->cb (ctx->cb_cls, - &h_donation_unit_pub, - &donation_unit_pub, - validity_year, - &value); + iret = ctx->cb (ctx->cb_cls, + &h_donation_unit_pub, + &donation_unit_pub, + validity_year, + &value); GNUNET_PQ_cleanup_result (rs); + if (GNUNET_OK != iret) + break; } } diff --git a/src/include/donau_crypto_lib.h b/src/include/donau_crypto_lib.h @@ -127,10 +127,9 @@ struct DONAU_DonationUnitHashP * @return 0 if the keys are equal, otherwise -1 or 1 */ int -DONAU_donation_unit_pub_cmp (const struct - DONAU_DonationUnitPublicKey *donation_unit1, - const struct - DONAU_DonationUnitPublicKey *donation_unit2); +DONAU_donation_unit_pub_cmp ( + const struct DONAU_DonationUnitPublicKey *donation_unit1, + const struct DONAU_DonationUnitPublicKey *donation_unit2); /** * Make a (deep) copy of the given @a donation_unit_src to @@ -140,12 +139,9 @@ DONAU_donation_unit_pub_cmp (const struct * @param donation_unit_src public key to copy */ void -DONAU_donation_unit_pub_deep_copy (struct - DONAU_DonationUnitPublicKey * - donation_unit_dst, - const struct - DONAU_DonationUnitPublicKey * - donation_unit_src); +DONAU_donation_unit_pub_deep_copy ( + struct DONAU_DonationUnitPublicKey *donation_unit_dst, + const struct DONAU_DonationUnitPublicKey *donation_unit_src); /** * Free internals of @a donation_unit_pub, but not @a donation_unit_pub itself. @@ -153,8 +149,8 @@ DONAU_donation_unit_pub_deep_copy (struct * @param[in] donation_unit_pub key to free */ void -DONAU_donation_unit_pub_free (struct - DONAU_DonationUnitPublicKey *donation_unit_pub); +DONAU_donation_unit_pub_free ( + struct DONAU_DonationUnitPublicKey *donation_unit_pub); /** * Compute the hash of the given @a donation_unit_pub. @@ -163,10 +159,10 @@ DONAU_donation_unit_pub_free (struct * @param[out] donation_unit_hash resulting hash value */ void -DONAU_donation_unit_pub_hash (const struct - DONAU_DonationUnitPublicKey *donation_unit_pub, - struct DONAU_DonationUnitHashP *donation_unit_hash - ); +DONAU_donation_unit_pub_hash ( + const struct DONAU_DonationUnitPublicKey *donation_unit_pub, + struct DONAU_DonationUnitHashP *donation_unit_hash + ); /** * Hash used to represent a Donation Receipt diff --git a/src/pq/Makefile.am b/src/pq/Makefile.am @@ -34,8 +34,9 @@ test_pq_SOURCES = \ test_pq_LDADD = \ libdonaupq.la \ $(top_builddir)/src/util/libdonauutil.la \ - -lgnunetpq \ -ltalerpq \ + -ltalerutil \ + -lgnunetpq \ -lgnunetutil \ -ljansson \ -lpq \ diff --git a/src/pq/pq_result_helper.c b/src/pq/pq_result_helper.c @@ -99,10 +99,10 @@ extract_donation_unit_pub (void *cls, GNUNET_free (bpk); return GNUNET_SYSERR; } - pk->bsign_pub_key = bpk; GNUNET_CRYPTO_hash (res, len, &bpk->pub_key_hash); + pk->bsign_pub_key = bpk; return GNUNET_OK; case GNUNET_CRYPTO_BSA_CS: if (sizeof (bpk->details.cs_public_key) != len) @@ -114,10 +114,10 @@ extract_donation_unit_pub (void *cls, GNUNET_memcpy (&bpk->details.cs_public_key, res, len); - pk->bsign_pub_key = bpk; GNUNET_CRYPTO_hash (res, len, &bpk->pub_key_hash); + pk->bsign_pub_key = bpk; return GNUNET_OK; } GNUNET_break (0); @@ -145,9 +145,9 @@ clean_donation_unit_pub (void *cls, struct GNUNET_PQ_ResultSpec -DONAU_PQ_result_spec_donation_unit_pub (const char *name, - struct DONAU_DonationUnitPublicKey * - donation_unit_pub) +DONAU_PQ_result_spec_donation_unit_pub ( + const char *name, + struct DONAU_DonationUnitPublicKey *donation_unit_pub) { struct GNUNET_PQ_ResultSpec res = { .conv = &extract_donation_unit_pub, diff --git a/src/pq/test_pq.c b/src/pq/test_pq.c @@ -107,6 +107,7 @@ run_queries (struct GNUNET_PQ_Context *conn) result = GNUNET_PQ_exec_prepared (conn, "test_insert", params_insert); + GNUNET_PQ_cleanup_query_params_closures (params_insert); if (PGRES_COMMAND_OK != PQresultStatus (result)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, diff --git a/src/util/donau_crypto.c b/src/util/donau_crypto.c @@ -61,10 +61,9 @@ DONAU_donation_unit_group_get_key ( int -DONAU_donation_unit_pub_cmp (const struct - DONAU_DonationUnitPublicKey *donation_unit1, - const struct - DONAU_DonationUnitPublicKey *donation_unit2) +DONAU_donation_unit_pub_cmp ( + const struct DONAU_DonationUnitPublicKey *donation_unit1, + const struct DONAU_DonationUnitPublicKey *donation_unit2) { if (donation_unit1->bsign_pub_key->cipher != donation_unit2->bsign_pub_key->cipher) @@ -76,12 +75,9 @@ DONAU_donation_unit_pub_cmp (const struct void -DONAU_donation_unit_pub_deep_copy (struct - DONAU_DonationUnitPublicKey * - donation_unit_dst, - const struct - DONAU_DonationUnitPublicKey * - donation_unit_src) +DONAU_donation_unit_pub_deep_copy ( + struct DONAU_DonationUnitPublicKey *donation_unit_dst, + const struct DONAU_DonationUnitPublicKey *donation_unit_src) { donation_unit_dst->bsign_pub_key = GNUNET_CRYPTO_bsign_pub_incref (donation_unit_src->bsign_pub_key); @@ -89,8 +85,8 @@ DONAU_donation_unit_pub_deep_copy (struct void -DONAU_donation_unit_pub_free (struct - DONAU_DonationUnitPublicKey *donation_unit_pub) +DONAU_donation_unit_pub_free ( + struct DONAU_DonationUnitPublicKey *donation_unit_pub) { if (NULL != donation_unit_pub->bsign_pub_key) { @@ -101,9 +97,10 @@ DONAU_donation_unit_pub_free (struct void -DONAU_donation_unit_pub_hash (const struct - DONAU_DonationUnitPublicKey *donation_unit_pub, - struct DONAU_DonationUnitHashP *donation_unit_hash) +DONAU_donation_unit_pub_hash ( + const struct DONAU_DonationUnitPublicKey *donation_unit_pub, + struct DONAU_DonationUnitHashP *donation_unit_hash + ) { struct GNUNET_CRYPTO_BlindSignPublicKey *bsp = donation_unit_pub->bsign_pub_key;