commit 535c7034e15fe31bbc7ffa5071fd05d0978d66e1
parent 00b3c5e0bbcfa0f4b78525601dc4ca7807f3efdc
Author: bohdan-potuzhnyi <bohdan.potuzhnyi@gmail.com>
Date: Mon, 4 Aug 2025 10:17:02 +0200
output_tokens update
Diffstat:
1 file changed, 54 insertions(+), 2 deletions(-)
diff --git a/src/backend/taler-merchant-httpd_post-orders-ID-pay.c b/src/backend/taler-merchant-httpd_post-orders-ID-pay.c
@@ -1962,6 +1962,22 @@ phase_process_donation_receipt (struct PayContext *pc)
pc->phase = PP_PAYMENT_NOTIFICATION;
return;
#else
+ if (pc->parse_wallet_data.num_bkps !=
+ pc->donau_receipt.num_sigs)
+ { /* Not supposed to happen, as it is already checked by donau c-api, but just in case */
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Mismatch in wallet_data.num_bkps %llu and "
+ "donau_receipt.num_sigs %llu",
+ (unsigned long long) pc->parse_wallet_data.num_bkps,
+ (unsigned long long) pc->donau_receipt.num_sigs);
+ pay_end (pc,
+ TALER_MHD_reply_with_error (pc->connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_GENERIC_PARAMETER_MALFORMED,
+ "Mismatch between blinded key pairs and donation signatures received from donau"));
+ return;
+ }
+
if ( (NULL == pc->donau_receipt.donau_sigs_json) ||
(! signatures_to_json (pc->donau_receipt.num_sigs,
pc->donau_receipt.sigs,
@@ -1980,6 +1996,7 @@ phase_process_donation_receipt (struct PayContext *pc)
/* Attaching first sig from the donau as output_token signature,
* to reference the output_token related to donau_sigs */
+ uint64_t d_out = -1;
const struct TALER_MERCHANT_ContractChoice *choice =
&pc->check_contract.contract_terms->details.v1
.choices[pc->parse_wallet_data.choice_index];
@@ -1988,8 +2005,43 @@ phase_process_donation_receipt (struct PayContext *pc)
if (i < choice->outputs_len &&
TALER_MERCHANT_CONTRACT_OUTPUT_TYPE_DONATION_RECEIPT ==
choice->outputs[i].type)
- pc->validate_tokens.output_tokens[i].sig.signature =
- pc->donau_receipt.sigs[0].blinded_sig;
+ {
+ d_out = i;
+ break;
+ }
+ GNUNET_assert (-1 != d_out);
+
+ {
+ uint64_t ot_len
+ = pc->validate_tokens.output_tokens_len;
+ uint64_t ot_len_with_donau_sig
+ = pc->validate_tokens.output_tokens_len + pc->donau_receipt.num_sigs - 1;
+
+ if (pc->donau_receipt.num_sigs > 1)
+ {
+ GNUNET_array_grow (pc->validate_tokens.output_tokens,
+ pc->validate_tokens.output_tokens_len,
+ ot_len_with_donau_sig);
+
+ memmove (
+ &pc->validate_tokens.output_tokens[d_out + pc->donau_receipt.num_sigs],
+ &pc->validate_tokens.output_tokens[d_out + 1],
+ (ot_len - d_out - 1) * sizeof (struct SignedOutputToken));
+ }
+
+ for (unsigned int i = 0; i < pc->donau_receipt.num_sigs; i++)
+ {
+ struct SignedOutputToken *ot =
+ &pc->validate_tokens.output_tokens[d_out + i];
+
+ ot->sig.signature = pc->donau_receipt.sigs[i].blinded_sig;
+ ot->h_issue.hash =
+ pc->parse_wallet_data.bkps[i].h_donation_unit_pub.hash;
+
+ }
+ pc->validate_tokens.output_tokens_len = ot_len_with_donau_sig;
+ }
+
/* To have the possibility to fetch the donau_sigs
* in case of contract_paid, we need to save