aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2020-04-04 13:27:46 +0200
committerChristian Grothoff <christian@grothoff.org>2020-04-04 13:27:46 +0200
commit299b4b78e0e4b8f194d0f0db18e22b540b174b88 (patch)
treebee0cf9a0e984926e1af69269d745974176ce945 /src
parent643b3e3be3e5aff3fe4074e27d867605c18cb0dc (diff)
return more error details for /wire and /keys to clients
Diffstat (limited to 'src')
-rw-r--r--src/include/taler_error_codes.h6
-rw-r--r--src/include/taler_exchange_service.h12
-rw-r--r--src/include/taler_testing_lib.h8
-rw-r--r--src/lib/exchange_api_handle.c126
-rw-r--r--src/lib/exchange_api_wire.c6
-rw-r--r--src/testing/testing_api_cmd_serialize_keys.c2
-rw-r--r--src/testing/testing_api_cmd_wire.c5
-rw-r--r--src/testing/testing_api_loop.c29
8 files changed, 121 insertions, 73 deletions
diff --git a/src/include/taler_error_codes.h b/src/include/taler_error_codes.h
index ce75cf6ac..7bdbd573a 100644
--- a/src/include/taler_error_codes.h
+++ b/src/include/taler_error_codes.h
@@ -112,6 +112,12 @@ enum TALER_ErrorCode
TALER_EC_WRONG_NUMBER_OF_SEGMENTS = 12,
/**
+ * The start and end-times in the wire fee structure leave a hole.
+ * This is not allowed. Generated as an error on the client-side.
+ */
+ TALER_EC_HOLE_IN_WIRE_FEE_STRUCTURE = 13,
+
+ /**
* The exchange failed to even just initialize its connection to the
* database. This response is provided with HTTP status code
* #MHD_HTTP_INTERNAL_SERVER_ERROR.
diff --git a/src/include/taler_exchange_service.h b/src/include/taler_exchange_service.h
index e935c9196..5f7cf6033 100644
--- a/src/include/taler_exchange_service.h
+++ b/src/include/taler_exchange_service.h
@@ -359,12 +359,18 @@ enum TALER_EXCHANGE_VersionCompatibility
* @param keys information about the various keys used
* by the exchange, NULL if /keys failed
* @param compat protocol compatibility information
+ * @param ec error code, #TALER_EC_NONE on success
+ * @param http_status status returned by /keys, #MHD_HTTP_OK on success
+ * @param full_reply JSON body of /keys request, NULL if reply was not in JSON
*/
typedef void
(*TALER_EXCHANGE_CertificationCallback) (
void *cls,
const struct TALER_EXCHANGE_Keys *keys,
- enum TALER_EXCHANGE_VersionCompatibility compat);
+ enum TALER_EXCHANGE_VersionCompatibility compat,
+ enum TALER_ErrorCode ec,
+ unsigned int http_status,
+ const json_t *full_reply);
/**
@@ -649,6 +655,7 @@ struct TALER_EXCHANGE_WireAccount
* @param ec taler-specific error code, #TALER_EC_NONE on success
* @param accounts_len length of the @a accounts array
* @param accounts list of wire accounts of the exchange, NULL on error
+ * @param full_reply the complete reply from the exchange (if it was in JSON)
*/
typedef void
(*TALER_EXCHANGE_WireCallback) (
@@ -656,7 +663,8 @@ typedef void
unsigned int http_status,
enum TALER_ErrorCode ec,
unsigned int accounts_len,
- const struct TALER_EXCHANGE_WireAccount *accounts);
+ const struct TALER_EXCHANGE_WireAccount *accounts,
+ const json_t *full_reply);
/**
diff --git a/src/include/taler_testing_lib.h b/src/include/taler_testing_lib.h
index c8949ee38..be20e0cd7 100644
--- a/src/include/taler_testing_lib.h
+++ b/src/include/taler_testing_lib.h
@@ -137,11 +137,17 @@ TALER_TESTING_prepare_exchange (const char *config_filename,
* all the commands to be run, and a closure for it.
* @param keys the exchange's keys.
* @param compat protocol compatibility information.
+ * @param ec error code, #TALER_EC_NONE on success
+ * @param http_status status returned by /keys, #MHD_HTTP_OK on success
+ * @param full_reply JSON body of /keys request, NULL if reply was not in JSON
*/
void
TALER_TESTING_cert_cb (void *cls,
const struct TALER_EXCHANGE_Keys *keys,
- enum TALER_EXCHANGE_VersionCompatibility compat);
+ enum TALER_EXCHANGE_VersionCompatibility compat,
+ enum TALER_ErrorCode ec,
+ unsigned int http_status,
+ const json_t *full_reply);
/**
diff --git a/src/lib/exchange_api_handle.c b/src/lib/exchange_api_handle.c
index cb02f68e0..8ae5b06d2 100644
--- a/src/lib/exchange_api_handle.c
+++ b/src/lib/exchange_api_handle.c
@@ -373,7 +373,6 @@ parse_json_signkey (struct TALER_EXCHANGE_SigningPublicKey *sign_key,
json_t *sign_key_obj,
const struct TALER_MasterPublicKeyP *master_key)
{
- struct TALER_ExchangeSigningKeyValidityPS sign_key_issue;
struct TALER_MasterSignatureP sign_key_issue_sig;
struct GNUNET_JSON_Specification spec[] = {
GNUNET_JSON_spec_fixed_auto ("master_sig",
@@ -400,23 +399,26 @@ parse_json_signkey (struct TALER_EXCHANGE_SigningPublicKey *sign_key,
if (! check_sigs)
return GNUNET_OK;
- sign_key_issue.signkey_pub = sign_key->key;
- sign_key_issue.purpose.purpose = htonl (
- TALER_SIGNATURE_MASTER_SIGNING_KEY_VALIDITY);
- sign_key_issue.purpose.size = htonl (sizeof (struct
- TALER_ExchangeSigningKeyValidityPS));
- sign_key_issue.master_public_key = *master_key;
- sign_key_issue.start = GNUNET_TIME_absolute_hton (sign_key->valid_from);
- sign_key_issue.expire = GNUNET_TIME_absolute_hton (sign_key->valid_until);
- sign_key_issue.end = GNUNET_TIME_absolute_hton (sign_key->valid_legal);
- if (GNUNET_OK !=
- GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MASTER_SIGNING_KEY_VALIDITY,
- &sign_key_issue.purpose,
- &sign_key_issue_sig.eddsa_signature,
- &master_key->eddsa_pub))
{
- GNUNET_break_op (0);
- return GNUNET_SYSERR;
+ struct TALER_ExchangeSigningKeyValidityPS sign_key_issue = {
+ .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_SIGNING_KEY_VALIDITY),
+ .purpose.size = htonl (sizeof (sign_key_issue)),
+ .signkey_pub = sign_key->key,
+ .master_public_key = *master_key,
+ .start = GNUNET_TIME_absolute_hton (sign_key->valid_from),
+ .expire = GNUNET_TIME_absolute_hton (sign_key->valid_until),
+ .end = GNUNET_TIME_absolute_hton (sign_key->valid_legal)
+ };
+
+ if (GNUNET_OK !=
+ GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MASTER_SIGNING_KEY_VALIDITY,
+ &sign_key_issue.purpose,
+ &sign_key_issue_sig.eddsa_signature,
+ &master_key->eddsa_pub))
+ {
+ GNUNET_break_op (0);
+ return GNUNET_SYSERR;
+ }
}
sign_key->master_sig = sign_key_issue_sig;
return GNUNET_OK;
@@ -441,7 +443,6 @@ parse_json_denomkey (struct TALER_EXCHANGE_DenomPublicKey *denom_key,
struct TALER_MasterPublicKeyP *master_key,
struct GNUNET_HashContext *hash_context)
{
- struct TALER_DenominationKeyValidityPS denom_key_issue;
struct GNUNET_JSON_Specification spec[] = {
GNUNET_JSON_spec_fixed_auto ("master_sig",
&denom_key->master_sig),
@@ -479,46 +480,50 @@ parse_json_denomkey (struct TALER_EXCHANGE_DenomPublicKey *denom_key,
GNUNET_CRYPTO_rsa_public_key_hash (denom_key->key.rsa_public_key,
&denom_key->h_key);
+ if (NULL != hash_context)
+ GNUNET_CRYPTO_hash_context_read (hash_context,
+ &denom_key->h_key,
+ sizeof (struct GNUNET_HashCode));
if (! check_sigs)
return GNUNET_OK;
- memset (&denom_key_issue,
- 0,
- sizeof (denom_key_issue));
- denom_key_issue.purpose.purpose
- = htonl (TALER_SIGNATURE_MASTER_DENOMINATION_KEY_VALIDITY);
- denom_key_issue.purpose.size
- = htonl (sizeof (struct TALER_DenominationKeyValidityPS));
- denom_key_issue.master = *master_key;
- denom_key_issue.denom_hash = denom_key->h_key;
- denom_key_issue.start = GNUNET_TIME_absolute_hton (denom_key->valid_from);
- denom_key_issue.expire_withdraw = GNUNET_TIME_absolute_hton (
- denom_key->withdraw_valid_until);
- denom_key_issue.expire_deposit = GNUNET_TIME_absolute_hton (
- denom_key->expire_deposit);
- denom_key_issue.expire_legal = GNUNET_TIME_absolute_hton (
- denom_key->expire_legal);
- TALER_amount_hton (&denom_key_issue.value,
- &denom_key->value);
- TALER_amount_hton (&denom_key_issue.fee_withdraw,
- &denom_key->fee_withdraw);
- TALER_amount_hton (&denom_key_issue.fee_deposit,
- &denom_key->fee_deposit);
- TALER_amount_hton (&denom_key_issue.fee_refresh,
- &denom_key->fee_refresh);
- TALER_amount_hton (&denom_key_issue.fee_refund,
- &denom_key->fee_refund);
- EXITIF (GNUNET_SYSERR ==
- GNUNET_CRYPTO_eddsa_verify (
- TALER_SIGNATURE_MASTER_DENOMINATION_KEY_VALIDITY,
- &denom_key_issue.purpose,
- &denom_key->master_sig.eddsa_signature,
- &master_key->eddsa_pub));
- GNUNET_CRYPTO_hash_context_read (hash_context,
- &denom_key_issue.denom_hash,
- sizeof (struct GNUNET_HashCode));
+ {
+ struct TALER_DenominationKeyValidityPS denom_key_issue = {
+ .purpose.purpose
+ = htonl (TALER_SIGNATURE_MASTER_DENOMINATION_KEY_VALIDITY),
+ .purpose.size = htonl (sizeof (denom_key_issue)),
+ .master = *master_key,
+ .denom_hash = denom_key->h_key,
+ .start = GNUNET_TIME_absolute_hton (denom_key->valid_from),
+ .expire_withdraw
+ = GNUNET_TIME_absolute_hton (denom_key->withdraw_valid_until),
+ .expire_deposit = GNUNET_TIME_absolute_hton (denom_key->expire_deposit),
+ .expire_legal = GNUNET_TIME_absolute_hton (denom_key->expire_legal)
+ };
+
+ TALER_amount_hton (&denom_key_issue.value,
+ &denom_key->value);
+ TALER_amount_hton (&denom_key_issue.fee_withdraw,
+ &denom_key->fee_withdraw);
+ TALER_amount_hton (&denom_key_issue.fee_deposit,
+ &denom_key->fee_deposit);
+ TALER_amount_hton (&denom_key_issue.fee_refresh,
+ &denom_key->fee_refresh);
+ TALER_amount_hton (&denom_key_issue.fee_refund,
+ &denom_key->fee_refund);
+ EXITIF (GNUNET_SYSERR ==
+ GNUNET_CRYPTO_eddsa_verify (
+ TALER_SIGNATURE_MASTER_DENOMINATION_KEY_VALIDITY,
+ &denom_key_issue.purpose,
+ &denom_key->master_sig.eddsa_signature,
+ &master_key->eddsa_pub));
+ }
return GNUNET_OK;
EXITIF_exit:
+ /* invalidate denom_key, just to be sure */
+ memset (denom_key,
+ 0,
+ sizeof (*denom_key));
GNUNET_JSON_parse_free (spec);
return GNUNET_SYSERR;
}
@@ -1376,7 +1381,10 @@ keys_completed_cb (void *cls,
/* notify application that we failed */
exchange->cert_cb (exchange->cert_cb_cls,
NULL,
- vc);
+ vc,
+ TALER_JSON_get_error_code (j),
+ response_code,
+ j);
return;
}
@@ -1390,7 +1398,10 @@ keys_completed_cb (void *cls,
/* notify application about the key information */
exchange->cert_cb (exchange->cert_cb_cls,
&exchange->key_data,
- vc);
+ vc,
+ TALER_EC_NONE,
+ MHD_HTTP_OK,
+ j);
free_key_data (&kd_old);
}
@@ -1612,7 +1623,10 @@ deserialize_data (struct TALER_EXCHANGE_Handle *exchange,
/* notify application about the key information */
exchange->cert_cb (exchange->cert_cb_cls,
&exchange->key_data,
- vc);
+ vc,
+ TALER_EC_NONE,
+ MHD_HTTP_OK,
+ data);
GNUNET_JSON_parse_free (spec);
}
diff --git a/src/lib/exchange_api_wire.c b/src/lib/exchange_api_wire.c
index ccab4562d..3f3998f5b 100644
--- a/src/lib/exchange_api_wire.c
+++ b/src/lib/exchange_api_wire.c
@@ -328,7 +328,8 @@ handle_wire_finished (void *cls,
response_code,
ec,
num_accounts,
- was);
+ was,
+ j);
wh->cb = NULL;
}
} /* end of 'parse accounts */
@@ -367,7 +368,8 @@ handle_wire_finished (void *cls,
response_code,
ec,
0,
- NULL);
+ NULL,
+ j);
TALER_EXCHANGE_wire_cancel (wh);
}
diff --git a/src/testing/testing_api_cmd_serialize_keys.c b/src/testing/testing_api_cmd_serialize_keys.c
index 296a2ddc7..8a723c5ba 100644
--- a/src/testing/testing_api_cmd_serialize_keys.c
+++ b/src/testing/testing_api_cmd_serialize_keys.c
@@ -209,7 +209,7 @@ connect_with_state_run (void *cls,
&exchange_url));
is->exchange = TALER_EXCHANGE_connect (is->ctx,
exchange_url,
- TALER_TESTING_cert_cb,
+ &TALER_TESTING_cert_cb,
cwss,
TALER_EXCHANGE_OPTION_DATA,
serialized_keys,
diff --git a/src/testing/testing_api_cmd_wire.c b/src/testing/testing_api_cmd_wire.c
index 2d79a546f..c8946bb93 100644
--- a/src/testing/testing_api_cmd_wire.c
+++ b/src/testing/testing_api_cmd_wire.c
@@ -77,19 +77,22 @@ struct WireState
* @param accounts_len length of the @a accounts array.
* @param accounts list of wire accounts of the exchange,
* NULL on error.
+ * @param full_reply the complete response from the exchange
*/
static void
wire_cb (void *cls,
unsigned int http_status,
enum TALER_ErrorCode ec,
unsigned int accounts_len,
- const struct TALER_EXCHANGE_WireAccount *accounts)
+ const struct TALER_EXCHANGE_WireAccount *accounts,
+ const json_t *full_reply)
{
struct WireState *ws = cls;
struct TALER_TESTING_Command *cmd = &ws->is->commands[ws->is->ip];
struct TALER_Amount expected_fee;
(void) ec;
+ (void) full_reply;
TALER_LOG_DEBUG ("Checking parsed /wire response\n");
ws->wh = NULL;
if (ws->expected_response_code != http_status)
diff --git a/src/testing/testing_api_loop.c b/src/testing/testing_api_loop.c
index 361fe6305..51cd74a23 100644
--- a/src/testing/testing_api_loop.c
+++ b/src/testing/testing_api_loop.c
@@ -570,7 +570,7 @@ struct MainContext
* respective handler by writing to the trigger pipe.
*/
static void
-sighandler_child_death ()
+sighandler_child_death (void)
{
static char c;
int old_errno = errno; /* back-up errno */
@@ -591,24 +591,31 @@ sighandler_child_death ()
* all the commands to be run, and a closure for it.
* @param keys the exchange's keys.
* @param compat protocol compatibility information.
+ * @param ec error code, #TALER_EC_NONE on success
+ * @param http_status status returned by /keys, #MHD_HTTP_OK on success
+ * @param full_reply JSON body of /keys request, NULL if reply was not in JSON
*/
void
TALER_TESTING_cert_cb (void *cls,
const struct TALER_EXCHANGE_Keys *keys,
- enum TALER_EXCHANGE_VersionCompatibility compat)
+ enum TALER_EXCHANGE_VersionCompatibility compat,
+ enum TALER_ErrorCode ec,
+ unsigned int http_status,
+ const json_t *full_reply)
{
struct MainContext *main_ctx = cls;
struct TALER_TESTING_Interpreter *is = main_ctx->is;
(void) compat;
+ (void) full_reply;
if (NULL == keys)
{
if (GNUNET_NO == is->working)
{
- GNUNET_log
- (GNUNET_ERROR_TYPE_WARNING,
- "Got NULL response for /keys"
- " during startup, retrying!\n");
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ "Got NULL response for /keys during startup (%u/%d), retrying!\n",
+ http_status,
+ (int) ec);
TALER_EXCHANGE_disconnect (is->exchange);
GNUNET_assert
(NULL != (is->exchange = TALER_EXCHANGE_connect
@@ -620,10 +627,12 @@ TALER_TESTING_cert_cb (void *cls,
return;
}
else
- GNUNET_log
- (GNUNET_ERROR_TYPE_ERROR,
- "Got NULL response for /keys"
- " during execution!\n");
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Got NULL response for /keys during execution (%u/%d)!\n",
+ http_status,
+ (int) ec);
+ }
}
else
{