summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/exchange/taler-exchange-httpd_deposit.c22
-rw-r--r--src/exchange/taler-exchange-httpd_melt.c22
-rw-r--r--src/exchange/taler-exchange-httpd_recoup.c22
-rw-r--r--src/exchange/taler-exchange-httpd_refreshes_reveal.c15
-rw-r--r--src/exchange/taler-exchange-httpd_refund.c11
-rw-r--r--src/exchange/taler-exchange-httpd_responses.c52
-rw-r--r--src/exchange/taler-exchange-httpd_responses.h20
-rw-r--r--src/exchange/taler-exchange-httpd_withdraw.c22
-rw-r--r--src/include/taler_signatures.h38
9 files changed, 171 insertions, 53 deletions
diff --git a/src/exchange/taler-exchange-httpd_deposit.c b/src/exchange/taler-exchange-httpd_deposit.c
index 44c3d14c..f0f6784f 100644
--- a/src/exchange/taler-exchange-httpd_deposit.c
+++ b/src/exchange/taler-exchange-httpd_deposit.c
@@ -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;
diff --git a/src/exchange/taler-exchange-httpd_melt.c b/src/exchange/taler-exchange-httpd_melt.c
index 5e9ae7f0..7276f9a6 100644
--- a/src/exchange/taler-exchange-httpd_melt.c
+++ b/src/exchange/taler-exchange-httpd_melt.c
@@ -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
{
diff --git a/src/exchange/taler-exchange-httpd_recoup.c b/src/exchange/taler-exchange-httpd_recoup.c
index c1aadb83..cd12be0d 100644
--- a/src/exchange/taler-exchange-httpd_recoup.c
+++ b/src/exchange/taler-exchange-httpd_recoup.c
@@ -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;
diff --git a/src/exchange/taler-exchange-httpd_refreshes_reveal.c b/src/exchange/taler-exchange-httpd_refreshes_reveal.c
index b6b1849c..d915aefc 100644
--- a/src/exchange/taler-exchange-httpd_refreshes_reveal.c
+++ b/src/exchange/taler-exchange-httpd_refreshes_reveal.c
@@ -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)
{
diff --git a/src/exchange/taler-exchange-httpd_refund.c b/src/exchange/taler-exchange-httpd_refund.c
index 56d987d9..d0865dd8 100644
--- a/src/exchange/taler-exchange-httpd_refund.c
+++ b/src/exchange/taler-exchange-httpd_refund.c
@@ -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;
}
diff --git a/src/exchange/taler-exchange-httpd_responses.c b/src/exchange/taler-exchange-httpd_responses.c
index 23407474..4bb3ffd4 100644
--- a/src/exchange/taler-exchange-httpd_responses.c
+++ b/src/exchange/taler-exchange-httpd_responses.c
@@ -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
diff --git a/src/exchange/taler-exchange-httpd_responses.h b/src/exchange/taler-exchange-httpd_responses.h
index 7182629e..d4acd213 100644
--- a/src/exchange/taler-exchange-httpd_responses.h
+++ b/src/exchange/taler-exchange-httpd_responses.h
@@ -63,6 +63,26 @@ TEH_RESPONSE_reply_unknown_denom_pub_hash (
/**
+ * 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
* 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 5833fcf4..d0216c4c 100644
--- a/src/exchange/taler-exchange-httpd_withdraw.c
+++ b/src/exchange/taler-exchange-httpd_withdraw.c
@@ -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");
}
}
diff --git a/src/include/taler_signatures.h b/src/include/taler_signatures.h
index 1a64d52f..6ed71153 100644
--- a/src/include/taler_signatures.h
+++ b/src/include/taler_signatures.h
@@ -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 */
/**********************/
@@ -1544,6 +1551,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.
*/