exchange

Base system with REST service to issue digital coins, run by the payment service provider
Log | Files | Refs | Submodules | README | LICENSE

commit de965ce14a88dcc196a43a96123abd1d9c0e2915
parent bf7964857d5c206c2f03f0f92bc75279ddd4a789
Author: Christian Grothoff <christian@grothoff.org>
Date:   Tue,  7 Apr 2026 11:02:16 +0200

turn force_dc into a proper option on batch-deposit API, and add option to verify signature

Diffstat:
Msrc/include/taler/taler-exchange/post-batch-deposit.h | 126+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
Msrc/lib/exchange_api_post-batch-deposit.c | 55++++++++++++++++++++++++++++++++++++++++++++-----------
2 files changed, 164 insertions(+), 17 deletions(-)

diff --git a/src/include/taler/taler-exchange/post-batch-deposit.h b/src/include/taler/taler-exchange/post-batch-deposit.h @@ -145,6 +145,44 @@ struct TALER_EXCHANGE_PostBatchDepositHandle; /** + * Possible options we can set for the POST /batch-deposit request. + */ +enum TALER_EXCHANGE_PostBatchDepositOption +{ + /** + * End of list of options. + */ + TALER_EXCHANGE_POST_BATCH_DEPOSIT_OPTION_END = 0, + + /** + * Change the chance that our deposit confirmation will be given to the + * auditor to 100%. + */ + TALER_EXCHANGE_POST_BATCH_DEPOSIT_OPTION_FORCE_DC, + + /** + * Verify the merchant signature on the contract terms. + * Not enabled by default as the caller typically just created the signature. + */ + TALER_EXCHANGE_POST_BATCH_DEPOSIT_OPTION_VERIFY_MERCHANT_SIG + +}; + + +/** + * Value for an option we can set for the POST /batch-deposit request. + */ +struct TALER_EXCHANGE_PostBatchDepositOptionValue +{ + /** + * Type of the option being set. + */ + enum TALER_EXCHANGE_PostBatchDepositOption option; + +}; + + +/** * Set up POST /batch-deposit operation. * Note that you must explicitly start the operation after setup. * @@ -173,14 +211,80 @@ TALER_EXCHANGE_post_batch_deposit_create ( /** - * Change the chance that our deposit confirmation will be given to the - * auditor to 100%. + * Terminate the list of options. * - * @param[in,out] pbdh the batch deposit handle + * @return the terminating object */ -void -TALER_EXCHANGE_post_batch_deposit_force_dc ( - struct TALER_EXCHANGE_PostBatchDepositHandle *pbdh); +#define TALER_EXCHANGE_post_batch_deposit_option_end_() \ + (const struct TALER_EXCHANGE_PostBatchDepositOptionValue) \ + { \ + .option = TALER_EXCHANGE_POST_BATCH_DEPOSIT_OPTION_END \ + } + +/** + * Force the deposit confirmation to be sent to the auditor with 100% + * probability. + * + * @return representation of the option + */ +#define TALER_EXCHANGE_post_batch_deposit_option_force_dc() \ + (const struct TALER_EXCHANGE_PostBatchDepositOptionValue) \ + { \ + .option = TALER_EXCHANGE_POST_BATCH_DEPOSIT_OPTION_FORCE_DC \ + } + +/** + * Enable verification of the merchant signature on the contract terms. + * + * @return representation of the option + */ +#define TALER_EXCHANGE_post_batch_deposit_option_verify_merchant_sig() \ + (const struct TALER_EXCHANGE_PostBatchDepositOptionValue) \ + { \ + .option = \ + TALER_EXCHANGE_POST_BATCH_DEPOSIT_OPTION_VERIFY_MERCHANT_SIG \ + } + + +/** + * Set the requested options for the operation. + * + * If any option fails, other options may or may not be applied. + * + * @param pbdh the request to set the options for + * @param num_options length of the @a options array + * @param options an array of options + * @return #GNUNET_OK on success, + * #GNUNET_NO on failure, + * #GNUNET_SYSERR on internal error + */ +enum GNUNET_GenericReturnValue +TALER_EXCHANGE_post_batch_deposit_set_options_ ( + struct TALER_EXCHANGE_PostBatchDepositHandle *pbdh, + unsigned int num_options, + const struct TALER_EXCHANGE_PostBatchDepositOptionValue options[]); + + +/** + * Set the requested options for the operation. + * + * If any option fails, other options may or may not be applied. + * + * @param pbdh the request to set the options for + * @param ... the list of the options, each created by a + * TALER_EXCHANGE_post_batch_deposit_option_NAME(VALUE) macro + * @return #GNUNET_OK on success, + * #GNUNET_NO on failure, + * #GNUNET_SYSERR on internal error + */ +#define TALER_EXCHANGE_post_batch_deposit_set_options(pbdh,...) \ + TALER_EXCHANGE_post_batch_deposit_set_options_ ( \ + pbdh, \ + TALER_EXCHANGE_COMMON_OPTIONS_ARRAY_MAX_SIZE, \ + ((const struct TALER_EXCHANGE_PostBatchDepositOptionValue[]) \ + {__VA_ARGS__, \ + TALER_EXCHANGE_post_batch_deposit_option_end_ ()} \ + )) /** @@ -245,6 +349,11 @@ struct TALER_EXCHANGE_PostBatchDepositResponse * The coin that had a conflict. */ struct TALER_CoinSpendPublicKeyP coin_pub; + + /** + * Hash of the denomination public key of the coin. + */ + struct TALER_DenominationHashP h_denom_pub; } insufficient_funds; struct @@ -253,6 +362,11 @@ struct TALER_EXCHANGE_PostBatchDepositResponse * The coin that had a conflict. */ struct TALER_CoinSpendPublicKeyP coin_pub; + + /** + * Hash of the denomination public key of the coin. + */ + struct TALER_DenominationHashP h_denom_pub; } coin_conflicting_age_hash; struct diff --git a/src/lib/exchange_api_post-batch-deposit.c b/src/lib/exchange_api_post-batch-deposit.c @@ -201,6 +201,11 @@ struct TALER_EXCHANGE_PostBatchDepositHandle */ unsigned int num_cdds; + /** + * Whether to verify the merchant signature on the contract terms. + */ + bool verify_merchant_sig; + }; @@ -482,8 +487,10 @@ handle_deposit_finished (void *cls, struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_fixed_auto ( "coin_pub", - &dr->details.conflict.details - .insufficient_funds.coin_pub), + &dr->details.conflict.details.insufficient_funds.coin_pub), + GNUNET_JSON_spec_fixed_auto ( + "h_denom_pub", + &dr->details.conflict.details.insufficient_funds.h_denom_pub), GNUNET_JSON_spec_end () }; @@ -506,6 +513,10 @@ handle_deposit_finished (void *cls, "coin_pub", &dr->details.conflict.details .coin_conflicting_age_hash.coin_pub), + GNUNET_JSON_spec_fixed_auto ( + "h_denom_pub", + &dr->details.conflict.details + .coin_conflicting_age_hash.h_denom_pub), GNUNET_JSON_spec_end () }; @@ -693,10 +704,6 @@ TALER_EXCHANGE_post_batch_deposit_create ( GNUNET_free (dh); return NULL; } - if (! GNUNET_is_zero (&dcd->merchant_sig)) - { - /* FIXME #9185: check merchant_sig!? */ - } if (GNUNET_is_zero (&cdd->h_age_commitment)) h_age_commitmentp = NULL; else @@ -770,12 +777,28 @@ TALER_EXCHANGE_post_batch_deposit_create ( } -void -TALER_EXCHANGE_post_batch_deposit_force_dc ( - struct TALER_EXCHANGE_PostBatchDepositHandle *pbdh) +enum GNUNET_GenericReturnValue +TALER_EXCHANGE_post_batch_deposit_set_options_ ( + struct TALER_EXCHANGE_PostBatchDepositHandle *pbdh, + unsigned int num_options, + const struct TALER_EXCHANGE_PostBatchDepositOptionValue options[]) { - // FIXME: turn this into an option! - pbdh->auditor_chance = 1; + for (unsigned int i = 0; i < num_options; i++) + { + const struct TALER_EXCHANGE_PostBatchDepositOptionValue *opt = &options[i]; + switch (opt->option) + { + case TALER_EXCHANGE_POST_BATCH_DEPOSIT_OPTION_END: + return GNUNET_OK; + case TALER_EXCHANGE_POST_BATCH_DEPOSIT_OPTION_FORCE_DC: + pbdh->auditor_chance = 1; + break; + case TALER_EXCHANGE_POST_BATCH_DEPOSIT_OPTION_VERIFY_MERCHANT_SIG: + pbdh->verify_merchant_sig = true; + break; + } + } + return GNUNET_OK; } @@ -787,6 +810,16 @@ TALER_EXCHANGE_post_batch_deposit_start ( { CURL *eh; + if (pbdh->verify_merchant_sig && + (GNUNET_OK != + TALER_merchant_contract_verify ( + &pbdh->dcd.h_contract_terms, + &pbdh->dcd.merchant_pub, + &pbdh->dcd.merchant_sig)) ) + { + GNUNET_break_op (0); + return TALER_EC_GENERIC_PARAMETER_MALFORMED; + } pbdh->cb = cb; pbdh->cb_cls = cb_cls; pbdh->url = TALER_url_join (pbdh->base_url,