merchant

Merchant backend to process payments, run by merchants
Log | Files | Refs | Submodules | README | LICENSE

commit b1682233abce99960736d720fa53684f7d7014d0
parent 3fb61e332d1a3968eb7c8831548bc0167244c4b2
Author: Christian Grothoff <christian@grothoff.org>
Date:   Sat, 27 Jun 2026 15:24:05 +0200

fix first case of private token family key not being found

Diffstat:
Msrc/backend/taler-merchant-httpd_post-orders-ORDER_ID-pay.c | 27+++++++++++++++++++++------
Msrc/backend/taler-merchant-httpd_post-private-orders.c | 11+++++++++--
2 files changed, 30 insertions(+), 8 deletions(-)

diff --git a/src/backend/taler-merchant-httpd_post-orders-ORDER_ID-pay.c b/src/backend/taler-merchant-httpd_post-orders-ORDER_ID-pay.c @@ -3339,8 +3339,7 @@ find_valid_input_tokens ( GNUNET_snprintf (end_str, sizeof (end_str), "%s", - GNUNET_STRINGS_timestamp_to_string (kig->valid_before)) - ; + GNUNET_STRINGS_timestamp_to_string (kig->valid_before)); /* FIXME: use more specific EC */ GNUNET_snprintf (emsg, sizeof (emsg), @@ -3489,7 +3488,7 @@ sign_token_envelopes ( if ( (pos >= pc->parse_wallet_data.token_envelopes_cnt) || (pos >= pc->output_tokens_len) ) { - GNUNET_assert (0); /* this should not happen */ + GNUNET_assert (0); /* this should not happen */ // FIXME: but it does! see merchant-tokenfamilies test! return GNUNET_NO; } if (NULL == env->blinded_token.blinded_pub) @@ -3673,13 +3672,30 @@ handle_output_token (struct PayContext *pc, case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: break; } - GNUNET_assert (NULL != details.priv.private_key); GNUNET_free (details.token_family.slug); GNUNET_free (details.token_family.name); GNUNET_free (details.token_family.description); json_decref (details.token_family.description_i18n); - GNUNET_CRYPTO_blind_sign_pub_decref (details.pub.public_key); + if (NULL != details.pub.public_key) + GNUNET_CRYPTO_blind_sign_pub_decref (details.pub.public_key); GNUNET_free (details.token_family.cipher_spec); + if (NULL == details.priv.private_key) + { + /* The key SHOULD have been created when we + created the order (after all, the client was able + to blind, and that requires us having had a public + key). So how did we loose it? Bad bug, this should + not be possible. */ + GNUNET_break (0); + pay_end (pc, + TALER_MHD_reply_with_error ( + pc->connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_GENERIC_DB_INVARIANT_FAILURE, + "private token family key not found")); + return GNUNET_NO; + + } /* Depending on the token family, decide if the token envelope * is mandatory or optional. (Simplified logic here: adapt as needed.) */ @@ -5253,7 +5269,6 @@ pay_context_cleanup (void *cls) if (NULL != pc->output_tokens[i].sig.signature) GNUNET_CRYPTO_blinded_sig_decref (pc->output_tokens[i].sig.signature); GNUNET_free (pc->output_tokens); - pc->output_tokens = NULL; } GNUNET_free (pc); } diff --git a/src/backend/taler-merchant-httpd_post-private-orders.c b/src/backend/taler-merchant-httpd_post-private-orders.c @@ -1859,7 +1859,10 @@ add_output_token_family (struct OrderContext *oc, if (GNUNET_OK != get_rounded_time_interval_down ( key_details.token_family.validity_granularity, - valid_at, + GNUNET_TIME_absolute_to_timestamp ( + GNUNET_TIME_absolute_subtract ( + valid_at.abs_time, + key_details.token_family.start_offset)), &round_start)) { GNUNET_break (0); @@ -1893,7 +1896,7 @@ add_output_token_family (struct OrderContext *oc, reply_with_error (oc, MHD_HTTP_INTERNAL_SERVER_ERROR, TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE, - "duration, validty_granularity and start_offset inconsistent for token family"); + "duration, validity_granularity and start_offset inconsistent for token family"); return GNUNET_SYSERR; } key.valid_after @@ -1915,6 +1918,10 @@ add_output_token_family (struct OrderContext *oc, key_details.token_family.validity_granularity, key.valid_before, &key_expires)); + /* Make sure key never expires before the payment deadline */ + key_expires = GNUNET_TIME_timestamp_max ( + oc->parse_order.order->pay_deadline, + key_expires); if (GNUNET_TIME_timestamp_cmp ( key_expires, ==,