aboutsummaryrefslogtreecommitdiff
path: root/src/testing
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2020-07-10 23:09:46 +0200
committerChristian Grothoff <christian@grothoff.org>2020-07-10 23:09:46 +0200
commit7085cfef70889a11508cdac4cd887b9959f59218 (patch)
tree610af337a248c92981ab6bf62697ee3e7d5a91e8 /src/testing
parentddf95c491af05732220ac35c6fb1bea48e6f4050 (diff)
downloadexchange-7085cfef70889a11508cdac4cd887b9959f59218.tar.xz
test coin_priv re-use with deposit and refresh, update handling of the error code client-side
Diffstat (limited to 'src/testing')
-rw-r--r--src/testing/test_exchange_api.c43
-rw-r--r--src/testing/testing_api_cmd_withdraw.c115
2 files changed, 148 insertions, 10 deletions
diff --git a/src/testing/test_exchange_api.c b/src/testing/test_exchange_api.c
index 410c1a492..75e3d480f 100644
--- a/src/testing/test_exchange_api.c
+++ b/src/testing/test_exchange_api.c
@@ -136,12 +136,12 @@ run (void *cls,
* Do another transfer to the same reserve
*/
TALER_TESTING_cmd_admin_add_incoming_with_ref ("create-reserve-1.2",
- "EUR:1",
+ "EUR:2.01",
&bc.exchange_auth,
bc.user42_payto,
"create-reserve-1"),
TALER_TESTING_cmd_check_bank_admin_transfer ("check-create-reserve-1.2",
- "EUR:1",
+ "EUR:2.01",
bc.user42_payto,
bc.exchange_payto,
"create-reserve-1.2"),
@@ -154,12 +154,28 @@ run (void *cls,
"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_amount_reuse_key ("withdraw-coin-1x",
+ "create-reserve-1",
+ "EUR:1",
+ "withdraw-coin-1",
+ MHD_HTTP_OK),
+ /**
* Check the reserve is depleted.
*/
TALER_TESTING_cmd_status ("status-1",
"create-reserve-1",
"EUR:0",
MHD_HTTP_OK),
+ /*
+ * Try to overdraw.
+ */
+ TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-2",
+ "create-reserve-1",
+ "EUR:5",
+ MHD_HTTP_CONFLICT),
TALER_TESTING_cmd_end ()
};
@@ -178,13 +194,14 @@ run (void *cls,
TALER_TESTING_cmd_deposit_replay ("deposit-simple-replay",
"deposit-simple",
MHD_HTTP_OK),
- /*
- * Try to overdraw.
- */
- TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-2",
- "create-reserve-1",
- "EUR:5",
- MHD_HTTP_CONFLICT),
+ TALER_TESTING_cmd_deposit ("deposit-reused-coin-key-failure",
+ "withdraw-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.
*/
@@ -225,6 +242,14 @@ run (void *cls,
};
struct TALER_TESTING_Command refresh[] = {
+ /**
+ * Try to melt the coin that shared the private key with another
+ * coin (should fail). */
+ TALER_TESTING_cmd_melt ("refresh-melt-reused-coin-key-failure",
+ "withdraw-coin-1x",
+ MHD_HTTP_CONFLICT,
+ NULL),
+
/* Fill reserve with EUR:5, 1ct is for fees. */
CMD_TRANSFER_TO_EXCHANGE ("refresh-create-reserve-1",
"EUR:5.01"),
diff --git a/src/testing/testing_api_cmd_withdraw.c b/src/testing/testing_api_cmd_withdraw.c
index 5db97cbff..5b2ad26e4 100644
--- a/src/testing/testing_api_cmd_withdraw.c
+++ b/src/testing/testing_api_cmd_withdraw.c
@@ -60,6 +60,12 @@ struct WithdrawState
const char *reserve_reference;
/**
+ * Reference to a withdraw or reveal operation from which we should
+ * re-use the private coin key, or NULL for regular withdrawal.
+ */
+ const char *reuse_coin_key_ref;
+
+ /**
* String describing the denomination value we should withdraw.
* A corresponding denomination key must exist in the exchange's
* offerings. Can be NULL if @e pk is set instead.
@@ -275,6 +281,50 @@ reserve_withdraw_cb (void *cls,
/**
+ * Parser reference to a coin.
+ *
+ * @param coin_reference of format $LABEL['#' $INDEX]?
+ * @param[out] cref where we return a copy of $LABEL
+ * @param[out] idx where we set $INDEX
+ * @return #GNUNET_SYSERR if $INDEX is present but not numeric
+ */
+static int
+parse_coin_reference (const char *coin_reference,
+ char **cref,
+ unsigned int *idx)
+{
+ const char *index;
+
+ /* We allow command references of the form "$LABEL#$INDEX" or
+ just "$LABEL", which implies the index is 0. Figure out
+ which one it is. */
+ index = strchr (coin_reference, '#');
+ if (NULL == index)
+ {
+ *idx = 0;
+ *cref = GNUNET_strdup (coin_reference);
+ return GNUNET_OK;
+ }
+ *cref = GNUNET_strndup (coin_reference,
+ index - coin_reference);
+ if (1 != sscanf (index + 1,
+ "%u",
+ idx))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Numeric index (not `%s') required after `#' in command reference of command in %s:%u\n",
+ index,
+ __FILE__,
+ __LINE__);
+ GNUNET_free (*cref);
+ *cref = NULL;
+ return GNUNET_SYSERR;
+ }
+ return GNUNET_OK;
+}
+
+
+/**
* Run the command.
*/
static void
@@ -307,7 +357,32 @@ withdraw_run (void *cls,
TALER_TESTING_interpreter_fail (is);
return;
}
- TALER_planchet_setup_random (&ws->ps);
+ if (NULL == ws->reuse_coin_key_ref)
+ {
+ TALER_planchet_setup_random (&ws->ps);
+ }
+ else
+ {
+ const struct TALER_CoinSpendPrivateKeyP *coin_priv;
+ const struct TALER_TESTING_Command *cref;
+ char *cstr;
+ unsigned int index;
+
+ GNUNET_assert (GNUNET_OK ==
+ parse_coin_reference (ws->reuse_coin_key_ref,
+ &cstr,
+ &index));
+ cref = TALER_TESTING_interpreter_lookup_command (is,
+ cstr);
+ GNUNET_assert (NULL != cref);
+ GNUNET_free (cstr);
+ GNUNET_assert (GNUNET_OK ==
+ TALER_TESTING_get_trait_coin_priv (cref,
+ index,
+ &coin_priv));
+ TALER_planchet_setup_random (&ws->ps);
+ ws->ps.coin_priv = *coin_priv;
+ }
ws->is = is;
if (NULL == ws->pk)
{
@@ -527,6 +602,44 @@ TALER_TESTING_cmd_withdraw_amount (const char *label,
/**
+ * Create a withdraw command, letting the caller specify
+ * the desired amount as string and also re-using an existing
+ * coin private key in the process (violating the specification,
+ * which will result in an error when spending the coin!).
+ *
+ * @param label command label.
+ * @param reserve_reference command providing us with a reserve to withdraw from
+ * @param amount how much we withdraw.
+ * @param coin_ref reference to (withdraw/reveal) command of a coin
+ * from which we should re-use the private key
+ * @param expected_response_code which HTTP response code
+ * we expect from the exchange.
+ * @return the withdraw command to be executed by the interpreter.
+ */
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_withdraw_amount_reuse_key (
+ const char *label,
+ const char *reserve_reference,
+ const char *amount,
+ const char *coin_ref,
+ unsigned int expected_response_code)
+{
+ struct TALER_TESTING_Command cmd;
+
+ cmd = TALER_TESTING_cmd_withdraw_amount (label,
+ reserve_reference,
+ amount,
+ expected_response_code);
+ {
+ struct WithdrawState *ws = cmd.cls;
+
+ ws->reuse_coin_key_ref = coin_ref;
+ }
+ return cmd;
+}
+
+
+/**
* Create withdraw command, letting the caller specify the
* amount by a denomination key.
*