commit 7aa9f1928e285e28b1653db07d5b7a3bfafd423e
parent 960ddaf6e693504769d3930002868644b9e6de4f
Author: Matyja Lukas Adam <lukas.matyja@students.bfh.ch>
Date: Wed, 3 Apr 2024 10:38:34 +0200
[testing][donau] work on issue receipts
Diffstat:
8 files changed, 215 insertions(+), 106 deletions(-)
diff --git a/src/donau/donau-httpd.c b/src/donau/donau-httpd.c
@@ -498,13 +498,13 @@ handle_mhd_request (void *cls,
.nargs_is_upper_bound = true
},
/* POST batch issue receipts */
- // {
- // .url = "batch-issue",
- // .method = MHD_HTTP_METHOD_POST,
- // .handler.post = &DH_handler_issue_receipts_post,
- // .nargs = 1,
- // .nargs_is_upper_bound = true
- // },
+ {
+ .url = "batch-issue",
+ .method = MHD_HTTP_METHOD_POST,
+ .handler.post = &DH_handler_issue_receipts_post,
+ .nargs = 1,
+ .nargs_is_upper_bound = true
+ },
/**
etc
diff --git a/src/donau/donau-httpd_post-batch-issue.c b/src/donau/donau-httpd_post-batch-issue.c
@@ -259,10 +259,20 @@ DH_handler_issue_receipts_post (struct DH_RequestContext *rc,
for (size_t i = 0; i < num_bkp; i++)
{
struct GNUNET_HashCode temp_hash;
- GNUNET_CRYPTO_hash (irc.bkp,
- sizeof (irc.bkp[0].blinded_udi) * num_bkp,
+ GNUNET_CRYPTO_hash (&irc.bkp[i].blinded_udi,
+ sizeof (irc.bkp[0].blinded_udi),
&temp_hash);
GNUNET_CRYPTO_hash_xor (&h_receipts.hash, &temp_hash, &h_receipts.hash);
+ GNUNET_CRYPTO_hash_xor (&h_receipts.hash,
+ &irc.bkp[i].h_donation_unit_pub.hash,
+ &h_receipts.hash);
+ }
+ {
+ struct GNUNET_HashCode sig_hash;
+ GNUNET_CRYPTO_hash (&irc.charity_sig,
+ sizeof (struct DONAU_CharitySignatureP),
+ &sig_hash);
+ GNUNET_CRYPTO_hash_xor (&h_receipts.hash, &sig_hash, &h_receipts.hash);
}
start:
qs_check_receipts = DH_plugin->lookup_issued_receipts (DH_plugin->cls,
@@ -293,7 +303,7 @@ start:
blind_signatures));
}
/* calculate new receipts to date and check annual limit */
- struct TALER_Amount receipts_sum;
+ struct TALER_Amount receipts_sum = {0};
for (size_t i = 0; i < num_bkp; i++)
{
MHD_RESULT mret;
@@ -308,7 +318,7 @@ start:
TALER_EC_GENERIC_PARAMETER_MALFORMED,
"budikeypairs");
}
- struct TALER_Amount new_receipts_to_date;
+ struct TALER_Amount new_receipts_to_date = {0};
TALER_amount_add (&new_receipts_to_date, &receipts_sum,
&charity_meta.receipts_to_date);
// new_receipts_to_date has to be smaller or equal as max_per_year
diff --git a/src/include/donau_json_lib.h b/src/include/donau_json_lib.h
@@ -115,4 +115,17 @@ DONAU_JSON_pack_blinded_donation_unit_sig (
const char *name,
const struct DONAU_BlindedDonationUnitSignature *sig);
+/**
+ * Generate packer instruction for a JSON field of type
+ * blinded udi.
+ *
+ * @param name name of the field to add to the object
+ * @param blinded_udi blinded unique donation identifier
+ * @return json pack specification
+ */
+struct GNUNET_JSON_PackSpec
+DONAU_JSON_pack_blinded_donation_identifier (
+ const char *name,
+ const struct DONAU_BlindedUniqueDonationIdentifier *blinded_udi);
+
#endif
diff --git a/src/include/donau_testing_lib.h b/src/include/donau_testing_lib.h
@@ -118,14 +118,16 @@ TALER_TESTING_cmd_charities_get (const char *label,
* @param label the command label.
* @param charity_reference reference for traits
* @param year current year (mostly)
+ * @param num_bkps number of budi key pairs
* @param expected_response_code expected HTTP response code.
* @return the command.
*/
struct TALER_TESTING_Command
TALER_TESTING_cmd_issue_receipts (const char *label,
- const char *charity_reference,
- const uint64_t year,
- unsigned int expected_response_code);
+ const char *charity_reference,
+ const uint64_t year,
+ const size_t num_bkp,
+ unsigned int expected_response_code);
/**
* Convenience function to run a test.
@@ -165,19 +167,19 @@ TALER_TESTING_get_donau_url (
* Call #op on all simple traits.
*/
#define DONAU_TESTING_SIMPLE_TRAITS(op) \
- op (charity_priv, const struct DONAU_CharityPrivateKeyP) \
- op (charity_pub, const struct DONAU_CharityPublicKeyP) \
- op (charity_id, const unsigned long long) \
- op (donau_url, const char) \
- op (donau_keys, struct DONAU_Keys)
+ op (charity_priv, const struct DONAU_CharityPrivateKeyP) \
+ op (charity_pub, const struct DONAU_CharityPublicKeyP) \
+ op (charity_id, const unsigned long long) \
+ op (donau_url, const char) \
+ op (donau_keys, struct DONAU_Keys)
/**
* Call #op on all indexed traits.
*/
#define DONAU_TESTING_INDEXED_TRAITS(op) \
- op (donation_unit_pub, const struct DONAU_DonationUnitInformation) \
- op (donau_pub, const struct TALER_ExchangePublicKeyP)
+ op (donation_unit_pub, const struct DONAU_DonationUnitInformation) \
+ op (donau_pub, const struct TALER_ExchangePublicKeyP)
DONAU_TESTING_SIMPLE_TRAITS (TALER_TESTING_MAKE_DECL_SIMPLE_TRAIT)
DONAU_TESTING_INDEXED_TRAITS (TALER_TESTING_MAKE_DECL_INDEXED_TRAIT)
diff --git a/src/json/donau_json.c b/src/json/donau_json.c
@@ -397,4 +397,50 @@ DONAU_JSON_pack_blinded_donation_unit_sig (
}
+struct GNUNET_JSON_PackSpec
+DONAU_JSON_pack_blinded_donation_identifier (
+ const char *name,
+ const struct DONAU_BlindedUniqueDonationIdentifier *blinded_udi)
+{
+ const struct GNUNET_CRYPTO_BlindedMessage *bm;
+ struct GNUNET_JSON_PackSpec ps = {
+ .field_name = name,
+ };
+
+ if (NULL == blinded_udi)
+ return ps;
+ bm = blinded_udi->blinded_message;
+ switch (bm->cipher)
+ {
+ case GNUNET_CRYPTO_BSA_INVALID:
+ break;
+ case GNUNET_CRYPTO_BSA_RSA:
+ ps.object = GNUNET_JSON_PACK (
+ GNUNET_JSON_pack_string ("cipher",
+ "RSA"),
+ GNUNET_JSON_pack_data_varsize (
+ "rsa_blinded_identifier",
+ bm->details.rsa_blinded_message.blinded_msg,
+ bm->details.rsa_blinded_message.blinded_msg_size));
+ return ps;
+ case GNUNET_CRYPTO_BSA_CS:
+ ps.object = GNUNET_JSON_PACK (
+ GNUNET_JSON_pack_string ("cipher",
+ "CS"),
+ GNUNET_JSON_pack_data_auto (
+ "cs_nonce",
+ &bm->details.cs_blinded_message.nonce),
+ GNUNET_JSON_pack_data_auto (
+ "cs_blinded_c0",
+ &bm->details.cs_blinded_message.c[0]),
+ GNUNET_JSON_pack_data_auto (
+ "cs_blinded_c1",
+ &bm->details.cs_blinded_message.c[1]));
+ return ps;
+ }
+ GNUNET_assert (0);
+ return ps;
+}
+
+
/* end of json/donau_json.c */
\ No newline at end of file
diff --git a/src/lib/donau_api_batch_issue_receipts.c b/src/lib/donau_api_batch_issue_receipts.c
@@ -83,38 +83,36 @@ struct DONAU_BatchIssueReceiptHandle
*/
json_t *
issue_receipt_body_to_json (const unsigned int num_bkp,
- const struct DONAU_BlindedUniqueDonationIdentifierKeyPair *bkp[static num_bkp],
- const uint64_t year,
- const struct DONAU_CharitySignatureP *charity_sig)
+ const struct
+ DONAU_BlindedUniqueDonationIdentifierKeyPair *bkp[
+ static num_bkp],
+ const uint64_t year,
+ const struct DONAU_CharitySignatureP *charity_sig)
{
- json_t *budikeypairs;
+ json_t *budikeypairs = json_array ();
+ GNUNET_assert (NULL != budikeypairs);
- budikeypairs = json_array ();
- GNUNET_assert (NULL != budikeypairs);
-
- for (unsigned int i = 0; i < num_bkp; i++)
- {
- json_t *budikeypair;
-
- budikeypair = GNUNET_JSON_PACK (
- GNUNET_JSON_pack_data_auto ("h_du_pub",
- &bkp[i]->h_donation_unit_pub),
- GNUNET_JSON_pack_data_auto ("blinded_udi",
- &bkp[i]->blinded_udi));
- GNUNET_assert (NULL != budikeypair);
- GNUNET_assert (0 ==
- json_array_append_new (budikeypairs,
- budikeypair));
- }
- return GNUNET_JSON_PACK (
- GNUNET_JSON_pack_array_steal ("budikeypairs",
- budikeypairs),
- GNUNET_JSON_pack_data_auto ("charity_sig",
- &charity_sig->eddsa_sig),
- GNUNET_JSON_pack_uint64 ("year",
- year));
+ for (size_t i = 0; i < num_bkp; i++)
+ {
+ json_t *budikeypair = GNUNET_JSON_PACK (
+ GNUNET_JSON_pack_data_auto ("h_du_pub",
+ &bkp[i]->h_donation_unit_pub));
+// DONAU_JSON_pack_blinded_donation_identifier ("blinded_udi",
+// &bkp[i]->blinded_udi));
+ GNUNET_assert (0 ==
+ json_array_append_new (budikeypairs,
+ budikeypair));
+ }
+ return GNUNET_JSON_PACK (
+ GNUNET_JSON_pack_array_steal ("budikeypairs",
+ budikeypairs),
+ GNUNET_JSON_pack_data_auto ("charity_sig",
+ &charity_sig->eddsa_sig),
+ GNUNET_JSON_pack_uint64 ("year",
+ year));
}
+
/**
* Function called when we're done processing the
* HTTP POST /batch-issue/$CHARITY_ID request.
@@ -172,7 +170,7 @@ handle_batch_issue_finished (void *cls,
if (NULL != birh->cb)
{
birh->cb (birh->cb_cls,
- &biresp);
+ &biresp);
birh->cb = NULL;
}
DONAU_charity_issue_receipt_cancel (birh);
@@ -181,15 +179,16 @@ handle_batch_issue_finished (void *cls,
struct DONAU_BatchIssueReceiptHandle *
DONAU_charity_issue_receipt (
- struct GNUNET_CURL_Context *ctx,
- const char *url,
- const struct DONAU_CharityPrivateKeyP *charity_priv,
- const uint64_t charity_id,
- const uint64_t year,
- const unsigned int num_bkp,
- const struct DONAU_BlindedUniqueDonationIdentifierKeyPair *bkp[static num_bkp],
- DONAU_BatchIssueReceiptsCallback cb,
- void *cb_cls)
+ struct GNUNET_CURL_Context *ctx,
+ const char *url,
+ const struct DONAU_CharityPrivateKeyP *charity_priv,
+ const uint64_t charity_id,
+ const uint64_t year,
+ const unsigned int num_bkp,
+ const struct DONAU_BlindedUniqueDonationIdentifierKeyPair *bkp[static
+ num_bkp],
+ DONAU_BatchIssueReceiptsCallback cb,
+ void *cb_cls)
{
struct DONAU_BatchIssueReceiptHandle *birh;
birh = GNUNET_new (struct DONAU_BatchIssueReceiptHandle);
@@ -197,7 +196,8 @@ DONAU_charity_issue_receipt (
json_t *body;
// make signature over budi-key-pair
- DONAU_charity_budi_key_pair_sign(num_bkp, bkp, charity_priv, &birh->charity_sig);
+ DONAU_charity_budi_key_pair_sign (num_bkp, bkp, charity_priv,
+ &birh->charity_sig);
TALER_LOG_DEBUG ("Connecting to the donau (%s)\n",
url);
@@ -207,24 +207,24 @@ DONAU_charity_issue_receipt (
birh->ctx = ctx;
char arg_str[sizeof (charity_id) * 2 + 32];
GNUNET_snprintf (arg_str,
- sizeof (arg_str),
- "batch-issue/%llu",
- (unsigned long long)
- charity_id);
+ sizeof (arg_str),
+ "batch-issue/%llu",
+ (unsigned long long)
+ charity_id);
birh->url = TALER_url_join (url,
- arg_str,
- NULL);
+ arg_str,
+ NULL);
if (NULL == birh->url)
{
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Could not construct request URL.\n");
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Could not construct request URL.\n");
GNUNET_free (birh);
return NULL;
}
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "issue receipts with URL `%s'.\n",
+ "issue_receipts_with_URL `%s'.\n",
birh->url);
- body = issue_receipt_body_to_json(num_bkp, bkp, year, &birh->charity_sig);
+ body = issue_receipt_body_to_json (num_bkp, bkp, year, &birh->charity_sig);
eh = DONAU_curl_easy_get_ (birh->url);
if ( (NULL == eh) ||
(GNUNET_OK !=
@@ -241,10 +241,10 @@ DONAU_charity_issue_receipt (
}
json_decref (body);
birh->job = GNUNET_CURL_job_add2 (ctx,
- eh,
- birh->post_ctx.headers,
- &handle_batch_issue_finished,
- birh);
+ eh,
+ birh->post_ctx.headers,
+ &handle_batch_issue_finished,
+ birh);
return birh;
}
diff --git a/src/testing/test_donau_api.c b/src/testing/test_donau_api.c
@@ -91,10 +91,11 @@ run (void *cls,
TALER_TESTING_cmd_charities_get ("get-charities",
&bearer,
MHD_HTTP_OK),
-// TALER_TESTING_cmd_issue_receipts ("issue-receipts",
-// "post-charity",
-// 2024,
-// MHD_HTTP_CREATED),
+ TALER_TESTING_cmd_issue_receipts ("issue-receipts",
+ "post-charity",
+ 2024,
+ 3, // number of budi key pairs
+ MHD_HTTP_CREATED),
TALER_TESTING_cmd_charity_delete ("delete-charity",
"post-charity", // cmd trait reference
&bearer,
diff --git a/src/testing/testing_api_cmd_issue_receipts.c b/src/testing/testing_api_cmd_issue_receipts.c
@@ -71,12 +71,12 @@ struct StatusState
/**
* number of budi key pair.
*/
- uint64_t num_bkp;
+ size_t num_bkp;
/**
* budi key pair array
*/
- const struct DONAU_BlindedUniqueDonationIdentifierKeyPair *bkp;
+ struct DONAU_BlindedUniqueDonationIdentifierKeyPair *bkps;
};
@@ -90,7 +90,7 @@ struct StatusState
*/
static void
issue_receipts_status_cb (void *cls,
- const struct DONAU_BatchIssueResponse *biresp)
+ const struct DONAU_BatchIssueResponse *biresp)
{
struct StatusState *ss = cls;
@@ -108,8 +108,8 @@ issue_receipts_status_cb (void *cls,
TALER_TESTING_interpreter_fail (ss->is);
return;
}
- //if (ss->expected_response_code == biresp->hr.http_status)
- //ss->charity_id = (unsigned long long) biresp->details.ok.charity_id;
+ // if (ss->expected_response_code == biresp->hr.http_status)
+ // ss->charity_id = (unsigned long long) biresp->details.ok.charity_id;
TALER_TESTING_interpreter_next (ss->is);
}
@@ -129,36 +129,61 @@ status_run (void *cls,
struct StatusState *ss = cls;
ss->is = is;
- /* Get charity id from trait */
+ /* Get charity id and the charity private key from trait */
{
- const struct TALER_TESTING_Command *charity_post_cmd;
- const unsigned long long *charity_id;
-
- charity_post_cmd = TALER_TESTING_interpreter_lookup_command (is,
- ss->charity_reference);
-
- if (GNUNET_OK !=
- TALER_TESTING_get_trait_charity_id (charity_post_cmd,
- &charity_id))
- {
- GNUNET_break (0);
- TALER_TESTING_interpreter_fail (is);
- return;
- }
- ss->charity_id = (uint64_t) *(charity_id);
+ const struct TALER_TESTING_Command *charity_post_cmd;
+ const unsigned long long *charity_id;
+ const struct DONAU_CharityPrivateKeyP *charity_priv;
+
+ charity_post_cmd = TALER_TESTING_interpreter_lookup_command (is,
+ ss->
+ charity_reference);
+
+ if (GNUNET_OK !=
+ TALER_TESTING_get_trait_charity_id (charity_post_cmd, &charity_id) ||
+ GNUNET_OK != TALER_TESTING_get_trait_charity_priv (charity_post_cmd,
+ &charity_priv))
+ {
+ GNUNET_break (0);
+ TALER_TESTING_interpreter_fail (is);
+ return;
+ }
+ ss->charity_id = (uint64_t) *(charity_id);
+ ss->charity_priv = *(charity_priv);
}
// TODO: build bkps with traits from /keys request, use the public sign key from the
// DONAU to verify the signatures
+ ss->bkps
+ = GNUNET_new_array (ss->num_bkp,
+ struct DONAU_BlindedUniqueDonationIdentifierKeyPair);
+ for (size_t cnt = 0; cnt < ss->num_bkp; cnt++)
+ {
+ struct GNUNET_CRYPTO_RsaBlindedMessage *rp;
+ struct DONAU_BlindedUniqueDonationIdentifier *bp;
+ bp = &ss->bkps[cnt].blinded_udi;
+ bp->blinded_message = GNUNET_new (struct GNUNET_CRYPTO_BlindedMessage);
+ bp->blinded_message->cipher = GNUNET_CRYPTO_BSA_RSA;
+ bp->blinded_message->rc = 1;
+ rp = &bp->blinded_message->details.rsa_blinded_message;
+ rp->blinded_msg_size = 1 + (size_t) GNUNET_CRYPTO_random_u64 (
+ GNUNET_CRYPTO_QUALITY_WEAK,
+ (1024 / 8) - 1); // 1024 is the RSA key size
+ rp->blinded_msg = GNUNET_malloc (rp->blinded_msg_size);
+ GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
+ rp->blinded_msg,
+ rp->blinded_msg_size);
+ }
+ const struct DONAU_BlindedUniqueDonationIdentifierKeyPair *bkps = ss->bkps;
ss->birh = DONAU_charity_issue_receipt (
TALER_TESTING_interpreter_get_context (is),
TALER_TESTING_get_donau_url (is),
&ss->charity_priv,
ss->charity_id,
ss->year,
- ss->num_bkp,
- &ss->bkp,
+ ss->num_bkp,
+ &bkps,
&issue_receipts_status_cb,
ss);
@@ -174,7 +199,7 @@ status_run (void *cls,
*/
static void
cleanup (void *cls,
- const struct TALER_TESTING_Command *cmd)
+ const struct TALER_TESTING_Command *cmd)
{
struct StatusState *ss = cls;
@@ -186,16 +211,26 @@ cleanup (void *cls,
DONAU_charity_issue_receipt_cancel (ss->birh);
ss->birh = NULL;
}
+// if (NULL != revealed_coins)
+// {
+// for (unsigned int cnt = 0; cnt < MELT_NEW_COINS; cnt++)
+// {
+// TALER_blinded_denom_sig_free (&revealed_coins[cnt].coin_sig);
+// TALER_blinded_planchet_free (&revealed_coins[cnt].blinded_planchet);
+// }
+// GNUNET_free (revealed_coins);
+// revealed_coins = NULL;
+// }
GNUNET_free (ss);
}
-
struct TALER_TESTING_Command
TALER_TESTING_cmd_issue_receipts (const char *label,
- const char *charity_reference,
- const uint64_t year,
- unsigned int expected_response_code)
+ const char *charity_reference,
+ const uint64_t year,
+ const size_t num_bkp,
+ unsigned int expected_response_code)
{
struct StatusState *ss;
@@ -204,6 +239,8 @@ TALER_TESTING_cmd_issue_receipts (const char *label,
ss->year = year;
ss->charity_reference = charity_reference;
ss->expected_response_code = expected_response_code;
+ ss->num_bkp = num_bkp;
+
{
struct TALER_TESTING_Command cmd = {
.cls = ss,