-modify C API to future-proof it for returning more details as required for KYC implementation

This commit is contained in:
Christian Grothoff 2021-10-13 18:52:59 +02:00
parent 9e25e39b80
commit acbadd5c6e
No known key found for this signature in database
GPG Key ID: 939E6BE1E29FC3CC
12 changed files with 390 additions and 244 deletions

View File

@ -472,7 +472,7 @@ echo "===========4: deposit wire target wrong================="
# Original target bank account was 43, changing to 44
SERIAL=`echo "SELECT deposit_serial_id FROM deposits WHERE amount_with_fee_val=3 AND amount_with_fee_frac=0 ORDER BY deposit_serial_id LIMIT 1" | psql $DB -Aqt`
OLD_WIRE=`echo "SELECT wire FROM deposits WHERE deposit_serial_id=${SERIAL};" | psql $DB -Aqt`
echo "UPDATE deposits SET wire='{\"payto_uri\":\"payto://x-taler-bank/localhost:8082/44\",\"salt\":\"test-salt\"}' WHERE deposit_serial_id=${SERIAL}" | psql -Aqt $DB
echo "UPDATE deposits SET wire='{\"payto_uri\":\"payto://x-taler-bank/localhost:8082/44\",\"salt\":\"9PE256FT5N3YX8H3F1QCHXVNGWAGG3MHDN4J360TSVWTA6WSSMNB8MY4GN5HQAP89TDZH8ANKEG1FB1FJZMN7ZC6NH6QRB0CDDR4TJ8\"}' WHERE deposit_serial_id=${SERIAL}" | psql -Aqt $DB
run_audit
@ -1500,7 +1500,7 @@ echo "===========26: deposit wire target malformed ================="
# Expects 'payto_uri', not 'url' (also breaks signature, but we cannot even check that).
SERIAL=`echo "SELECT deposit_serial_id FROM deposits WHERE amount_with_fee_val=3 AND amount_with_fee_frac=0 ORDER BY deposit_serial_id LIMIT 1" | psql $DB -Aqt`
OLD_WIRE=`echo "SELECT wire FROM deposits WHERE deposit_serial_id=${SERIAL};" | psql $DB -Aqt`
echo "UPDATE deposits SET wire='{\"url\":\"payto://x-taler-bank/localhost:8082/44\",\"salt\":\"test-salt\"}' WHERE deposit_serial_id=${SERIAL}" | psql -Aqt $DB
echo "UPDATE deposits SET wire='{\"url\":\"payto://x-taler-bank/localhost:8082/44\",\"salt\":\"9PE256FT5N3YX8H3F1QCHXVNGWAGG3MHDN4J360TSVWTA6WSSMNB8MY4GN5HQAP89TDZH8ANKEG1FB1FJZMN7ZC6NH6QRB0CDDR4TJ8\"}' WHERE deposit_serial_id=${SERIAL}" | psql -Aqt $DB
run_audit

View File

