diff options
author | Lucien Heuzeveldt <lucienclaude.heuzeveldt@students.bfh.ch> | 2022-01-10 22:09:35 +0100 |
---|---|---|
committer | Gian Demarmels <gian@demarmels.org> | 2022-02-04 15:36:10 +0100 |
commit | daa7fdcfb1053bdd943ad7cd1bd8eb623d1c9157 (patch) | |
tree | 1cfce5401b493dfd017608cbbb05ee91ab9b247b | |
parent | 9c2aefaa515ce8d493bfe4de4eab9edc09d5447e (diff) | |
download | exchange-daa7fdcfb1053bdd943ad7cd1bd8eb623d1c9157.tar.xz |
implement spend
-rw-r--r-- | src/exchange/taler-exchange-httpd_deposit.c | 8 | ||||
-rw-r--r-- | src/json/json_helper.c | 22 | ||||
-rw-r--r-- | src/json/json_pack.c | 21 | ||||
-rw-r--r-- | src/pq/pq_result_helper.c | 11 | ||||
-rw-r--r-- | src/testing/test_exchange_api.c | 204 | ||||
-rw-r--r-- | src/util/denom.c | 18 |
6 files changed, 205 insertions, 79 deletions
diff --git a/src/exchange/taler-exchange-httpd_deposit.c b/src/exchange/taler-exchange-httpd_deposit.c index 84741b5c3..11f94f2c5 100644 --- a/src/exchange/taler-exchange-httpd_deposit.c +++ b/src/exchange/taler-exchange-httpd_deposit.c @@ -356,6 +356,14 @@ TEH_handler_deposit (struct MHD_Connection *connection, TALER_EC_EXCHANGE_GENERIC_DENOMINATION_REVOKED, "DEPOSIT"); } + if (dk->denom_pub.cipher != deposit.coin.denom_sig.cipher) + { + /* denomination cipher and denomination signature cipher not the same */ + GNUNET_JSON_parse_free (spec); + return TEH_RESPONSE_reply_unknown_denom_pub_hash ( + connection, + &deposit.coin.denom_pub_hash); + } deposit.deposit_fee = dk->meta.fee_deposit; /* check coin signature */ diff --git a/src/json/json_helper.c b/src/json/json_helper.c index 6ee9c15a7..41d5c82e0 100644 --- a/src/json/json_helper.c +++ b/src/json/json_helper.c @@ -388,7 +388,27 @@ parse_denom_sig (void *cls, } return GNUNET_OK; } - // TODO: case TALER_DENOMINATION_CS: + case TALER_DENOMINATION_CS: + { + struct GNUNET_JSON_Specification ispec[] = { + GNUNET_JSON_spec_fixed_auto ("cs_signature_r", + &denom_sig->details.cs_signature.r_point), + GNUNET_JSON_spec_fixed_auto ("cs_signature_s", + &denom_sig->details.cs_signature.s_scalar), + GNUNET_JSON_spec_end () + }; + + if (GNUNET_OK != + GNUNET_JSON_parse (root, + ispec, + &emsg, + &eline)) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + return GNUNET_OK; + } default: GNUNET_break_op (0); return GNUNET_SYSERR; diff --git a/src/json/json_pack.c b/src/json/json_pack.c index cc147c4c0..8b056f34e 100644 --- a/src/json/json_pack.c +++ b/src/json/json_pack.c @@ -98,14 +98,21 @@ TALER_JSON_pack_denom_sig ( switch (sig->cipher) { case TALER_DENOMINATION_RSA: - ps.object - = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_uint64 ("cipher", - TALER_DENOMINATION_RSA), - GNUNET_JSON_pack_rsa_signature ("rsa_signature", - sig->details.rsa_signature)); + ps.object = GNUNET_JSON_PACK ( + GNUNET_JSON_pack_uint64 ("cipher", + TALER_DENOMINATION_RSA), + GNUNET_JSON_pack_rsa_signature ("rsa_signature", + sig->details.rsa_signature)); + break; + case TALER_DENOMINATION_CS: + ps.object = GNUNET_JSON_PACK ( + GNUNET_JSON_pack_uint64 ("cipher", + TALER_DENOMINATION_CS), + GNUNET_JSON_pack_data_auto ("cs_signature_r", + &sig->details.cs_signature.r_point), + GNUNET_JSON_pack_data_auto ("cs_signature_s", + &sig->details.cs_signature.s_scalar)); break; - // TODO: case TALER_DENOMINATION_CS: default: GNUNET_assert (0); } diff --git a/src/pq/pq_result_helper.c b/src/pq/pq_result_helper.c index 2009f0e33..02733f298 100644 --- a/src/pq/pq_result_helper.c +++ b/src/pq/pq_result_helper.c @@ -552,7 +552,16 @@ extract_denom_sig (void *cls, return GNUNET_SYSERR; } return GNUNET_OK; - // FIXME: add CS case! + case TALER_DENOMINATION_CS: + if (sizeof (sig->details.cs_signature) != len) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + memcpy (&sig->details.cs_signature, + res, + len); + return GNUNET_OK; default: GNUNET_break (0); } diff --git a/src/testing/test_exchange_api.c b/src/testing/test_exchange_api.c index ba293d4b9..ac5dfdc00 100644 --- a/src/testing/test_exchange_api.c +++ b/src/testing/test_exchange_api.c @@ -407,61 +407,6 @@ run (void *cls, }; /** - * Test CS withdrawal plus spending. - */ - struct TALER_TESTING_Command withdraw_cs[] = { - /** - * Move money to the exchange's bank account. - */ - CMD_TRANSFER_TO_EXCHANGE ("create-reserve-cs-1", - "EUR:6.02"), - TALER_TESTING_cmd_check_bank_admin_transfer ("check-create-reserve-cs-1", - "EUR:6.02", - bc.user42_payto, - bc.exchange_payto, - "create-reserve-cs-1"), - /** - * Make a reserve exist, according to the previous - * transfer. - */ - CMD_EXEC_WIREWATCH ("wirewatch-cs-1"), - /** - * Withdraw EUR:5. - */ - TALER_TESTING_cmd_withdraw_cs_amount ("withdraw-cs-coin-1", - "create-reserve-cs-1", - "EUR:5", - MHD_HTTP_OK), - /** - * Withdraw EUR:1 using the SAME private coin key as for the previous coin - * (in violation of the specification, to be detected on spending!). - */ - TALER_TESTING_cmd_withdraw_cs_amount_reuse_key ("withdraw-cs-coin-1x", - "create-reserve-cs-1", - "EUR:1", - "withdraw-cs-coin-1", - MHD_HTTP_OK), - /** - * Check the reserve is depleted. - */ - TALER_TESTING_cmd_status ("status-cs-1", - "create-reserve-cs-1", - "EUR:0", - MHD_HTTP_OK), - /* - * Try to overdraw. - */ - TALER_TESTING_cmd_withdraw_cs_amount ("withdraw-cs-coin-2", - "create-reserve-cs-1", - "EUR:5", - MHD_HTTP_CONFLICT), - // TODO: add test for nonce reuse - TALER_TESTING_cmd_end () - }; - - // TODO: CS related tests - - /** * This block checks whether a wire deadline * very far in the future does NOT get aggregated now. */ @@ -946,6 +891,145 @@ run (void *cls, TALER_TESTING_cmd_end () }; + /** + * Test CS withdrawal plus spending. + */ + struct TALER_TESTING_Command withdraw_cs[] = { + /** + * Move money to the exchange's bank account. + */ + CMD_TRANSFER_TO_EXCHANGE ("create-reserve-cs-1", + "EUR:6.02"), + TALER_TESTING_cmd_check_bank_admin_transfer ("check-create-reserve-cs-1", + "EUR:6.02", + bc.user42_payto, + bc.exchange_payto, + "create-reserve-cs-1"), + /** + * Make a reserve exist, according to the previous + * transfer. + */ + CMD_EXEC_WIREWATCH ("wirewatch-cs-1"), + /** + * Withdraw EUR:5. + */ + TALER_TESTING_cmd_withdraw_cs_amount ("withdraw-cs-coin-1", + "create-reserve-cs-1", + "EUR:5", + MHD_HTTP_OK), + /** + * Withdraw EUR:1 using the SAME private coin key as for the previous coin + * (in violation of the specification, to be detected on spending!). + */ + TALER_TESTING_cmd_withdraw_cs_amount_reuse_key ("withdraw-cs-coin-1x", + "create-reserve-cs-1", + "EUR:1", + "withdraw-cs-coin-1", + MHD_HTTP_OK), + /** + * Check the reserve is depleted. + */ + TALER_TESTING_cmd_status ("status-cs-1", + "create-reserve-cs-1", + "EUR:0", + MHD_HTTP_OK), + /* + * Try to overdraw. + */ + TALER_TESTING_cmd_withdraw_cs_amount ("withdraw-cs-coin-2", + "create-reserve-cs-1", + "EUR:5", + MHD_HTTP_CONFLICT), + // TODO: add test for nonce reuse + TALER_TESTING_cmd_end () + }; + + struct TALER_TESTING_Command spend_cs[] = { + /** + * Spend the coin. + */ + TALER_TESTING_cmd_deposit ("deposit-cs-simple", + "withdraw-cs-coin-1", + 0, + bc.user42_payto, + "{\"items\":[{\"name\":\"ice cream\",\"value\":1}]}", + GNUNET_TIME_UNIT_ZERO, + "EUR:5", + MHD_HTTP_OK), + TALER_TESTING_cmd_deposit_replay ("deposit-cs-simple-replay", + "deposit-cs-simple", + MHD_HTTP_OK), + TALER_TESTING_cmd_deposit ("deposit-cs-reused-coin-key-failure", + "withdraw-cs-coin-1x", + 0, + bc.user42_payto, + "{\"items\":[{\"name\":\"ice cream\",\"value\":1}]}", + GNUNET_TIME_UNIT_ZERO, + "EUR:1", + MHD_HTTP_CONFLICT), + /** + * Try to double spend using different wire details. + */ + TALER_TESTING_cmd_deposit ("deposit-cs-double-1", + "withdraw-cs-coin-1", + 0, + bc.user43_payto, + "{\"items\":[{\"name\":\"ice cream\",\"value\":1}]}", + GNUNET_TIME_UNIT_ZERO, + "EUR:5", + MHD_HTTP_CONFLICT), + /* Try to double spend using a different transaction id. + * The test needs the contract terms to differ. This + * is currently the case because of the "timestamp" field, + * which is set automatically by #TALER_TESTING_cmd_deposit(). + * This could theoretically fail if at some point a deposit + * command executes in less than 1 ms. */// + TALER_TESTING_cmd_deposit ("deposit-cs-double-1", + "withdraw-cs-coin-1", + 0, + bc.user43_payto, + "{\"items\":[{\"name\":\"ice cream\",\"value\":1}]}", + GNUNET_TIME_UNIT_ZERO, + "EUR:5", + MHD_HTTP_CONFLICT), + /** + * Try to double spend with different proposal. + */ + TALER_TESTING_cmd_deposit ("deposit-cs-double-2", + "withdraw-cs-coin-1", + 0, + bc.user43_payto, + "{\"items\":[{\"name\":\"ice cream\",\"value\":2}]}", + GNUNET_TIME_UNIT_ZERO, + "EUR:5", + MHD_HTTP_CONFLICT), + TALER_TESTING_cmd_end () + }; + + // TODO: CS refresh + + struct TALER_TESTING_Command track_cs[] = { + /* Try resolving a deposit's WTID, as we never triggered + * execution of transactions, the answer should be that + * the exchange knows about the deposit, but has no WTID yet. + */// + TALER_TESTING_cmd_track_transaction ("deposit-cs-wtid-found", + "deposit-cs-simple", + 0, + MHD_HTTP_ACCEPTED, + NULL), + /* Try resolving a deposit's WTID for a failed deposit. + * As the deposit failed, the answer should be that the + * exchange does NOT know about the deposit. + */ + TALER_TESTING_cmd_track_transaction ("deposit-cs-wtid-failing", + "deposit-cs-double-2", + 0, + MHD_HTTP_NOT_FOUND, + NULL), + TALER_TESTING_cmd_end () + }; + #define RESERVE_OPEN_CLOSE_CHUNK 4 #define RESERVE_OPEN_CLOSE_ITERATIONS 3 @@ -1007,9 +1091,6 @@ run (void *cls, refresh), TALER_TESTING_cmd_batch ("track", track), - TALER_TESTING_cmd_batch ("withdraw-cs", - withdraw_cs), - // TODO: Clause Schnorr related tests TALER_TESTING_cmd_batch ("unaggregation", unaggregation), TALER_TESTING_cmd_batch ("aggregation", @@ -1018,6 +1099,13 @@ run (void *cls, refund), TALER_TESTING_cmd_batch ("recoup", recoup), + TALER_TESTING_cmd_batch ("withdraw-cs", + withdraw_cs), + TALER_TESTING_cmd_batch ("spend-cs", + spend_cs), + // TODO: Clause Schnorr refresh + TALER_TESTING_cmd_batch ("track-cs", + track_cs), TALER_TESTING_cmd_batch ("reserve-open-close", reserve_open_close), /* End the suite. */ diff --git a/src/util/denom.c b/src/util/denom.c index a4965c050..c7cf62c3e 100644 --- a/src/util/denom.c +++ b/src/util/denom.c @@ -625,10 +625,8 @@ TALER_denom_pub_cmp (const struct TALER_DenominationPublicKey *denom1, return GNUNET_CRYPTO_rsa_public_key_cmp (denom1->details.rsa_public_key, denom2->details.rsa_public_key); case TALER_DENOMINATION_CS: - return 0 == GNUNET_memcmp (&denom1->details.cs_public_key, - &denom2->details.cs_public_key) - ? GNUNET_OK - : GNUNET_SYSERR; + return GNUNET_memcmp (&denom1->details.cs_public_key, + &denom2->details.cs_public_key); default: GNUNET_assert (0); } @@ -650,10 +648,8 @@ TALER_denom_sig_cmp (const struct TALER_DenominationSignature *sig1, return GNUNET_CRYPTO_rsa_signature_cmp (sig1->details.rsa_signature, sig2->details.rsa_signature); case TALER_DENOMINATION_CS: - return 0 == GNUNET_memcmp (&sig1->details.cs_signature, - &sig2->details.cs_signature) - ? GNUNET_OK - : GNUNET_SYSERR; + return GNUNET_memcmp (&sig1->details.cs_signature, + &sig2->details.cs_signature); default: GNUNET_assert (0); } @@ -676,10 +672,8 @@ TALER_blinded_denom_sig_cmp ( return GNUNET_CRYPTO_rsa_signature_cmp (sig1->details.blinded_rsa_signature, sig2->details.blinded_rsa_signature); case TALER_DENOMINATION_CS: - return 0 == GNUNET_memcmp (&sig1->details.blinded_cs_answer, - &sig2->details.blinded_cs_answer) - ? GNUNET_OK - : GNUNET_SYSERR; + return GNUNET_memcmp (&sig1->details.blinded_cs_answer, + &sig2->details.blinded_cs_answer); default: GNUNET_assert (0); } |