summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLucien Heuzeveldt <lucienclaude.heuzeveldt@students.bfh.ch>2022-01-10 22:09:35 +0100
committerGian Demarmels <gian@demarmels.org>2022-02-04 15:36:10 +0100
commitdaa7fdcfb1053bdd943ad7cd1bd8eb623d1c9157 (patch)
tree1cfce5401b493dfd017608cbbb05ee91ab9b247b
parent9c2aefaa515ce8d493bfe4de4eab9edc09d5447e (diff)
downloadexchange-daa7fdcfb1053bdd943ad7cd1bd8eb623d1c9157.tar.gz
exchange-daa7fdcfb1053bdd943ad7cd1bd8eb623d1c9157.tar.bz2
exchange-daa7fdcfb1053bdd943ad7cd1bd8eb623d1c9157.zip
implement spend
-rw-r--r--src/exchange/taler-exchange-httpd_deposit.c8
-rw-r--r--src/json/json_helper.c22
-rw-r--r--src/json/json_pack.c21
-rw-r--r--src/pq/pq_result_helper.c11
-rw-r--r--src/testing/test_exchange_api.c204
-rw-r--r--src/util/denom.c18
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);
}