aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Blättler <blatc2@bfh.ch>2024-05-06 21:08:58 +0200
committerChristian Blättler <blatc2@bfh.ch>2024-05-06 21:08:58 +0200
commitd1461b2485cb8a633e93f4ed59c560619f08af72 (patch)
tree4f02bc539ebd9fbe5aeb2b0ae75a2250b437a549
parent4a3145fca389fca1bbfc7ba61b7cafd1156ef656 (diff)
work on tokens
-rw-r--r--src/backend/taler-merchant-httpd_post-orders-ID-pay.c33
-rw-r--r--src/include/taler_merchant_service.h10
-rw-r--r--src/lib/merchant_api_post_order_pay.c89
-rw-r--r--src/testing/testing_api_cmd_pay_order.c15
4 files changed, 81 insertions, 66 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
index 0dad53db..c56fa63b 100644
--- a/src/backend/taler-merchant-httpd_post-orders-ID-pay.c
+++ b/src/backend/taler-merchant-httpd_post-orders-ID-pay.c
@@ -451,7 +451,7 @@ struct PayContext
struct GNUNET_HashCode h_wallet_data;
/**
- * Output commitment hash.
+ * Output commitment hash calculated from the 'tokens_evs' field of the request.
*/
struct GNUNET_HashCode h_outputs;
@@ -2644,6 +2644,7 @@ phase_contract_paid (struct PayContext *pc)
TALER_merchant_pay_sign (&pc->h_contract_terms,
&pc->hc->instance->merchant_priv,
&sig);
+ /* TODO: Add token_sigs to response body. */
pay_end (pc,
TALER_MHD_REPLY_JSON_PACK (
pc->connection,
@@ -2938,6 +2939,7 @@ phase_check_contract (struct PayContext *pc)
static void
phase_parse_wallet_data (struct PayContext *pc)
{
+ struct GNUNET_HashCode h_outputs_req;
pc->choice_index = -1;
if (NULL == pc->wallet_data)
@@ -2951,11 +2953,10 @@ phase_parse_wallet_data (struct PayContext *pc)
GNUNET_JSON_spec_int64 ("choice_index",
&pc->choice_index),
NULL),
- /* TODO: Add h_outputs to wallet_data */
- // GNUNET_JSON_spec_mark_optional(
- // GNUNET_JSON_spec_fixed_auto ("h_outputs",
- // &pc->h_outputs),
- // NULL),
+ GNUNET_JSON_spec_mark_optional(
+ GNUNET_JSON_spec_fixed_auto ("h_outputs",
+ &h_outputs_req),
+ NULL),
GNUNET_JSON_spec_end ()
};
@@ -2974,6 +2975,17 @@ phase_parse_wallet_data (struct PayContext *pc)
return;
}
+ if (0 != GNUNET_CRYPTO_hash_cmp(&h_outputs_req, &pc->h_outputs))
+ {
+ GNUNET_break_op (0);
+ pay_end (pc,
+ TALER_MHD_reply_with_error (pc->connection,
+ MHD_HTTP_BAD_REQUEST,
+ TALER_EC_GENERIC_PARAMETER_MALFORMED,
+ "'wallet_data.h_outputs' does not match hash of tokens_evs"));
+ return;
+ }
+
TALER_json_hash (pc->wallet_data,
&pc->h_wallet_data);
@@ -3253,9 +3265,16 @@ phase_parse_pay (struct PayContext *pc)
pc->connection,
MHD_HTTP_BAD_REQUEST,
TALER_EC_GENERIC_PARAMETER_MALFORMED,
- "'token_evs' array too long"));
+ "'tokens_evs' array too long"));
return;
}
+ if (0 < pc->token_envelopes_cnt)
+ {
+ /* Calculate output commitment to be verified later. */
+ TALER_json_hash (tokens_evs,
+ &pc->h_outputs);
+
+ }
pc->token_envelopes = GNUNET_new_array (pc->token_envelopes_cnt,
struct TokenEnvelope);
diff --git a/src/include/taler_merchant_service.h b/src/include/taler_merchant_service.h
index 1907f88f..24f5e61c 100644
--- a/src/include/taler_merchant_service.h
+++ b/src/include/taler_merchant_service.h
@@ -3344,8 +3344,7 @@ struct TALER_MERCHANT_OutputToken
* @param coins array of coins to pay with
* @param num_tokens length of the @a tokens array
* @param tokens array of tokens used
- * @param num_output_tokens length of the @a output_tokens array
- * @param output_tokens array of output token to be issued by the merchant
+ * @param j_output_tokens json array of token envelopes, NULL for none
* @param pay_cb the callback to call when a reply for this request is available
* @param pay_cb_cls closure for @a pay_cb
* @return a handle for this request
@@ -3361,8 +3360,7 @@ TALER_MERCHANT_order_pay_frontend (
const struct TALER_MERCHANT_PaidCoin coins[static num_coins],
unsigned int num_tokens,
const struct TALER_MERCHANT_UsedToken tokens[static num_tokens],
- unsigned int num_output_tokens,
- const struct TALER_MERCHANT_OutputToken output_tokens[static num_output_tokens],
+ json_t *j_output_tokens,
TALER_MERCHANT_OrderPayCallback pay_cb,
void *pay_cb_cls);
@@ -3449,7 +3447,7 @@ struct TALER_MERCHANT_UseToken
* @param merchant_url base URL of the merchant
* @param session_id session to pay for, or NULL for none
* @param h_contract hash of the contact of the merchant with the customer
- * @param wallet_data inputs from the wallet for the contract, NULL for none
+ * @param choice_index index of the selected contract coice, -1 for none
* @param amount total value of the contract to be paid to the merchant
* @param max_fee maximum fee covered by the merchant (according to the contract)
* @param merchant_pub the public key of the merchant (used to identify the merchant for refund requests)
@@ -3475,7 +3473,7 @@ TALER_MERCHANT_order_pay (
const char *merchant_url,
const char *session_id,
const struct TALER_PrivateContractHashP *h_contract,
- const json_t *wallet_data,
+ int choice_index,
const struct TALER_Amount *amount,
const struct TALER_Amount *max_fee,
const struct TALER_MerchantPublicKeyP *merchant_pub,
diff --git a/src/lib/merchant_api_post_order_pay.c b/src/lib/merchant_api_post_order_pay.c
index 39e4e35b..ca4e8a18 100644
--- a/src/lib/merchant_api_post_order_pay.c
+++ b/src/lib/merchant_api_post_order_pay.c
@@ -384,8 +384,7 @@ TALER_MERCHANT_order_pay_frontend (
const struct TALER_MERCHANT_PaidCoin coins[static num_coins],
unsigned int num_tokens,
const struct TALER_MERCHANT_UsedToken tokens[static num_tokens],
- unsigned int num_output_tokens,
- const struct TALER_MERCHANT_OutputToken output_tokens[static num_output_tokens],
+ json_t *j_output_tokens,
TALER_MERCHANT_OrderPayCallback pay_cb,
void *pay_cb_cls)
{
@@ -393,7 +392,6 @@ TALER_MERCHANT_order_pay_frontend (
json_t *pay_obj;
json_t *j_coins;
json_t *j_tokens = NULL;
- json_t *j_output_tokens = NULL;
CURL *eh;
struct TALER_Amount total_fee;
struct TALER_Amount total_amount;
@@ -502,31 +500,6 @@ TALER_MERCHANT_order_pay_frontend (
}
}
- if (0 < num_output_tokens)
- {
- j_output_tokens = json_array ();
- GNUNET_assert (NULL != j_output_tokens);
- for (unsigned int i = 0; i<num_output_tokens; i++)
- {
- json_t *j_token_ev;
- const struct TALER_MERCHANT_OutputToken *ev = &output_tokens[i];
-
- j_token_ev = GNUNET_JSON_PACK (
- TALER_JSON_pack_token_envelope ("token_ev",
- &ev->envelope),
- GNUNET_JSON_pack_data_auto ("h_issue",
- &ev->h_issue.hash));
- if (0 !=
- json_array_append_new (j_output_tokens,
- j_token_ev))
- {
- GNUNET_break (0);
- json_decref (j_output_tokens);
- return NULL;
- }
- }
- }
-
pay_obj = GNUNET_JSON_PACK (
GNUNET_JSON_pack_array_steal ("coins",
j_coins),
@@ -534,8 +507,8 @@ TALER_MERCHANT_order_pay_frontend (
GNUNET_JSON_pack_array_steal ("tokens",
j_tokens)),
GNUNET_JSON_pack_allow_null (
- GNUNET_JSON_pack_array_steal ("tokens_evs",
- j_output_tokens)),
+ GNUNET_JSON_pack_array_incref ("tokens_evs",
+ j_output_tokens)),
GNUNET_JSON_pack_allow_null (
GNUNET_JSON_pack_object_incref ("wallet_data",
(json_t *) wallet_data)),
@@ -576,7 +549,7 @@ TALER_MERCHANT_order_pay_frontend (
GNUNET_memcpy (oph->coins,
coins,
num_coins * sizeof (struct TALER_MERCHANT_PaidCoin));
- /* TODO: Copy token_evs to pay handle so they
+ /* TODO: Copy tokens_evs to pay handle so they
can be unblinded in the callback. */
eh = TALER_MERCHANT_curl_easy_get_ (oph->url);
@@ -608,7 +581,7 @@ TALER_MERCHANT_order_pay (
const char *merchant_url,
const char *session_id,
const struct TALER_PrivateContractHashP *h_contract_terms,
- const json_t *wallet_data,
+ int choice_index,
const struct TALER_Amount *amount,
const struct TALER_Amount *max_fee,
const struct TALER_MerchantPublicKeyP *merchant_pub,
@@ -627,6 +600,9 @@ TALER_MERCHANT_order_pay (
TALER_MERCHANT_OrderPayCallback pay_cb,
void *pay_cb_cls)
{
+ json_t *j_output_tokens = NULL;
+ const json_t *wallet_data = NULL;
+ struct GNUNET_HashCode h_outputs;
struct GNUNET_HashCode wallet_data_hash;
if (GNUNET_YES !=
@@ -636,17 +612,51 @@ TALER_MERCHANT_order_pay (
GNUNET_break (0);
return NULL;
}
- if (0 < num_tokens && NULL == wallet_data)
+ if ((0 < num_tokens || 0 < num_output_tokens) && 0 > choice_index)
{
- /* Since the wallet has to sign over the wallet_data_hash
- to use tokens, wallet data must not be NULL if input
- tokens are provided */
+ /* Tokens (input or output) require a valid choice_index to be set.
+ Only contracts with coices can use or issue tokens. */
GNUNET_break (0);
return NULL;
}
- if (NULL != wallet_data)
+ if (0 < num_output_tokens)
+ {
+ /* Build token envelopes json array. */
+ j_output_tokens = json_array ();
+ GNUNET_assert (NULL != j_output_tokens);
+ for (unsigned int i = 0; i<num_output_tokens; i++)
+ {
+ json_t *j_token_ev;
+ const struct TALER_MERCHANT_OutputToken *ev = &output_tokens[i];
+
+ j_token_ev = GNUNET_JSON_PACK (
+ TALER_JSON_pack_token_envelope ("token_ev",
+ &ev->envelope),
+ GNUNET_JSON_pack_data_auto ("h_issue",
+ &ev->h_issue.hash));
+ if (0 !=
+ json_array_append_new (j_output_tokens,
+ j_token_ev))
+ {
+ GNUNET_break (0);
+ json_decref (j_output_tokens);
+ return NULL;
+ }
+ }
+
+ TALER_json_hash (j_output_tokens, &h_outputs);
+ }
+ if (0 <= choice_index)
+ {
+ wallet_data = GNUNET_JSON_PACK (
+ GNUNET_JSON_pack_int64 ("choice_index",
+ choice_index),
+ GNUNET_JSON_pack_allow_null (
+ GNUNET_JSON_pack_data_auto ("h_outputs",
+ &h_outputs)));
TALER_json_hash (wallet_data,
- &wallet_data_hash);
+ &wallet_data_hash);
+ }
{
struct TALER_MERCHANT_PaidCoin pc[num_coins];
struct TALER_MERCHANT_UsedToken ut[num_tokens];
@@ -720,8 +730,7 @@ TALER_MERCHANT_order_pay (
pc,
num_tokens,
ut,
- num_output_tokens,
- output_tokens,
+ j_output_tokens,
pay_cb,
pay_cb_cls);
if (NULL == oph)
diff --git a/src/testing/testing_api_cmd_pay_order.c b/src/testing/testing_api_cmd_pay_order.c
index 143540e9..a356d327 100644
--- a/src/testing/testing_api_cmd_pay_order.c
+++ b/src/testing/testing_api_cmd_pay_order.c
@@ -131,11 +131,6 @@ struct PayState
enum TALER_MerchantConfirmationAlgorithm pos_alg;
/**
- * Wallet data json object. Used in the pay request if not NULL.
- */
- const json_t *wallet_data;
-
- /**
* Index of the choice to be used in the payment. -1 for orders without choices.
*/
int choice_index;
@@ -849,7 +844,7 @@ pay_run (void *cls,
GNUNET_assert (GNUNET_CRYPTO_BSA_RSA == details->issue_pub.public_key->cipher);
TALER_token_blind_input_copy (&details->blinding_inputs,
- TALER_token_bling_input_rsa_singleton ());
+ TALER_token_blind_input_rsa_singleton ());
/* TODO: Where to get details->blinding_inputs from? */
TALER_token_use_setup_random (&details->master);
TALER_token_use_setup_priv (&details->master,
@@ -904,7 +899,7 @@ pay_run (void *cls,
ps->merchant_url,
ps->session_id,
h_proposal,
- ps->wallet_data,
+ ps->choice_index,
&ps->total_amount,
&max_fee,
&merchant_pub,
@@ -1066,12 +1061,6 @@ TALER_TESTING_cmd_merchant_pay_order_choices (const char *label,
ps->session_id = session_id;
ps->token_reference = token_reference;
ps->choice_index = choice_index;
- if (0 <= choice_index)
- {
- ps->wallet_data = json_pack ("{s:i}",
- "choice_index",
- choice_index);
- }
{
struct TALER_TESTING_Command cmd = {
.cls = ps,