aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Blättler <blatc2@bfh.ch>2024-04-25 15:46:19 +0200
committerChristian Blättler <blatc2@bfh.ch>2024-04-25 15:46:19 +0200
commitcb751157cccfbead1337416bc9e6357699ff7691 (patch)
tree42a2cb991bb2ade709a275ccf46c4be448e76806
parent10c796e8c7e6a558a4f448b073c8a017e243a10d (diff)
parse and hash wallet data in pay handler
-rw-r--r--src/backend/taler-merchant-httpd_contract.h2
-rw-r--r--src/backend/taler-merchant-httpd_post-orders-ID-pay.c132
-rw-r--r--src/backend/taler-merchant-httpd_private-post-orders.c4
-rw-r--r--src/backenddb/pg_insert_token_family_key.c4
-rw-r--r--src/backenddb/pg_insert_token_family_key.h4
-rw-r--r--src/backenddb/test_merchantdb.c4
-rw-r--r--src/include/taler_merchantdb_plugin.h12
7 files changed, 119 insertions, 43 deletions
diff --git a/src/backend/taler-merchant-httpd_contract.h b/src/backend/taler-merchant-httpd_contract.h
index 476fdcc0..0e52b6e2 100644
--- a/src/backend/taler-merchant-httpd_contract.h
+++ b/src/backend/taler-merchant-httpd_contract.h
@@ -259,7 +259,7 @@ struct TALER_MerchantContractTokenFamilyKey
/**
* Public key.
*/
- struct TALER_TokenIssuePublicKey pub;
+ struct TALER_TokenIssuePublicKeyP pub;
/**
* Tokens signed by this key will be valid after this time.
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;
diff --git a/src/backend/taler-merchant-httpd_private-post-orders.c b/src/backend/taler-merchant-httpd_private-post-orders.c
index 704c3823..5a850b2f 100644
--- a/src/backend/taler-merchant-httpd_private-post-orders.c
+++ b/src/backend/taler-merchant-httpd_private-post-orders.c
@@ -1539,10 +1539,10 @@ set_token_family (struct OrderContext *oc,
GNUNET_CRYPTO_BSA_RSA,
4096);
- struct TALER_TokenIssuePublicKey token_pub = {
+ struct TALER_TokenIssuePublicKeyP token_pub = {
.public_key = pub,
};
- struct TALER_TokenIssuePrivateKey token_priv = {
+ struct TALER_TokenIssuePrivateKeyP token_priv = {
.private_key = priv,
};
diff --git a/src/backenddb/pg_insert_token_family_key.c b/src/backenddb/pg_insert_token_family_key.c
index 69d49bbb..95b5a852 100644
--- a/src/backenddb/pg_insert_token_family_key.c
+++ b/src/backenddb/pg_insert_token_family_key.c
@@ -30,8 +30,8 @@
enum GNUNET_DB_QueryStatus
TMH_PG_insert_token_family_key (void *cls,
const char *token_family_slug,
- const struct TALER_TokenIssuePublicKey *pub,
- const struct TALER_TokenIssuePrivateKey *priv,
+ const struct TALER_TokenIssuePublicKeyP *pub,
+ const struct TALER_TokenIssuePrivateKeyP *priv,
const struct GNUNET_TIME_Timestamp valid_after,
const struct GNUNET_TIME_Timestamp valid_before)
{
diff --git a/src/backenddb/pg_insert_token_family_key.h b/src/backenddb/pg_insert_token_family_key.h
index 45ba8589..00806777 100644
--- a/src/backenddb/pg_insert_token_family_key.h
+++ b/src/backenddb/pg_insert_token_family_key.h
@@ -38,8 +38,8 @@
enum GNUNET_DB_QueryStatus
TMH_PG_insert_token_family_key (void *cls,
const char *token_family_slug,
- const struct TALER_TokenIssuePublicKey *pub,
- const struct TALER_TokenIssuePrivateKey *priv,
+ const struct TALER_TokenIssuePublicKeyP *pub,
+ const struct TALER_TokenIssuePrivateKeyP *priv,
const struct GNUNET_TIME_Timestamp valid_after,
const struct GNUNET_TIME_Timestamp valid_before);
diff --git a/src/backenddb/test_merchantdb.c b/src/backenddb/test_merchantdb.c
index fbb662f8..f113b01f 100644
--- a/src/backenddb/test_merchantdb.c
+++ b/src/backenddb/test_merchantdb.c
@@ -1860,6 +1860,7 @@ test_lookup_payment_status (const char *instance_id,
bool wired;
bool matches;
uint64_t os;
+ int16_t choice_index;
TEST_COND_RET_ON_FAIL (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT ==
plugin->lookup_contract_terms3 (plugin->cls,
@@ -1871,7 +1872,8 @@ test_lookup_payment_status (const char *instance_id,
&paid,
&wired,
&matches,
- NULL),
+ NULL,
+ &choice_index),
"Lookup payment status failed\n");
if ( (NULL != session_id) && (! matches) )
{
diff --git a/src/include/taler_merchantdb_plugin.h b/src/include/taler_merchantdb_plugin.h
index bd935045..f39a5a54 100644
--- a/src/include/taler_merchantdb_plugin.h
+++ b/src/include/taler_merchantdb_plugin.h
@@ -1096,12 +1096,12 @@ struct TALER_MERCHANTDB_TokenFamilyKeyDetails
/**
* Token family public key.
*/
- struct TALER_TokenIssuePublicKey pub;
+ struct TALER_TokenIssuePublicKeyP pub;
/**
* Token family private key.
*/
- struct TALER_TokenIssuePrivateKey priv;
+ struct TALER_TokenIssuePrivateKeyP priv;
/**
* Details about the token family this key belongs to.
@@ -1117,7 +1117,7 @@ struct TALER_MERCHANTDB_SpentTokenDetails
/**
* Public key of the spent token.
*/
- struct TALER_TokenUsePublicKey pub;
+ struct TALER_TokenUsePublicKeyP pub;
/**
* Signature that this token was spent on the specified order.
@@ -1127,7 +1127,7 @@ struct TALER_MERCHANTDB_SpentTokenDetails
/**
* Blind signature for the spent token to prove validity of it.
*/
- struct TALER_TokenIssueBlindSignature blind_sig;
+ struct TALER_TokenIssueBlindSignatureP blind_sig;
};
@@ -3294,8 +3294,8 @@ struct TALER_MERCHANTDB_Plugin
(*insert_token_family_key)(
void *cls,
const char *token_family_slug,
- const struct TALER_TokenIssuePublicKey *pub,
- const struct TALER_TokenIssuePrivateKey *priv,
+ const struct TALER_TokenIssuePublicKeyP *pub,
+ const struct TALER_TokenIssuePrivateKeyP *priv,
struct GNUNET_TIME_Timestamp valid_after,
struct GNUNET_TIME_Timestamp valid_before);