@ -1303,12 +1303,16 @@ test_wire_out (const struct TALER_EXCHANGEDB_Deposit *deposit)
putting in the WTID into the wire_out table */
{
json_t *wire_out_account;
struct TALER_WireSalt salt;
memset (&salt,
44,
sizeof (salt));
wire_out_account = GNUNET_JSON_PACK (
GNUNET_JSON_pack_string ("payto_uri",
"payto://x-taler-bank/localhost:8080/1"),
GNUNET_JSON_pack_string ("salt",
"this-is-my-salt"));
GNUNET_JSON_pack_data_auto ("salt",
&salt));
if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
plugin->store_wire_transfer_out (plugin->cls,
wire_out_date,
@ -1513,15 +1517,19 @@ run (void *cls)
uint64_t rr;
enum GNUNET_DB_QueryStatus qs;
struct GNUNET_TIME_Absolute now;
struct TALER_WireSalt salt;
dkp = NULL;
rh = NULL;
deposit.coin.denom_sig.rsa_signature = NULL;
memset (&salt,
45,
sizeof (salt));
wire = GNUNET_JSON_PACK (
GNUNET_JSON_pack_string ("payto_uri",
"payto://iban/DE67830654080004822650?receiver-name=Test"),
GNUNET_JSON_pack_string ("salt",
"this-is-a-salt-value"));
GNUNET_JSON_pack_data_auto ("salt",
&salt));
ZR_BLK (&cbc);
ZR_BLK (&cbc2);
if (NULL ==

View File

@ -793,23 +793,78 @@ TALER_EXCHANGE_deposit_permission_sign (
struct TALER_EXCHANGE_DepositHandle;
/**
* Structure with information about a deposit
* operation's result.
*/
struct TALER_EXCHANGE_DepositResult
{
/**
* HTTP response data
*/
struct TALER_EXCHANGE_HttpResponse hr;
union
{
/**
* Information returned if the HTTP status is
* #MHD_HTTP_OK.
*/
struct
{
/**
* Time when the exchange generated the deposit confirmation
*/
struct GNUNET_TIME_Absolute deposit_timestamp;
/**
* signature provided by the exchange
*/
const struct TALER_ExchangeSignatureP *exchange_sig;
/**
* exchange key used to sign @a exchange_sig.
*/
const struct TALER_ExchangePublicKeyP *exchange_pub;
/**
* Base URL for looking up wire transfers, or
* NULL to use the default base URL.
*/
const char *transaction_base_url;
/**
* Payment target that the merchant should use
* to check for its KYC status.
*/
uint64_t payment_target_uuid;
} success;
/**
* Information returned if the HTTP status is
* #MHD_HTTP_CONFLICT.
*/
struct
{
/* TODO: returning full details is not implemented */
} conflict;
} details;
};
/**
* Callbacks of this type are used to serve the result of submitting a
* deposit permission request to a exchange.
*
* @param cls closure
* @param hr HTTP response data
* @param deposit_timestamp time when the exchange generated the deposit confirmation
* @param exchange_sig signature provided by the exchange
* @param exchange_pub exchange key used to sign @a obj, or NULL
* @param dr deposit response details
*/
typedef void
(*TALER_EXCHANGE_DepositResultCallback) (
void *cls,
const struct TALER_EXCHANGE_HttpResponse *hr,
struct GNUNET_TIME_Absolute deposit_timestamp,
const struct TALER_ExchangeSignatureP *exchange_sig,
const struct TALER_ExchangePublicKeyP *exchange_pub);
const struct TALER_EXCHANGE_DepositResult *dr);
/**
@ -1200,19 +1255,75 @@ TALER_EXCHANGE_reserves_get_cancel (
struct TALER_EXCHANGE_WithdrawHandle;
/**
* Details about a response for a withdraw request.
*/
struct TALER_EXCHANGE_WithdrawResponse
{
/**
* HTTP response data.
*/
struct TALER_EXCHANGE_HttpResponse hr;
/**
* Details about the response.
*/
union
{
/**
* Details if the status is #MHD_HTTP_OK.
*/
struct
{
/**
* Signature over the coin.
*/
struct TALER_DenominationSignature sig;
} success;
/**
* Details if the status is #MHD_HTTP_ACCEPTED.
*/
struct
{
/**
* Payment target that the merchant should use
* to check for its KYC status.
*/
uint64_t payment_target_uuid;
} accepted;
/**
* Details if the status is #MHD_HTTP_CONFLICT.
*/
struct
{
/* TODO: returning full details is not implemented */
} conflict;
/**
* Details if the status is #MHD_HTTP_GONE.
*/
struct
{
/* TODO: returning full details is not implemented */
} gone;
} details;
};
/**
* Callbacks of this type are used to serve the result of submitting a
* withdraw request to a exchange.
*
* @param cls closure
* @param hr HTTP response data
* @param sig signature over the coin, NULL on error
* @param wr response details
*/
typedef void
(*TALER_EXCHANGE_WithdrawCallback) (
void *cls,
const struct TALER_EXCHANGE_HttpResponse *hr,
const struct TALER_DenominationSignature *sig);
const struct TALER_EXCHANGE_WithdrawResponse *wr);
/**
@ -1684,13 +1795,27 @@ struct TALER_EXCHANGE_DepositGetHandle;
/**
* Data returned for a successful GET /deposits/ request. Note that
* most fields are only set if the status is #MHD_HTTP_OK. Only
* the @e execution_time is available if the status is #MHD_HTTP_ACCEPTED.
* Data returned for a successful GET /deposits/ request.
*/
struct TALER_EXCHANGE_DepositData
struct TALER_EXCHANGE_GetDepositResponse
{
/**
* HTTP response data.
*/
struct TALER_EXCHANGE_HttpResponse hr;
/**
* Details about the response.
*/
union
{
/**
* Response if the status was #MHD_HTTP_OK
*/
struct TALER_EXCHANGE_DepositData
{
/**
* exchange key used to sign, all zeros if exchange did not
* yet execute the transaction
@ -1710,7 +1835,7 @@ struct TALER_EXCHANGE_DepositData
struct TALER_WireTransferIdentifierRawP wtid;
/**
* actual or planned execution time for the wire transfer
* actual execution time for the wire transfer
*/
struct GNUNET_TIME_Absolute execution_time;
@ -1719,6 +1844,33 @@ struct TALER_EXCHANGE_DepositData
* yet execute the transaction
*/
struct TALER_Amount coin_contribution;
/**
* Payment target that the merchant should use
* to check for its KYC status.
*/
uint64_t payment_target_uuid;
} success;
/**
* Response if the status was #MHD_HTTP_ACCEPTED
*/
struct
{
/**
* planned execution time for the wire transfer
*/
struct GNUNET_TIME_Absolute execution_time;
/**
* Payment target that the merchant should use
* to check for its KYC status.
*/
uint64_t payment_target_uuid;
} accepted;
} details;
};
@ -1732,8 +1884,7 @@ struct TALER_EXCHANGE_DepositData
typedef void
(*TALER_EXCHANGE_DepositGetCallback)(
void *cls,
const struct TALER_EXCHANGE_HttpResponse *hr,
const struct TALER_EXCHANGE_DepositData *dd);
const struct TALER_EXCHANGE_GetDepositResponse *dr);
/**

View File

@ -324,19 +324,17 @@ handle_deposit_finished (void *cls,
struct TALER_EXCHANGE_DepositHandle *dh = cls;
struct TALER_ExchangeSignatureP exchange_sig;
struct TALER_ExchangePublicKeyP exchange_pub;
struct TALER_ExchangeSignatureP *es = NULL;
struct TALER_ExchangePublicKeyP *ep = NULL;
const json_t *j = response;
struct TALER_EXCHANGE_HttpResponse hr = {
.reply = j,
.http_status = (unsigned int) response_code
struct TALER_EXCHANGE_DepositResult dr = {
.hr.reply = j,
.hr.http_status = (unsigned int) response_code
};
dh->job = NULL;
switch (response_code)
{
case 0:
hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
dr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
break;
case MHD_HTTP_OK:
if (GNUNET_OK !=
@ -346,31 +344,35 @@ handle_deposit_finished (void *cls,
&exchange_pub))
{
GNUNET_break_op (0);
hr.http_status = 0;
hr.ec = TALER_EC_EXCHANGE_DEPOSIT_INVALID_SIGNATURE_BY_EXCHANGE;
dr.hr.http_status = 0;
dr.hr.ec = TALER_EC_EXCHANGE_DEPOSIT_INVALID_SIGNATURE_BY_EXCHANGE;
}
else
{
es = &exchange_sig;
ep = &exchange_pub;
dr.details.success.exchange_sig = &exchange_sig;
dr.details.success.exchange_pub = &exchange_pub;
dr.details.success.deposit_timestamp
= GNUNET_TIME_absolute_ntoh (dh->depconf.exchange_timestamp);
dr.details.success.transaction_base_url; // FIXME
dr.details.success.payment_target_uuid; // FIXME
}
break;
case MHD_HTTP_BAD_REQUEST:
/* This should never happen, either us or the exchange is buggy
(or API version conflict); just pass JSON reply to the application */
hr.ec = TALER_JSON_get_error_code (j);
hr.hint = TALER_JSON_get_error_hint (j);
dr.hr.ec = TALER_JSON_get_error_code (j);
dr.hr.hint = TALER_JSON_get_error_hint (j);
break;
case MHD_HTTP_FORBIDDEN:
hr.ec = TALER_JSON_get_error_code (j);
hr.hint = TALER_JSON_get_error_hint (j);
dr.hr.ec = TALER_JSON_get_error_code (j);
dr.hr.hint = TALER_JSON_get_error_hint (j);
/* Nothing really to verify, exchange says one of the signatures is
invalid; as we checked them, this should never happen, we
should pass the JSON reply to the application */
break;
case MHD_HTTP_NOT_FOUND:
hr.ec = TALER_JSON_get_error_code (j);
hr.hint = TALER_JSON_get_error_hint (j);
dr.hr.ec = TALER_JSON_get_error_code (j);
dr.hr.hint = TALER_JSON_get_error_hint (j);
/* Nothing really to verify, this should never
happen, we should pass the JSON reply to the application */
break;
@ -381,13 +383,13 @@ handle_deposit_finished (void *cls,
j))
{
GNUNET_break_op (0);
hr.http_status = 0;
hr.ec = TALER_EC_EXCHANGE_DEPOSIT_INVALID_SIGNATURE_BY_EXCHANGE;
dr.hr.http_status = 0;
dr.hr.ec = TALER_EC_EXCHANGE_DEPOSIT_INVALID_SIGNATURE_BY_EXCHANGE;
}
else
{
hr.ec = TALER_JSON_get_error_code (j);
hr.hint = TALER_JSON_get_error_hint (j);
dr.hr.ec = TALER_JSON_get_error_code (j);
dr.hr.hint = TALER_JSON_get_error_hint (j);
}
break;
case MHD_HTTP_GONE:
@ -395,31 +397,28 @@ handle_deposit_finished (void *cls,
/* Note: one might want to check /keys for revocation
signature here, alas tricky in case our /keys
is outdated => left to clients */
hr.ec = TALER_JSON_get_error_code (j);
hr.hint = TALER_JSON_get_error_hint (j);
dr.hr.ec = TALER_JSON_get_error_code (j);
dr.hr.hint = TALER_JSON_get_error_hint (j);
break;
case MHD_HTTP_INTERNAL_SERVER_ERROR:
hr.ec = TALER_JSON_get_error_code (j);
hr.hint = TALER_JSON_get_error_hint (j);
dr.hr.ec = TALER_JSON_get_error_code (j);
dr.hr.hint = TALER_JSON_get_error_hint (j);
/* Server had an internal issue; we should retry, but this API
leaves this to the application */
break;
default:
/* unexpected response code */
hr.ec = TALER_JSON_get_error_code (j);
hr.hint = TALER_JSON_get_error_hint (j);
dr.hr.ec = TALER_JSON_get_error_code (j);
dr.hr.hint = TALER_JSON_get_error_hint (j);
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Unexpected response code %u/%d for exchange deposit\n",
(unsigned int) response_code,
hr.ec);
dr.hr.ec);
GNUNET_break_op (0);
break;
}
dh->cb (dh->cb_cls,
&hr,
GNUNET_TIME_absolute_ntoh (dh->depconf.exchange_timestamp),
es,
ep);
&dr);
TALER_EXCHANGE_deposit_cancel (dh);
}

