return signed 404 statements for unknown denomination key hashes (#6889)

This commit is contained in:
Christian Grothoff 2021-05-25 20:52:58 +02:00
parent b2b1f88ab6
commit 0d1ab614c0
No known key found for this signature in database
GPG Key ID: 939E6BE1E29FC3CC
11 changed files with 137 additions and 78 deletions

View File

@ -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)

View File

@ -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;

View File

@ -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

View File

@ -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)
{

View File

@ -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)
{

View File

@ -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)
{

View File

@ -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 >=

View File

@ -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

View File

@ -48,6 +48,20 @@ TEH_RESPONSE_compile_reserve_history (
struct TALER_Amount *balance);
/**
* 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

View File

@ -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)

View File

@ -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 */
@ -1514,6 +1519,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.