From 70462f0b94d933bec7b735fecb66a75a45c91c66 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Tue, 18 Oct 2016 23:05:29 +0200 Subject: implement #4497/#4705 -- addition of unique numeric error codes -- for the server-side of the exchange --- src/exchange-lib/exchange_api_reserve.c | 4 +- src/exchange-lib/test_exchange_api.c | 4 +- src/exchange/taler-exchange-httpd_admin.c | 2 + src/exchange/taler-exchange-httpd_db.c | 179 ++++-- src/exchange/taler-exchange-httpd_deposit.c | 88 ++- src/exchange/taler-exchange-httpd_parsing.c | 12 +- src/exchange/taler-exchange-httpd_refresh.c | 24 +- src/exchange/taler-exchange-httpd_refund.c | 7 +- src/exchange/taler-exchange-httpd_reserve.c | 4 +- src/exchange/taler-exchange-httpd_responses.c | 102 +++- src/exchange/taler-exchange-httpd_responses.h | 34 +- src/exchange/taler-exchange-httpd_test.c | 7 + src/exchange/taler-exchange-httpd_tracking.c | 11 +- src/include/taler_error_codes.h | 761 +++++++++++++++++++++++++- 14 files changed, 1071 insertions(+), 168 deletions(-) (limited to 'src') diff --git a/src/exchange-lib/exchange_api_reserve.c b/src/exchange-lib/exchange_api_reserve.c index 0bff767e6..9de2b268f 100644 --- a/src/exchange-lib/exchange_api_reserve.c +++ b/src/exchange-lib/exchange_api_reserve.c @@ -599,7 +599,7 @@ reserve_withdraw_ok (struct TALER_EXCHANGE_ReserveWithdrawHandle *wsh, /** - * We got a 402 PAYMENT REQUIRED response for the /reserve/withdraw operation. + * We got a 403 FORBIDDEN response for the /reserve/withdraw operation. * Check the signatures on the withdraw transactions in the provided * history and that the balances add up. We don't do anything directly * with the information, as the JSON will be returned to the application. @@ -723,7 +723,7 @@ handle_reserve_withdraw_finished (void *cls, /* This should never happen, either us or the exchange is buggy (or API version conflict); just pass JSON reply to the application */ break; - case MHD_HTTP_PAYMENT_REQUIRED: + case MHD_HTTP_FORBIDDEN: /* The exchange says that the reserve has insufficient funds; check the signatures in the history... */ if (GNUNET_OK != diff --git a/src/exchange-lib/test_exchange_api.c b/src/exchange-lib/test_exchange_api.c index 541a621d2..6bd4358e3 100644 --- a/src/exchange-lib/test_exchange_api.c +++ b/src/exchange-lib/test_exchange_api.c @@ -1009,7 +1009,7 @@ reserve_withdraw_cb (void *cls, cmd->details.reserve_withdraw.sig.rsa_signature = GNUNET_CRYPTO_rsa_signature_dup (sig->rsa_signature); break; - case MHD_HTTP_PAYMENT_REQUIRED: + case MHD_HTTP_FORBIDDEN: /* nothing to check */ break; default: @@ -2737,7 +2737,7 @@ run (void *cls) /* Try to overdraw funds ... */ { .oc = OC_WITHDRAW_SIGN, .label = "withdraw-coin-2", - .expected_response_code = MHD_HTTP_PAYMENT_REQUIRED, + .expected_response_code = MHD_HTTP_FORBIDDEN, .details.reserve_withdraw.reserve_reference = "create-reserve-1", .details.reserve_withdraw.amount = "EUR:5" }, diff --git a/src/exchange/taler-exchange-httpd_admin.c b/src/exchange/taler-exchange-httpd_admin.c index e99448f87..72cdcb7d6 100644 --- a/src/exchange/taler-exchange-httpd_admin.c +++ b/src/exchange/taler-exchange-httpd_admin.c @@ -89,6 +89,7 @@ TEH_ADMIN_handler_admin_add_incoming (struct TEH_RequestHandler *rh, GNUNET_break_op (0); GNUNET_JSON_parse_free (spec); return TEH_RESPONSE_reply_arg_unknown (connection, + TALER_EC_ADMIN_ADD_INCOMING_WIREFORMAT_UNSUPPORTED, "sender_account_details"); } if (0 != strcasecmp (amount.currency, @@ -100,6 +101,7 @@ TEH_ADMIN_handler_admin_add_incoming (struct TEH_RequestHandler *rh, amount.currency); GNUNET_JSON_parse_free (spec); return TEH_RESPONSE_reply_arg_invalid (connection, + TALER_EC_ADMIN_ADD_INCOMING_CURRENCY_UNSUPPORTED, "amount:currency"); } res = TEH_DB_execute_admin_add_incoming (connection, diff --git a/src/exchange/taler-exchange-httpd_db.c b/src/exchange/taler-exchange-httpd_db.c index 6b27a22a6..870f7a251 100644 --- a/src/exchange/taler-exchange-httpd_db.c +++ b/src/exchange/taler-exchange-httpd_db.c @@ -53,7 +53,8 @@ transaction_start_label: /* we will use goto for retries */ \ session)) \ { \ GNUNET_break (0); \ - return TEH_RESPONSE_reply_internal_db_error (connection); \ + return TEH_RESPONSE_reply_internal_db_error (connection, \ + TALER_EC_DB_START_FAILED); \ } /** @@ -73,8 +74,9 @@ transaction_start_label: /* we will use goto for retries */ \ if (GNUNET_SYSERR == transaction_commit_result) \ { \ TALER_LOG_WARNING ("Transaction commit failed in %s\n", __FUNCTION__); \ - return TEH_RESPONSE_reply_commit_error (connection); \ - } \ + return TEH_RESPONSE_reply_commit_error (connection, \ + TALER_EC_DB_COMMIT_FAILED_HARD); \ + } \ if (GNUNET_NO == transaction_commit_result) \ { \ TALER_LOG_WARNING ("Transaction commit failed in %s\n", __FUNCTION__); \ @@ -83,7 +85,8 @@ transaction_start_label: /* we will use goto for retries */ \ TALER_LOG_WARNING ("Transaction commit failed %u times in %s\n", \ transaction_retries, \ __FUNCTION__); \ - return TEH_RESPONSE_reply_commit_error (connection); \ + return TEH_RESPONSE_reply_commit_error (connection, \ + TALER_EC_DB_COMMIT_FAILED_ON_RETRY); \ } \ } /* end of scope opened by BEGIN_TRANSACTION */ @@ -197,7 +200,8 @@ TEH_DB_execute_deposit (struct MHD_Connection *connection, if (NULL == (session = TEH_plugin->get_session (TEH_plugin->cls))) { GNUNET_break (0); - return TEH_RESPONSE_reply_internal_db_error (connection); + return TEH_RESPONSE_reply_internal_db_error (connection, + TALER_EC_DB_SETUP_FAILED); } if (GNUNET_YES == TEH_plugin->have_deposit (TEH_plugin->cls, @@ -225,8 +229,8 @@ TEH_DB_execute_deposit (struct MHD_Connection *connection, if (NULL == dki) { TEH_KS_release (mks); - return TEH_RESPONSE_reply_arg_invalid (connection, - "denom_pub"); + return TEH_RESPONSE_reply_internal_db_error (connection, + TALER_EC_DEPOSIT_DB_DENOMINATION_KEY_UNKNOWN); } TALER_amount_ntoh (&value, &dki->issue.properties.value); @@ -249,7 +253,8 @@ TEH_DB_execute_deposit (struct MHD_Connection *connection, session); TEH_plugin->free_coin_transaction_list (TEH_plugin->cls, tl); - return TEH_RESPONSE_reply_internal_db_error (connection); + return TEH_RESPONSE_reply_internal_db_error (connection, + TALER_EC_DEPOSIT_HISTORY_DB_ERROR); } /* Check that cost of all transactions is smaller than the value of the coin. */ @@ -274,7 +279,8 @@ TEH_DB_execute_deposit (struct MHD_Connection *connection, TALER_LOG_WARNING ("Failed to store /deposit information in database\n"); TEH_plugin->rollback (TEH_plugin->cls, session); - return TEH_RESPONSE_reply_internal_db_error (connection); + return TEH_RESPONSE_reply_internal_db_error (connection, + TALER_EC_DEPOSIT_STORE_DB_ERROR); } COMMIT_TRANSACTION(session, connection); @@ -324,7 +330,8 @@ TEH_DB_execute_refund (struct MHD_Connection *connection, if (NULL == (session = TEH_plugin->get_session (TEH_plugin->cls))) { GNUNET_break (0); - return TEH_RESPONSE_reply_internal_db_error (connection); + return TEH_RESPONSE_reply_internal_db_error (connection, + TALER_EC_DB_SETUP_FAILED); } dep = NULL; ref = NULL; @@ -337,7 +344,8 @@ TEH_DB_execute_refund (struct MHD_Connection *connection, TEH_plugin->rollback (TEH_plugin->cls, session); return TEH_RESPONSE_reply_refund_failure (connection, - MHD_HTTP_NOT_FOUND); + MHD_HTTP_NOT_FOUND, + TALER_EC_REFUND_COIN_NOT_FOUND); } deposit_found = GNUNET_NO; refund_found = GNUNET_NO; @@ -411,7 +419,8 @@ TEH_DB_execute_refund (struct MHD_Connection *connection, session); TEH_plugin->free_coin_transaction_list (TEH_plugin->cls, tl); - return TEH_RESPONSE_reply_transaction_unknown (connection); + return TEH_RESPONSE_reply_transaction_unknown (connection, + TALER_EC_REFUND_DEPOSIT_NOT_FOUND); } /* handle if conflicting refund found */ if (GNUNET_SYSERR == refund_found) @@ -449,7 +458,8 @@ TEH_DB_execute_refund (struct MHD_Connection *connection, TEH_plugin->rollback (TEH_plugin->cls, session); return TEH_RESPONSE_reply_refund_failure (connection, - MHD_HTTP_PRECONDITION_FAILED); + MHD_HTTP_PRECONDITION_FAILED, + TALER_EC_REFUND_CURRENCY_MISSMATCH); } /* check if we already send the money for the /deposit */ @@ -466,6 +476,7 @@ TEH_DB_execute_refund (struct MHD_Connection *connection, TEH_plugin->rollback (TEH_plugin->cls, session); return TEH_RESPONSE_reply_internal_error (connection, + TALER_EC_REFUND_DB_INCONSISTENT, "database inconsistent"); } if (GNUNET_YES == done) @@ -476,7 +487,8 @@ TEH_DB_execute_refund (struct MHD_Connection *connection, TEH_plugin->free_coin_transaction_list (TEH_plugin->cls, tl); return TEH_RESPONSE_reply_refund_failure (connection, - MHD_HTTP_GONE); + MHD_HTTP_GONE, + TALER_EC_REFUND_MERCHANT_ALREADY_PAID); } /* check refund amount is sufficiently low */ @@ -487,7 +499,8 @@ TEH_DB_execute_refund (struct MHD_Connection *connection, TEH_plugin->free_coin_transaction_list (TEH_plugin->cls, tl); return TEH_RESPONSE_reply_refund_failure (connection, - MHD_HTTP_PRECONDITION_FAILED); + MHD_HTTP_PRECONDITION_FAILED, + TALER_EC_REFUND_INSUFFICIENT_FUNDS); } /* Check refund fee matches fee of denomination key! */ @@ -504,6 +517,7 @@ TEH_DB_execute_refund (struct MHD_Connection *connection, TEH_plugin->free_coin_transaction_list (TEH_plugin->cls, tl); return TEH_RESPONSE_reply_internal_error (connection, + TALER_EC_REFUND_DENOMINATION_KEY_NOT_FOUND, "denomination key not found"); } TALER_amount_ntoh (&expect_fee, @@ -519,6 +533,7 @@ TEH_DB_execute_refund (struct MHD_Connection *connection, TEH_plugin->free_coin_transaction_list (TEH_plugin->cls, tl); return TEH_RESPONSE_reply_arg_invalid (connection, + TALER_EC_REFUND_FEE_TOO_LOW, "refund_fee"); } if (1 == fee_cmp) @@ -538,7 +553,8 @@ TEH_DB_execute_refund (struct MHD_Connection *connection, TALER_LOG_WARNING ("Failed to store /refund information in database\n"); TEH_plugin->rollback (TEH_plugin->cls, session); - return TEH_RESPONSE_reply_internal_db_error (connection); + return TEH_RESPONSE_reply_internal_db_error (connection, + TALER_EC_REFUND_STORE_DB_ERROR); } COMMIT_TRANSACTION(session, connection); @@ -566,7 +582,8 @@ TEH_DB_execute_reserve_status (struct MHD_Connection *connection, if (NULL == (session = TEH_plugin->get_session (TEH_plugin->cls))) { GNUNET_break (0); - return TEH_RESPONSE_reply_internal_db_error (connection); + return TEH_RESPONSE_reply_internal_db_error (connection, + TALER_EC_DB_SETUP_FAILED); } rh = TEH_plugin->get_reserve_history (TEH_plugin->cls, session, @@ -637,6 +654,7 @@ execute_reserve_withdraw_transaction (struct MHD_Connection *connection, TEH_plugin->rollback (TEH_plugin->cls, session); return TEH_RESPONSE_reply_arg_unknown (connection, + TALER_EC_WITHDRAW_RESERVE_UNKNOWN, "reserve_pub"); } @@ -653,7 +671,8 @@ execute_reserve_withdraw_transaction (struct MHD_Connection *connection, { TEH_plugin->rollback (TEH_plugin->cls, session); - return TEH_RESPONSE_reply_internal_db_error (connection); + return TEH_RESPONSE_reply_internal_db_error (connection, + TALER_EC_WITHDRAW_AMOUNT_FEE_OVERFLOW); } /* calculate balance of the reserve */ @@ -673,7 +692,8 @@ execute_reserve_withdraw_transaction (struct MHD_Connection *connection, { TEH_plugin->rollback (TEH_plugin->cls, session); - return TEH_RESPONSE_reply_internal_db_error (connection); + return TEH_RESPONSE_reply_internal_db_error (connection, + TALER_EC_WITHDRAW_AMOUNT_DEPOSITS_OVERFLOW); } res |= 1; break; @@ -686,7 +706,8 @@ execute_reserve_withdraw_transaction (struct MHD_Connection *connection, GNUNET_break (0); TEH_plugin->rollback (TEH_plugin->cls, session); - return TEH_RESPONSE_reply_internal_db_error (connection); + return TEH_RESPONSE_reply_internal_db_error (connection, + TALER_EC_WITHDRAW_HISTORIC_DENOMINATION_KEY_NOT_FOUND); } TALER_amount_ntoh (&value, &tdki->issue.properties.value); @@ -700,7 +721,8 @@ execute_reserve_withdraw_transaction (struct MHD_Connection *connection, { TEH_plugin->rollback (TEH_plugin->cls, session); - return TEH_RESPONSE_reply_internal_db_error (connection); + return TEH_RESPONSE_reply_internal_db_error (connection, + TALER_EC_WITHDRAW_AMOUNT_WITHDRAWALS_OVERFLOW); } res |= 2; break; @@ -708,9 +730,10 @@ execute_reserve_withdraw_transaction (struct MHD_Connection *connection, } if (0 == (res & 1)) { - /* did not encounter any deposit operations, how can we have a reserve? */ + /* did not encounter any wire transfer operations, how can we have a reserve? */ GNUNET_break (0); - return TEH_RESPONSE_reply_internal_db_error (connection); + return TEH_RESPONSE_reply_internal_db_error (connection, + TALER_EC_WITHDRAW_RESERVE_WITHOUT_WIRE_TRANSFER); } if (0 == (res & 2)) { @@ -748,6 +771,7 @@ execute_reserve_withdraw_transaction (struct MHD_Connection *connection, TEH_plugin->rollback (TEH_plugin->cls, session); return TEH_RESPONSE_reply_internal_error (connection, + TALER_EC_WITHDRAW_SIGNATURE_FAILED, "Internal error"); } collectable.sig = *denom_sig; @@ -765,7 +789,8 @@ execute_reserve_withdraw_transaction (struct MHD_Connection *connection, GNUNET_break (0); TEH_plugin->rollback (TEH_plugin->cls, session); - return TEH_RESPONSE_reply_internal_db_error (connection); + return TEH_RESPONSE_reply_internal_db_error (connection, + TALER_EC_WITHDRAW_DB_STORE_ERROR); } COMMIT_TRANSACTION (session, connection); @@ -811,7 +836,8 @@ TEH_DB_execute_reserve_withdraw (struct MHD_Connection *connection, if (NULL == (session = TEH_plugin->get_session (TEH_plugin->cls))) { GNUNET_break (0); - return TEH_RESPONSE_reply_internal_db_error (connection); + return TEH_RESPONSE_reply_internal_db_error (connection, + TALER_EC_DB_SETUP_FAILED); } res = TEH_plugin->get_withdraw_info (TEH_plugin->cls, session, @@ -820,7 +846,8 @@ TEH_DB_execute_reserve_withdraw (struct MHD_Connection *connection, if (GNUNET_SYSERR == res) { GNUNET_break (0); - return TEH_RESPONSE_reply_internal_db_error (connection); + return TEH_RESPONSE_reply_internal_db_error (connection, + TALER_EC_WITHDRAW_DB_FETCH_ERROR); } /* Don't sign again if we have already signed the coin */ @@ -834,6 +861,7 @@ TEH_DB_execute_reserve_withdraw (struct MHD_Connection *connection, } GNUNET_assert (GNUNET_NO == res); + /* FIXME: do we have to do this a second time here? */ key_state = TEH_KS_acquire (); dki = TEH_KS_denomination_key_lookup (key_state, denomination_pub, @@ -843,9 +871,11 @@ TEH_DB_execute_reserve_withdraw (struct MHD_Connection *connection, TEH_KS_release (key_state); return TEH_RESPONSE_reply_json_pack (connection, MHD_HTTP_NOT_FOUND, - "{s:s}", + "{s:s, s:I}", "error", - "Denomination not found"); + "Denomination not found", + "code", + (json_int_t) TALER_EC_WITHDRAW_DENOMINATION_KEY_NOT_FOUND); } denom_sig.rsa_signature = NULL; res = execute_reserve_withdraw_transaction (connection, @@ -901,8 +931,9 @@ refresh_check_melt (struct MHD_Connection *connection, TEH_KS_DKU_DEPOSIT); if (NULL == dk) return (MHD_YES == - TEH_RESPONSE_reply_arg_unknown (connection, - "denom_pub")) + TEH_RESPONSE_reply_internal_error (connection, + TALER_EC_REFRESH_MELT_DB_DENOMINATION_KEY_NOT_FOUND, + "denomination key no longer available while executing transaction")) ? GNUNET_NO : GNUNET_SYSERR; dki = &dk->issue; TALER_amount_ntoh (&coin_value, @@ -922,7 +953,8 @@ refresh_check_melt (struct MHD_Connection *connection, TEH_plugin->free_coin_transaction_list (TEH_plugin->cls, tl); return (MHD_YES == - TEH_RESPONSE_reply_internal_db_error (connection)) + TEH_RESPONSE_reply_internal_db_error (connection, + TALER_EC_REFRESH_MELT_COIN_HISTORY_COMPUTATION_FAILED)) ? GNUNET_NO : GNUNET_SYSERR; } /* Refuse to refresh when the coin's value is insufficient @@ -995,7 +1027,8 @@ TEH_DB_execute_refresh_melt (struct MHD_Connection *connection, if (NULL == (session = TEH_plugin->get_session (TEH_plugin->cls))) { GNUNET_break (0); - return TEH_RESPONSE_reply_internal_db_error (connection); + return TEH_RESPONSE_reply_internal_db_error (connection, + TALER_EC_DB_SETUP_FAILED); } START_TRANSACTION (session, connection); res = TEH_plugin->get_refresh_session (TEH_plugin->cls, @@ -1015,14 +1048,15 @@ TEH_DB_execute_refresh_melt (struct MHD_Connection *connection, { TEH_plugin->rollback (TEH_plugin->cls, session); - return TEH_RESPONSE_reply_internal_db_error (connection); + return TEH_RESPONSE_reply_internal_db_error (connection, + TALER_EC_REFRESH_MELT_DB_FETCH_ERROR); } /* store 'global' session data */ refresh_session.num_newcoins = num_new_denoms; refresh_session.noreveal_index - = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_STRONG, - TALER_CNC_KAPPA); + = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_STRONG, + TALER_CNC_KAPPA); key_state = TEH_KS_acquire (); if (GNUNET_OK != (res = refresh_check_melt (connection, @@ -1047,7 +1081,8 @@ TEH_DB_execute_refresh_melt (struct MHD_Connection *connection, { TEH_plugin->rollback (TEH_plugin->cls, session); - return TEH_RESPONSE_reply_internal_db_error (connection); + return TEH_RESPONSE_reply_internal_db_error (connection, + TALER_EC_REFRESH_MELT_DB_STORE_SESSION_ERROR); } /* store requested new denominations */ @@ -1060,7 +1095,8 @@ TEH_DB_execute_refresh_melt (struct MHD_Connection *connection, { TEH_plugin->rollback (TEH_plugin->cls, session); - return TEH_RESPONSE_reply_internal_db_error (connection); + return TEH_RESPONSE_reply_internal_db_error (connection, + TALER_EC_REFRESH_MELT_DB_STORE_ORDER_ERROR); } if (GNUNET_OK != @@ -1072,7 +1108,8 @@ TEH_DB_execute_refresh_melt (struct MHD_Connection *connection, { TEH_plugin->rollback (TEH_plugin->cls, session); - return TEH_RESPONSE_reply_internal_db_error (connection); + return TEH_RESPONSE_reply_internal_db_error (connection, + TALER_EC_REFRESH_MELT_DB_STORE_ORDER_ERROR); } if (GNUNET_OK != TEH_plugin->insert_refresh_transfer_public_key (TEH_plugin->cls, @@ -1082,7 +1119,8 @@ TEH_DB_execute_refresh_melt (struct MHD_Connection *connection, { TEH_plugin->rollback (TEH_plugin->cls, session); - return TEH_RESPONSE_reply_internal_db_error (connection); + return TEH_RESPONSE_reply_internal_db_error (connection, + TALER_EC_REFRESH_MELT_DB_STORE_TRANSFER_ERROR); } COMMIT_TRANSACTION (session, connection); @@ -1126,8 +1164,6 @@ check_commitment (struct MHD_Connection *connection, struct TALER_TransferSecretP transfer_secret; unsigned int j; - /* FIXME: instead of consulting DB, reconstruct everything - from transfer_priv here! */ TALER_link_reveal_transfer_secret (transfer_priv, &melt->coin.coin_pub, &transfer_secret); @@ -1158,8 +1194,10 @@ check_commitment (struct MHD_Connection *connection, { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Blind failed (bad denomination key!?)\n"); - return (MHD_YES == TEH_RESPONSE_reply_internal_error (connection, - "Blinding error")) + return (MHD_YES == + TEH_RESPONSE_reply_internal_error (connection, + TALER_EC_REFRESH_REVEAL_BLINDING_ERROR, + "Blinding error")) ? GNUNET_NO : GNUNET_SYSERR; } GNUNET_CRYPTO_hash_context_read (hash_context, @@ -1274,7 +1312,8 @@ execute_refresh_reveal_transaction (struct MHD_Connection *connection, j); if (NULL == ev_sigs[j].rsa_signature) { - ret = TEH_RESPONSE_reply_internal_db_error (connection); + ret = TEH_RESPONSE_reply_internal_db_error (connection, + TALER_EC_REFRESH_REVEAL_SIGNING_ERROR); goto cleanup; } } @@ -1323,7 +1362,8 @@ TEH_DB_execute_refresh_reveal (struct MHD_Connection *connection, if (NULL == (session = TEH_plugin->get_session (TEH_plugin->cls))) { GNUNET_break (0); - return TEH_RESPONSE_reply_internal_db_error (connection); + return TEH_RESPONSE_reply_internal_db_error (connection, + TALER_EC_DB_SETUP_FAILED); } res = TEH_plugin->get_refresh_session (TEH_plugin->cls, @@ -1332,10 +1372,12 @@ TEH_DB_execute_refresh_reveal (struct MHD_Connection *connection, &refresh_session); if (GNUNET_NO == res) return TEH_RESPONSE_reply_arg_invalid (connection, + TALER_EC_REFRESH_REVEAL_SESSION_UNKNOWN, "session_hash"); if ( (GNUNET_SYSERR == res) || (refresh_session.noreveal_index >= TALER_CNC_KAPPA) ) - return TEH_RESPONSE_reply_internal_db_error (connection); + return TEH_RESPONSE_reply_internal_db_error (connection, + TALER_EC_REFRESH_REVEAL_DB_FETCH_SESSION_ERROR); denom_pubs = GNUNET_new_array (refresh_session.num_newcoins, struct TALER_DenominationPublicKey); if (GNUNET_OK != @@ -1349,7 +1391,8 @@ TEH_DB_execute_refresh_reveal (struct MHD_Connection *connection, GNUNET_free (denom_pubs); GNUNET_CRYPTO_rsa_signature_free (refresh_session.melt.coin.denom_sig.rsa_signature); GNUNET_CRYPTO_rsa_public_key_free (refresh_session.melt.coin.denom_pub.rsa_public_key); - return (MHD_YES == TEH_RESPONSE_reply_internal_db_error (connection)) + return (MHD_YES == TEH_RESPONSE_reply_internal_db_error (connection, + TALER_EC_REFRESH_REVEAL_DB_FETCH_ORDER_ERROR)) ? GNUNET_NO : GNUNET_SYSERR; } @@ -1373,7 +1416,8 @@ TEH_DB_execute_refresh_reveal (struct MHD_Connection *connection, GNUNET_CRYPTO_rsa_signature_free (refresh_session.melt.coin.denom_sig.rsa_signature); GNUNET_CRYPTO_rsa_public_key_free (refresh_session.melt.coin.denom_pub.rsa_public_key); GNUNET_CRYPTO_hash_context_abort (hash_context); - return (MHD_YES == TEH_RESPONSE_reply_internal_db_error (connection)) + return (MHD_YES == TEH_RESPONSE_reply_internal_db_error (connection, + TALER_EC_REFRESH_REVEAL_DB_FETCH_TRANSFER_ERROR)) ? GNUNET_NO : GNUNET_SYSERR; } GNUNET_CRYPTO_hash_context_read (hash_context, @@ -1410,7 +1454,8 @@ TEH_DB_execute_refresh_reveal (struct MHD_Connection *connection, GNUNET_CRYPTO_rsa_signature_free (refresh_session.melt.coin.denom_sig.rsa_signature); GNUNET_CRYPTO_rsa_public_key_free (refresh_session.melt.coin.denom_pub.rsa_public_key); GNUNET_CRYPTO_hash_context_abort (hash_context); - return (MHD_YES == TEH_RESPONSE_reply_internal_db_error (connection)) + return (MHD_YES == TEH_RESPONSE_reply_internal_db_error (connection, + TALER_EC_REFRESH_REVEAL_DB_FETCH_ORDER_ERROR)) ? GNUNET_NO : GNUNET_SYSERR; } for (i=0;iget_session (TEH_plugin->cls))) { GNUNET_break (0); - return TEH_RESPONSE_reply_internal_db_error (connection); + return TEH_RESPONSE_reply_internal_db_error (connection, + TALER_EC_DB_SETUP_FAILED); } ctx.connection = connection; ctx.num_sessions = 0; @@ -1680,6 +1727,7 @@ TEH_DB_execute_refresh_link (struct MHD_Connection *connection, GNUNET_assert (GNUNET_OK == ctx.status); if (0 == ctx.num_sessions) return TEH_RESPONSE_reply_arg_unknown (connection, + TALER_EC_REFRESH_LINK_COIN_UNKNOWN, "coin_pub"); res = TEH_RESPONSE_reply_refresh_link_success (connection, ctx.num_sessions, @@ -1720,7 +1768,8 @@ TEH_DB_execute_admin_add_incoming (struct MHD_Connection *connection, if (NULL == (session = TEH_plugin->get_session (TEH_plugin->cls))) { GNUNET_break (0); - return TEH_RESPONSE_reply_internal_db_error (connection); + return TEH_RESPONSE_reply_internal_db_error (connection, + TALER_EC_DB_SETUP_FAILED); } ret = TEH_plugin->reserves_in_insert (TEH_plugin->cls, session, @@ -1732,7 +1781,8 @@ TEH_DB_execute_admin_add_incoming (struct MHD_Connection *connection, if (GNUNET_SYSERR == ret) { GNUNET_break (0); - return TEH_RESPONSE_reply_internal_db_error (connection); + return TEH_RESPONSE_reply_internal_db_error (connection, + TALER_EC_ADMIN_ADD_INCOMING_DB_STORE); } return TEH_RESPONSE_reply_json_pack (connection, MHD_HTTP_OK, @@ -1913,7 +1963,8 @@ TEH_DB_execute_track_transfer (struct MHD_Connection *connection, if (NULL == (session = TEH_plugin->get_session (TEH_plugin->cls))) { GNUNET_break (0); - return TEH_RESPONSE_reply_internal_db_error (connection); + return TEH_RESPONSE_reply_internal_db_error (connection, + TALER_EC_DB_SETUP_FAILED); } ctx.is_valid = GNUNET_NO; ctx.wdd_head = NULL; @@ -1926,18 +1977,21 @@ TEH_DB_execute_track_transfer (struct MHD_Connection *connection, if (GNUNET_SYSERR == ret) { GNUNET_break (0); - ret = TEH_RESPONSE_reply_internal_db_error (connection); + ret = TEH_RESPONSE_reply_internal_db_error (connection, + TALER_EC_TRACK_TRANSFER_DB_FETCH_FAILED); goto cleanup; } if (GNUNET_SYSERR == ctx.is_valid) { GNUNET_break (0); - ret = TEH_RESPONSE_reply_internal_db_error (connection); + ret = TEH_RESPONSE_reply_internal_db_error (connection, + TALER_EC_TRACK_TRANSFER_DB_INCONSISTENT); goto cleanup; } if (GNUNET_NO == ctx.is_valid) { ret = TEH_RESPONSE_reply_arg_unknown (connection, + TALER_EC_TRACK_TRANSFER_WTID_NOT_FOUND, "wtid"); goto cleanup; } @@ -2035,7 +2089,8 @@ handle_wtid_data (void *cls, coin_fee)) { GNUNET_break (0); - ctx->res = TEH_RESPONSE_reply_internal_db_error (ctx->connection); + ctx->res = TEH_RESPONSE_reply_internal_db_error (ctx->connection, + TALER_EC_TRACK_TRANSACTION_DB_FEE_INCONSISTENT); } else { @@ -2079,7 +2134,8 @@ TEH_DB_execute_track_transaction (struct MHD_Connection *connection, if (NULL == (session = TEH_plugin->get_session (TEH_plugin->cls))) { GNUNET_break (0); - return TEH_RESPONSE_reply_internal_db_error (connection); + return TEH_RESPONSE_reply_internal_db_error (connection, + TALER_EC_DB_SETUP_FAILED); } ctx.connection = connection; ctx.h_contract = *h_contract; @@ -2100,17 +2156,20 @@ TEH_DB_execute_track_transaction (struct MHD_Connection *connection, { GNUNET_break (0); GNUNET_break (GNUNET_SYSERR == ctx.res); - return TEH_RESPONSE_reply_internal_db_error (connection); + return TEH_RESPONSE_reply_internal_db_error (connection, + TALER_EC_TRACK_TRANSACTION_DB_FETCH_FAILED); } if (GNUNET_NO == ret) { GNUNET_break (GNUNET_SYSERR == ctx.res); - return TEH_RESPONSE_reply_transaction_unknown (connection); + return TEH_RESPONSE_reply_transaction_unknown (connection, + TALER_EC_TRACK_TRANSACTION_NOT_FOUND); } if (GNUNET_SYSERR == ctx.res) { GNUNET_break (0); return TEH_RESPONSE_reply_internal_error (connection, + TALER_EC_TRACK_TRANSACTION_WTID_RESOLUTION_ERROR, "bug resolving deposit wtid"); } return ctx.res; diff --git a/src/exchange/taler-exchange-httpd_deposit.c b/src/exchange/taler-exchange-httpd_deposit.c index a97dd0514..1784f6fdf 100644 --- a/src/exchange/taler-exchange-httpd_deposit.c +++ b/src/exchange/taler-exchange-httpd_deposit.c @@ -48,12 +48,9 @@ */ static int verify_and_execute_deposit (struct MHD_Connection *connection, - const struct TALER_EXCHANGEDB_Deposit *deposit) + const struct TALER_EXCHANGEDB_Deposit *deposit) { - struct TEH_KS_StateHandle *key_state; struct TALER_DepositRequestPS dr; - struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki; - struct TALER_Amount fee_deposit; dr.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_DEPOSIT); dr.purpose.size = htonl (sizeof (struct TALER_DepositRequestPS)); @@ -76,39 +73,9 @@ verify_and_execute_deposit (struct MHD_Connection *connection, { TALER_LOG_WARNING ("Invalid signature on /deposit request\n"); return TEH_RESPONSE_reply_signature_invalid (connection, + TALER_EC_DEPOSIT_COIN_SIGNATURE_INVALID, "coin_sig"); } - /* check denomination exists and is valid */ - key_state = TEH_KS_acquire (); - dki = TEH_KS_denomination_key_lookup (key_state, - &deposit->coin.denom_pub, - TEH_KS_DKU_DEPOSIT); - if (NULL == dki) - { - TEH_KS_release (key_state); - TALER_LOG_WARNING ("Unknown denomination key in /deposit request\n"); - return TEH_RESPONSE_reply_arg_unknown (connection, - "denom_pub"); - } - /* check coin signature */ - if (GNUNET_YES != - TALER_test_coin_valid (&deposit->coin)) - { - TALER_LOG_WARNING ("Invalid coin passed for /deposit\n"); - TEH_KS_release (key_state); - return TEH_RESPONSE_reply_signature_invalid (connection, - "ub_sig"); - } - TALER_amount_ntoh (&fee_deposit, - &dki->issue.properties.fee_deposit); - if (0 < TALER_amount_cmp (&fee_deposit, - &deposit->amount_with_fee)) - { - TEH_KS_release (key_state); - return TEH_RESPONSE_reply_external_error (connection, - "deposited amount smaller than depositing fee"); - } - TEH_KS_release (key_state); return TEH_DB_execute_deposit (connection, deposit); @@ -141,12 +108,11 @@ TEH_DEPOSIT_handler_deposit (struct TEH_RequestHandler *rh, json_t *wire; struct TALER_EXCHANGEDB_Deposit deposit; struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki; - struct TEH_KS_StateHandle *ks; + struct TEH_KS_StateHandle *key_state; struct GNUNET_HashCode my_h_wire; - struct TALER_Amount amount; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_json ("wire", &wire), - TALER_JSON_spec_amount ("f", &amount), + TALER_JSON_spec_amount ("f", &deposit.amount_with_fee), TALER_JSON_spec_denomination_public_key ("denom_pub", &deposit.coin.denom_pub), TALER_JSON_spec_denomination_signature ("ub_sig", &deposit.coin.denom_sig), GNUNET_JSON_spec_fixed_auto ("coin_pub", &deposit.coin.coin_pub), @@ -180,11 +146,13 @@ TEH_DEPOSIT_handler_deposit (struct TEH_RequestHandler *rh, if (GNUNET_NO == res) return MHD_YES; /* failure */ + deposit.receiver_wire_account = wire; if (deposit.refund_deadline.abs_value_us > deposit.wire_deadline.abs_value_us) { GNUNET_break_op (0); GNUNET_JSON_parse_free (spec); return TEH_RESPONSE_reply_arg_invalid (connection, + TALER_EC_DEPOSIT_REFUND_DEADLINE_AFTER_WIRE_DEADLINE, "refund_deadline"); } @@ -194,6 +162,7 @@ TEH_DEPOSIT_handler_deposit (struct TEH_RequestHandler *rh, { GNUNET_JSON_parse_free (spec); return TEH_RESPONSE_reply_arg_unknown (connection, + TALER_EC_DEPOSIT_INVALID_WIRE_FORMAT, "wire"); } if (GNUNET_OK != @@ -203,6 +172,7 @@ TEH_DEPOSIT_handler_deposit (struct TEH_RequestHandler *rh, TALER_LOG_WARNING ("Failed to parse JSON wire format specification for /deposit request\n"); GNUNET_JSON_parse_free (spec); return TEH_RESPONSE_reply_arg_invalid (connection, + TALER_EC_DEPOSIT_INVALID_WIRE_FORMAT_JSON, "wire"); } if (0 != memcmp (&deposit.h_wire, @@ -212,32 +182,48 @@ TEH_DEPOSIT_handler_deposit (struct TEH_RequestHandler *rh, /* Client hashed contract differently than we did, reject */ GNUNET_JSON_parse_free (spec); return TEH_RESPONSE_reply_arg_invalid (connection, + TALER_EC_DEPOSIT_INVALID_WIRE_FORMAT_CONTRACT_HASH_CONFLICT, "H_wire"); } - ks = TEH_KS_acquire (); - dki = TEH_KS_denomination_key_lookup (ks, + + /* check denomination exists and is valid */ + key_state = TEH_KS_acquire (); + dki = TEH_KS_denomination_key_lookup (key_state, &deposit.coin.denom_pub, TEH_KS_DKU_DEPOSIT); if (NULL == dki) { - TEH_KS_release (ks); - GNUNET_JSON_parse_free (spec); + TEH_KS_release (key_state); + TALER_LOG_WARNING ("Unknown denomination key in /deposit request\n"); return TEH_RESPONSE_reply_arg_unknown (connection, + TALER_EC_DEPOSIT_DENOMINATION_KEY_UNKNOWN, "denom_pub"); } TALER_amount_ntoh (&deposit.deposit_fee, &dki->issue.properties.fee_deposit); - TEH_KS_release (ks); - deposit.receiver_wire_account = wire; - deposit.amount_with_fee = amount; - if (-1 == TALER_amount_cmp (&deposit.amount_with_fee, - &deposit.deposit_fee)) + /* check coin signature */ + if (GNUNET_YES != + TALER_test_coin_valid (&deposit.coin)) { - /* Total amount smaller than fee, invalid */ - GNUNET_JSON_parse_free (spec); - return TEH_RESPONSE_reply_arg_invalid (connection, - "f"); + TALER_LOG_WARNING ("Invalid coin passed for /deposit\n"); + TEH_KS_release (key_state); + return TEH_RESPONSE_reply_signature_invalid (connection, + TALER_EC_DEPOSIT_DENOMINATION_SIGNATURE_INVALID, + "ub_sig"); } + TALER_amount_ntoh (&deposit.deposit_fee, + &dki->issue.properties.fee_deposit); + TEH_KS_release (key_state); + + if (0 < TALER_amount_cmp (&deposit.deposit_fee, + &deposit.amount_with_fee)) + { + return TEH_RESPONSE_reply_external_error (connection, + TALER_EC_DEPOSIT_NEGATIVE_VALUE_AFTER_FEE, + "deposited amount smaller than depositing fee"); + } + TEH_KS_release (key_state); + res = verify_and_execute_deposit (connection, &deposit); GNUNET_JSON_parse_free (spec); diff --git a/src/exchange/taler-exchange-httpd_parsing.c b/src/exchange/taler-exchange-httpd_parsing.c index c7118c462..e9c38eb82 100644 --- a/src/exchange/taler-exchange-httpd_parsing.c +++ b/src/exchange/taler-exchange-httpd_parsing.c @@ -79,6 +79,7 @@ TEH_PARSE_post_json (struct MHD_Connection *connection, case GNUNET_JSON_PR_OUT_OF_MEMORY: return (MHD_NO == TEH_RESPONSE_reply_internal_error (connection, + TALER_EC_PARSER_OUT_OF_MEMORY, "out of memory")) ? GNUNET_SYSERR : GNUNET_NO; case GNUNET_JSON_PR_CONTINUE: @@ -144,7 +145,9 @@ TEH_PARSE_mhd_request_arg_data (struct MHD_Connection *connection, if (NULL == str) { return (MHD_NO == - TEH_RESPONSE_reply_arg_missing (connection, param_name)) + TEH_RESPONSE_reply_arg_missing (connection, + TALER_EC_PARAMETER_MISSING, + param_name)) ? GNUNET_SYSERR : GNUNET_NO; } if (GNUNET_OK != @@ -153,7 +156,9 @@ TEH_PARSE_mhd_request_arg_data (struct MHD_Connection *connection, out_data, out_size)) return (MHD_NO == - TEH_RESPONSE_reply_arg_invalid (connection, param_name)) + TEH_RESPONSE_reply_arg_invalid (connection, + TALER_EC_PARAMETER_MALFORMED, + param_name)) ? GNUNET_SYSERR : GNUNET_NO; return GNUNET_OK; } @@ -193,8 +198,9 @@ TEH_PARSE_json_data (struct MHD_Connection *connection, ret = (MHD_YES == TEH_RESPONSE_reply_json_pack (connection, MHD_HTTP_BAD_REQUEST, - "{s:s, s:s, s:I}", + "{s:s, s:I, s:s, s:I}", "error", "parse error", + "code", (json_int_t) TALER_EC_JSON_INVALID_WITH_DETAILS, "field", error_json_name, "line", (json_int_t) error_line)) ? GNUNET_NO : GNUNET_SYSERR; diff --git a/src/exchange/taler-exchange-httpd_refresh.c b/src/exchange/taler-exchange-httpd_refresh.c index 0c500920d..3a8875f44 100644 --- a/src/exchange/taler-exchange-httpd_refresh.c +++ b/src/exchange/taler-exchange-httpd_refresh.c @@ -69,7 +69,7 @@ handle_refresh_melt_binary (struct MHD_Connection *connection, struct TALER_Amount total_melt; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "melt request for session %s\n", + "/refresh/melt request for session %s\n", GNUNET_h2s (session_hash)); GNUNET_assert (GNUNET_OK == @@ -86,6 +86,7 @@ handle_refresh_melt_binary (struct MHD_Connection *connection, GNUNET_break_op (0); TEH_KS_release (key_state); return TEH_RESPONSE_reply_arg_invalid (connection, + TALER_EC_REFRESH_MELT_FRESH_DENOMINATION_KEY_NOT_FOUND, "new_denoms"); } dki = &dk->issue; @@ -105,6 +106,7 @@ handle_refresh_melt_binary (struct MHD_Connection *connection, GNUNET_break_op (0); TEH_KS_release (key_state); return TEH_RESPONSE_reply_internal_error (connection, + TALER_EC_REFRESH_MELT_COST_CALCULATION_OVERFLOW, "cost calculation failure"); } } @@ -115,8 +117,9 @@ handle_refresh_melt_binary (struct MHD_Connection *connection, if (NULL == dk) { GNUNET_break (0); - return TEH_RESPONSE_reply_arg_invalid (connection, - "denom_pub"); + return TEH_RESPONSE_reply_arg_unknown (connection, + TALER_EC_REFRESH_MELT_DENOMINATION_KEY_NOT_FOUND, + "denom_pub"); } dki = &dk->issue; TALER_amount_ntoh (&fee_melt, @@ -129,6 +132,7 @@ handle_refresh_melt_binary (struct MHD_Connection *connection, GNUNET_break_op (0); TEH_KS_release (key_state); return TEH_RESPONSE_reply_external_error (connection, + TALER_EC_REFRESH_MELT_FEES_EXCEED_CONTRIBUTION, "Melt contribution below melting fee"); } TEH_KS_release (key_state); @@ -141,8 +145,9 @@ handle_refresh_melt_binary (struct MHD_Connection *connection, total value of coins being generated to match! */ return TEH_RESPONSE_reply_json_pack (connection, MHD_HTTP_BAD_REQUEST, - "{s:s}", - "error", "value mismatch"); + "{s:s, s:I}", + "error", "value mismatch", + "code", (json_int_t) TALER_EC_REFRESH_MELT_FEES_MISSMATCH); } return TEH_DB_execute_refresh_melt (connection, session_hash, @@ -203,6 +208,7 @@ get_coin_public_info (struct MHD_Connection *connection, r_melt_detail->coin_info.denom_pub.rsa_public_key = NULL; return (MHD_YES == TEH_RESPONSE_reply_signature_invalid (connection, + TALER_EC_REFRESH_MELT_DENOMINATION_SIGNATURE_INVALID, "denom_sig")) ? GNUNET_NO : GNUNET_SYSERR; } @@ -237,6 +243,8 @@ verify_coin_public_info (struct MHD_Connection *connection, struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki; struct TALER_Amount fee_refresh; + /* FIXME: we lookup the dki twice during /refresh/melt. + This should be avoided. */ key_state = TEH_KS_acquire (); dki = TEH_KS_denomination_key_lookup (key_state, &melt_detail->coin_info.denom_pub, @@ -246,6 +254,7 @@ verify_coin_public_info (struct MHD_Connection *connection, TEH_KS_release (key_state); TALER_LOG_WARNING ("Unknown denomination key in /refresh/melt request\n"); return TEH_RESPONSE_reply_arg_unknown (connection, + TALER_EC_REFRESH_MELT_DENOMINATION_KEY_NOT_FOUND, "denom_pub"); } TALER_amount_ntoh (&fee_refresh, @@ -266,6 +275,7 @@ verify_coin_public_info (struct MHD_Connection *connection, TEH_KS_release (key_state); return (MHD_YES == TEH_RESPONSE_reply_external_error (connection, + TALER_EC_REFRESH_MELT_AMOUNT_INSUFFICIENT, "melt amount smaller than melting fee")) ? GNUNET_NO : GNUNET_SYSERR; } @@ -280,6 +290,7 @@ verify_coin_public_info (struct MHD_Connection *connection, GNUNET_break_op (0); if (MHD_YES != TEH_RESPONSE_reply_signature_invalid (connection, + TALER_EC_REFRESH_MELT_COIN_SIGNATURE_INVALID, "confirm_sig")) return GNUNET_SYSERR; return GNUNET_NO; @@ -565,6 +576,7 @@ TEH_REFRESH_handler_refresh_melt (struct TEH_RequestHandler *rh, GNUNET_break_op (0); GNUNET_JSON_parse_free (spec); return TEH_RESPONSE_reply_arg_invalid (connection, + TALER_EC_REFRESH_MELT_CNC_COIN_ARRAY_SIZE_INVALID, "coin_evs"); } if (TALER_CNC_KAPPA != json_array_size (transfer_pubs)) @@ -572,6 +584,7 @@ TEH_REFRESH_handler_refresh_melt (struct TEH_RequestHandler *rh, GNUNET_break_op (0); GNUNET_JSON_parse_free (spec); return TEH_RESPONSE_reply_arg_invalid (connection, + TALER_EC_REFRESH_MELT_CNC_TRANSFER_ARRAY_SIZE_INVALID, "transfer_pubs"); } res = handle_refresh_melt_json (connection, @@ -694,6 +707,7 @@ TEH_REFRESH_handler_refresh_reveal (struct TEH_RequestHandler *rh, GNUNET_JSON_parse_free (spec); GNUNET_break_op (0); return TEH_RESPONSE_reply_arg_invalid (connection, + TALER_EC_REFRESH_REVEAL_CNC_TRANSFER_ARRAY_SIZE_INVALID, "transfer_privs"); } res = handle_refresh_reveal_json (connection, diff --git a/src/exchange/taler-exchange-httpd_refund.c b/src/exchange/taler-exchange-httpd_refund.c index fdb6f8b76..591bb188d 100644 --- a/src/exchange/taler-exchange-httpd_refund.c +++ b/src/exchange/taler-exchange-httpd_refund.c @@ -69,14 +69,16 @@ verify_and_execute_refund (struct MHD_Connection *connection, { GNUNET_break_op (0); return TEH_RESPONSE_reply_arg_invalid (connection, + TALER_EC_REFUND_FEE_CURRENCY_MISSMATCH, "refund_fee"); } if (-1 == TALER_amount_cmp (&refund->refund_amount, &refund->refund_fee) ) { GNUNET_break_op (0); - return TEH_RESPONSE_reply_signature_invalid (connection, - "refund_amount"); + return TEH_RESPONSE_reply_arg_invalid (connection, + TALER_EC_REFUND_FEE_ABOVE_AMOUNT, + "refund_amount"); } if (GNUNET_OK != GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MERCHANT_REFUND, @@ -86,6 +88,7 @@ verify_and_execute_refund (struct MHD_Connection *connection, { TALER_LOG_WARNING ("Invalid signature on /refund request\n"); return TEH_RESPONSE_reply_signature_invalid (connection, + TALER_EC_REFUND_MERCHANT_SIGNATURE_INVALID, "merchant_sig"); } return TEH_DB_execute_refund (connection, diff --git a/src/exchange/taler-exchange-httpd_reserve.c b/src/exchange/taler-exchange-httpd_reserve.c index 7098e99a2..0abe37c5a 100644 --- a/src/exchange/taler-exchange-httpd_reserve.c +++ b/src/exchange/taler-exchange-httpd_reserve.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014,2015 GNUnet e.V. + Copyright (C) 2014, 2015, 2016 GNUnet e.V. 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 @@ -138,6 +138,7 @@ TEH_RESERVE_handler_reserve_withdraw (struct TEH_RequestHandler *rh, GNUNET_JSON_parse_free (spec); TEH_KS_release (ks); return TEH_RESPONSE_reply_arg_unknown (connection, + TALER_EC_WITHDRAW_DENOMINATION_KEY_NOT_FOUND, "denom_pub"); } TALER_amount_ntoh (&amount, @@ -171,6 +172,7 @@ TEH_RESERVE_handler_reserve_withdraw (struct TEH_RequestHandler *rh, TALER_LOG_WARNING ("Client supplied invalid signature for /reserve/withdraw request\n"); GNUNET_JSON_parse_free (spec); return TEH_RESPONSE_reply_signature_invalid (connection, + TALER_EC_WITHDRAW_RESERVE_SIGNATURE_INVALID, "reserve_sig"); } res = TEH_DB_execute_reserve_withdraw (connection, diff --git a/src/exchange/taler-exchange-httpd_responses.c b/src/exchange/taler-exchange-httpd_responses.c index cacd933f1..182bb5295 100644 --- a/src/exchange/taler-exchange-httpd_responses.c +++ b/src/exchange/taler-exchange-httpd_responses.c @@ -132,17 +132,20 @@ TEH_RESPONSE_reply_json_pack (struct MHD_Connection *connection, * Send a response indicating an invalid argument. * * @param connection the MHD connection to use + * @param ec error code uniquely identifying the error * @param param_name the parameter that is invalid * @return a MHD result code */ int TEH_RESPONSE_reply_arg_invalid (struct MHD_Connection *connection, + enum TALER_ErrorCode ec, const char *param_name) { return TEH_RESPONSE_reply_json_pack (connection, MHD_HTTP_BAD_REQUEST, - "{s:s, s:s}", + "{s:s, s:I, s:s}", "error", "invalid parameter", + "code", (json_int_t) ec, "parameter", param_name); } @@ -153,17 +156,20 @@ TEH_RESPONSE_reply_arg_invalid (struct MHD_Connection *connection, * denomination key). * * @param connection the MHD connection to use + * @param ec error code uniquely identifying the error * @param param_name the parameter that is invalid * @return a MHD result code */ int TEH_RESPONSE_reply_arg_unknown (struct MHD_Connection *connection, + enum TALER_ErrorCode ec, const char *param_name) { return TEH_RESPONSE_reply_json_pack (connection, MHD_HTTP_NOT_FOUND, - "{s:s, s:s}", + "{s:s, s:I, s:s}", "error", "unknown entity referenced", + "code", (json_int_t) ec, "parameter", param_name); } @@ -172,17 +178,20 @@ TEH_RESPONSE_reply_arg_unknown (struct MHD_Connection *connection, * Send a response indicating an invalid signature. * * @param connection the MHD connection to use + * @param ec error code uniquely identifying the error * @param param_name the parameter that is invalid * @return a MHD result code */ int TEH_RESPONSE_reply_signature_invalid (struct MHD_Connection *connection, + enum TALER_ErrorCode ec, const char *param_name) { return TEH_RESPONSE_reply_json_pack (connection, MHD_HTTP_UNAUTHORIZED, - "{s:s, s:s}", + "{s:s, s:I, s:s}", "error", "invalid signature", + "code", (json_int_t) ec, "parameter", param_name); } @@ -191,17 +200,20 @@ TEH_RESPONSE_reply_signature_invalid (struct MHD_Connection *connection, * Send a response indicating a missing argument. * * @param connection the MHD connection to use + * @param ec error code uniquely identifying the error * @param param_name the parameter that is missing * @return a MHD result code */ int TEH_RESPONSE_reply_arg_missing (struct MHD_Connection *connection, + enum TALER_ErrorCode ec, const char *param_name) { return TEH_RESPONSE_reply_json_pack (connection, MHD_HTTP_BAD_REQUEST, - "{ s:s, s:s}", + "{ s:s, s:I, s:s}", "error", "missing parameter", + "code", (json_int_t) ec, "parameter", param_name); } @@ -210,17 +222,20 @@ TEH_RESPONSE_reply_arg_missing (struct MHD_Connection *connection, * Send a response indicating permission denied. * * @param connection the MHD connection to use + * @param ec error code uniquely identifying the error * @param hint hint about why access was denied * @return a MHD result code */ int TEH_RESPONSE_reply_permission_denied (struct MHD_Connection *connection, + enum TALER_ErrorCode ec, const char *hint) { return TEH_RESPONSE_reply_json_pack (connection, MHD_HTTP_FORBIDDEN, - "{s:s, s:s}", + "{s:s, s:I, s:s}", "error", "permission denied", + "code", (json_int_t) ec, "hint", hint); } @@ -229,17 +244,20 @@ TEH_RESPONSE_reply_permission_denied (struct MHD_Connection *connection, * Send a response indicating an internal error. * * @param connection the MHD connection to use + * @param ec error code uniquely identifying the error * @param hint hint about the internal error's nature * @return a MHD result code */ int TEH_RESPONSE_reply_internal_error (struct MHD_Connection *connection, + enum TALER_ErrorCode ec, const char *hint) { return TEH_RESPONSE_reply_json_pack (connection, MHD_HTTP_INTERNAL_SERVER_ERROR, - "{s:s, s:s}", + "{s:s, s:I, s:s}", "error", "internal error", + "code", (json_int_t) ec, "hint", hint); } @@ -248,17 +266,20 @@ TEH_RESPONSE_reply_internal_error (struct MHD_Connection *connection, * Send a response indicating an external error. * * @param connection the MHD connection to use + * @param ec error code uniquely identifying the error * @param hint hint about the error's nature * @return a MHD result code */ int TEH_RESPONSE_reply_external_error (struct MHD_Connection *connection, + enum TALER_ErrorCode ec, const char *hint) { return TEH_RESPONSE_reply_json_pack (connection, MHD_HTTP_BAD_REQUEST, - "{s:s, s:s}", + "{s:s, s:I, s:s}", "error", "client error", + "code", (json_int_t) ec, "hint", hint); } @@ -268,15 +289,18 @@ TEH_RESPONSE_reply_external_error (struct MHD_Connection *connection, * transaction (concurrent interference). * * @param connection the MHD connection to use + * @param ec error code uniquely identifying the error * @return a MHD result code */ int -TEH_RESPONSE_reply_commit_error (struct MHD_Connection *connection) +TEH_RESPONSE_reply_commit_error (struct MHD_Connection *connection, + enum TALER_ErrorCode ec) { return TEH_RESPONSE_reply_json_pack (connection, MHD_HTTP_BAD_REQUEST, - "{s:s}", - "error", "commit failure"); + "{s:s, s:I}", + "error", "commit failure", + "code", (json_int_t) ec); } @@ -285,12 +309,15 @@ TEH_RESPONSE_reply_commit_error (struct MHD_Connection *connection) * database. * * @param connection the MHD connection to use + * @param ec error code uniquely identifying the error * @return a MHD result code */ int -TEH_RESPONSE_reply_internal_db_error (struct MHD_Connection *connection) +TEH_RESPONSE_reply_internal_db_error (struct MHD_Connection *connection, + enum TALER_ErrorCode ec) { return TEH_RESPONSE_reply_internal_error (connection, + ec, "Failed to connect to database"); } @@ -332,9 +359,9 @@ TEH_RESPONSE_reply_invalid_json (struct MHD_Connection *connection) { return TEH_RESPONSE_reply_json_pack (connection, MHD_HTTP_BAD_REQUEST, - "{s:s}", - "error", - "invalid json"); + "{s:s, s:I}", + "error", "invalid json", + "code", (json_int_t) TALER_EC_JSON_INVALID); } @@ -556,11 +583,13 @@ TEH_RESPONSE_reply_deposit_insufficient_funds (struct MHD_Connection *connection history = compile_transaction_history (tl); if (NULL == history) - return TEH_RESPONSE_reply_internal_db_error (connection); + return TEH_RESPONSE_reply_internal_db_error (connection, + TALER_EC_DEPOSIT_HISTORY_DB_ERROR_INSUFFICIENT_FUNDS); return TEH_RESPONSE_reply_json_pack (connection, MHD_HTTP_FORBIDDEN, "{s:s, s:o}", "error", "insufficient funds", + "code", TALER_EC_DEPOSIT_INSUFFICIENT_FUNDS, "history", history); } @@ -696,8 +725,9 @@ TEH_RESPONSE_reply_refund_conflict (struct MHD_Connection *connection, { return TEH_RESPONSE_reply_json_pack (connection, MHD_HTTP_CONFLICT, - "{s:s, s:o}", + "{s:s, s:I, s:o}", "status", "conflicting refund", + "code", TALER_EC_REFUND_CONFLICT, "history", compile_transaction_history (tl)); } @@ -708,17 +738,19 @@ TEH_RESPONSE_reply_refund_conflict (struct MHD_Connection *connection, * * @param connection connection to the client * @param response_code response code to generate + * @param ec taler error code to include * @return MHD result code */ int TEH_RESPONSE_reply_refund_failure (struct MHD_Connection *connection, - unsigned int response_code) + unsigned int response_code, + enum TALER_ErrorCode ec) { return TEH_RESPONSE_reply_json_pack (connection, response_code, - "{s:s}", - "error", - "no details"); + "{s:s, s:I}", + "status", "refund failure", + "code", (json_int_t) ec); } @@ -779,6 +811,7 @@ TEH_RESPONSE_reply_reserve_status_success (struct MHD_Connection *connection, &balance); if (NULL == json_history) return TEH_RESPONSE_reply_internal_error (connection, + TALER_EC_RESERVE_STATUS_DB_ERROR, "balance calculation failure"); json_balance = TALER_JSON_from_amount (&balance); return TEH_RESPONSE_reply_json_pack (connection, @@ -810,12 +843,14 @@ TEH_RESPONSE_reply_reserve_withdraw_insufficient_funds (struct MHD_Connection *c &balance); if (NULL == json_history) return TEH_RESPONSE_reply_internal_error (connection, + TALER_EC_WITHDRAW_HISTORY_DB_ERROR_INSUFFICIENT_FUNDS, "balance calculation failure"); json_balance = TALER_JSON_from_amount (&balance); return TEH_RESPONSE_reply_json_pack (connection, - MHD_HTTP_PAYMENT_REQUIRED, - "{s:s, s:o, s:o}", + MHD_HTTP_FORBIDDEN, + "{s:s, s:I, s:o, s:o}", "error", "Insufficient funds", + "code", TALER_EC_WITHDRAW_INSUFFICIENT_FUNDS, "balance", json_balance, "history", json_history); } @@ -830,7 +865,7 @@ TEH_RESPONSE_reply_reserve_withdraw_insufficient_funds (struct MHD_Connection *c */ int TEH_RESPONSE_reply_reserve_withdraw_success (struct MHD_Connection *connection, - const struct TALER_EXCHANGEDB_CollectableBlindcoin *collectable) + const struct TALER_EXCHANGEDB_CollectableBlindcoin *collectable) { json_t *sig_json; @@ -869,12 +904,15 @@ TEH_RESPONSE_reply_refresh_melt_insufficient_funds (struct MHD_Connection *conne history = compile_transaction_history (tl); if (NULL == history) - return TEH_RESPONSE_reply_internal_db_error (connection); + return TEH_RESPONSE_reply_internal_db_error (connection, + TALER_EC_REFRESH_MELT_HISTORY_DB_ERROR_INSUFFICIENT_FUNDS); return TEH_RESPONSE_reply_json_pack (connection, MHD_HTTP_FORBIDDEN, - "{s:s, s:o, s:o, s:o, s:o, s:o}", + "{s:s, s:I, s:o, s:o, s:o, s:o, s:o}", "error", - "insufficient funds", + "insufficient funds", + "code", + TALER_EC_REFRESH_MELT_INSUFFICIENT_FUNDS, "coin_pub", GNUNET_JSON_from_data_auto (coin_pub), "original_value", @@ -1011,8 +1049,9 @@ TEH_RESPONSE_reply_refresh_reveal_missmatch (struct MHD_Connection *connection, } return TEH_RESPONSE_reply_json_pack (connection, MHD_HTTP_CONFLICT, - "{s:s, s:o, s:o, s:o, s:o, s:o, s:o, s:o, s:i}", + "{s:s, s:I, s:o, s:o, s:o, s:o, s:o, s:o, s:o, s:i}", "error", "commitment violation", + "code", (json_int_t) TALER_EC_REFRESH_REVEAL_COMMITMENT_VIOLATION, "coin_sig", GNUNET_JSON_from_data_auto (&session->melt.coin_sig), "coin_pub", GNUNET_JSON_from_data_auto (&session->melt.coin.coin_pub), "melt_amount_with_fee", TALER_JSON_from_amount (&session->melt.amount_with_fee), @@ -1089,15 +1128,18 @@ TEH_RESPONSE_reply_refresh_link_success (struct MHD_Connection *connection, * 404 reply. * * @param connection connection to the client + * @param ec Taler error code * @return MHD result code */ int -TEH_RESPONSE_reply_transaction_unknown (struct MHD_Connection *connection) +TEH_RESPONSE_reply_transaction_unknown (struct MHD_Connection *connection, + enum TALER_ErrorCode ec) { return TEH_RESPONSE_reply_json_pack (connection, MHD_HTTP_NOT_FOUND, - "{s:s}", - "error", "Deposit unknown"); + "{s:s, s:I}", + "error", "Deposit unknown", + "code", ec); } diff --git a/src/exchange/taler-exchange-httpd_responses.h b/src/exchange/taler-exchange-httpd_responses.h index 742a95b91..23cae16d7 100644 --- a/src/exchange/taler-exchange-httpd_responses.h +++ b/src/exchange/taler-exchange-httpd_responses.h @@ -29,6 +29,7 @@ #include #include #include +#include "taler_error_codes.h" #include "taler-exchange-httpd.h" #include "taler-exchange-httpd_db.h" @@ -78,11 +79,13 @@ TEH_RESPONSE_reply_json_pack (struct MHD_Connection *connection, * Send a response indicating an invalid signature. * * @param connection the MHD connection to use + * @param ec error code uniquely identifying the error * @param param_name the parameter that is invalid * @return a MHD result code */ int TEH_RESPONSE_reply_signature_invalid (struct MHD_Connection *connection, + enum TALER_ErrorCode ec, const char *param_name); @@ -90,11 +93,13 @@ TEH_RESPONSE_reply_signature_invalid (struct MHD_Connection *connection, * Send a response indicating an invalid argument. * * @param connection the MHD connection to use + * @param ec error code uniquely identifying the error * @param param_name the parameter that is invalid * @return MHD result code */ int TEH_RESPONSE_reply_arg_invalid (struct MHD_Connection *connection, + enum TALER_ErrorCode ec, const char *param_name); @@ -104,11 +109,13 @@ TEH_RESPONSE_reply_arg_invalid (struct MHD_Connection *connection, * denomination key). * * @param connection the MHD connection to use + * @param ec error code uniquely identifying the error * @param param_name the parameter that is invalid * @return a MHD result code */ int TEH_RESPONSE_reply_arg_unknown (struct MHD_Connection *connection, + enum TALER_ErrorCode ec, const char *param_name); @@ -116,11 +123,13 @@ TEH_RESPONSE_reply_arg_unknown (struct MHD_Connection *connection, * Send a response indicating a missing argument. * * @param connection the MHD connection to use + * @param ec error code uniquely identifying the error * @param param_name the parameter that is missing * @return a MHD result code */ int TEH_RESPONSE_reply_arg_missing (struct MHD_Connection *connection, + enum TALER_ErrorCode ec, const char *param_name); @@ -128,11 +137,13 @@ TEH_RESPONSE_reply_arg_missing (struct MHD_Connection *connection, * Send a response indicating permission denied. * * @param connection the MHD connection to use + * @param ec error code uniquely identifying the error * @param hint hint about why access was denied * @return a MHD result code */ int TEH_RESPONSE_reply_permission_denied (struct MHD_Connection *connection, + enum TALER_ErrorCode ec, const char *hint); @@ -140,11 +151,13 @@ TEH_RESPONSE_reply_permission_denied (struct MHD_Connection *connection, * Send a response indicating an internal error. * * @param connection the MHD connection to use + * @param ec error code uniquely identifying the error * @param hint hint about the internal error's nature * @return a MHD result code */ int TEH_RESPONSE_reply_internal_error (struct MHD_Connection *connection, + enum TALER_ErrorCode ec, const char *hint); @@ -152,11 +165,13 @@ TEH_RESPONSE_reply_internal_error (struct MHD_Connection *connection, * Send a response indicating an external error. * * @param connection the MHD connection to use + * @param ec error code uniquely identifying the error * @param hint hint about the error's nature * @return a MHD result code */ int TEH_RESPONSE_reply_external_error (struct MHD_Connection *connection, + enum TALER_ErrorCode ec, const char *hint); @@ -165,21 +180,24 @@ TEH_RESPONSE_reply_external_error (struct MHD_Connection *connection, * transaction (concurrent interference). * * @param connection the MHD connection to use + * @param ec error code uniquely identifying the error * @return a MHD result code */ int -TEH_RESPONSE_reply_commit_error (struct MHD_Connection *connection); - +TEH_RESPONSE_reply_commit_error (struct MHD_Connection *connection, + enum TALER_ErrorCode ec); /** * Send a response indicating a failure to talk to the Exchange's * database. * * @param connection the MHD connection to use + * @param ec error code uniquely identifying the error * @return a MHD result code */ int -TEH_RESPONSE_reply_internal_db_error (struct MHD_Connection *connection); +TEH_RESPONSE_reply_internal_db_error (struct MHD_Connection *connection, + enum TALER_ErrorCode ec); /** @@ -266,11 +284,13 @@ TEH_RESPONSE_reply_refund_conflict (struct MHD_Connection *connection, * * @param connection connection to the client * @param response_code response code to generate + * @param ec error code uniquely identifying the error * @return MHD result code */ int TEH_RESPONSE_reply_refund_failure (struct MHD_Connection *connection, - unsigned int response_code); + unsigned int response_code, + enum TALER_ErrorCode ec); /** @@ -291,10 +311,12 @@ TEH_RESPONSE_reply_refund_success (struct MHD_Connection *connection, * 404 reply. * * @param connection connection to the client + * @param ec Taler error code * @return MHD result code */ int -TEH_RESPONSE_reply_transaction_unknown (struct MHD_Connection *connection); +TEH_RESPONSE_reply_transaction_unknown (struct MHD_Connection *connection, + enum TALER_ErrorCode ec); /** @@ -307,7 +329,7 @@ TEH_RESPONSE_reply_transaction_unknown (struct MHD_Connection *connection); */ int TEH_RESPONSE_reply_transfer_pending (struct MHD_Connection *connection, - struct GNUNET_TIME_Absolute planned_exec_time); + struct GNUNET_TIME_Absolute planned_exec_time); /** diff --git a/src/exchange/taler-exchange-httpd_test.c b/src/exchange/taler-exchange-httpd_test.c index 7c3252b10..731da36ce 100644 --- a/src/exchange/taler-exchange-httpd_test.c +++ b/src/exchange/taler-exchange-httpd_test.c @@ -295,6 +295,7 @@ TEH_TEST_handler_test_ecdhe (struct TEH_RequestHandler *rh, { GNUNET_JSON_parse_free (spec); return TEH_RESPONSE_reply_internal_error (connection, + TALER_EC_TEST_ECDH_ERROR, "Failed to perform ECDH"); } GNUNET_JSON_parse_free (spec); @@ -365,6 +366,7 @@ TEH_TEST_handler_test_eddsa (struct TEH_RequestHandler *rh, { GNUNET_JSON_parse_free (spec); return TEH_RESPONSE_reply_signature_invalid (connection, + TALER_EC_TEST_EDDSA_INVALID, "eddsa_sig"); } GNUNET_JSON_parse_free (spec); @@ -377,6 +379,7 @@ TEH_TEST_handler_test_eddsa (struct TEH_RequestHandler *rh, { GNUNET_free (pk); return TEH_RESPONSE_reply_internal_error (connection, + TALER_EC_TEST_EDDSA_ERROR, "Failed to EdDSA-sign"); } GNUNET_CRYPTO_eddsa_key_get_public (pk, @@ -419,6 +422,7 @@ TEH_TEST_handler_test_rsa_get (struct TEH_RequestHandler *rh, { GNUNET_break (0); return TEH_RESPONSE_reply_internal_error (connection, + TALER_EC_TEST_RSA_GEN_ERROR, "Failed to create RSA key"); } pub = GNUNET_CRYPTO_rsa_private_key_get_public (rsa_pk); @@ -426,6 +430,7 @@ TEH_TEST_handler_test_rsa_get (struct TEH_RequestHandler *rh, { GNUNET_break (0); return TEH_RESPONSE_reply_internal_error (connection, + TALER_EC_TEST_RSA_PUB_ERROR, "Failed to get public RSA key"); } res = TEH_RESPONSE_reply_json_pack (connection, @@ -489,6 +494,7 @@ TEH_TEST_handler_test_rsa_sign (struct TEH_RequestHandler *rh, GNUNET_break (0); GNUNET_JSON_parse_free (spec); return TEH_RESPONSE_reply_internal_error (connection, + TALER_EC_TEST_RSA_GEN_ERROR, "Failed to create RSA key"); } sig = GNUNET_CRYPTO_rsa_sign_blinded (rsa_pk, @@ -499,6 +505,7 @@ TEH_TEST_handler_test_rsa_sign (struct TEH_RequestHandler *rh, GNUNET_break (0); GNUNET_JSON_parse_free (spec); return TEH_RESPONSE_reply_internal_error (connection, + TALER_EC_TEST_RSA_SIGN_ERROR, "Failed to RSA-sign"); } GNUNET_JSON_parse_free (spec); diff --git a/src/exchange/taler-exchange-httpd_tracking.c b/src/exchange/taler-exchange-httpd_tracking.c index f4d106628..e5d1139f1 100644 --- a/src/exchange/taler-exchange-httpd_tracking.c +++ b/src/exchange/taler-exchange-httpd_tracking.c @@ -88,14 +88,15 @@ check_and_handle_track_transaction_request (struct MHD_Connection *connection, { GNUNET_break_op (0); return TEH_RESPONSE_reply_signature_invalid (connection, + TALER_EC_TRACK_TRANSACTION_MERCHANT_SIGNATURE_INVALID, "merchant_sig"); } return TEH_DB_execute_track_transaction (connection, - &tps->h_contract, - &tps->h_wire, - &tps->coin_pub, - merchant_pub, - transaction_id); + &tps->h_contract, + &tps->h_wire, + &tps->coin_pub, + merchant_pub, + transaction_id); } diff --git a/src/include/taler_error_codes.h b/src/include/taler_error_codes.h index bbb300440..3c3ddcfd4 100644 --- a/src/include/taler_error_codes.h +++ b/src/include/taler_error_codes.h @@ -35,10 +35,769 @@ enum TALER_ErrorCode /** * Special code to indicate no error. */ - TALER_EC_NONE = 0 + TALER_EC_NONE = 0, + /* ********** generic error codes ************* */ + + /** + * The exchange failed to even just initialize its connection to the + * database. + * This response is provided with HTTP status code + * MHD_HTTP_INTERNAL_SERVER_ERROR. + */ + TALER_EC_DB_SETUP_FAILED = 1001, + + /** + * The exchange encountered an error event to just start + * the database transaction. + * This response is provided with HTTP status code + * MHD_HTTP_INTERNAL_SERVER_ERROR. + */ + TALER_EC_DB_START_FAILED = 1002, + + /** + * The exchange encountered an error event to commit + * the database transaction (hard, unrecoverable error). + * This response is provided with HTTP status code + * MHD_HTTP_INTERNAL_SERVER_ERROR. + */ + TALER_EC_DB_COMMIT_FAILED_HARD = 1003, + + /** + * The exchange encountered an error event to commit + * the database transaction, even after repeatedly + * retrying it there was always a conflicting transaction. + * (This indicates a repeated serialization error; should + * only happen if some client maliciously tries to create + * conflicting concurrent transactions.) + * This response is provided with HTTP status code + * MHD_HTTP_INTERNAL_SERVER_ERROR. + */ + TALER_EC_DB_COMMIT_FAILED_ON_RETRY = 1004, + + /** + * The exchange had insufficient memory to parse the request. This + * response is provided with HTTP status code + * MHD_HTTP_INTERNAL_SERVER_ERROR. + */ + TALER_EC_PARSER_OUT_OF_MEMORY = 1005, + + /** + * The JSON in the client's request to the exchange was malformed. + * (Generic parse error). + * This response is provided with HTTP status code + * MHD_HTTP_BAD_REQUEST. + */ + TALER_EC_JSON_INVALID = 1006, + + /** + * The JSON in the client's request to the exchange was malformed. + * Details about the location of the parse error are provided. + * This response is provided with HTTP status code + * MHD_HTTP_BAD_REQUEST. + */ + TALER_EC_JSON_INVALID_WITH_DETAILS = 1007, + + /** + * A required parameter in the request to the exchange was missing. + * This response is provided with HTTP status code + * MHD_HTTP_BAD_REQUEST. + */ + TALER_EC_PARAMETER_MISSING = 1008, + + /** + * A parameter in the request to the exchange was malformed. + * This response is provided with HTTP status code + * MHD_HTTP_BAD_REQUEST. + */ + TALER_EC_PARAMETER_MALFORMED = 1009, + + /* ********** request-specific error codes ************* */ + + /** + * The given reserve does not have sufficient funds to admit the + * requested withdraw operation at this time. The response includes + * the current "balance" of the reserve as well as the transaction + * "history" that lead to this balance. This response is provided + * with HTTP status code MHD_HTTP_FORBIDDEN. + */ + TALER_EC_WITHDRAW_INSUFFICIENT_FUNDS = 1100, + + /** + * The exchange has no information about the "reserve_pub" that + * was given. + * This response is provided with HTTP status code MHD_HTTP_NOT_FOUND. + */ + TALER_EC_WITHDRAW_RESERVE_UNKNOWN = 1101, + + /** + * The amount to withdraw together with the fee exceeds the + * numeric range for Taler amounts. This is not a client + * failure, as the coin value and fees come from the exchange's + * configuration. + * This response is provided with HTTP status code MHD_HTTP_INTERNAL_ERROR. + */ + TALER_EC_WITHDRAW_AMOUNT_FEE_OVERFLOW = 1102, + + /** + * All of the deposited amounts into this reserve total up to a + * value that is too big for the numeric range for Taler amounts. + * This is not a client failure, as the transaction history comes + * from the exchange's configuration. This response is provided + * with HTTP status code MHD_HTTP_INTERNAL_ERROR. + */ + TALER_EC_WITHDRAW_AMOUNT_DEPOSITS_OVERFLOW = 1103, + + /** + * For one of the historic withdrawals from this reserve, the + * exchange could not find the denomination key. + * This is not a client failure, as the transaction history comes + * from the exchange's configuration. This response is provided + * with HTTP status code MHD_HTTP_INTERNAL_ERROR. + */ + TALER_EC_WITHDRAW_HISTORIC_DENOMINATION_KEY_NOT_FOUND = 1104, + + /** + * All of the withdrawals from reserve total up to a + * value that is too big for the numeric range for Taler amounts. + * This is not a client failure, as the transaction history comes + * from the exchange's configuration. This response is provided + * with HTTP status code MHD_HTTP_INTERNAL_ERROR. + */ + TALER_EC_WITHDRAW_AMOUNT_WITHDRAWALS_OVERFLOW = 1105, + + /** + * The exchange somehow knows about this reserve, but there seem to + * have been no wire transfers made. This is not a client failure, + * as this is a database consistency issue of the exchange. This + * response is provided with HTTP status code + * MHD_HTTP_INTERNAL_ERROR. + */ + TALER_EC_WITHDRAW_RESERVE_WITHOUT_WIRE_TRANSFER = 1106, + + /** + * The exchange failed to create the signature using the + * denomination key. This response is provided with HTTP status + * code MHD_HTTP_INTERNAL_ERROR. + */ + TALER_EC_WITHDRAW_SIGNATURE_FAILED = 1107, + + /** + * The exchange failed to store the withdraw operation in its + * database. This response is provided with HTTP status code + * MHD_HTTP_INTERNAL_ERROR. + */ + TALER_EC_WITHDRAW_DB_STORE_ERROR = 1108, + + /** + * The exchange failed to check against historic withdraw data from + * database (as part of ensuring the idempotency of the operation). + * This response is provided with HTTP status code + * MHD_HTTP_INTERNAL_ERROR. + */ + TALER_EC_WITHDRAW_DB_FETCH_ERROR = 1109, + + /** + * The exchange is not aware of the denomination key + * the wallet requested for the withdrawal. + * This response is provided + * with HTTP status code MHD_HTTP_NOT_FOUND. + */ + TALER_EC_WITHDRAW_DENOMINATION_KEY_NOT_FOUND = 1110, + + /** + * The signature of the reserve is not valid. This response is + * provided with HTTP status code MHD_HTTP_BAD_REQUEST. + */ + TALER_EC_WITHDRAW_RESERVE_SIGNATURE_INVALID = 1111, + + /** + * The exchange failed to obtain the transaction history of the + * given reserve from the database while generating an insufficient + * funds errors. + * This response is provided with HTTP status code + * MHD_HTTP_INTERNAL_SERVER_ERROR. + */ + TALER_EC_WITHDRAW_HISTORY_DB_ERROR_INSUFFICIENT_FUNDS = 1112, + + /** + * The exchange failed to obtain the transaction history of the + * given reserve from the database. + * This response is provided with HTTP status code + * MHD_HTTP_INTERNAL_SERVER_ERROR. + */ + TALER_EC_RESERVE_STATUS_DB_ERROR = 1150, + + + /** + * The respective coin did not have sufficient residual value + * for the /deposit operation (i.e. due to double spending). + * The "history" in the respose provides the transaction history + * of the coin proving this fact. This response is provided + * with HTTP status code MHD_HTTP_FORBIDDEN. + */ + TALER_EC_DEPOSIT_INSUFFICIENT_FUNDS = 1200, + + /** + * The exchange failed to obtain the transaction history of the + * given coin from the database (this does not happen merely because + * the coin is seen by the exchange for the first time). + * This response is provided with HTTP status code + * MHD_HTTP_INTERNAL_SERVER_ERROR. + */ + TALER_EC_DEPOSIT_HISTORY_DB_ERROR = 1201, + + /** + * The exchange failed to store the /depost information in the + * database. This response is provided with HTTP status code + * MHD_HTTP_INTERNAL_SERVER_ERROR. + */ + TALER_EC_DEPOSIT_STORE_DB_ERROR = 1202, + + /** + * The exchange database is unaware of the denomination key that + * signed the coin (however, the exchange process is; this is not + * supposed to happen; it can happen if someone decides to purge the + * DB behind the back of the exchange process). Hence the deposit + * is being refused. This response is provided with HTTP status + * code MHD_HTTP_INTERNAL_SERVER_ERROR. + */ + TALER_EC_DEPOSIT_DB_DENOMINATION_KEY_UNKNOWN = 1203, + + /** + * The exchange database is unaware of the denomination key that + * signed the coin (however, the exchange process is; this is not + * supposed to happen; it can happen if someone decides to purge the + * DB behind the back of the exchange process). Hence the deposit + * is being refused. This response is provided with HTTP status + * code MHD_HTTP_NOT_FOUND. + */ + TALER_EC_DEPOSIT_DENOMINATION_KEY_UNKNOWN = 1204, + + /** + * The signature of the coin is not valid. This response is + * provided with HTTP status code MHD_HTTP_BAD_REQUEST. + */ + TALER_EC_DEPOSIT_COIN_SIGNATURE_INVALID = 1205, + + /** + * The signature of the denomination key over the coin is not valid. + * This response is provided with HTTP status code + * MHD_HTTP_BAD_REQUEST. + */ + TALER_EC_DEPOSIT_DENOMINATION_SIGNATURE_INVALID = 1206, + + /** + * The stated value of the coin after the deposit fee is subtracted + * would be negative. + * This response is provided with HTTP status code + * MHD_HTTP_BAD_REQUEST. + */ + TALER_EC_DEPOSIT_NEGATIVE_VALUE_AFTER_FEE = 1207, + + /** + * The stated refund deadline is after the wire deadline. + * This response is provided with HTTP status code + * MHD_HTTP_BAD_REQUEST. + */ + TALER_EC_DEPOSIT_REFUND_DEADLINE_AFTER_WIRE_DEADLINE = 1208, + + /** + * The exchange does not recognize the validity of or support the + * given wire (bank account) address. This response is provided + * with HTTP status code MHD_HTTP_BAD_REQUEST. + */ + TALER_EC_DEPOSIT_INVALID_WIRE_FORMAT = 1209, + + /** + * The exchange failed to canonicalize and hash the given wire format. + * This response is provided + * with HTTP status code MHD_HTTP_BAD_REQUEST. + */ + TALER_EC_DEPOSIT_INVALID_WIRE_FORMAT_JSON = 1210, + + /** + * The hash of the given wire address does not match the hash + * specified in the contract. + * This response is provided + * with HTTP status code MHD_HTTP_BAD_REQUEST. + */ + TALER_EC_DEPOSIT_INVALID_WIRE_FORMAT_CONTRACT_HASH_CONFLICT = 1211, + + /** + * The exchange failed to obtain the transaction history of the + * given coin from the database while generating an insufficient + * funds errors. + * This response is provided with HTTP status code + * MHD_HTTP_INTERNAL_SERVER_ERROR. + */ + TALER_EC_DEPOSIT_HISTORY_DB_ERROR_INSUFFICIENT_FUNDS = 1212, + + /** + * The respective coin did not have sufficient residual value + * for the /refresh/melt operation. The "history" in this + * response provdes the "residual_value" of the coin, which may + * be less than its "original_value". This response is provided + * with HTTP status code MHD_HTTP_FORBIDDEN. + */ + TALER_EC_REFRESH_MELT_INSUFFICIENT_FUNDS = 1300, + + /** + * The exchange is unaware of the denomination key that was + * used to sign the melted coin. This response is provided + * with HTTP status code MHD_HTTP_NOT_FOUND. + */ + TALER_EC_REFRESH_MELT_DENOMINATION_KEY_NOT_FOUND = 1301, + + /** + * The exchange had an internal error reconstructing the + * transaction history of the coin that was being melted. + * This response is provided with HTTP status code + * MHD_HTTP_INTERNAL_SERVER_ERROR. + */ + TALER_EC_REFRESH_MELT_COIN_HISTORY_COMPUTATION_FAILED = 1302, + + /** + * The exchange failed to check against historic melt data from + * database (as part of ensuring the idempotency of the operation). + * This response is provided with HTTP status code + * MHD_HTTP_INTERNAL_ERROR. + */ + TALER_EC_REFRESH_MELT_DB_FETCH_ERROR = 1303, + + /** + * The exchange failed to store session data in the + * database. + * This response is provided with HTTP status code + * MHD_HTTP_INTERNAL_ERROR. + */ + TALER_EC_REFRESH_MELT_DB_STORE_SESSION_ERROR = 1304, + + /** + * The exchange failed to store refresh order data in the + * database. + * This response is provided with HTTP status code + * MHD_HTTP_INTERNAL_ERROR. + */ + TALER_EC_REFRESH_MELT_DB_STORE_ORDER_ERROR = 1305, + + /** + * The exchange failed to store commit data in the + * database. + * This response is provided with HTTP status code + * MHD_HTTP_INTERNAL_ERROR. + */ + TALER_EC_REFRESH_MELT_DB_STORE_COMMIT_ERROR = 1306, + + /** + * The exchange failed to store transfer keys in the + * database. + * This response is provided with HTTP status code + * MHD_HTTP_INTERNAL_ERROR. + */ + TALER_EC_REFRESH_MELT_DB_STORE_TRANSFER_ERROR = 1307, + + /** + * The exchange is unaware of the denomination key that was + * requested for one of the fresh coins. This response is provided + * with HTTP status code MHD_HTTP_BAD_REQUEST. + */ + TALER_EC_REFRESH_MELT_FRESH_DENOMINATION_KEY_NOT_FOUND = 1308, + + /** + * The exchange encountered a numeric overflow totaling up + * the cost for the refresh operation. This response is provided + * with HTTP status code MHD_HTTP_INTERNAL_SERVER_ERROR. + */ + TALER_EC_REFRESH_MELT_COST_CALCULATION_OVERFLOW = 1309, + + /** + * During the transaction phase, the exchange could suddenly + * no longer find the denomination key that was + * used to sign the melted coin. This response is provided + * with HTTP status code MHD_HTTP_INTERNAL_SERVER_ERROR. + */ + TALER_EC_REFRESH_MELT_DB_DENOMINATION_KEY_NOT_FOUND = 1310, + + /** + * The exchange encountered melt fees exceeding the melted + * coin's contribution. This response is provided + * with HTTP status code MHD_HTTP_BAD_REQUEST. + */ + TALER_EC_REFRESH_MELT_FEES_EXCEED_CONTRIBUTION = 1311, + + /** + * The exchange's cost calculation does not add up to the + * melt fees specified in the request. This response is provided + * with HTTP status code MHD_HTTP_BAD_REQUEST. + */ + TALER_EC_REFRESH_MELT_FEES_MISSMATCH = 1312, + + /** + * The denomination key signature on the melted coin is invalid. + * This response is provided with HTTP status code + * MHD_HTTP_BAD_REQUEST. + */ + TALER_EC_REFRESH_MELT_DENOMINATION_SIGNATURE_INVALID = 1313, + + /** + * The exchange's cost calculation shows that the melt amount + * is below the costs of the transaction. This response is provided + * with HTTP status code MHD_HTTP_BAD_REQUEST. + */ + TALER_EC_REFRESH_MELT_AMOUNT_INSUFFICIENT = 1314, + + /** + * The signature made with the coin to be melted is invalid. + * This response is provided with HTTP status code + * MHD_HTTP_BAD_REQUEST. + */ + TALER_EC_REFRESH_MELT_COIN_SIGNATURE_INVALID = 1315, + + /** + * The size of the cut-and-choose dimension of the + * blinded coins request does not match #TALER_CNC_KAPPA. + * This response is provided with HTTP status code + * MHD_HTTP_BAD_REQUEST. + */ + TALER_EC_REFRESH_MELT_CNC_COIN_ARRAY_SIZE_INVALID = 1316, + + /** + * The size of the cut-and-choose dimension of the + * transfer keys request does not match #TALER_CNC_KAPPA. + * This response is provided with HTTP status code + * MHD_HTTP_BAD_REQUEST. + */ + TALER_EC_REFRESH_MELT_CNC_TRANSFER_ARRAY_SIZE_INVALID = 1317, + + /** + * The exchange failed to obtain the transaction history of the + * given coin from the database while generating an insufficient + * funds errors. + * This response is provided with HTTP status code + * MHD_HTTP_INTERNAL_SERVER_ERROR. + */ + TALER_EC_REFRESH_MELT_HISTORY_DB_ERROR_INSUFFICIENT_FUNDS = 1318, + + /** + * The provided transfer keys do not match up with the + * original commitment. Information about the original + * commitment is included in the response. This response is + * provided with HTTP status code MHD_HTTP_CONFLICT. + */ + TALER_EC_REFRESH_REVEAL_COMMITMENT_VIOLATION = 1350, + + /** + * Failed to blind the envelope to reconstruct the blinded + * coins for revealation checks. + * This response is provided with HTTP status code + * MHD_HTTP_INTERNAL_ERROR. + */ + TALER_EC_REFRESH_REVEAL_BLINDING_ERROR = 1351, + + /** + * Failed to produce the blinded signatures over the coins + * to be returned. + * This response is provided with HTTP status code + * MHD_HTTP_INTERNAL_ERROR. + */ + TALER_EC_REFRESH_REVEAL_SIGNING_ERROR = 1352, + + /** + * The exchange is unaware of the refresh sessino specified in + * the request. + * This response is provided with HTTP status code + * MHD_HTTP_BAD_REQUEST. + */ + TALER_EC_REFRESH_REVEAL_SESSION_UNKNOWN = 1353, + + /** + * The exchange failed to retrieve valid session data from the + * database. + * This response is provided with HTTP status code + * MHD_HTTP_INTERNAL_ERROR. + */ + TALER_EC_REFRESH_REVEAL_DB_FETCH_SESSION_ERROR = 1354, + + /** + * The exchange failed to retrieve order data from the + * database. + * This response is provided with HTTP status code + * MHD_HTTP_INTERNAL_ERROR. + */ + TALER_EC_REFRESH_REVEAL_DB_FETCH_ORDER_ERROR = 1355, + + /** + * The exchange failed to retrieve transfer keys from the + * database. + * This response is provided with HTTP status code + * MHD_HTTP_INTERNAL_ERROR. + */ + TALER_EC_REFRESH_REVEAL_DB_FETCH_TRANSFER_ERROR = 1356, + + /** + * The exchange failed to retrieve commitment data from the + * database. + * This response is provided with HTTP status code + * MHD_HTTP_INTERNAL_ERROR. + */ + TALER_EC_REFRESH_REVEAL_DB_FETCH_COMMIT_ERROR = 1357, + + /** + * The size of the cut-and-choose dimension of the + * private transfer keys request does not match #TALER_CNC_KAPPA - 1. + * This response is provided with HTTP status code + * MHD_HTTP_BAD_REQUEST. + */ + TALER_EC_REFRESH_REVEAL_CNC_TRANSFER_ARRAY_SIZE_INVALID = 1358, + + + /** + * The coin specified in the link request is unknown to the exchange. + * This response is provided with HTTP status code + * MHD_HTTP_NOT_FOUND. + */ + TALER_EC_REFRESH_LINK_COIN_UNKNOWN = 1400, + + + /** + * The exchange knows literally nothing about the coin we were asked + * to refund. But without a transaction history, we cannot issue a + * refund. This is kind-of OK, the owner should just refresh it + * directly without executing the refund. This response is provided + * with HTTP status code MHD_HTTP_NOT_FOUND. + */ + TALER_EC_REFUND_COIN_NOT_FOUND = 1500, + + /** + * We could not process the refund request as the coin's transaction + * history does not permit the requested refund at this time. The + * "history" in the response proves this. This response is provided + * with HTTP status code MHD_HTTP_CONFLICT. + */ + TALER_EC_REFUND_CONFLICT = 1501, + + /** + * The exchange knows about the coin we were asked to refund, but + * not about the specific /deposit operation. Hence, we cannot + * issue a refund (as we do not know if this merchant public key is + * authorized to do a refund). This response is provided with HTTP + * status code MHD_HTTP_NOT_FOUND. + */ + TALER_EC_REFUND_DEPOSIT_NOT_FOUND = 1503, + /** + * The currency specified for the refund is different from + * the currency of the coin. This response is provided with HTTP + * status code MHD_HTTP_PRECONDITION_FAILED. + */ + TALER_EC_REFUND_CURRENCY_MISSMATCH = 1504, + + /** + * When we tried to check if we already paid out the coin, the + * exchange's database suddenly disagreed with data it previously + * provided (internal inconsistency). + * This response is provided with HTTP status code + * MHD_HTTP_INTERNAL_SERVER_ERROR. + */ + TALER_EC_REFUND_DB_INCONSISTENT = 1505, + /** + * The exchange can no longer refund the customer/coin as the + * money was already transferred (paid out) to the merchant. + * (It should be past the refund deadline.) + * This response is provided with HTTP status code + * MHD_HTTP_GONE. + */ + TALER_EC_REFUND_MERCHANT_ALREADY_PAID = 1506, + + /** + * The amount the exchange was asked to refund exceeds + * (with fees) the total amount of the deposit (including fees). + * This response is provided with HTTP status code + * MHD_HTTP_PRECONDITION_FAILED. + */ + TALER_EC_REFUND_INSUFFICIENT_FUNDS = 1507, + + /** + * The exchange failed to recover information about the + * denomination key of the refunded coin (even though it + * recognizes the key). Hence it could not check the fee + * strucutre. + * This response is provided with HTTP status code + * MHD_HTTP_INTERNAL_SERVER_ERROR. + */ + TALER_EC_REFUND_DENOMINATION_KEY_NOT_FOUND = 1508, + + /** + * The refund fee specified for the request is lower than + * the refund fee charged by the exchange for the given + * denomination key of the refunded coin. + * This response is provided with HTTP status code + * MHD_HTTP_BAD_REQUEST. + */ + TALER_EC_REFUND_FEE_TOO_LOW = 1509, + + /** + * The exchange failed to store the refund information to + * its database. + * This response is provided with HTTP status code + * MHD_HTTP_INTERNAL_SERVER_ERROR. + */ + TALER_EC_REFUND_STORE_DB_ERROR = 1510, + + /** + * The refund fee is specified in a different currency + * than the refund amount. + * This response is provided with HTTP status code + * MHD_HTTP_BAD_REQUEST. + */ + TALER_EC_REFUND_FEE_CURRENCY_MISSMATCH = 1511, + + /** + * The refunded amount is smaller than the refund fee, + * which would result in a negative refund. + * This response is provided with HTTP status code + * MHD_HTTP_BAD_REQUEST. + */ + TALER_EC_REFUND_FEE_ABOVE_AMOUNT = 1512, + + /** + * The signature of the merchant is invalid. + * This response is provided with HTTP status code + * MHD_HTTP_BAD_REQUEST. + */ + TALER_EC_REFUND_MERCHANT_SIGNATURE_INVALID = 1513, + + + /** + * The wire format specified in the "sender_account_details" + * is not understood or not supported by this exchange. + * Returned with an HTTP status code of MHD_HTTP_NOT_FOUND. + * (As we did not find an interpretation of the wire format.) + */ + TALER_EC_ADMIN_ADD_INCOMING_WIREFORMAT_UNSUPPORTED = 1600, + + /** + * The currency specified in the "amount" parameter is not + * supported by this exhange. Returned with an HTTP status + * code of MHD_HTTP_BAD_REQUEST. + */ + TALER_EC_ADMIN_ADD_INCOMING_CURRENCY_UNSUPPORTED = 1601, + + /** + * The exchange failed to store information about the incoming + * transfer in its database. This response is provided with HTTP + * status code MHD_HTTP_INTERNAL_SERVER_ERROR. + */ + TALER_EC_ADMIN_ADD_INCOMING_DB_STORE = 1602, + + /** + * The exchange encountered an error (that is not about not finding + * the wire transfer) trying to lookup a wire transfer identifier + * in the database. This response is provided with HTTP + * status code MHD_HTTP_INTERNAL_SERVER_ERROR. + */ + TALER_EC_TRACK_TRANSFER_DB_FETCH_FAILED = 1700, + + /** + * The exchange found internally inconsistent data when resolving a + * wire transfer identifier in the database. This response is + * provided with HTTP status code MHD_HTTP_INTERNAL_SERVER_ERROR. + */ + TALER_EC_TRACK_TRANSFER_DB_INCONSISTENT = 1701, + + /** + * The exchange did not find information about the specified + * wire transfer identifier in the database. This response is + * provided with HTTP status code MHD_HTTP_NOT_FOUND. + */ + TALER_EC_TRACK_TRANSFER_WTID_NOT_FOUND = 1702, + + + /** + * The exchange found internally inconsistent fee data when + * resolving a transaction in the database. This + * response is provided with HTTP status code + * MHD_HTTP_INTERNAL_SERVER_ERROR. + */ + TALER_EC_TRACK_TRANSACTION_DB_FEE_INCONSISTENT = 1800, + + /** + * The exchange encountered an error (that is not about not finding + * the transaction) trying to lookup a transaction + * in the database. This response is provided with HTTP + * status code MHD_HTTP_INTERNAL_SERVER_ERROR. + */ + TALER_EC_TRACK_TRANSACTION_DB_FETCH_FAILED = 1801, + + /** + * The exchange did not find information about the specified + * transaction in the database. This response is + * provided with HTTP status code MHD_HTTP_NOT_FOUND. + */ + TALER_EC_TRACK_TRANSACTION_NOT_FOUND = 1802, + + /** + * The exchange failed to identify the wire transfer of the + * transaction (or information about the plan that it was supposed + * to still happen in the future). This response is provided with + * HTTP status code MHD_HTTP_INTERNAL_SERVER_ERROR. + */ + TALER_EC_TRACK_TRANSACTION_WTID_RESOLUTION_ERROR = 1803, + + /** + * The signature of the merchant is invalid. + * This response is provided with HTTP status code + * MHD_HTTP_BAD_REQUEST. + */ + TALER_EC_TRACK_TRANSACTION_MERCHANT_SIGNATURE_INVALID = 1804, + + + /* ********** /test API error codes ************* */ + + /** + * The exchange failed to compute ECDH. This response is provided + * with HTTP status code MHD_HTTP_INTERNAL_SERVER_ERROR. + */ + TALER_EC_TEST_ECDH_ERROR = 4000, + + /** + * The EdDSA test signature is invalid. This response is provided + * with HTTP status code MHD_HTTP_BAD_REQUEST. + */ + TALER_EC_TEST_EDDSA_INVALID = 4001, + + /** + * The exchange failed to compute the EdDSA test signature. This response is provided + * with HTTP status code MHD_HTTP_INTERNAL_SERVER_ERROR. + */ + TALER_EC_TEST_EDDSA_ERROR = 4002, + + /** + * The exchange failed to generate an RSA key. This response is provided + * with HTTP status code MHD_HTTP_INTERNAL_SERVER_ERROR. + */ + TALER_EC_TEST_RSA_GEN_ERROR = 4003, + + /** + * The exchange failed to compute the public RSA key. This response + * is provided with HTTP status code MHD_HTTP_INTERNAL_SERVER_ERROR. + */ + TALER_EC_TEST_RSA_PUB_ERROR = 4004, + + /** + * The exchange failed to compute the RSA signature. This response + * is provided with HTTP status code MHD_HTTP_INTERNAL_SERVER_ERROR. + */ + TALER_EC_TEST_RSA_SIGN_ERROR = 4005, + + + /** + * End of error code range. + */ + TALER_EC_END = 9999 + }; -- cgit v1.2.3