diff options
author | Christian Blättler <blatc2@bfh.ch> | 2024-04-25 15:46:19 +0200 |
---|---|---|
committer | Christian Blättler <blatc2@bfh.ch> | 2024-04-25 15:46:19 +0200 |
commit | cb751157cccfbead1337416bc9e6357699ff7691 (patch) | |
tree | 42a2cb991bb2ade709a275ccf46c4be448e76806 | |
parent | 10c796e8c7e6a558a4f448b073c8a017e243a10d (diff) |
parse and hash wallet data in pay handler
-rw-r--r-- | src/backend/taler-merchant-httpd_contract.h | 2 | ||||
-rw-r--r-- | src/backend/taler-merchant-httpd_post-orders-ID-pay.c | 132 | ||||
-rw-r--r-- | src/backend/taler-merchant-httpd_private-post-orders.c | 4 | ||||
-rw-r--r-- | src/backenddb/pg_insert_token_family_key.c | 4 | ||||
-rw-r--r-- | src/backenddb/pg_insert_token_family_key.h | 4 | ||||
-rw-r--r-- | src/backenddb/test_merchantdb.c | 4 | ||||
-rw-r--r-- | src/include/taler_merchantdb_plugin.h | 12 |
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); |