donau

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

commit 71f9e391a3d2a3137bdd8c6d2362a9e502914175
parent a3e460689d063d1947dd6cf1d6dfa34c2be61cdc
Author: Casaburi Johannes <johannes.casaburi@students.bfh.ch>
Date:   Wed,  3 Jan 2024 13:40:47 +0100

working on key path

Diffstat:
Msrc/donau/Makefile.am | 1+
Msrc/donau/donau-httpd.c | 50++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/donau/donau-httpd_keys.c | 187++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
Msrc/donau/donau-httpd_keys.h | 23+++++++++++++++++++----
4 files changed, 252 insertions(+), 9 deletions(-)

diff --git a/src/donau/Makefile.am b/src/donau/Makefile.am @@ -41,6 +41,7 @@ donau_httpd_LDADD = \ donau_httpd_SOURCES = \ donau-httpd.c donau-httpd.h \ + donau-httpd_keys.c donau-httpd_keys.h \ donau-httpd_config.c donau-httpd_config.h # Testcases diff --git a/src/donau/donau-httpd.c b/src/donau/donau-httpd.c @@ -34,6 +34,7 @@ #include <gnunet/gnunet_mhd_compat.h> #include "donau_util.h" #include "donau-httpd_config.h" +#include "donau-httpd_keys.h" /** * Backlog for listen operation on unix domain sockets. @@ -180,6 +181,24 @@ typedef MHD_RESULT const struct TALER_CoinSpendPublicKeyP *coin_pub, const json_t *root); + +/** + * Generate a 404 "not found" reply on @a connection with + * the hint @a details. + * + * @param connection where to send the reply on + * @param details details for the error message, can be NULL + */ +static MHD_RESULT +r404 (struct MHD_Connection *connection, + const char *details) +{ + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_NOT_FOUND, + TALER_EC_EXCHANGE_GENERIC_OPERATION_UNKNOWN, + 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 @@ -378,6 +397,30 @@ proceed_with_handler (struct DH_RequestContext *rc, return ret; } +/** + * Handle a GET "/management" request. + * + * @param rc request context + * @param args array of additional options (must be [0] == "keys") + * @return MHD result code + */ +static MHD_RESULT +handle_get_management (struct DH_RequestContext *rc, + const char *const args[2]) +{ + if ( (NULL != args[0]) && + (0 == strcmp (args[0], + "keys")) && + (NULL == args[1]) ) + { + return DH_keys_management_get_keys_handler (rc->rh, + rc->connection); + } + GNUNET_break_op (0); + return r404 (rc->connection, + "/management/*"); +} + /** * Handle incoming HTTP request. @@ -418,6 +461,13 @@ handle_mhd_request (void *cls, .method = MHD_HTTP_METHOD_GET, .handler.get = &DH_handler_config }, + /* GET management endpoints (we only really have "/management/keys") */ + { + .url = "management", + .method = MHD_HTTP_METHOD_GET, + .handler.get = &handle_get_management, + .nargs = 1 + }, /* mark end of list */ { .url = NULL diff --git a/src/donau/donau-httpd_keys.c b/src/donau/donau-httpd_keys.c @@ -24,7 +24,8 @@ #include "taler/taler_mhd_lib.h" #include "donau-httpd.h" #include "donau-httpd_keys.h" -#include "donau-httpd_responses.h" +//#include "donau-httpd_config.h" +//#include "donau-httpd_responses.h" #include "donaudb_plugin.h" @@ -40,6 +41,17 @@ */ #define KEYS_TIMEOUT GNUNET_TIME_UNIT_MINUTES +/** + * Obtain the key state if we should NOT run finish_keys_response() because we + * only need the state for the /management/keys API + */ +struct DH_KeyStateHandle * +DH_keys_get_state_for_management_only (void); + +/** + * 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 @@ -51,18 +63,183 @@ struct SigningKey /** * The donau's (online signing) public key. */ - struct DONAU_DonauPublicKeyP donau_pub; + struct DONAU_DonationUnitPublicKey donau_pub; /** * Meta data about the signing key, such as validity periods. */ - struct DONAUDB_SignkeyMetaData meta; + struct DONAUDB_DonationUnitKeyMetaData meta; }; /** - * Are we shutting down? + * 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). */ -static bool terminating; +struct HelperState +{ + + /** + * Handle for the esign/EdDSA helper. + */ + struct TALER_CRYPTO_ExchangeSignHelper *esh; + + /** + * Handle for the denom/RSA helper. + */ + struct TALER_CRYPTO_RsaDenominationHelper *rsadh; + + /** + * Handle for the denom/CS helper. + */ + struct TALER_CRYPTO_CsDenominationHelper *csdh; + + /** + * Map from H(denom_pub) to `struct HelperDenomination` entries. + */ + struct GNUNET_CONTAINER_MultiHashMap *denom_keys; + + /** + * Map from H(rsa_pub) to `struct HelperDenomination` entries. + */ + struct GNUNET_CONTAINER_MultiHashMap *rsa_keys; + + /** + * Map from H(cs_pub) to `struct HelperDenomination` entries. + */ + struct GNUNET_CONTAINER_MultiHashMap *cs_keys; + + /** + * Map from `struct TALER_ExchangePublicKey` to `struct HelperSignkey` + * entries. Based on the fact that a `struct GNUNET_PeerIdentity` is also + * an EdDSA public key. + */ + struct GNUNET_CONTAINER_MultiPeerMap *esign_keys; + +}; + +//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); +//} + +MHD_RESULT +DH_keys_management_get_keys_handler (const struct DH_RequestHandler *rh, + struct MHD_Connection *connection) +{ + struct DH_KeyStateHandle *ksh; + json_t *reply; + + (void) rh; + //ksh = DH_keys_get_state_for_management_only (); + ksh = NULL; + if (NULL == ksh) + { + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_SERVICE_UNAVAILABLE, + 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; + //} + return TALER_MHD_reply_json (connection, + reply, + MHD_HTTP_OK); +} /* end of donau-httpd_keys.c */ 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" @@ -40,17 +40,32 @@ struct DH_DonationUnitKey * Decoded donation unit public key (the hash of it is in * @e issue, but we sometimes need the full public key as well). */ - struct DONAU_DonationUnitPublicKey du_pub; + struct DONAU_DonationUnitPublicKey donation_unit_pub; /** * Hash code of the donation unit public key. */ - struct DONAU_DonationUnitHashP h_du_pub; + struct DONAU_DonationUnitHashP h_donation_unit_pub; /** * 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; }; + +/** + * Function to call to handle requests to "/management/keys" by sending + * back our future key material. + * + * @param rh context of the handler + * @param connection the MHD connection to handle + * @return MHD result code + */ +MHD_RESULT +DH_keys_management_get_keys_handler (const struct DH_RequestHandler *rh, + struct MHD_Connection *connection); + + +#endif