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:
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,