View File

@ -1,6 +1,6 @@
/*
This file is part of TALER
Copyright (C) 2014-2020 Taler Systems SA
Copyright (C) 2014-2021 Taler Systems SA
TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
@ -88,7 +88,7 @@ struct TALER_EXCHANGE_DepositGetHandle
* @param exchange_sig the exchange's signature
* @return #GNUNET_OK if the signature is valid, #GNUNET_SYSERR if not
*/
static int
static enum GNUNET_GenericReturnValue
verify_deposit_wtid_signature_ok (
const struct TALER_EXCHANGE_DepositGetHandle *dwh,
const json_t *json,
@ -133,26 +133,30 @@ handle_deposit_wtid_finished (void *cls,
{
struct TALER_EXCHANGE_DepositGetHandle *dwh = cls;
const json_t *j = response;
struct TALER_EXCHANGE_HttpResponse hr = {
.reply = j,
.http_status = (unsigned int) response_code
struct TALER_EXCHANGE_GetDepositResponse dr = {
.hr.reply = j,
.hr.http_status = (unsigned int) response_code
};
dwh->job = NULL;
switch (response_code)
{
case 0:
hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
dr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
break;
case MHD_HTTP_OK:
{
struct TALER_EXCHANGE_DepositData dd;
struct GNUNET_JSON_Specification spec[] = {
GNUNET_JSON_spec_fixed_auto ("wtid", &dwh->depconf.wtid),
TALER_JSON_spec_absolute_time ("execution_time", &dd.execution_time),
TALER_JSON_spec_amount_any ("coin_contribution", &dd.coin_contribution),
GNUNET_JSON_spec_fixed_auto ("exchange_sig", &dd.exchange_sig),
GNUNET_JSON_spec_fixed_auto ("exchange_pub", &dd.exchange_pub),
GNUNET_JSON_spec_fixed_auto ("wtid",
&dr.details.success.wtid),
TALER_JSON_spec_absolute_time ("execution_time",
&dr.details.success.execution_time),
TALER_JSON_spec_amount_any ("coin_contribution",
&dr.details.success.coin_contribution),
GNUNET_JSON_spec_fixed_auto ("exchange_sig",
&dr.details.success.exchange_sig),
GNUNET_JSON_spec_fixed_auto ("exchange_pub",
&dr.details.success.exchange_pub),
GNUNET_JSON_spec_end ()
};
@ -162,41 +166,37 @@ handle_deposit_wtid_finished (void *cls,
NULL, NULL))
{
GNUNET_break_op (0);
hr.http_status = 0;
hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
dr.hr.http_status = 0;
dr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
break;
}
dwh->depconf.execution_time = GNUNET_TIME_absolute_hton (
dd.execution_time);
dr.details.success.execution_time);
dwh->depconf.wtid = dr.details.success.wtid;
TALER_amount_hton (&dwh->depconf.coin_contribution,
&dd.coin_contribution);
&dr.details.success.coin_contribution);
if (GNUNET_OK !=
verify_deposit_wtid_signature_ok (dwh,
j,
&dd.exchange_pub,
&dd.exchange_sig))
&dr.details.success.exchange_pub,
&dr.details.success.exchange_sig))
{
GNUNET_break_op (0);
hr.http_status = 0;
hr.ec = TALER_EC_EXCHANGE_DEPOSITS_GET_INVALID_SIGNATURE_BY_EXCHANGE;
dr.hr.http_status = 0;
dr.hr.ec = TALER_EC_EXCHANGE_DEPOSITS_GET_INVALID_SIGNATURE_BY_EXCHANGE;
break;
}
else
{
dd.wtid = dwh->depconf.wtid;
dwh->cb (dwh->cb_cls,
&hr,
&dd);
&dr);
TALER_EXCHANGE_deposits_get_cancel (dwh);
return;
}
}
break;
case MHD_HTTP_ACCEPTED:
{
/* Transaction known, but not executed yet */
struct GNUNET_TIME_Absolute execution_time;
struct GNUNET_JSON_Specification spec[] = {
TALER_JSON_spec_absolute_time ("execution_time", &execution_time),
TALER_JSON_spec_absolute_time ("execution_time",
&dr.details.accepted.execution_time),
GNUNET_JSON_spec_end ()
};
@ -206,63 +206,54 @@ handle_deposit_wtid_finished (void *cls,
NULL, NULL))
{
GNUNET_break_op (0);
hr.http_status = 0;
hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
dr.hr.http_status = 0;
dr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
break;
}
else
{
struct TALER_EXCHANGE_DepositData dd = {
.execution_time = execution_time
};
dr.details.accepted.payment_target_uuid; // FIXME
dwh->cb (dwh->cb_cls,
&hr,
&dd);
&dr);
TALER_EXCHANGE_deposits_get_cancel (dwh);
return;
}
}
break;
case MHD_HTTP_BAD_REQUEST:
hr.ec = TALER_JSON_get_error_code (j);
hr.hint = TALER_JSON_get_error_hint (j);
dr.hr.ec = TALER_JSON_get_error_code (j);
dr.hr.hint = TALER_JSON_get_error_hint (j);
/* This should never happen, either us or the exchange is buggy
(or API version conflict); just pass JSON reply to the application */
break;
case MHD_HTTP_FORBIDDEN:
hr.ec = TALER_JSON_get_error_code (j);
hr.hint = TALER_JSON_get_error_hint (j);
dr.hr.ec = TALER_JSON_get_error_code (j);
dr.hr.hint = TALER_JSON_get_error_hint (j);
/* Nothing really to verify, exchange says one of the signatures is
invalid; as we checked them, this should never happen, we
should pass the JSON reply to the application */
break;
case MHD_HTTP_NOT_FOUND:
hr.ec = TALER_JSON_get_error_code (j);
hr.hint = TALER_JSON_get_error_hint (j);
dr.hr.ec = TALER_JSON_get_error_code (j);
dr.hr.hint = TALER_JSON_get_error_hint (j);
/* Exchange does not know about transaction;
we should pass the reply to the application */
break;
case MHD_HTTP_INTERNAL_SERVER_ERROR:
hr.ec = TALER_JSON_get_error_code (j);
hr.hint = TALER_JSON_get_error_hint (j);
dr.hr.ec = TALER_JSON_get_error_code (j);
dr.hr.hint = TALER_JSON_get_error_hint (j);
/* Server had an internal issue; we should retry, but this API
leaves this to the application */
break;
default:
/* unexpected response code */
hr.ec = TALER_JSON_get_error_code (j);
hr.hint = TALER_JSON_get_error_hint (j);
dr.hr.ec = TALER_JSON_get_error_code (j);
dr.hr.hint = TALER_JSON_get_error_hint (j);
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Unexpected response code %u/%d for exchange GET deposits\n",
(unsigned int) response_code,
(int) hr.ec);
(int) dr.hr.ec);
GNUNET_break_op (0);
break;
}
dwh->cb (dwh->cb_cls,
&hr,
NULL);
&dr);
TALER_EXCHANGE_deposits_get_cancel (dwh);
}

