donau

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

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

Merge remote-tracking branch 'refs/remotes/origin/master'

Diffstat:
Msrc/donau/donau-httpd_keys.c | 13++++++++++++-
Msrc/donau/donau-httpd_post-batch-issue.c | 277+++++++++++++++++++++++++++++++++++--------------------------------------------
2 files changed, 134 insertions(+), 156 deletions(-)

diff --git a/src/donau/donau-httpd_keys.c b/src/donau/donau-httpd_keys.c @@ -269,7 +269,18 @@ struct DH_KeyStateHandle struct GNUNET_CONTAINER_MultiPeerMap *signkey_map; /** - * Information we track for thecrypto helpers. Preserved + * 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 the crypto helpers. Preserved * when the @e key_generation changes, thus kept separate. */ struct HelperState *helpers; diff --git a/src/donau/donau-httpd_post-batch-issue.c b/src/donau/donau-httpd_post-batch-issue.c @@ -15,7 +15,7 @@ */ /** * @file donau-httpd_post-batch-issue.c - * @brief Handle request to insert a charity. + * @brief Handle request to issue receipts. * @author Lukas Matyja */ #include <taler/platform.h> @@ -34,7 +34,7 @@ /** - * Closure for #insert_charity() + * Closure for #issue_receipts() */ struct IssueReceiptsContext { @@ -54,13 +54,13 @@ struct IssueReceiptsContext */ static enum GNUNET_GenericReturnValue parse_json_bkp (struct DONAU_BlindedUniqueDonationIdentifierKeyPair *bkp, - const json_t *bkp_key_obj) + const json_t *bkp_key_obj) { struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_fixed_auto ("h_du_pub", &bkp->h_donation_unit_pub), GNUNET_JSON_spec_fixed_auto ("blinded_udi", - &bkp->blinded_udi), + &bkp->blinded_udi), GNUNET_JSON_spec_end () }; @@ -75,87 +75,42 @@ parse_json_bkp (struct DONAU_BlindedUniqueDonationIdentifierKeyPair *bkp, return GNUNET_OK; } -/** - * Function implementing insert charity transaction. - * - * Runs the transaction logic; IF it returns a non-error code, the - * transaction logic MUST NOT queue a MHD response. IF it returns an hard - * error, the transaction logic MUST queue a MHD response and set @a mhd_ret. - * IF it returns the soft error code, the function MAY be called again to - * retry and MUST not queue a MHD response. - * - * @param cls closure with a `struct InsertCharityContext` - * @param connection MHD request which triggered the transaction - * @param[out] mhd_ret set to MHD response status for @a connection, - * if transaction failed (!) - * @return transaction status - */ -//static enum GNUNET_DB_QueryStatus -//issue_receipts (void *cls, -// struct MHD_Connection *connection, -// MHD_RESULT *mhd_ret) -//{ -// struct InsertCharityContext *icc = cls; -// enum GNUNET_DB_QueryStatus qs; -// -// qs = DH_plugin->insert_charity (DH_plugin->cls, -// &icc->charity_pub, -// icc->charity_name, -// icc->charity_url, -// &icc->max_per_year, -// &icc->receipts_to_date, -// &icc->current_year, -// &icc->charity_id); -// if (qs <= 0) -// { -// if (GNUNET_DB_STATUS_SOFT_ERROR != qs) -// { -// GNUNET_break (0); -// *mhd_ret = TALER_MHD_reply_with_error (connection, -// MHD_HTTP_INTERNAL_SERVER_ERROR, -// TALER_EC_GENERIC_DB_STORE_FAILED, -// "insert_charity"); -// return GNUNET_DB_STATUS_HARD_ERROR; -// } -// return qs; -// } -// -// return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT; -//} - MHD_RESULT DH_handler_issue_receipts_post (struct DH_RequestContext *rc, - const json_t *root, - const char *const args[1]) + const json_t *root, + const char *const args[1]) { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "issue receipts request! \n"); + unsigned long long charity_id; char dummy; if ( (NULL == args[0]) || - (1 != sscanf (args[0], - "%llu%c", - &charity_id, - &dummy)) ) + (1 != sscanf (args[0], + "%llu%c", + &charity_id, + &dummy)) ) { GNUNET_break_op (0); return TALER_MHD_reply_with_error (rc->connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_GENERIC_PARAMETER_MALFORMED, - "charity_id"); + MHD_HTTP_BAD_REQUEST, + TALER_EC_GENERIC_PARAMETER_MALFORMED, + "charity_id"); } GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "issue receipts for charity id: %llu\n", - charity_id); + "issue receipts for charity id: %llu\n", + charity_id); struct IssueReceiptsContext irc; const json_t *budikeypairs; struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_array_const ("budikeypairs", - &budikeypairs), + GNUNET_JSON_spec_array_const ("budikeypairs", + &budikeypairs), GNUNET_JSON_spec_fixed_auto ("charity_sig", - &irc.charity_sig), + &irc.charity_sig), GNUNET_JSON_spec_uint64 ("year", &irc.year), GNUNET_JSON_spec_end () @@ -176,6 +131,8 @@ DH_handler_issue_receipts_post (struct DH_RequestContext *rc, } } + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "parse some values!"); /* parse the budikeypairs array */ const uint64_t num_bkp = json_array_size (budikeypairs); @@ -184,66 +141,79 @@ DH_handler_issue_receipts_post (struct DH_RequestContext *rc, json_t *bkp_obj; unsigned int index; - struct DONAU_BlindedUniqueDonationIdentifierKeyPair *bkp = GNUNET_new_array (num_bkp, - struct DONAU_BlindedUniqueDonationIdentifierKeyPair); + struct DONAU_BlindedUniqueDonationIdentifierKeyPair *bkp + = GNUNET_new_array + (num_bkp, + struct DONAU_BlindedUniqueDonationIdentifierKeyPair); json_array_foreach (budikeypairs, index, bkp_obj) { - if (GNUNET_SYSERR == - parse_json_bkp(&bkp[index], bkp_obj)) { - return TALER_MHD_reply_with_error (rc->connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_GENERIC_PARAMETER_MALFORMED, - "budikeypairs"); - } + if (GNUNET_SYSERR == + parse_json_bkp (&bkp[index], bkp_obj)) + { + return TALER_MHD_reply_with_error (rc->connection, + MHD_HTTP_BAD_REQUEST, + TALER_EC_GENERIC_PARAMETER_MALFORMED, + "budikeypairs"); + } } irc.bkp = bkp; - } else { - return TALER_MHD_reply_with_error (rc->connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_GENERIC_PARAMETER_MALFORMED, - "budikeypairs"); + } + else + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "empty array of budi key pairs!"); + return TALER_MHD_reply_with_error (rc->connection, + MHD_HTTP_BAD_REQUEST, + TALER_EC_GENERIC_PARAMETER_MALFORMED, + "budikeypairs"); } + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "budi key pairs array is parsed!"); // Get charity pub struct DONAUDB_CharityMetaData charity_meta; enum GNUNET_DB_QueryStatus qs_charity; qs_charity = DH_plugin->lookup_charity (DH_plugin->cls, - (uint64_t) charity_id, - &charity_meta); + (uint64_t) charity_id, + &charity_meta); switch (qs_charity) { case GNUNET_DB_STATUS_HARD_ERROR: case GNUNET_DB_STATUS_SOFT_ERROR: - GNUNET_break (0); - return TALER_MHD_reply_with_error (rc->connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_FETCH_FAILED, - NULL); + GNUNET_break (0); + return TALER_MHD_reply_with_error (rc->connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_GENERIC_DB_FETCH_FAILED, + NULL); case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: - return TALER_MHD_reply_with_error ( - rc->connection, - MHD_HTTP_NOT_FOUND, - TALER_EC_DONAU_CHARITY_NOT_FOUND, - NULL); - break; - case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: - break; - } + return TALER_MHD_reply_with_error ( + rc->connection, + MHD_HTTP_NOT_FOUND, + TALER_EC_DONAU_CHARITY_NOT_FOUND, + NULL); + break; + case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: + break; + } + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "got charity from db!"); /* verify charity signature */ if (GNUNET_OK != - DONAU_charity_budi_key_pair_verify(num_bkp, &irc.bkp, - &charity_meta.charity_pub, - &irc.charity_sig)) + DONAU_charity_budi_key_pair_verify (num_bkp, &irc.bkp, + &charity_meta.charity_pub, + &irc.charity_sig)) { - GNUNET_break_op (0); - return TALER_MHD_reply_with_error ( - rc->connection, - MHD_HTTP_FORBIDDEN, - TALER_EC_DONAU_CHARITY_SIGNATURE_INVALID, - NULL); + GNUNET_break_op (0); + return TALER_MHD_reply_with_error ( + rc->connection, + MHD_HTTP_FORBIDDEN, + TALER_EC_DONAU_CHARITY_SIGNATURE_INVALID, + NULL); } + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "charity signature valid!"); /* request already made? -> idempotent */ enum GNUNET_DB_QueryStatus qs_check_receipts; struct DONAUDB_IssuedReceiptsMetaData check_receipts_meta; @@ -253,67 +223,64 @@ DH_handler_issue_receipts_post (struct DH_RequestContext *rc, &bkp_hash.hash); qs_check_receipts = DH_plugin->lookup_issued_receipts (DH_plugin->cls, - bkp_hash, - &check_receipts_meta); + bkp_hash, + &check_receipts_meta); switch (qs_check_receipts) { case GNUNET_DB_STATUS_HARD_ERROR: case GNUNET_DB_STATUS_SOFT_ERROR: - GNUNET_break (0); - return TALER_MHD_reply_with_error (rc->connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_FETCH_FAILED, - NULL); + GNUNET_break (0); + return TALER_MHD_reply_with_error (rc->connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_GENERIC_DB_FETCH_FAILED, + NULL); case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: - break; // it's the first request from the charity, we can proceed + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "request have not been made yet (first time)!"); + break; // it's the first request from the charity, we can proceed case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: - // A request was already made. We do not change the annual limit - break; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "request have been made already!"); + // A request was already made. We do not change the annual limit + break; } /* check annual limit and change it -> Rollback if we could not save the request*/ /* save Request (charity signature, charity id, amount, hash over bkps) and make it idempotent*/ /* sign budis and send the signatures back */ + int i = 0; + json_t *blind_signatures; + blind_signatures = json_array (); + while (i < num_bkp) + { + struct DONAU_BlindedDonationUnitSignature du_sig; + // TODO: get donation unit private key + const struct DONAU_DonationUnitPrivateKey du_priv; + const struct DONAU_BlindedUniqueDonationIdentifier budi = irc.bkp[i]. + blinded_udi; + if (GNUNET_SYSERR == TALER_donation_unit_sign_blinded (&du_sig, &du_priv, & + budi)) + { + GNUNET_break (0); + return TALER_MHD_reply_with_error (rc->connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_GENERIC_DB_FETCH_FAILED, + NULL); + } + GNUNET_assert ( + 0 == json_array_append ( + blind_signatures, + GNUNET_JSON_PACK ( + GNUNET_JSON_pack_data_auto ("du_sig", + &du_sig)))); + } -// { -// MHD_RESULT mhd_ret; -// -// if (GNUNET_OK != -// DH_DB_run_transaction (rc->connection, -// "issue_receipts", -// DH_MT_REQUEST_OTHER, -// &mhd_ret, -// &issue_receipts, -// &irc)) -// { -// return mhd_ret; -// } -// } -// -// GNUNET_log (GNUNET_ERROR_TYPE_INFO, -// "receipts were successfully issued\n"); -// -// result = TALER_MHD_REPLY_JSON_PACK ( -// rc->connection, -// MHD_HTTP_OK, -// GNUNET_JSON_pack_data_auto ("charity_pub", -// &meta.charity_pub), -// GNUNET_JSON_pack_string ("url", -// meta.charity_url), -// GNUNET_JSON_pack_string ("name", -// meta.charity_name), -// TALER_JSON_pack_amount ("max_per_year", -// &meta.max_per_year), -// TALER_JSON_pack_amount ("receipts_to_date", -// &meta.receipts_to_date), -// GNUNET_JSON_pack_uint64 ("current_year", -// meta.current_year)); - - - return TALER_MHD_reply_with_error ( - rc->connection, - MHD_HTTP_NOT_FOUND, - TALER_EC_DONAU_CHARITY_NOT_FOUND, - NULL); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "made blind signatures!"); + return TALER_MHD_REPLY_JSON_PACK ( + rc->connection, + MHD_HTTP_OK, + GNUNET_JSON_pack_array_steal ("blind_signatures", + blind_signatures)); }