aboutsummaryrefslogtreecommitdiff
path: root/src/backend/taler-merchant-httpd_post-orders-ID-pay.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/taler-merchant-httpd_post-orders-ID-pay.c')
-rw-r--r--src/backend/taler-merchant-httpd_post-orders-ID-pay.c132
1 files changed, 103 insertions, 29 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 f6375b70..959c9e13 100644
--- a/src/backend/taler-merchant-httpd_post-orders-ID-pay.c
+++ b/src/backend/taler-merchant-httpd_post-orders-ID-pay.c
@@ -84,6 +84,11 @@ enum PayPhase
PP_INIT = 0,
/**
+ * Parse wallet data object from the pay request.
+ */
+ PP_PARSE_WALLET_DATA,
+
+ /**
* Check database state for the given order.
*/
PP_CHECK_CONTRACT,
@@ -231,24 +236,25 @@ struct TokenUseConfirmation
char *slug;
/**
- * Signature on the deposit request made using the token private key.
+ * Signature on the deposit request made using the token use private key.
*/
struct TALER_TokenUseSignatureP sig;
/**
- * Public key of the token.
+ * Token use public key. This key was blindly signed by the merchant during
+ * the token issuance process.
*/
- struct TALER_TokenUsePublicKey pub;
+ struct TALER_TokenUsePublicKeyP pub;
/**
- * Unblinded signature done by the merchant.
+ * Unblinded signature on the token use public key done by the merchant.
*/
- struct TALER_TokenIssueSignature unblinded_sig;
+ struct TALER_TokenIssueSignatureP unblinded_sig;
/**
* Hash of the token issue public key associated with this token.
*/
- struct TALER_TokenIssuePublicKeyHash h_issue;
+ struct TALER_TokenIssuePublicKeyHashP h_issue;
};
@@ -377,6 +383,22 @@ struct PayContext
json_t *contract_terms;
/**
+ * Wallet data json object from the request. Containing additional
+ * wallet data such as the selected choice_index.
+ */
+ const json_t *wallet_data;
+
+ /**
+ * Hash of the canonicalized wallet data json object.
+ */
+ struct GNUNET_HashCode h_wallet_data;
+
+ /**
+ * Output commitment hash.
+ */
+ struct GNUNET_HashCode h_outputs;
+
+ /**
* Placeholder for #TALER_MHD_parse_post_json() to keep its internal state.
*/
void *json_parse_context;
@@ -2222,8 +2244,9 @@ phase_validate_tokens (struct PayContext *pc)
continue;
}
- /* TODO: Design data structures for signature and implement it. */
- if (GNUNET_OK != TALER_merchant_token_issue_verify ())
+ if (GNUNET_OK != TALER_merchant_token_issue_verify (&pc->tokens[j].pub,
+ &key->pub,
+ &pc->tokens[j].unblinded_sig))
{
GNUNET_break (0);
pay_end (pc,
@@ -2234,6 +2257,20 @@ phase_validate_tokens (struct PayContext *pc)
return;
}
+ if (GNUNET_OK != TALER_wallet_token_use_verify (&pc->h_contract_terms,
+ &pc->h_wallet_data,
+ &pc->tokens[j].pub,
+ &pc->tokens[j].sig))
+ {
+ GNUNET_break (0);
+ pay_end (pc,
+ TALER_MHD_reply_with_error (pc->connection,
+ MHD_HTTP_BAD_REQUEST,
+ TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_TOKEN_USE_SIG_INVALID,
+ NULL));
+ return;
+ }
+
num_validated++;
}
@@ -2635,6 +2672,56 @@ phase_check_contract (struct PayContext *pc)
/**
+ * Try to parse the wallet_data object of the pay request into
+ * the given context. Schedules an error response in the connection
+ * on failure.
+ *
+ * @param[in,out] pc context we use to handle the payment
+ */
+static void
+phase_parse_wallet_data (struct PayContext *pc)
+{
+ pc->choice_index = -1;
+
+ if (NULL == pc->wallet_data)
+ {
+ pc->phase = PP_CHECK_CONTRACT;
+ return;
+ }
+
+ struct GNUNET_JSON_Specification spec[] = {
+ GNUNET_JSON_spec_mark_optional(
+ GNUNET_JSON_spec_int64 ("choice_index",
+ &pc->choice_index),
+ NULL),
+ GNUNET_JSON_spec_mark_optional(
+ GNUNET_JSON_spec_fixed_auto ("h_outputs",
+ &pc->choice_index),
+ NULL),
+ GNUNET_JSON_spec_end ()
+ };
+
+ enum GNUNET_GenericReturnValue res;
+
+ res = TALER_MHD_parse_json_data (pc->connection,
+ pc->wallet_data,
+ spec);
+ if (GNUNET_YES != res)
+ {
+ GNUNET_break_op (0);
+ pay_end (pc,
+ (GNUNET_NO == res)
+ ? MHD_YES
+ : MHD_NO);
+ return;
+ }
+
+ TALER_json_hash (pc->wallet_data,
+ &pc->h_wallet_data);
+}
+
+
+/**
* Try to parse the pay request into the given pay context.
* Schedules an error response in the connection on failure.
*
@@ -2646,7 +2733,6 @@ phase_parse_pay (struct PayContext *pc)
const char *session_id = NULL;
const json_t *coins;
const json_t *tokens;
- bool choice_index_missing = false;
struct GNUNET_JSON_Specification spec[] = {
GNUNET_JSON_spec_array_const ("coins",
&coins),
@@ -2655,9 +2741,9 @@ phase_parse_pay (struct PayContext *pc)
&session_id),
NULL),
GNUNET_JSON_spec_mark_optional (
- GNUNET_JSON_spec_int64 ("choice_index",
- &pc->choice_index),
- &choice_index_missing),
+ GNUNET_JSON_spec_object_const ("wallet_data",
+ &pc->wallet_data),
+ NULL),
GNUNET_JSON_spec_mark_optional (
GNUNET_JSON_spec_array_const ("tokens",
&tokens),
@@ -2693,11 +2779,6 @@ phase_parse_pay (struct PayContext *pc)
/* use empty string as default if client didn't specify it */
pc->session_id = GNUNET_strdup ("");
}
- /* set choice_index to -1 to indicate it was not provided */
- if (choice_index_missing)
- {
- pc->choice_index = -1;
- }
pc->coins_cnt = json_array_size (coins);
if (pc->coins_cnt > MAX_COIN_ALLOWED_COINS)
{
@@ -2879,17 +2960,7 @@ phase_parse_pay (struct PayContext *pc)
: MHD_NO);
return;
}
- /* TODO: Design data structures for signature and implement it. */
- if (GNUNET_OK != TALER_wallet_token_use_verify ())
- {
- GNUNET_break_op (0);
- pay_end (pc,
- TALER_MHD_reply_with_error (pc->connection,
- MHD_HTTP_BAD_REQUEST,
- TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_TOKEN_USE_SIG_INVALID,
- "invalid token signature"));
- return;
- }
+
for (unsigned int j = 0; j<tokens_index; j++)
{
if (0 ==
@@ -2907,7 +2978,7 @@ phase_parse_pay (struct PayContext *pc)
}
}
}
- pc->phase = PP_CHECK_CONTRACT;
+ pc->phase = PP_PARSE_WALLET_DATA;
}
@@ -2993,6 +3064,9 @@ TMH_post_orders_ID_pay (const struct TMH_RequestHandler *rh,
case PP_INIT:
phase_parse_pay (pc);
break;
+ case PP_PARSE_WALLET_DATA:
+ phase_parse_wallet_data (pc);
+ break;
case PP_CHECK_CONTRACT:
phase_check_contract (pc);
break;