View File

@ -91,15 +91,14 @@ handle_reserve_withdraw_finished (
const struct GNUNET_CRYPTO_RsaSignature *blind_sig)
{
struct TALER_EXCHANGE_WithdrawHandle *wh = cls;
struct TALER_EXCHANGE_WithdrawResponse wr = {
.hr = *hr
};
wh->wh2 = NULL;
if (MHD_HTTP_OK != hr->http_status)
switch (hr->http_status)
{
wh->cb (wh->cb_cls,
hr,
NULL);
}
else
case MHD_HTTP_OK:
{
struct TALER_FreshCoin fc;
@ -110,25 +109,23 @@ handle_reserve_withdraw_finished (
&wh->c_hash,
&fc))
{
struct TALER_EXCHANGE_HttpResponse hrx = {
.reply = hr->reply,
.http_status = 0,
.ec = TALER_EC_EXCHANGE_WITHDRAW_UNBLIND_FAILURE
};
wr.hr.http_status = 0;
wr.hr.ec = TALER_EC_EXCHANGE_WITHDRAW_UNBLIND_FAILURE;
break;
}
wr.details.success.sig = fc.sig;
break;
}
case MHD_HTTP_ACCEPTED:
wr.details.accepted.payment_target_uuid; // FIXME
break;
default:
break;
}
wh->cb (wh->cb_cls,
&hrx,
NULL);
}
else
{
wh->cb (wh->cb_cls,
hr,
&fc.sig);
GNUNET_CRYPTO_rsa_signature_free (fc.sig.rsa_signature);
}
}
&wr);
if (MHD_HTTP_OK == hr->http_status)
GNUNET_CRYPTO_rsa_signature_free (wr.details.success.sig.rsa_signature);
TALER_EXCHANGE_withdraw_cancel (wh);
}

