aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2019-11-01 15:36:14 +0100
committerChristian Grothoff <christian@grothoff.org>2019-11-01 15:36:14 +0100
commit375a47d5023c9eccf45d8142a0568824eb4ed7ab (patch)
treedab8a343adfd77a8ddcc6a579cecbe918cba095a
parent40d9674856dd77a98053f0451d76791de146551f (diff)
downloadexchange-375a47d5023c9eccf45d8142a0568824eb4ed7ab.tar.gz
exchange-375a47d5023c9eccf45d8142a0568824eb4ed7ab.zip
improve status codes returned in case of denomination key troubles
-rw-r--r--src/exchange/taler-exchange-httpd_deposit.c23
-rw-r--r--src/exchange/taler-exchange-httpd_keystate.c50
-rw-r--r--src/exchange/taler-exchange-httpd_keystate.h6
-rw-r--r--src/exchange/taler-exchange-httpd_payback.c12
-rw-r--r--src/exchange/taler-exchange-httpd_refresh_melt.c20
-rw-r--r--src/exchange/taler-exchange-httpd_refresh_reveal.c12
-rw-r--r--src/exchange/taler-exchange-httpd_refund.c12
-rw-r--r--src/exchange/taler-exchange-httpd_reserve_withdraw.c12
-rw-r--r--src/exchange/taler-exchange-httpd_responses.c20
-rw-r--r--src/exchange/taler-exchange-httpd_responses.h14
-rw-r--r--src/include/taler_error_codes.h76
11 files changed, 224 insertions, 33 deletions
diff --git a/src/exchange/taler-exchange-httpd_deposit.c b/src/exchange/taler-exchange-httpd_deposit.c
index e1b30272c..fd36bb4a0 100644
--- a/src/exchange/taler-exchange-httpd_deposit.c
+++ b/src/exchange/taler-exchange-httpd_deposit.c
@@ -250,6 +250,8 @@ verify_and_execute_deposit (struct MHD_Connection *connection,
250 struct DepositContext dc; 250 struct DepositContext dc;
251 struct TEH_KS_StateHandle *mks; 251 struct TEH_KS_StateHandle *mks;
252 const struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki; 252 const struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki;
253 enum TALER_ErrorCode ec;
254 unsigned int hc;
253 255
254 /* check signature */ 256 /* check signature */
255 dr.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_DEPOSIT); 257 dr.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_DEPOSIT);
@@ -287,12 +289,15 @@ verify_and_execute_deposit (struct MHD_Connection *connection,
287 } 289 }
288 dki = TEH_KS_denomination_key_lookup_by_hash (mks, 290 dki = TEH_KS_denomination_key_lookup_by_hash (mks,
289 &deposit->coin.denom_pub_hash, 291 &deposit->coin.denom_pub_hash,
290 TEH_KS_DKU_DEPOSIT); 292 TEH_KS_DKU_DEPOSIT,
293 &ec,
294 &hc);
291 if (NULL == dki) 295 if (NULL == dki)
292 { 296 {
293 TEH_KS_release (mks); 297 TEH_KS_release (mks);
294 return TEH_RESPONSE_reply_internal_db_error (connection, 298 return TEH_RESPONSE_reply_with_error (connection,
295 TALER_EC_DEPOSIT_DB_DENOMINATION_KEY_UNKNOWN); 299 ec,
300 hc);
296 } 301 }
297 TALER_amount_ntoh (&dc.value, 302 TALER_amount_ntoh (&dc.value,
298 &dki->issue.properties.value); 303 &dki->issue.properties.value);
@@ -388,6 +393,7 @@ TEH_DEPOSIT_handler_deposit (struct TEH_RequestHandler *rh,
388 json_t *wire; 393 json_t *wire;
389 char *emsg; 394 char *emsg;
390 enum TALER_ErrorCode ec; 395 enum TALER_ErrorCode ec;
396 unsigned int hc;
391 struct TALER_EXCHANGEDB_Deposit deposit; 397 struct TALER_EXCHANGEDB_Deposit deposit;
392 struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki; 398 struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki;
393 struct TEH_KS_StateHandle *key_state; 399 struct TEH_KS_StateHandle *key_state;
@@ -497,16 +503,17 @@ TEH_DEPOSIT_handler_deposit (struct TEH_RequestHandler *rh,
497 } 503 }
498 dki = TEH_KS_denomination_key_lookup_by_hash (key_state, 504 dki = TEH_KS_denomination_key_lookup_by_hash (key_state,
499 &deposit.coin.denom_pub_hash, 505 &deposit.coin.denom_pub_hash,
500 TEH_KS_DKU_DEPOSIT); 506 TEH_KS_DKU_DEPOSIT,
507 &ec,
508 &hc);
501 if (NULL == dki) 509 if (NULL == dki)
502 { 510 {
503 /* FIXME: #3887: if DK was revoked, we might want to give a 403 and not a 404! */
504 TEH_KS_release (key_state); 511 TEH_KS_release (key_state);
505 TALER_LOG_WARNING ("Unknown denomination key in /deposit request\n"); 512 TALER_LOG_WARNING ("Unknown denomination key in /deposit request\n");
506 GNUNET_JSON_parse_free (spec); 513 GNUNET_JSON_parse_free (spec);
507 return TEH_RESPONSE_reply_arg_unknown (connection, 514 return TEH_RESPONSE_reply_with_error (connection,
508 TALER_EC_DEPOSIT_DENOMINATION_KEY_UNKNOWN, 515 ec,
509 "denom_pub"); 516 hc);
510 } 517 }
511 TALER_amount_ntoh (&deposit.deposit_fee, 518 TALER_amount_ntoh (&deposit.deposit_fee,
512 &dki->issue.properties.fee_deposit); 519 &dki->issue.properties.fee_deposit);
diff --git a/src/exchange/taler-exchange-httpd_keystate.c b/src/exchange/taler-exchange-httpd_keystate.c
index ce6a856d9..bde5c7d7e 100644
--- a/src/exchange/taler-exchange-httpd_keystate.c
+++ b/src/exchange/taler-exchange-httpd_keystate.c
@@ -1954,6 +1954,8 @@ TEH_KS_acquire_ (struct GNUNET_TIME_Absolute now,
1954 * @param key_state state to look in 1954 * @param key_state state to look in
1955 * @param denom_pub_hash hash of denomination public key 1955 * @param denom_pub_hash hash of denomination public key
1956 * @param use purpose for which the key is being located 1956 * @param use purpose for which the key is being located
1957 * @param ec[out] set to the error code, in case the operation failed
1958 * @param hc[out] set to the HTTP status code to use
1957 * @return the denomination key issue, 1959 * @return the denomination key issue,
1958 * or NULL if denom_pub could not be found (or is not valid at this time for the given @a use) 1960 * or NULL if denom_pub could not be found (or is not valid at this time for the given @a use)
1959 */ 1961 */
@@ -1962,7 +1964,9 @@ TEH_KS_denomination_key_lookup_by_hash (const struct
1962 TEH_KS_StateHandle *key_state, 1964 TEH_KS_StateHandle *key_state,
1963 const struct 1965 const struct
1964 GNUNET_HashCode *denom_pub_hash, 1966 GNUNET_HashCode *denom_pub_hash,
1965 enum TEH_KS_DenominationKeyUse use) 1967 enum TEH_KS_DenominationKeyUse use,
1968 enum TALER_ErrorCode *ec,
1969 unsigned int *hc)
1966{ 1970{
1967 struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki; 1971 struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki;
1968 struct GNUNET_TIME_Absolute now; 1972 struct GNUNET_TIME_Absolute now;
@@ -1976,7 +1980,25 @@ TEH_KS_denomination_key_lookup_by_hash (const struct
1976 dki = GNUNET_CONTAINER_multihashmap_get (key_state->revoked_map, 1980 dki = GNUNET_CONTAINER_multihashmap_get (key_state->revoked_map,
1977 denom_pub_hash); 1981 denom_pub_hash);
1978 if (NULL == dki) 1982 if (NULL == dki)
1983 {
1984 *hc = MHD_HTTP_NOT_FOUND;
1985 switch (use)
1986 {
1987 case TEH_KS_DKU_PAYBACK:
1988 *ec = TALER_EC_PAYBACK_DENOMINATION_KEY_UNKNOWN;
1989 break;
1990 case TEH_KS_DKU_ZOMBIE:
1991 *ec = TALER_EC_REFRESH_PAYBACK_DENOMINATION_KEY_NOT_FOUND;
1992 break;
1993 case TEH_KS_DKU_WITHDRAW:
1994 *ec = TALER_EC_WITHDRAW_DENOMINATION_KEY_NOT_FOUND;
1995 break;
1996 case TEH_KS_DKU_DEPOSIT:
1997 *ec = TALER_EC_DEPOSIT_DENOMINATION_KEY_UNKNOWN;
1998 break;
1999 }
1979 return NULL; 2000 return NULL;
2001 }
1980 now = GNUNET_TIME_absolute_get (); 2002 now = GNUNET_TIME_absolute_get ();
1981 if (now.abs_value_us < 2003 if (now.abs_value_us <
1982 GNUNET_TIME_absolute_ntoh (dki->issue.properties.start).abs_value_us) 2004 GNUNET_TIME_absolute_ntoh (dki->issue.properties.start).abs_value_us)
@@ -1984,6 +2006,22 @@ TEH_KS_denomination_key_lookup_by_hash (const struct
1984 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 2006 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1985 "Not returning DKI for %s, as start time is in the future\n", 2007 "Not returning DKI for %s, as start time is in the future\n",
1986 GNUNET_h2s (denom_pub_hash)); 2008 GNUNET_h2s (denom_pub_hash));
2009 *hc = MHD_HTTP_PRECONDITION_FAILED;
2010 switch (use)
2011 {
2012 case TEH_KS_DKU_PAYBACK:
2013 *ec = TALER_EC_PAYBACK_DENOMINATION_VALIDITY_IN_FUTURE;
2014 break;
2015 case TEH_KS_DKU_ZOMBIE:
2016 *ec = TALER_EC_REFRESH_PAYBACK_DENOMINATION_VALIDITY_IN_FUTURE;
2017 break;
2018 case TEH_KS_DKU_WITHDRAW:
2019 *ec = TALER_EC_WITHDRAW_VALIDITY_IN_FUTURE;
2020 break;
2021 case TEH_KS_DKU_DEPOSIT:
2022 *ec = TALER_EC_DEPOSIT_DENOMINATION_VALIDITY_IN_FUTURE;
2023 break;
2024 }
1987 return NULL; 2025 return NULL;
1988 } 2026 }
1989 now = GNUNET_TIME_absolute_get (); 2027 now = GNUNET_TIME_absolute_get ();
@@ -1997,6 +2035,8 @@ TEH_KS_denomination_key_lookup_by_hash (const struct
1997 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 2035 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1998 "Not returning DKI for %s, as time to create coins has passed\n", 2036 "Not returning DKI for %s, as time to create coins has passed\n",
1999 GNUNET_h2s (denom_pub_hash)); 2037 GNUNET_h2s (denom_pub_hash));
2038 *ec = TALER_EC_WITHDRAW_VALIDITY_IN_PAST;
2039 *hc = MHD_HTTP_GONE;
2000 return NULL; 2040 return NULL;
2001 } 2041 }
2002 if (NULL == dki->denom_priv.rsa_private_key) 2042 if (NULL == dki->denom_priv.rsa_private_key)
@@ -2004,6 +2044,8 @@ TEH_KS_denomination_key_lookup_by_hash (const struct
2004 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 2044 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2005 "Not returning DKI of %s for WITHDRAW operation as we lack the private key, even though the withdraw period did not yet expire!\n", 2045 "Not returning DKI of %s for WITHDRAW operation as we lack the private key, even though the withdraw period did not yet expire!\n",
2006 GNUNET_h2s (denom_pub_hash)); 2046 GNUNET_h2s (denom_pub_hash));
2047 *ec = TALER_EC_DENOMINATION_KEY_LOST;
2048 *hc = MHD_HTTP_SERVICE_UNAVAILABLE;
2007 return NULL; 2049 return NULL;
2008 } 2050 }
2009 break; 2051 break;
@@ -2015,6 +2057,8 @@ TEH_KS_denomination_key_lookup_by_hash (const struct
2015 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 2057 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2016 "Not returning DKI for %s, as time to spend coin has passed\n", 2058 "Not returning DKI for %s, as time to spend coin has passed\n",
2017 GNUNET_h2s (denom_pub_hash)); 2059 GNUNET_h2s (denom_pub_hash));
2060 *ec = TALER_EC_DEPOSIT_DENOMINATION_EXPIRED;
2061 *hc = MHD_HTTP_GONE;
2018 return NULL; 2062 return NULL;
2019 } 2063 }
2020 break; 2064 break;
@@ -2026,6 +2070,8 @@ TEH_KS_denomination_key_lookup_by_hash (const struct
2026 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 2070 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2027 "Not returning DKI for %s, as time to payback coin has passed\n", 2071 "Not returning DKI for %s, as time to payback coin has passed\n",
2028 GNUNET_h2s (denom_pub_hash)); 2072 GNUNET_h2s (denom_pub_hash));
2073 *ec = TALER_EC_REFRESH_PAYBACK_DENOMINATION_EXPIRED;
2074 *hc = MHD_HTTP_GONE;
2029 return NULL; 2075 return NULL;
2030 } 2076 }
2031 break; 2077 break;
@@ -2037,6 +2083,8 @@ TEH_KS_denomination_key_lookup_by_hash (const struct
2037 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 2083 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2038 "Not returning DKI for %s, as legal expiration of coin has passed\n", 2084 "Not returning DKI for %s, as legal expiration of coin has passed\n",
2039 GNUNET_h2s (denom_pub_hash)); 2085 GNUNET_h2s (denom_pub_hash));
2086 *ec = TALER_EC_REFRESH_ZOMBIE_DENOMINATION_EXPIRED;
2087 *hc = MHD_HTTP_GONE;
2040 return NULL; 2088 return NULL;
2041 } 2089 }
2042 break; 2090 break;
diff --git a/src/exchange/taler-exchange-httpd_keystate.h b/src/exchange/taler-exchange-httpd_keystate.h
index 7e2a659ef..708b043b5 100644
--- a/src/exchange/taler-exchange-httpd_keystate.h
+++ b/src/exchange/taler-exchange-httpd_keystate.h
@@ -129,6 +129,8 @@ enum TEH_KS_DenominationKeyUse
129 * @param key_state state to look in 129 * @param key_state state to look in
130 * @param denom_pub_hash hash of denomination public key 130 * @param denom_pub_hash hash of denomination public key
131 * @param use purpose for which the key is being located 131 * @param use purpose for which the key is being located
132 * @param ec[out] set to the error code, in case the operation failed
133 * @param hc[out] set to the HTTP status code to use
132 * @return the denomination key issue, 134 * @return the denomination key issue,
133 * or NULL if denom_pub could not be found (or is not valid at this time for the given @a use) 135 * or NULL if denom_pub could not be found (or is not valid at this time for the given @a use)
134 */ 136 */
@@ -137,7 +139,9 @@ TEH_KS_denomination_key_lookup_by_hash (const struct
137 TEH_KS_StateHandle *key_state, 139 TEH_KS_StateHandle *key_state,
138 const struct 140 const struct
139 GNUNET_HashCode *denom_pub_hash, 141 GNUNET_HashCode *denom_pub_hash,
140 enum TEH_KS_DenominationKeyUse use); 142 enum TEH_KS_DenominationKeyUse use,
143 enum TALER_ErrorCode *ec,
144 unsigned int *hc);
141 145
142 146
143/** 147/**
diff --git a/src/exchange/taler-exchange-httpd_payback.c b/src/exchange/taler-exchange-httpd_payback.c
index 8a881ffff..05a2355a3 100644
--- a/src/exchange/taler-exchange-httpd_payback.c
+++ b/src/exchange/taler-exchange-httpd_payback.c
@@ -429,6 +429,8 @@ verify_and_execute_payback (struct MHD_Connection *connection,
429 struct GNUNET_HashCode c_hash; 429 struct GNUNET_HashCode c_hash;
430 char *coin_ev; 430 char *coin_ev;
431 size_t coin_ev_size; 431 size_t coin_ev_size;
432 enum TALER_ErrorCode ec;
433 unsigned int hc;
432 434
433 /* check denomination exists and is in payback mode */ 435 /* check denomination exists and is in payback mode */
434 key_state = TEH_KS_acquire (GNUNET_TIME_absolute_get ()); 436 key_state = TEH_KS_acquire (GNUNET_TIME_absolute_get ());
@@ -441,15 +443,17 @@ verify_and_execute_payback (struct MHD_Connection *connection,
441 } 443 }
442 dki = TEH_KS_denomination_key_lookup_by_hash (key_state, 444 dki = TEH_KS_denomination_key_lookup_by_hash (key_state,
443 &coin->denom_pub_hash, 445 &coin->denom_pub_hash,
444 TEH_KS_DKU_PAYBACK); 446 TEH_KS_DKU_PAYBACK,
447 &ec,
448 &hc);
445 if (NULL == dki) 449 if (NULL == dki)
446 { 450 {
447 TEH_KS_release (key_state); 451 TEH_KS_release (key_state);
448 TALER_LOG_WARNING ( 452 TALER_LOG_WARNING (
449 "Denomination key in /payback request not in payback mode\n"); 453 "Denomination key in /payback request not in payback mode\n");
450 return TEH_RESPONSE_reply_arg_unknown (connection, 454 return TEH_RESPONSE_reply_with_error (connection,
451 TALER_EC_PAYBACK_DENOMINATION_KEY_UNKNOWN, 455 ec,
452 "denom_pub"); 456 hc);
453 } 457 }
454 TALER_amount_ntoh (&pc.value, 458 TALER_amount_ntoh (&pc.value,
455 &dki->issue.properties.value); 459 &dki->issue.properties.value);
diff --git a/src/exchange/taler-exchange-httpd_refresh_melt.c b/src/exchange/taler-exchange-httpd_refresh_melt.c
index 538d8afe2..a00fda14f 100644
--- a/src/exchange/taler-exchange-httpd_refresh_melt.c
+++ b/src/exchange/taler-exchange-httpd_refresh_melt.c
@@ -447,6 +447,8 @@ TEH_REFRESH_handler_refresh_melt (struct TEH_RequestHandler *rh,
447 json_t *root; 447 json_t *root;
448 struct RefreshMeltContext rmc; 448 struct RefreshMeltContext rmc;
449 int res; 449 int res;
450 unsigned int hc;
451 enum TALER_ErrorCode ec;
450 struct TEH_KS_StateHandle *key_state; 452 struct TEH_KS_StateHandle *key_state;
451 struct GNUNET_JSON_Specification spec[] = { 453 struct GNUNET_JSON_Specification spec[] = {
452 GNUNET_JSON_spec_fixed_auto ("coin_pub", 454 GNUNET_JSON_spec_fixed_auto ("coin_pub",
@@ -501,7 +503,9 @@ TEH_REFRESH_handler_refresh_melt (struct TEH_RequestHandler *rh,
501 rmc.dki = TEH_KS_denomination_key_lookup_by_hash (key_state, 503 rmc.dki = TEH_KS_denomination_key_lookup_by_hash (key_state,
502 &rmc.refresh_session.coin. 504 &rmc.refresh_session.coin.
503 denom_pub_hash, 505 denom_pub_hash,
504 TEH_KS_DKU_DEPOSIT); 506 TEH_KS_DKU_DEPOSIT,
507 &ec,
508 &hc);
505 /* Consider case that denomination was revoked but 509 /* Consider case that denomination was revoked but
506 this coin was already seen and thus refresh is OK. */ 510 this coin was already seen and thus refresh is OK. */
507 if (NULL == rmc.dki) 511 if (NULL == rmc.dki)
@@ -511,7 +515,9 @@ TEH_REFRESH_handler_refresh_melt (struct TEH_RequestHandler *rh,
511 dki = TEH_KS_denomination_key_lookup_by_hash (key_state, 515 dki = TEH_KS_denomination_key_lookup_by_hash (key_state,
512 &rmc.refresh_session.coin. 516 &rmc.refresh_session.coin.
513 denom_pub_hash, 517 denom_pub_hash,
514 TEH_KS_DKU_PAYBACK); 518 TEH_KS_DKU_PAYBACK,
519 &ec,
520 &hc);
515 if (NULL != dki) 521 if (NULL != dki)
516 { 522 {
517 struct TALER_CoinPublicInfo coin_info; 523 struct TALER_CoinPublicInfo coin_info;
@@ -547,7 +553,9 @@ TEH_REFRESH_handler_refresh_melt (struct TEH_RequestHandler *rh,
547 dki = TEH_KS_denomination_key_lookup_by_hash (key_state, 553 dki = TEH_KS_denomination_key_lookup_by_hash (key_state,
548 &rmc.refresh_session.coin. 554 &rmc.refresh_session.coin.
549 denom_pub_hash, 555 denom_pub_hash,
550 TEH_KS_DKU_ZOMBIE); 556 TEH_KS_DKU_ZOMBIE,
557 &ec,
558 &hc);
551 if (NULL != dki) 559 if (NULL != dki)
552 { 560 {
553 rmc.dki = dki; 561 rmc.dki = dki;
@@ -558,9 +566,9 @@ TEH_REFRESH_handler_refresh_melt (struct TEH_RequestHandler *rh,
558 if (NULL == rmc.dki) 566 if (NULL == rmc.dki)
559 { 567 {
560 TALER_LOG_WARNING ("Unknown denomination key in /refresh/melt request\n"); 568 TALER_LOG_WARNING ("Unknown denomination key in /refresh/melt request\n");
561 res = TEH_RESPONSE_reply_arg_unknown (connection, 569 res = TEH_RESPONSE_reply_with_error (connection,
562 TALER_EC_REFRESH_MELT_DENOMINATION_KEY_NOT_FOUND, 570 ec,
563 "denom_pub"); 571 hc);
564 goto cleanup; 572 goto cleanup;
565 } 573 }
566 574
diff --git a/src/exchange/taler-exchange-httpd_refresh_reveal.c b/src/exchange/taler-exchange-httpd_refresh_reveal.c
index c1a7b6392..be5228dd9 100644
--- a/src/exchange/taler-exchange-httpd_refresh_reveal.c
+++ b/src/exchange/taler-exchange-httpd_refresh_reveal.c
@@ -610,6 +610,8 @@ handle_refresh_reveal_json (struct MHD_Connection *connection,
610 &dki_h[i]), 610 &dki_h[i]),
611 GNUNET_JSON_spec_end () 611 GNUNET_JSON_spec_end ()
612 }; 612 };
613 unsigned int hc;
614 enum TALER_ErrorCode ec;
613 615
614 res = TEH_PARSE_json_array (connection, 616 res = TEH_PARSE_json_array (connection,
615 new_denoms_h_json, 617 new_denoms_h_json,
@@ -623,13 +625,15 @@ handle_refresh_reveal_json (struct MHD_Connection *connection,
623 } 625 }
624 dkis[i] = TEH_KS_denomination_key_lookup_by_hash (key_state, 626 dkis[i] = TEH_KS_denomination_key_lookup_by_hash (key_state,
625 &dki_h[i], 627 &dki_h[i],
626 TEH_KS_DKU_WITHDRAW); 628 TEH_KS_DKU_WITHDRAW,
629 &ec,
630 &hc);
627 if (NULL == dkis[i]) 631 if (NULL == dkis[i])
628 { 632 {
629 TEH_KS_release (key_state); 633 TEH_KS_release (key_state);
630 return TEH_RESPONSE_reply_arg_invalid (connection, 634 return TEH_RESPONSE_reply_with_error (connection,
631 TALER_EC_REFRESH_REVEAL_FRESH_DENOMINATION_KEY_NOT_FOUND, 635 ec,
632 "new_denoms_h"); 636 hc);
633 } 637 }
634 GNUNET_assert (NULL != dkis[i]->denom_priv.rsa_private_key); 638 GNUNET_assert (NULL != dkis[i]->denom_priv.rsa_private_key);
635 } 639 }
diff --git a/src/exchange/taler-exchange-httpd_refund.c b/src/exchange/taler-exchange-httpd_refund.c
index 93df54c8a..48532a2ce 100644
--- a/src/exchange/taler-exchange-httpd_refund.c
+++ b/src/exchange/taler-exchange-httpd_refund.c
@@ -161,6 +161,8 @@ refund_transaction (void *cls,
161 int deposit_found; 161 int deposit_found;
162 int refund_found; 162 int refund_found;
163 int fee_cmp; 163 int fee_cmp;
164 unsigned int hc;
165 enum TALER_ErrorCode ec;
164 166
165 dep = NULL; 167 dep = NULL;
166 ref = NULL; 168 ref = NULL;
@@ -354,7 +356,9 @@ refund_transaction (void *cls,
354 } 356 }
355 dki = TEH_KS_denomination_key_lookup_by_hash (mks, 357 dki = TEH_KS_denomination_key_lookup_by_hash (mks,
356 &dep->coin.denom_pub_hash, 358 &dep->coin.denom_pub_hash,
357 TEH_KS_DKU_DEPOSIT); 359 TEH_KS_DKU_DEPOSIT,
360 &ec,
361 &hc);
358 if (NULL == dki) 362 if (NULL == dki)
359 { 363 {
360 /* DKI not found, but we do have a coin with this DK in our database; 364 /* DKI not found, but we do have a coin with this DK in our database;
@@ -363,9 +367,9 @@ refund_transaction (void *cls,
363 TEH_KS_release (mks); 367 TEH_KS_release (mks);
364 TEH_plugin->free_coin_transaction_list (TEH_plugin->cls, 368 TEH_plugin->free_coin_transaction_list (TEH_plugin->cls,
365 tl); 369 tl);
366 *mhd_ret = TEH_RESPONSE_reply_internal_error (connection, 370 *mhd_ret = TEH_RESPONSE_reply_with_error (connection,
367 TALER_EC_REFUND_DENOMINATION_KEY_NOT_FOUND, 371 ec,
368 "denomination key not found"); 372 hc);
369 return GNUNET_DB_STATUS_HARD_ERROR; 373 return GNUNET_DB_STATUS_HARD_ERROR;
370 } 374 }
371 TALER_amount_ntoh (&expect_fee, 375 TALER_amount_ntoh (&expect_fee,
diff --git a/src/exchange/taler-exchange-httpd_reserve_withdraw.c b/src/exchange/taler-exchange-httpd_reserve_withdraw.c
index 1199ed67d..578aace31 100644
--- a/src/exchange/taler-exchange-httpd_reserve_withdraw.c
+++ b/src/exchange/taler-exchange-httpd_reserve_withdraw.c
@@ -365,6 +365,8 @@ TEH_RESERVE_handler_reserve_withdraw (struct TEH_RequestHandler *rh,
365 json_t *root; 365 json_t *root;
366 int res; 366 int res;
367 int mhd_ret; 367 int mhd_ret;
368 unsigned int hc;
369 enum TALER_ErrorCode ec;
368 struct TALER_Amount amount; 370 struct TALER_Amount amount;
369 struct TALER_Amount fee_withdraw; 371 struct TALER_Amount fee_withdraw;
370 struct GNUNET_JSON_Specification spec[] = { 372 struct GNUNET_JSON_Specification spec[] = {
@@ -407,14 +409,16 @@ TEH_RESERVE_handler_reserve_withdraw (struct TEH_RequestHandler *rh,
407 } 409 }
408 wc.dki = TEH_KS_denomination_key_lookup_by_hash (wc.key_state, 410 wc.dki = TEH_KS_denomination_key_lookup_by_hash (wc.key_state,
409 &wc.denom_pub_hash, 411 &wc.denom_pub_hash,
410 TEH_KS_DKU_WITHDRAW); 412 TEH_KS_DKU_WITHDRAW,
413 &ec,
414 &hc);
411 if (NULL == wc.dki) 415 if (NULL == wc.dki)
412 { 416 {
413 GNUNET_JSON_parse_free (spec); 417 GNUNET_JSON_parse_free (spec);
414 TEH_KS_release (wc.key_state); 418 TEH_KS_release (wc.key_state);
415 return TEH_RESPONSE_reply_arg_unknown (connection, 419 return TEH_RESPONSE_reply_with_error (connection,
416 TALER_EC_WITHDRAW_DENOMINATION_KEY_NOT_FOUND, 420 ec,
417 "denom_pub"); 421 hc);
418 } 422 }
419 GNUNET_assert (NULL != wc.dki->denom_priv.rsa_private_key); 423 GNUNET_assert (NULL != wc.dki->denom_priv.rsa_private_key);
420 TALER_amount_ntoh (&amount, 424 TALER_amount_ntoh (&amount,
diff --git a/src/exchange/taler-exchange-httpd_responses.c b/src/exchange/taler-exchange-httpd_responses.c
index 2e1835845..048a8bef0 100644
--- a/src/exchange/taler-exchange-httpd_responses.c
+++ b/src/exchange/taler-exchange-httpd_responses.c
@@ -362,6 +362,26 @@ TEH_RESPONSE_reply_internal_error (struct MHD_Connection *connection,
362 362
363 363
364/** 364/**
365 * Send a response indicating an error.
366 *
367 * @param connection the MHD connection to use
368 * @param ec error code uniquely identifying the error
369 * @param http_status HTTP status code to use
370 * @return a MHD result code
371 */
372int
373TEH_RESPONSE_reply_with_error (struct MHD_Connection *connection,
374 enum TALER_ErrorCode ec,
375 unsigned int http_status)
376{
377 return TEH_RESPONSE_reply_json_pack (connection,
378 http_status,
379 "{s:I}",
380 "code", (json_int_t) ec);
381}
382
383
384/**
365 * Send a response indicating an external error. 385 * Send a response indicating an external error.
366 * 386 *
367 * @param connection the MHD connection to use 387 * @param connection the MHD connection to use
diff --git a/src/exchange/taler-exchange-httpd_responses.h b/src/exchange/taler-exchange-httpd_responses.h
index 177eaa43e..9b6a78859 100644
--- a/src/exchange/taler-exchange-httpd_responses.h
+++ b/src/exchange/taler-exchange-httpd_responses.h
@@ -171,6 +171,20 @@ TEH_RESPONSE_reply_internal_error (struct MHD_Connection *connection,
171 171
172 172
173/** 173/**
174 * Send a response indicating an error.
175 *
176 * @param connection the MHD connection to use
177 * @param ec error code uniquely identifying the error
178 * @param http_status HTTP status code to use
179 * @return a MHD result code
180 */
181int
182TEH_RESPONSE_reply_with_error (struct MHD_Connection *connection,
183 enum TALER_ErrorCode ec,
184 unsigned int http_status);
185
186
187/**
174 * Send a response indicating an external error. 188 * Send a response indicating an external error.
175 * 189 *
176 * @param connection the MHD connection to use 190 * @param connection the MHD connection to use
diff --git a/src/include/taler_error_codes.h b/src/include/taler_error_codes.h
index 4962d5fe5..57dbd2db9 100644
--- a/src/include/taler_error_codes.h
+++ b/src/include/taler_error_codes.h
@@ -298,6 +298,29 @@ enum TALER_ErrorCode
298 TALER_EC_WITHDRAW_RESERVE_HISTORY_IMPOSSIBLE = 1113, 298 TALER_EC_WITHDRAW_RESERVE_HISTORY_IMPOSSIBLE = 1113,
299 299
300 /** 300 /**
301 * Validity period of the coin to be withdrawn
302 * is in the future. Returned with an HTTP
303 * status of #MHD_HTTP_PRECONDITION_FAILED.
304 */
305 TALER_EC_WITHDRAW_VALIDITY_IN_FUTURE = 1114,
306
307 /**
308 * Withdraw period of the coin to be withdrawn
309 * is in the past. Returned with an HTTP
310 * status of #MHD_HTTP_GONE.
311 */
312 TALER_EC_WITHDRAW_VALIDITY_IN_PAST = 1115,
313
314 /**
315 * The private key associated with the denomination
316 * key is unknown to the server, possibly because
317 * the key was revoked. Returned with an HTTP
318 * status of #MHD_HTTP_SERVICE_UNAVAILABLE.
319 */
320 TALER_EC_DENOMINATION_KEY_LOST = 1116,
321
322
323 /**
301 * The exchange failed to obtain the transaction history of the 324 * The exchange failed to obtain the transaction history of the
302 * given reserve from the database. 325 * given reserve from the database.
303 * This response is provided with HTTP status code 326 * This response is provided with HTTP status code
@@ -453,6 +476,20 @@ enum TALER_ErrorCode
453 */ 476 */
454 TALER_EC_DEPOSIT_INVALID_TIMESTAMP = 1218, 477 TALER_EC_DEPOSIT_INVALID_TIMESTAMP = 1218,
455 478
479 /**
480 * Validity period of the denomination key
481 * is in the future. Returned with an HTTP
482 * status of #MHD_HTTP_PRECONDITION_FAILED.
483 */
484 TALER_EC_DEPOSIT_DENOMINATION_VALIDITY_IN_FUTURE = 1219,
485
486 /**
487 * Denomination key of the coin is past the
488 * deposit deadline. Returned with an HTTP
489 * status of #MHD_HTTP_GONE.
490 */
491 TALER_EC_DEPOSIT_DENOMINATION_EXPIRED = 1220,
492
456 493
457 /** 494 /**
458 * The respective coin did not have sufficient residual value 495 * The respective coin did not have sufficient residual value
@@ -532,6 +569,35 @@ enum TALER_ErrorCode
532 TALER_EC_REFRESH_MELT_COIN_EXPIRED_NO_ZOMBIE = 1309, 569 TALER_EC_REFRESH_MELT_COIN_EXPIRED_NO_ZOMBIE = 1309,
533 570
534 /** 571 /**
572 * The exchange is unaware of the denomination key that was
573 * used to sign the melted zombie coin. This response is provided
574 * with HTTP status code MHD_HTTP_NOT_FOUND.
575 */
576 TALER_EC_REFRESH_PAYBACK_DENOMINATION_KEY_NOT_FOUND = 1301,
577
578 /**
579 * Validity period of the denomination key
580 * is in the future. Returned with an HTTP
581 * status of #MHD_HTTP_PRECONDITION_FAILED.
582 */
583 TALER_EC_REFRESH_PAYBACK_DENOMINATION_VALIDITY_IN_FUTURE = 1301,
584
585 /**
586 * Denomination key of the coin is past the
587 * deposit deadline. Returned with an HTTP
588 * status of #MHD_HTTP_GONE.
589 */
590 TALER_EC_REFRESH_PAYBACK_DENOMINATION_EXPIRED = 1302,
591
592 /**
593 * Denomination key of the coin is past the
594 * deposit deadline. Returned with an HTTP
595 * status of #MHD_HTTP_GONE.
596 */
597 TALER_EC_REFRESH_ZOMBIE_DENOMINATION_EXPIRED = 1303,
598
599
600 /**
535 * The provided transfer keys do not match up with the 601 * The provided transfer keys do not match up with the
536 * original commitment. Information about the original 602 * original commitment. Information about the original
537 * commitment is included in the response. This response is 603 * commitment is included in the response. This response is
@@ -921,7 +987,15 @@ enum TALER_ErrorCode
921 * This response is provided with an HTTP status code of 987 * This response is provided with an HTTP status code of
922 * MHD_HTTP_INTERNAL_SERVER_ERROR 988 * MHD_HTTP_INTERNAL_SERVER_ERROR
923 */ 989 */
924 TALER_EC_PAYBACK_COIN_BALANCE_NEGATIVE = 1857, 990 TALER_EC_PAYBACK_COIN_BALANCE_NEGATIVE = 1859,
991
992 /**
993 * Validity period of the denomination key
994 * is in the future. Returned with an HTTP
995 * status of #MHD_HTTP_PRECONDITION_FAILED.
996 */
997 TALER_EC_PAYBACK_DENOMINATION_VALIDITY_IN_FUTURE = 1860,
998
925 999
926 /** 1000 /**
927 * The "have" parameter was not a natural number. 1001 * The "have" parameter was not a natural number.