aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2021-05-25 20:52:58 +0200
committerChristian Grothoff <christian@grothoff.org>2021-05-25 20:52:58 +0200
commit0d1ab614c06f60f79de75a0f2ec30c33a69820dd (patch)
tree3776ec42d7bd6ed64b3b71888b5a3fbafcb213ea
parentb2b1f88ab617ee9a01ac263b8b1c679f24277076 (diff)
return signed 404 statements for unknown denomination key hashes (#6889)
-rw-r--r--src/exchange/taler-exchange-httpd_deposit.c13
-rw-r--r--src/exchange/taler-exchange-httpd_keys.c22
-rw-r--r--src/exchange/taler-exchange-httpd_keys.h16
-rw-r--r--src/exchange/taler-exchange-httpd_melt.c15
-rw-r--r--src/exchange/taler-exchange-httpd_recoup.c17
-rw-r--r--src/exchange/taler-exchange-httpd_refreshes_reveal.c14
-rw-r--r--src/exchange/taler-exchange-httpd_refund.c12
-rw-r--r--src/exchange/taler-exchange-httpd_responses.c51
-rw-r--r--src/exchange/taler-exchange-httpd_responses.h14
-rw-r--r--src/exchange/taler-exchange-httpd_withdraw.c12
-rw-r--r--src/include/taler_signatures.h29
11 files changed, 137 insertions, 78 deletions
diff --git a/src/exchange/taler-exchange-httpd_deposit.c b/src/exchange/taler-exchange-httpd_deposit.c
index 2f7d49c93..44c3d14cf 100644
--- a/src/exchange/taler-exchange-httpd_deposit.c
+++ b/src/exchange/taler-exchange-httpd_deposit.c
@@ -431,21 +431,16 @@ TEH_handler_deposit (struct MHD_Connection *connection,
/* check denomination exists and is valid */
{
struct TEH_DenominationKey *dk;
- enum TALER_ErrorCode ec;
- unsigned int hc;
struct GNUNET_TIME_Absolute now;
+ MHD_RESULT mret;
dk = TEH_keys_denomination_by_hash (&deposit.coin.denom_pub_hash,
- &ec,
- &hc);
+ connection,
+ &mret);
if (NULL == dk)
{
- TALER_LOG_DEBUG ("Unknown denomination key in /deposit request\n");
GNUNET_JSON_parse_free (spec);
- return TALER_MHD_reply_with_error (connection,
- hc,
- ec,
- NULL);
+ return mret;
}
now = GNUNET_TIME_absolute_get ();
if (now.abs_value_us >= dk->meta.expire_deposit.abs_value_us)
diff --git a/src/exchange/taler-exchange-httpd_keys.c b/src/exchange/taler-exchange-httpd_keys.c
index 579cb6b36..a0d359e32 100644
--- a/src/exchange/taler-exchange-httpd_keys.c
+++ b/src/exchange/taler-exchange-httpd_keys.c
@@ -1801,30 +1801,32 @@ TEH_keys_get_state (void)
struct TEH_DenominationKey *
TEH_keys_denomination_by_hash (const struct GNUNET_HashCode *h_denom_pub,
- enum TALER_ErrorCode *ec,
- unsigned int *hc)
+ struct MHD_Connection *conn,
+ MHD_RESULT *mret)
{
struct TEH_KeyStateHandle *ksh;
ksh = TEH_keys_get_state ();
if (NULL == ksh)
{
- *hc = MHD_HTTP_INTERNAL_SERVER_ERROR;
- *ec = TALER_EC_EXCHANGE_GENERIC_KEYS_MISSING;
+ *mret = TALER_MHD_reply_with_error (conn,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_EXCHANGE_GENERIC_KEYS_MISSING,
+ NULL);
return NULL;
}
return TEH_keys_denomination_by_hash2 (ksh,
h_denom_pub,
- ec,
- hc);
+ conn,
+ mret);
}
struct TEH_DenominationKey *
TEH_keys_denomination_by_hash2 (struct TEH_KeyStateHandle *ksh,
const struct GNUNET_HashCode *h_denom_pub,
- enum TALER_ErrorCode *ec,
- unsigned int *hc)
+ struct MHD_Connection *conn,
+ MHD_RESULT *mret)
{
struct TEH_DenominationKey *dk;
@@ -1832,8 +1834,8 @@ TEH_keys_denomination_by_hash2 (struct TEH_KeyStateHandle *ksh,
h_denom_pub);
if (NULL == dk)
{
- *hc = MHD_HTTP_NOT_FOUND;
- *ec = TALER_EC_EXCHANGE_GENERIC_DENOMINATION_KEY_UNKNOWN;
+ *mret = TEH_RESPONSE_reply_unknown_denom_pub_hash (conn,
+ h_denom_pub);
return NULL;
}
return dk;
diff --git a/src/exchange/taler-exchange-httpd_keys.h b/src/exchange/taler-exchange-httpd_keys.h
index eeb4bdd2d..c13e97882 100644
--- a/src/exchange/taler-exchange-httpd_keys.h
+++ b/src/exchange/taler-exchange-httpd_keys.h
@@ -129,15 +129,15 @@ TEH_keys_update_states (void);
* key state is resolved.
*
* @param h_denom_pub hash of denomination public key
- * @param[out] ec set to the error code, in case the operation failed
- * @param[out] hc set to the HTTP status code to use
+ * @param[in,out] connection used to return status message if NULL is returned
+ * @param[out] mret set to the MHD status if NULL is returned
* @return the denomination key issue,
* or NULL if @a h_denom_pub could not be found
*/
struct TEH_DenominationKey *
TEH_keys_denomination_by_hash (const struct GNUNET_HashCode *h_denom_pub,
- enum TALER_ErrorCode *ec,
- unsigned int *hc);
+ struct MHD_Connection *conn,
+ MHD_RESULT *mret);
/**
@@ -148,16 +148,16 @@ TEH_keys_denomination_by_hash (const struct GNUNET_HashCode *h_denom_pub,
*
* @param ksh key state state to look in
* @param h_denom_pub hash of denomination public key
- * @param[out] ec set to the error code, in case the operation failed
- * @param[out] hc set to the HTTP status code to use
+ * @param[in,out] connection used to return status message if NULL is returned
+ * @param[out] mret set to the MHD status if NULL is returned
* @return the denomination key issue,
* or NULL if @a h_denom_pub could not be found
*/
struct TEH_DenominationKey *
TEH_keys_denomination_by_hash2 (struct TEH_KeyStateHandle *ksh,
const struct GNUNET_HashCode *h_denom_pub,
- enum TALER_ErrorCode *ec,
- unsigned int *hc);
+ struct MHD_Connection *conn,
+ MHD_RESULT *mret);
/**
* Request to sign @a msg using the public key corresponding to
diff --git a/src/exchange/taler-exchange-httpd_melt.c b/src/exchange/taler-exchange-httpd_melt.c
index 143e3f3ac..5e9ae7f0d 100644
--- a/src/exchange/taler-exchange-httpd_melt.c
+++ b/src/exchange/taler-exchange-httpd_melt.c
@@ -466,22 +466,15 @@ check_for_denomination_key (struct MHD_Connection *connection,
/* Baseline: check if deposits/refreshs are generally
simply still allowed for this denomination */
struct TEH_DenominationKey *dk;
- unsigned int hc;
- enum TALER_ErrorCode ec;
struct GNUNET_TIME_Absolute now;
+ MHD_RESULT mret;
dk = TEH_keys_denomination_by_hash (
&rmc->refresh_session.coin.denom_pub_hash,
- &ec,
- &hc);
+ connection,
+ &mret);
if (NULL == dk)
- {
- return TALER_MHD_reply_with_error (
- connection,
- MHD_HTTP_NOT_FOUND,
- TALER_EC_EXCHANGE_GENERIC_DENOMINATION_KEY_UNKNOWN,
- NULL);
- }
+ return mret;
now = GNUNET_TIME_absolute_get ();
if (now.abs_value_us >= dk->meta.expire_legal.abs_value_us)
{
diff --git a/src/exchange/taler-exchange-httpd_recoup.c b/src/exchange/taler-exchange-httpd_recoup.c
index f63bf0722..c1aadb83e 100644
--- a/src/exchange/taler-exchange-httpd_recoup.c
+++ b/src/exchange/taler-exchange-httpd_recoup.c
@@ -363,24 +363,15 @@ verify_and_execute_recoup (struct MHD_Connection *connection,
struct GNUNET_HashCode c_hash;
void *coin_ev;
size_t coin_ev_size;
- enum TALER_ErrorCode ec;
- unsigned int hc;
+ MHD_RESULT mret;
struct GNUNET_TIME_Absolute now;
/* check denomination exists and is in recoup mode */
dk = TEH_keys_denomination_by_hash (&coin->denom_pub_hash,
- &ec,
- &hc);
+ connection,
+ &mret);
if (NULL == dk)
- {
- TALER_LOG_WARNING (
- "Denomination key in recoup request not in recoup mode\n");
- return TALER_MHD_reply_with_error (connection,
- hc,
- ec,
- NULL);
- }
-
+ return mret;
now = GNUNET_TIME_absolute_get ();
if (now.abs_value_us >= dk->meta.expire_deposit.abs_value_us)
{
diff --git a/src/exchange/taler-exchange-httpd_refreshes_reveal.c b/src/exchange/taler-exchange-httpd_refreshes_reveal.c
index d7ec02c88..b6b1849c7 100644
--- a/src/exchange/taler-exchange-httpd_refreshes_reveal.c
+++ b/src/exchange/taler-exchange-httpd_refreshes_reveal.c
@@ -565,8 +565,7 @@ resolve_refreshes_reveal_denominations (struct MHD_Connection *connection,
&dk_h[i]),
GNUNET_JSON_spec_end ()
};
- unsigned int hc;
- enum TALER_ErrorCode ec;
+ MHD_RESULT mret;
res = TALER_MHD_parse_json_array (connection,
new_denoms_h_json,
@@ -579,15 +578,10 @@ resolve_refreshes_reveal_denominations (struct MHD_Connection *connection,
}
dks[i] = TEH_keys_denomination_by_hash2 (ksh,
&dk_h[i],
- &ec,
- &hc);
+ connection,
+ &mret);
if (NULL == dks[i])
- {
- return TALER_MHD_reply_with_error (connection,
- hc,
- ec,
- NULL);
- }
+ return mret;
if (now.abs_value_us >= dks[i]->meta.expire_withdraw.abs_value_us)
{
diff --git a/src/exchange/taler-exchange-httpd_refund.c b/src/exchange/taler-exchange-httpd_refund.c
index ace6e28f4..56d987d94 100644
--- a/src/exchange/taler-exchange-httpd_refund.c
+++ b/src/exchange/taler-exchange-httpd_refund.c
@@ -449,21 +449,17 @@ verify_and_execute_refund (struct MHD_Connection *connection,
{
/* Obtain information about the coin's denomination! */
struct TEH_DenominationKey *dk;
- unsigned int hc;
- enum TALER_ErrorCode ec;
+ MHD_RESULT mret;
dk = TEH_keys_denomination_by_hash (&denom_hash,
- &ec,
- &hc);
+ connection,
+ &mret);
if (NULL == dk)
{
/* DKI not found, but we do have a coin with this DK in our database;
not good... */
GNUNET_break (0);
- return TALER_MHD_reply_with_error (connection,
- hc,
- ec,
- NULL);
+ return mret;
}
if (GNUNET_TIME_absolute_get ().abs_value_us >=
diff --git a/src/exchange/taler-exchange-httpd_responses.c b/src/exchange/taler-exchange-httpd_responses.c
index ea9729af0..234074747 100644
--- a/src/exchange/taler-exchange-httpd_responses.c
+++ b/src/exchange/taler-exchange-httpd_responses.c
@@ -1,6 +1,6 @@
/*
This file is part of TALER
- Copyright (C) 2014-2017 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 Affero General Public License as published by the Free Software
@@ -417,6 +417,55 @@ TEH_RESPONSE_compile_transaction_history (
}
+MHD_RESULT
+TEH_RESPONSE_reply_unknown_denom_pub_hash (
+ struct MHD_Connection *connection,
+ const struct GNUNET_HashCode *dph)
+{
+ struct TALER_ExchangePublicKeyP epub;
+ struct TALER_ExchangeSignatureP esig;
+ struct GNUNET_TIME_Absolute now;
+ enum TALER_ErrorCode ec;
+
+ now = GNUNET_TIME_absolute_get ();
+ GNUNET_TIME_round_abs (&now);
+ {
+ struct TALER_DenominationUnknownAffirmationPS dua = {
+ .purpose.size = htonl (sizeof (dua)),
+ .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_UNKNOWN),
+ .timestamp = GNUNET_TIME_absolute_hton (now),
+ .h_denom_pub = *dph,
+ };
+
+ ec = TEH_keys_exchange_sign (&dua,
+ &epub,
+ &esig);
+ }
+ if (TALER_EC_NONE != ec)
+ {
+ GNUNET_break (0);
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ ec,
+ NULL);
+ }
+ return TALER_MHD_reply_json_pack (
+ connection,
+ MHD_HTTP_NOT_FOUND,
+ "{s:I,s:o,s:o,s:o,s:o}",
+ "code",
+ TALER_EC_EXCHANGE_GENERIC_DENOMINATION_KEY_UNKNOWN,
+ "timestamp",
+ GNUNET_JSON_from_time_abs (now),
+ "exchange_pub",
+ GNUNET_JSON_from_data_auto (&epub),
+ "exchange_sig",
+ GNUNET_JSON_from_data_auto (&esig),
+ "h_denom_pub",
+ GNUNET_JSON_from_data_auto (dph));
+}
+
+
/**
* Send proof that a request is invalid to client because of
* insufficient funds. This function will create a message with all
diff --git a/src/exchange/taler-exchange-httpd_responses.h b/src/exchange/taler-exchange-httpd_responses.h
index 6486b5d93..7182629eb 100644
--- a/src/exchange/taler-exchange-httpd_responses.h
+++ b/src/exchange/taler-exchange-httpd_responses.h
@@ -49,6 +49,20 @@ TEH_RESPONSE_compile_reserve_history (
/**
+ * Send assertion that the given denomination key hash
+ * is unknown to us at this time.
+ *
+ * @param connection connection to the client
+ * @param dph denomination public key hash
+ * @return MHD result code
+ */
+MHD_RESULT
+TEH_RESPONSE_reply_unknown_denom_pub_hash (
+ struct MHD_Connection *connection,
+ const struct GNUNET_HashCode *dph);
+
+
+/**
* Send proof that a request is invalid to client because of
* insufficient funds. This function will create a message with all
* of the operations affecting the coin that demonstrate that the coin
diff --git a/src/exchange/taler-exchange-httpd_withdraw.c b/src/exchange/taler-exchange-httpd_withdraw.c
index 68a8e5fd0..5833fcf48 100644
--- a/src/exchange/taler-exchange-httpd_withdraw.c
+++ b/src/exchange/taler-exchange-httpd_withdraw.c
@@ -379,20 +379,16 @@ TEH_handler_withdraw (const struct TEH_RequestHandler *rh,
return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES;
}
{
- unsigned int hc;
- enum TALER_ErrorCode ec;
+ MHD_RESULT mret;
struct GNUNET_TIME_Absolute now;
dk = TEH_keys_denomination_by_hash (&wc.denom_pub_hash,
- &ec,
- &hc);
+ connection,
+ &mret);
if (NULL == dk)
{
GNUNET_JSON_parse_free (spec);
- return TALER_MHD_reply_with_error (connection,
- hc,
- ec,
- NULL);
+ return mret;
}
now = GNUNET_TIME_absolute_get ();
if (now.abs_value_us >= dk->meta.expire_withdraw.abs_value_us)
diff --git a/src/include/taler_signatures.h b/src/include/taler_signatures.h
index f80a71d7c..1a64d52f6 100644
--- a/src/include/taler_signatures.h
+++ b/src/include/taler_signatures.h
@@ -155,6 +155,11 @@
*/
#define TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_REFRESH 1041
+/**
+ * Signature where the Exchange confirms that it does not know a denomination (hash).
+ */
+#define TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_UNKNOWN 1042
+
/**********************/
/* Auditor signatures */
@@ -1515,6 +1520,30 @@ struct TALER_RecoupRefreshConfirmationPS
/**
+ * Response by which the exchange affirms that it does not
+ * currently know a denomination by the given hash.
+ */
+struct TALER_DenominationUnknownAffirmationPS
+{
+
+ /**
+ * Purpose is #TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_UNKNOWN
+ */
+ struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
+
+ /**
+ * When did the exchange sign this message.
+ */
+ struct GNUNET_TIME_AbsoluteNBO timestamp;
+
+ /**
+ * Hash of the public denomination key we do not know.
+ */
+ struct GNUNET_HashCode h_denom_pub;
+};
+
+
+/**
* Response by which the exchange affirms that it has
* closed a reserve and send back the funds.
*/