View File

@ -1,6 +1,6 @@
/*
This file is part of TALER
Copyright (C) 2018-2020 Taler Systems SA
Copyright (C) 2018-2021 Taler Systems SA
TALER is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
@ -207,38 +207,30 @@ do_retry (void *cls)
* check if the response code is acceptable.
*
* @param cls closure.
* @param hr HTTP response details
* @param exchange_timestamp when did the exchange receive the deposit permission
* @param exchange_sig signature provided by the exchange
* (NULL on errors)
* @param exchange_pub public key of the exchange,
* used for signing the response.
* @param dr deposit response details
*/
static void
deposit_cb (void *cls,
const struct TALER_EXCHANGE_HttpResponse *hr,
const struct GNUNET_TIME_Absolute exchange_timestamp,
const struct TALER_ExchangeSignatureP *exchange_sig,
const struct TALER_ExchangePublicKeyP *exchange_pub)
const struct TALER_EXCHANGE_DepositResult *dr)
{
struct DepositState *ds = cls;
ds->dh = NULL;
if (ds->expected_response_code != hr->http_status)
if (ds->expected_response_code != dr->hr.http_status)
{
if (0 != ds->do_retry)
{
ds->do_retry--;
if ( (0 == hr->http_status) ||
(TALER_EC_GENERIC_DB_SOFT_FAILURE == hr->ec) ||
(MHD_HTTP_INTERNAL_SERVER_ERROR == hr->http_status) )
if ( (0 == dr->hr.http_status) ||
(TALER_EC_GENERIC_DB_SOFT_FAILURE == dr->hr.ec) ||
(MHD_HTTP_INTERNAL_SERVER_ERROR == dr->hr.http_status) )
{
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Retrying deposit failed with %u/%d\n",
hr->http_status,
(int) hr->ec);
dr->hr.http_status,
(int) dr->hr.ec);
/* on DB conflicts, do not use backoff */
if (TALER_EC_GENERIC_DB_SOFT_FAILURE == hr->ec)
if (TALER_EC_GENERIC_DB_SOFT_FAILURE == dr->hr.ec)
ds->backoff = GNUNET_TIME_UNIT_ZERO;
else
ds->backoff = GNUNET_TIME_randomized_backoff (ds->backoff,
@ -253,22 +245,22 @@ deposit_cb (void *cls,
}
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Unexpected response code %u to command %s in %s:%u\n",
hr->http_status,
dr->hr.http_status,
ds->is->commands[ds->is->ip].label,
__FILE__,
__LINE__);
json_dumpf (hr->reply,
json_dumpf (dr->hr.reply,
stderr,
0);
TALER_TESTING_interpreter_fail (ds->is);
return;
}
if (MHD_HTTP_OK == hr->http_status)
if (MHD_HTTP_OK == dr->hr.http_status)
{
ds->deposit_succeeded = GNUNET_YES;
ds->exchange_timestamp = exchange_timestamp;
ds->exchange_pub = *exchange_pub;
ds->exchange_sig = *exchange_sig;
ds->exchange_timestamp = dr->details.success.deposit_timestamp;
ds->exchange_pub = *dr->details.success.exchange_pub;
ds->exchange_sig = *dr->details.success.exchange_sig;
}
TALER_TESTING_interpreter_next (ds->is);
}

View File

@ -1,6 +1,6 @@
/*
This file is part of TALER
Copyright (C) 2014-2020 Taler Systems SA
Copyright (C) 2014-2021 Taler Systems SA
TALER is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as
@ -80,38 +80,36 @@ struct TrackTransactionState
* line matches our expectations.
*
* @param cls closure.
* @param hr HTTP response details
* @param dd data about the wire transfer associated with the deposit
* @param dr GET deposit response details
*/
static void
deposit_wtid_cb (void *cls,
const struct TALER_EXCHANGE_HttpResponse *hr,
const struct TALER_EXCHANGE_DepositData *dd)
const struct TALER_EXCHANGE_GetDepositResponse *dr)
{
struct TrackTransactionState *tts = cls;
struct TALER_TESTING_Interpreter *is = tts->is;
struct TALER_TESTING_Command *cmd = &is->commands[is->ip];
tts->tth = NULL;
if (tts->expected_response_code != hr->http_status)
if (tts->expected_response_code != dr->hr.http_status)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Unexpected response code %u/%d to command %s in %s:%u\n",
hr->http_status,
(int) hr->ec,
dr->hr.http_status,
(int) dr->hr.ec,
cmd->label,
__FILE__,
__LINE__);
json_dumpf (hr->reply,
json_dumpf (dr->hr.reply,
stderr,
0);
TALER_TESTING_interpreter_fail (is);
return;
}
switch (hr->http_status)
switch (dr->hr.http_status)
{
case MHD_HTTP_OK:
tts->wtid = dd->wtid;
tts->wtid = dr->details.success.wtid;
if (NULL != tts->bank_transfer_reference)
{
const struct TALER_TESTING_Command *bank_transfer_cmd;
@ -139,7 +137,7 @@ deposit_wtid_cb (void *cls,
}
/* Compare that expected and gotten subjects match. */
if (0 != GNUNET_memcmp (&dd->wtid,
if (0 != GNUNET_memcmp (&dr->details.success.wtid,
wtid_want))
{
GNUNET_break (0);
@ -147,8 +145,6 @@ deposit_wtid_cb (void *cls,
return;
}
}
break;
case MHD_HTTP_ACCEPTED:
/* allowed, nothing to check here */

View File

@ -200,14 +200,18 @@ insert_deposit_run (void *cls,
&hc);
{
char *str;
struct TALER_WireSalt salt;
GNUNET_asprintf (&str,
"payto://x-taler-bank/localhost/%s",
ids->merchant_account);
memset (&salt,
46,
sizeof (salt));
deposit.receiver_wire_account
= GNUNET_JSON_PACK (
GNUNET_JSON_pack_string ("salt",
"this-is-a-salt-value"),
GNUNET_JSON_pack_data_auto ("salt",
&salt),
GNUNET_JSON_pack_string ("payto_uri",
str));
GNUNET_free (str);

View File

@ -1,6 +1,6 @@
/*
This file is part of TALER
Copyright (C) 2018-2020 Taler Systems SA
Copyright (C) 2018-2021 Taler Systems SA
TALER is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
@ -178,38 +178,36 @@ do_retry (void *cls)
* in the state.
*
* @param cls closure.
* @param hr HTTP response details
* @param sig signature over the coin, NULL on error.
* @param wr withdraw response details
*/
static void
reserve_withdraw_cb (void *cls,
const struct TALER_EXCHANGE_HttpResponse *hr,
const struct TALER_DenominationSignature *sig)
const struct TALER_EXCHANGE_WithdrawResponse *wr)
{
struct WithdrawState *ws = cls;
struct TALER_TESTING_Interpreter *is = ws->is;
ws->wsh = NULL;
if (ws->expected_response_code != hr->http_status)
if (ws->expected_response_code != wr->hr.http_status)
{
if (0 != ws->do_retry)
{
if (TALER_EC_EXCHANGE_WITHDRAW_RESERVE_UNKNOWN != hr->ec)
if (TALER_EC_EXCHANGE_WITHDRAW_RESERVE_UNKNOWN != wr->hr.ec)
ws->do_retry--; /* we don't count reserve unknown as failures here */
if ( (0 == hr->http_status) ||
(TALER_EC_GENERIC_DB_SOFT_FAILURE == hr->ec) ||
(TALER_EC_EXCHANGE_WITHDRAW_INSUFFICIENT_FUNDS == hr->ec) ||
(TALER_EC_EXCHANGE_WITHDRAW_RESERVE_UNKNOWN == hr->ec) ||
(MHD_HTTP_INTERNAL_SERVER_ERROR == hr->http_status) )
if ( (0 == wr->hr.http_status) ||
(TALER_EC_GENERIC_DB_SOFT_FAILURE == wr->hr.ec) ||
(TALER_EC_EXCHANGE_WITHDRAW_INSUFFICIENT_FUNDS == wr->hr.ec) ||
(TALER_EC_EXCHANGE_WITHDRAW_RESERVE_UNKNOWN == wr->hr.ec) ||
(MHD_HTTP_INTERNAL_SERVER_ERROR == wr->hr.http_status) )
{
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Retrying withdraw failed with %u/%d\n",
hr->http_status,
(int) hr->ec);
wr->hr.http_status,
(int) wr->hr.ec);
/* on DB conflicts, do not use backoff */
if (TALER_EC_GENERIC_DB_SOFT_FAILURE == hr->ec)
if (TALER_EC_GENERIC_DB_SOFT_FAILURE == wr->hr.ec)
ws->backoff = GNUNET_TIME_UNIT_ZERO;
else if (TALER_EC_EXCHANGE_WITHDRAW_RESERVE_UNKNOWN != hr->ec)
else if (TALER_EC_EXCHANGE_WITHDRAW_RESERVE_UNKNOWN != wr->hr.ec)
ws->backoff = EXCHANGE_LIB_BACKOFF (ws->backoff);
else
ws->backoff = GNUNET_TIME_relative_max (UNKNOWN_MIN_BACKOFF,
@ -227,29 +225,23 @@ reserve_withdraw_cb (void *cls,
}
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Unexpected response code %u/%d to command %s in %s:%u\n",
hr->http_status,
(int) hr->ec,
wr->hr.http_status,
(int) wr->hr.ec,
TALER_TESTING_interpreter_get_current_label (is),
__FILE__,
__LINE__);
json_dumpf (hr->reply,
json_dumpf (wr->hr.reply,
stderr,
0);
GNUNET_break (0);
TALER_TESTING_interpreter_fail (is);
return;
}
switch (hr->http_status)
switch (wr->hr.http_status)
{
case MHD_HTTP_OK:
if (NULL == sig)
{
GNUNET_break (0);
TALER_TESTING_interpreter_fail (is);
return;
}
ws->sig.rsa_signature = GNUNET_CRYPTO_rsa_signature_dup (
sig->rsa_signature);
wr->details.success.sig.rsa_signature);
if (0 != ws->total_backoff.rel_value_us)
{
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
@ -259,23 +251,27 @@ reserve_withdraw_cb (void *cls,
GNUNET_YES));
}
break;
case MHD_HTTP_ACCEPTED:
/* nothing to check */
/* TODO: trait for returned uuid! */
break;
case MHD_HTTP_FORBIDDEN:
/* nothing to check */
break;
case MHD_HTTP_NOT_FOUND:
/* nothing to check */
break;
case MHD_HTTP_CONFLICT:
/* nothing to check */
break;
case MHD_HTTP_GONE:
/* theoretically could check that the key was actually */
break;
case MHD_HTTP_NOT_FOUND:
/* nothing to check */
break;
default:
/* Unsupported status code (by test harness) */
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"Withdraw test command does not support status code %u\n",
hr->http_status);
wr->hr.http_status);
GNUNET_break (0);
break;
}

View File

@ -670,11 +670,17 @@ TALER_TESTING_prepare_fakebank (const char *config_filename,
json_t *
TALER_TESTING_make_wire_details (const char *payto)
{
struct TALER_WireSalt salt;
/* salt must be constant for aggregation tests! */
memset (&salt,
47,
sizeof (salt));
return GNUNET_JSON_PACK (
GNUNET_JSON_pack_string ("payto_uri",
payto),
GNUNET_JSON_pack_string ("salt",
"test-salt (must be constant for aggregation tests)"));
GNUNET_JSON_pack_data_auto ("salt",
&salt));
}

View File

@ -158,21 +158,24 @@ static int
test_merchant_sigs ()
{
const char *pt = "payto://x-taler-bank/localhost/Account";
const char *salt = "my test salt";
struct TALER_WireSalt salt;
struct TALER_MerchantPrivateKeyP priv;
struct TALER_MerchantPublicKeyP pub;
struct TALER_MerchantSignatureP sig;
GNUNET_CRYPTO_eddsa_key_create (&priv.eddsa_priv);
memset (&salt,
42,
sizeof (salt));
TALER_merchant_wire_signature_make (pt,
salt,
&salt,
&priv,
&sig);
GNUNET_CRYPTO_eddsa_key_get_public (&priv.eddsa_priv,
&pub.eddsa_pub);
if (GNUNET_OK !=
TALER_merchant_wire_signature_check (pt,
salt,
&salt,
&pub,
&sig))
{
@ -182,16 +185,19 @@ test_merchant_sigs ()
if (GNUNET_OK ==
TALER_merchant_wire_signature_check (
"payto://x-taler-bank/localhost/Other",
salt,
&salt,
&pub,
&sig))
{
GNUNET_break (0);
return 1;
}
memset (&salt,
43,
sizeof (salt));
if (GNUNET_OK ==
TALER_merchant_wire_signature_check (pt,
"other salt",
&salt,
&pub,
&sig))
{