return signed error message with HTTP_GONE status if denomination is not currently valid for specified operation (#6889)

This commit is contained in:
Christian Grothoff 2021-05-25 21:34:18 +02:00
parent 0d1ab614c0
commit 068068f40f
No known key found for this signature in database
GPG Key ID: 939E6BE1E29FC3CC
9 changed files with 171 additions and 53 deletions

View File

@ -443,35 +443,39 @@ TEH_handler_deposit (struct MHD_Connection *connection,
return mret;
}
now = GNUNET_TIME_absolute_get ();
(void) GNUNET_TIME_round_abs (&now);
if (now.abs_value_us >= dk->meta.expire_deposit.abs_value_us)
{
/* This denomination is past the expiration time for deposits */
GNUNET_JSON_parse_free (spec);
return TALER_MHD_reply_with_error (
return TEH_RESPONSE_reply_expired_denom_pub_hash (
connection,
MHD_HTTP_GONE,
&deposit.coin.denom_pub_hash,
now,
TALER_EC_EXCHANGE_GENERIC_DENOMINATION_EXPIRED,
NULL);
"DEPOSIT");
}
if (now.abs_value_us < dk->meta.start.abs_value_us)
{
/* This denomination is not yet valid */
GNUNET_JSON_parse_free (spec);
return TALER_MHD_reply_with_error (
return TEH_RESPONSE_reply_expired_denom_pub_hash (
connection,
MHD_HTTP_PRECONDITION_FAILED,
&deposit.coin.denom_pub_hash,
now,
TALER_EC_EXCHANGE_GENERIC_DENOMINATION_VALIDITY_IN_FUTURE,
NULL);
"DEPOSIT");
}
if (dk->recoup_possible)
{
/* This denomination has been revoked */
GNUNET_JSON_parse_free (spec);
return TALER_MHD_reply_with_error (
return TEH_RESPONSE_reply_expired_denom_pub_hash (
connection,
MHD_HTTP_GONE,
&deposit.coin.denom_pub_hash,
now,
TALER_EC_EXCHANGE_GENERIC_DENOMINATION_REVOKED,
NULL);
"DEPOSIT");
}
deposit.deposit_fee = dk->meta.fee_deposit;

View File

@ -476,23 +476,26 @@ check_for_denomination_key (struct MHD_Connection *connection,
if (NULL == dk)
return mret;
now = GNUNET_TIME_absolute_get ();
(void) GNUNET_TIME_round_abs (&now);
if (now.abs_value_us >= dk->meta.expire_legal.abs_value_us)
{
/* Way too late now, even zombies have expired */
return TALER_MHD_reply_with_error (
return TEH_RESPONSE_reply_expired_denom_pub_hash (
connection,
MHD_HTTP_GONE,
&rmc->refresh_session.coin.denom_pub_hash,
now,
TALER_EC_EXCHANGE_GENERIC_DENOMINATION_EXPIRED,
NULL);
"MELT");
}
if (now.abs_value_us < dk->meta.start.abs_value_us)
{
/* This denomination is not yet valid */
return TALER_MHD_reply_with_error (
return TEH_RESPONSE_reply_expired_denom_pub_hash (
connection,
MHD_HTTP_PRECONDITION_FAILED,
&rmc->refresh_session.coin.denom_pub_hash,
now,
TALER_EC_EXCHANGE_GENERIC_DENOMINATION_VALIDITY_IN_FUTURE,
NULL);
"MELT");
}
if (now.abs_value_us >= dk->meta.expire_deposit.abs_value_us)
{
@ -524,11 +527,12 @@ check_for_denomination_key (struct MHD_Connection *connection,
if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs)
{
/* We never saw this coin before, so _this_ justification is not OK */
return TALER_MHD_reply_with_error (
return TEH_RESPONSE_reply_expired_denom_pub_hash (
connection,
MHD_HTTP_GONE,
&rmc->refresh_session.coin.denom_pub_hash,
now,
TALER_EC_EXCHANGE_GENERIC_DENOMINATION_EXPIRED,
NULL);
"MELT");
}
else
{

View File

@ -373,32 +373,36 @@ verify_and_execute_recoup (struct MHD_Connection *connection,
if (NULL == dk)
return mret;
now = GNUNET_TIME_absolute_get ();
(void) GNUNET_TIME_round_abs (&now);
if (now.abs_value_us >= dk->meta.expire_deposit.abs_value_us)
{
/* This denomination is past the expiration time for recoup */
return TALER_MHD_reply_with_error (
return TEH_RESPONSE_reply_expired_denom_pub_hash (
connection,
MHD_HTTP_GONE,
&coin->denom_pub_hash,
now,
TALER_EC_EXCHANGE_GENERIC_DENOMINATION_EXPIRED,
NULL);
"RECOUP");
}
if (now.abs_value_us < dk->meta.start.abs_value_us)
{
/* This denomination is not yet valid */
return TALER_MHD_reply_with_error (
return TEH_RESPONSE_reply_expired_denom_pub_hash (
connection,
MHD_HTTP_PRECONDITION_FAILED,
&coin->denom_pub_hash,
now,
TALER_EC_EXCHANGE_GENERIC_DENOMINATION_VALIDITY_IN_FUTURE,
NULL);
"RECOUP");
}
if (! dk->recoup_possible)
{
/* This denomination is not eligible for recoup */
return TALER_MHD_reply_with_error (
return TEH_RESPONSE_reply_expired_denom_pub_hash (
connection,
MHD_HTTP_NOT_FOUND,
&coin->denom_pub_hash,
now,
TALER_EC_EXCHANGE_RECOUP_NOT_ELIGIBLE,
NULL);
"RECOUP");
}
pc.value = dk->meta.value;

View File

@ -558,6 +558,7 @@ resolve_refreshes_reveal_denominations (struct MHD_Connection *connection,
}
/* Parse denomination key hashes */
now = GNUNET_TIME_absolute_get ();
(void) GNUNET_TIME_round_abs (&now);
for (unsigned int i = 0; i<num_fresh_coins; i++)
{
struct GNUNET_JSON_Specification spec[] = {
@ -586,20 +587,22 @@ resolve_refreshes_reveal_denominations (struct MHD_Connection *connection,
if (now.abs_value_us >= dks[i]->meta.expire_withdraw.abs_value_us)
{
/* This denomination is past the expiration time for withdraws */
return TALER_MHD_reply_with_error (
return TEH_RESPONSE_reply_expired_denom_pub_hash (
connection,
MHD_HTTP_GONE,
&dk_h[i],
now,
TALER_EC_EXCHANGE_GENERIC_DENOMINATION_EXPIRED,
NULL);
"REVEAL");
}
if (now.abs_value_us < dks[i]->meta.start.abs_value_us)
{
/* This denomination is not yet valid */
return TALER_MHD_reply_with_error (
return TEH_RESPONSE_reply_expired_denom_pub_hash (
connection,
MHD_HTTP_PRECONDITION_FAILED,
&dk_h[i],
now,
TALER_EC_EXCHANGE_GENERIC_DENOMINATION_VALIDITY_IN_FUTURE,
NULL);
"REVEAL");
}
if (dks[i]->recoup_possible)
{

View File

@ -461,17 +461,6 @@ verify_and_execute_refund (struct MHD_Connection *connection,
GNUNET_break (0);
return mret;
}
if (GNUNET_TIME_absolute_get ().abs_value_us >=
dk->meta.expire_deposit.abs_value_us)
{
/* This denomination is past the expiration time for deposits, and thus refunds */
return TALER_MHD_reply_with_error (
connection,
MHD_HTTP_GONE,
TALER_EC_EXCHANGE_GENERIC_DENOMINATION_EXPIRED,
NULL);
}
refund->details.refund_fee = dk->meta.fee_refund;
}

View File

@ -466,6 +466,58 @@ TEH_RESPONSE_reply_unknown_denom_pub_hash (
}
MHD_RESULT
TEH_RESPONSE_reply_expired_denom_pub_hash (
struct MHD_Connection *connection,
const struct GNUNET_HashCode *dph,
struct GNUNET_TIME_Absolute now,
enum TALER_ErrorCode ec,
const char *oper)
{
struct TALER_ExchangePublicKeyP epub;
struct TALER_ExchangeSignatureP esig;
enum TALER_ErrorCode ecr;
struct TALER_DenominationExpiredAffirmationPS dua = {
.purpose.size = htonl (sizeof (dua)),
.purpose.purpose = htonl (
TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_EXPIRED),
.timestamp = GNUNET_TIME_absolute_hton (now),
.h_denom_pub = *dph,
};
strncpy (dua.operation,
oper,
sizeof (dua.operation));
ecr = TEH_keys_exchange_sign (&dua,
&epub,
&esig);
if (TALER_EC_NONE != ecr)
{
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_GONE,
"{s:I,s:s,s:o,s:o,s:o,s:o}",
"code",
ec,
"oper",
oper,
"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

@ -62,6 +62,26 @@ TEH_RESPONSE_reply_unknown_denom_pub_hash (
const struct GNUNET_HashCode *dph);
/**
* Send assertion that the given denomination key hash
* is not usable (typically expired) at this time.
*
* @param connection connection to the client
* @param dph denomination public key hash
* @param now timestamp to use
* @param ec error code to use
* @param name of the operation that is not allowed at this time
* @return MHD result code
*/
MHD_RESULT
TEH_RESPONSE_reply_expired_denom_pub_hash (
struct MHD_Connection *connection,
const struct GNUNET_HashCode *dph,
struct GNUNET_TIME_Absolute now,
enum TALER_ErrorCode ec,
const char *oper);
/**
* Send proof that a request is invalid to client because of
* insufficient funds. This function will create a message with all

View File

@ -391,35 +391,39 @@ TEH_handler_withdraw (const struct TEH_RequestHandler *rh,
return mret;
}
now = GNUNET_TIME_absolute_get ();
(void) GNUNET_TIME_round_abs (&now);
if (now.abs_value_us >= dk->meta.expire_withdraw.abs_value_us)
{
/* This denomination is past the expiration time for withdraws */
GNUNET_JSON_parse_free (spec);
return TALER_MHD_reply_with_error (
return TEH_RESPONSE_reply_expired_denom_pub_hash (
connection,
MHD_HTTP_GONE,
&wc.denom_pub_hash,
now,
TALER_EC_EXCHANGE_GENERIC_DENOMINATION_EXPIRED,
NULL);
"WITHDRAW");
}
if (now.abs_value_us < dk->meta.start.abs_value_us)
{
/* This denomination is not yet valid */
GNUNET_JSON_parse_free (spec);
return TALER_MHD_reply_with_error (
return TEH_RESPONSE_reply_expired_denom_pub_hash (
connection,
MHD_HTTP_PRECONDITION_FAILED,
&wc.denom_pub_hash,
now,
TALER_EC_EXCHANGE_GENERIC_DENOMINATION_VALIDITY_IN_FUTURE,
NULL);
"WITHDRAW");
}
if (dk->recoup_possible)
{
/* This denomination has been revoked */
GNUNET_JSON_parse_free (spec);
return TALER_MHD_reply_with_error (
return TEH_RESPONSE_reply_expired_denom_pub_hash (
connection,
MHD_HTTP_GONE,
&wc.denom_pub_hash,
now,
TALER_EC_EXCHANGE_GENERIC_DENOMINATION_REVOKED,
NULL);
"WITHDRAW");
}
}

View File

@ -161,6 +161,13 @@
#define TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_UNKNOWN 1042
/**
* Signature where the Exchange confirms that it does not consider a denomination valid for the given operation
* at this time.
*/
#define TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_EXPIRED 1043
/**********************/
/* Auditor signatures */
/**********************/
@ -1543,6 +1550,37 @@ struct TALER_DenominationUnknownAffirmationPS
};
/**
* Response by which the exchange affirms that it does not
* currently consider the given denomination to be valid
* for the requested operation.
*/
struct TALER_DenominationExpiredAffirmationPS
{
/**
* Purpose is #TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_EXPIRED
*/
struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
/**
* When did the exchange sign this message.
*/
struct GNUNET_TIME_AbsoluteNBO timestamp;
/**
* Name of the operation that is not allowed at this time. Might NOT be 0-terminated, but is padded with 0s.
*/
char operation[8];
/**
* 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.