aboutsummaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/auditor_api_curl_defaults.c61
-rw-r--r--src/lib/auditor_api_curl_defaults.h38
-rw-r--r--src/lib/auditor_api_deposit_confirmation.c418
-rw-r--r--src/lib/auditor_api_exchanges.c244
-rw-r--r--src/lib/auditor_api_get_config.c288
-rw-r--r--src/lib/exchange_api_age_withdraw.c1117
-rw-r--r--src/lib/exchange_api_age_withdraw_reveal.c471
-rw-r--r--src/lib/exchange_api_auditor_add_denomination.c238
-rw-r--r--src/lib/exchange_api_csr_melt.c317
-rw-r--r--src/lib/exchange_api_kyc_check.c329
-rw-r--r--src/lib/exchange_api_kyc_proof.c217
-rw-r--r--src/lib/exchange_api_kyc_wallet.c230
-rw-r--r--src/lib/exchange_api_lookup_aml_decision.c419
-rw-r--r--src/lib/exchange_api_lookup_aml_decisions.c378
-rw-r--r--src/lib/exchange_api_management_add_partner.c218
-rw-r--r--src/lib/exchange_api_management_auditor_disable.c219
-rw-r--r--src/lib/exchange_api_management_auditor_enable.c224
-rw-r--r--src/lib/exchange_api_management_drain_profits.c213
-rw-r--r--src/lib/exchange_api_management_post_extensions.c213
-rw-r--r--src/lib/exchange_api_management_post_keys.c237
-rw-r--r--src/lib/exchange_api_management_revoke_denomination_key.c221
-rw-r--r--src/lib/exchange_api_management_revoke_signing_key.c211
-rw-r--r--src/lib/exchange_api_management_set_global_fee.c235
-rw-r--r--src/lib/exchange_api_management_set_wire_fee.c227
-rw-r--r--src/lib/exchange_api_management_update_aml_officer.c229
-rw-r--r--src/lib/exchange_api_management_wire_disable.c220
-rw-r--r--src/lib/exchange_api_management_wire_enable.c245
-rw-r--r--src/lib/exchange_api_melt.c596
-rw-r--r--src/lib/exchange_api_recoup.c369
-rw-r--r--src/lib/exchange_api_recoup_refresh.c363
-rw-r--r--src/lib/exchange_api_refresh_common.c249
-rw-r--r--src/lib/exchange_api_refresh_common.h201
-rw-r--r--src/lib/exchange_api_refreshes_reveal.c531
-rw-r--r--src/lib/exchange_api_refund.c480
-rw-r--r--src/lib/exchange_api_stefan.c320
-rw-r--r--src/lib/test_stefan.c206
36 files changed, 0 insertions, 10992 deletions
diff --git a/src/lib/auditor_api_curl_defaults.c b/src/lib/auditor_api_curl_defaults.c
deleted file mode 100644
index 81fcd7bac..000000000
--- a/src/lib/auditor_api_curl_defaults.c
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2014-2018 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software
- Foundation; either version 3, or (at your option) any later version.
-
- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- TALER; see the file COPYING. If not, see
- <http://www.gnu.org/licenses/>
-*/
-/**
- * @file lib/auditor_api_curl_defaults.c
- * @brief curl easy handle defaults
- * @author Florian Dold
- */
-#include "auditor_api_curl_defaults.h"
-
-
-CURL *
-TALER_AUDITOR_curl_easy_get_ (const char *url)
-{
- CURL *eh;
- struct GNUNET_AsyncScopeSave scope;
-
- GNUNET_async_scope_get (&scope);
-
- eh = curl_easy_init ();
- if (NULL == eh)
- return NULL;
- GNUNET_assert (CURLE_OK ==
- curl_easy_setopt (eh,
- CURLOPT_URL,
- url));
- GNUNET_assert (CURLE_OK ==
- curl_easy_setopt (eh,
- CURLOPT_FOLLOWLOCATION,
- 1L));
- /* Enable compression (using whatever curl likes), see
- https://curl.se/libcurl/c/CURLOPT_ACCEPT_ENCODING.html */
- GNUNET_break (CURLE_OK ==
- curl_easy_setopt (eh,
- CURLOPT_ACCEPT_ENCODING,
- ""));
- /* limit MAXREDIRS to 5 as a simple security measure against
- a potential infinite loop caused by a malicious target */
- GNUNET_assert (CURLE_OK ==
- curl_easy_setopt (eh,
- CURLOPT_MAXREDIRS,
- 5L));
- GNUNET_assert (CURLE_OK ==
- curl_easy_setopt (eh,
- CURLOPT_TCP_FASTOPEN,
- 1L));
- return eh;
-}
diff --git a/src/lib/auditor_api_curl_defaults.h b/src/lib/auditor_api_curl_defaults.h
deleted file mode 100644
index 99e1e07e6..000000000
--- a/src/lib/auditor_api_curl_defaults.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2014-2018 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software
- Foundation; either version 3, or (at your option) any later version.
-
- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- TALER; see the file COPYING. If not, see
- <http://www.gnu.org/licenses/>
-*/
-/**
- * @file lib/auditor_api_curl_defaults.h
- * @brief curl easy handle defaults
- * @author Florian Dold
- */
-#ifndef _TALER_CURL_DEFAULTS_H
-#define _TALER_CURL_DEFAULTS_H
-
-#include "platform.h"
-#include <gnunet/gnunet_curl_lib.h>
-
-
-/**
- * Get a curl handle with the right defaults
- * for the auditor lib. In the future, we might manage a pool of connections here.
- *
- * @param url URL to query
- */
-CURL *
-TALER_AUDITOR_curl_easy_get_ (const char *url);
-
-#endif /* _TALER_CURL_DEFAULTS_H */
diff --git a/src/lib/auditor_api_deposit_confirmation.c b/src/lib/auditor_api_deposit_confirmation.c
deleted file mode 100644
index 1e2ecc6cc..000000000
--- a/src/lib/auditor_api_deposit_confirmation.c
+++ /dev/null
@@ -1,418 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2014-2023 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software
- Foundation; either version 3, or (at your option) any later version.
-
- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- TALER; see the file COPYING. If not, see
- <http://www.gnu.org/licenses/>
-*/
-/**
- * @file lib/auditor_api_deposit_confirmation.c
- * @brief Implementation of the /deposit request of the auditor's HTTP API
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include <jansson.h>
-#include <microhttpd.h> /* just for HTTP status codes */
-#include <gnunet/gnunet_util_lib.h>
-#include <gnunet/gnunet_json_lib.h>
-#include <gnunet/gnunet_curl_lib.h>
-#include "taler_util.h"
-#include "taler_curl_lib.h"
-#include "taler_json_lib.h"
-#include "taler_auditor_service.h"
-#include "taler_signatures.h"
-#include "auditor_api_curl_defaults.h"
-
-
-/**
- * @brief A DepositConfirmation Handle
- */
-struct TALER_AUDITOR_DepositConfirmationHandle
-{
-
- /**
- * The url for this request.
- */
- char *url;
-
- /**
- * Context for #TEH_curl_easy_post(). Keeps the data that must
- * persist for Curl to make the upload.
- */
- struct TALER_CURL_PostContext ctx;
-
- /**
- * Handle for the request.
- */
- struct GNUNET_CURL_Job *job;
-
- /**
- * Function to call with the result.
- */
- TALER_AUDITOR_DepositConfirmationResultCallback cb;
-
- /**
- * Closure for @a cb.
- */
- void *cb_cls;
-
-};
-
-
-/**
- * Function called when we're done processing the
- * HTTP /deposit-confirmation request.
- *
- * @param cls the `struct TALER_AUDITOR_DepositConfirmationHandle`
- * @param response_code HTTP response code, 0 on error
- * @param djson parsed JSON result, NULL on error
- */
-static void
-handle_deposit_confirmation_finished (void *cls,
- long response_code,
- const void *djson)
-{
- const json_t *json = djson;
- struct TALER_AUDITOR_DepositConfirmationHandle *dh = cls;
- struct TALER_AUDITOR_DepositConfirmationResponse dcr = {
- .hr.reply = json,
- .hr.http_status = (unsigned int) response_code
- };
-
- dh->job = NULL;
- switch (response_code)
- {
- case 0:
- dcr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
- break;
- case MHD_HTTP_OK:
- dcr.hr.ec = TALER_EC_NONE;
- break;
- case MHD_HTTP_BAD_REQUEST:
- dcr.hr.ec = TALER_JSON_get_error_code (json);
- dcr.hr.hint = TALER_JSON_get_error_hint (json);
- /* This should never happen, either us or the auditor is buggy
- (or API version conflict); just pass JSON reply to the application */
- break;
- case MHD_HTTP_FORBIDDEN:
- dcr.hr.ec = TALER_JSON_get_error_code (json);
- dcr.hr.hint = TALER_JSON_get_error_hint (json);
- /* Nothing really to verify, auditor says one of the signatures is
- invalid; as we checked them, this should never happen, we
- should pass the JSON reply to the application */
- break;
- case MHD_HTTP_NOT_FOUND:
- dcr.hr.ec = TALER_JSON_get_error_code (json);
- dcr.hr.hint = TALER_JSON_get_error_hint (json);
- /* Nothing really to verify, this should never
- happen, we should pass the JSON reply to the application */
- break;
- case MHD_HTTP_GONE:
- dcr.hr.ec = TALER_JSON_get_error_code (json);
- dcr.hr.hint = TALER_JSON_get_error_hint (json);
- /* Nothing really to verify, auditor says one of the signatures is
- invalid; as we checked them, this should never happen, we
- should pass the JSON reply to the application */
- break;
- case MHD_HTTP_INTERNAL_SERVER_ERROR:
- dcr.hr.ec = TALER_JSON_get_error_code (json);
- dcr.hr.hint = TALER_JSON_get_error_hint (json);
- /* Server had an internal issue; we should retry, but this API
- leaves this to the application */
- break;
- default:
- /* unexpected response code */
- dcr.hr.ec = TALER_JSON_get_error_code (json);
- dcr.hr.hint = TALER_JSON_get_error_hint (json);
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Unexpected response code %u/%d for auditor deposit confirmation\n",
- (unsigned int) response_code,
- dcr.hr.ec);
- break;
- }
- dh->cb (dh->cb_cls,
- &dcr);
- TALER_AUDITOR_deposit_confirmation_cancel (dh);
-}
-
-
-/**
- * Verify signature information about the deposit-confirmation.
- *
- * @param h_wire hash of merchant wire details
- * @param h_policy hash over the policy extension, if any
- * @param h_contract_terms hash of the contact of the merchant with the customer (further details are never disclosed to the auditor)
- * @param exchange_timestamp timestamp when the deposit was received by the wallet
- * @param wire_deadline by what time must the amount be wired to the merchant
- * @param refund_deadline date until which the merchant can issue a refund to the customer via the auditor (can be zero if refunds are not allowed); must not be after the @a wire_deadline
- * @param amount_without_fee the amount confirmed to be wired by the exchange to the merchant
- * @param coin_pub coin’s public key
- * @param merchant_pub the public key of the merchant (used to identify the merchant for refund requests)
- * @param exchange_sig the signature made with purpose #TALER_SIGNATURE_EXCHANGE_CONFIRM_DEPOSIT
- * @param exchange_pub the public key of the exchange that matches @a exchange_sig
- * @param master_pub master public key of the exchange
- * @param ep_start when does @a exchange_pub validity start
- * @param ep_expire when does @a exchange_pub usage end
- * @param ep_end when does @a exchange_pub legal validity end
- * @param master_sig master signature affirming validity of @a exchange_pub
- * @return #GNUNET_OK if signatures are OK, #GNUNET_SYSERR if not
- */
-static enum GNUNET_GenericReturnValue
-verify_signatures (
- const struct TALER_MerchantWireHashP *h_wire,
- const struct TALER_ExtensionPolicyHashP *h_policy,
- const struct TALER_PrivateContractHashP *h_contract_terms,
- struct GNUNET_TIME_Timestamp exchange_timestamp,
- struct GNUNET_TIME_Timestamp wire_deadline,
- struct GNUNET_TIME_Timestamp refund_deadline,
- const struct TALER_Amount *amount_without_fee,
- unsigned int num_coins,
- const struct TALER_CoinSpendSignatureP *coin_sigs[
- static num_coins],
- const struct TALER_MerchantPublicKeyP *merchant_pub,
- const struct TALER_ExchangePublicKeyP *exchange_pub,
- const struct TALER_ExchangeSignatureP *exchange_sig,
- const struct TALER_MasterPublicKeyP *master_pub,
- struct GNUNET_TIME_Timestamp ep_start,
- struct GNUNET_TIME_Timestamp ep_expire,
- struct GNUNET_TIME_Timestamp ep_end,
- const struct TALER_MasterSignatureP *master_sig)
-{
- if (GNUNET_OK !=
- TALER_exchange_online_deposit_confirmation_verify (
- h_contract_terms,
- h_wire,
- h_policy,
- exchange_timestamp,
- wire_deadline,
- refund_deadline,
- amount_without_fee,
- num_coins,
- coin_sigs,
- merchant_pub,
- exchange_pub,
- exchange_sig))
- {
- GNUNET_break_op (0);
- TALER_LOG_WARNING (
- "Invalid signature on /deposit-confirmation request!\n");
- {
- TALER_LOG_DEBUG ("... amount_without_fee was %s\n",
- TALER_amount2s (amount_without_fee));
- }
- return GNUNET_SYSERR;
- }
-
- if (GNUNET_OK !=
- TALER_exchange_offline_signkey_validity_verify (
- exchange_pub,
- ep_start,
- ep_expire,
- ep_end,
- master_pub,
- master_sig))
- {
- GNUNET_break (0);
- TALER_LOG_WARNING ("Invalid signature on exchange signing key!\n");
- return GNUNET_SYSERR;
- }
- if (GNUNET_TIME_absolute_is_past (ep_end.abs_time))
- {
- GNUNET_break (0);
- TALER_LOG_WARNING ("Exchange signing key is no longer valid!\n");
- return GNUNET_SYSERR;
- }
- return GNUNET_OK;
-}
-
-
-struct TALER_AUDITOR_DepositConfirmationHandle *
-TALER_AUDITOR_deposit_confirmation (
- struct GNUNET_CURL_Context *ctx,
- const char *url,
- const struct TALER_MerchantWireHashP *h_wire,
- const struct TALER_ExtensionPolicyHashP *h_policy,
- const struct TALER_PrivateContractHashP *h_contract_terms,
- struct GNUNET_TIME_Timestamp exchange_timestamp,
- struct GNUNET_TIME_Timestamp wire_deadline,
- struct GNUNET_TIME_Timestamp refund_deadline,
- const struct TALER_Amount *total_without_fee,
- unsigned int num_coins,
- const struct TALER_CoinSpendPublicKeyP *coin_pubs[
- static num_coins],
- const struct TALER_CoinSpendSignatureP *coin_sigs[
- static num_coins],
- const struct TALER_MerchantPublicKeyP *merchant_pub,
- const struct TALER_ExchangePublicKeyP *exchange_pub,
- const struct TALER_ExchangeSignatureP *exchange_sig,
- const struct TALER_MasterPublicKeyP *master_pub,
- struct GNUNET_TIME_Timestamp ep_start,
- struct GNUNET_TIME_Timestamp ep_expire,
- struct GNUNET_TIME_Timestamp ep_end,
- const struct TALER_MasterSignatureP *master_sig,
- TALER_AUDITOR_DepositConfirmationResultCallback cb,
- void *cb_cls)
-{
- struct TALER_AUDITOR_DepositConfirmationHandle *dh;
- json_t *deposit_confirmation_obj;
- CURL *eh;
- json_t *jcoin_sigs;
- json_t *jcoin_pubs;
-
- if (0 == num_coins)
- {
- GNUNET_break (0);
- return NULL;
- }
- if (GNUNET_OK !=
- verify_signatures (h_wire,
- h_policy,
- h_contract_terms,
- exchange_timestamp,
- wire_deadline,
- refund_deadline,
- total_without_fee,
- num_coins,
- coin_sigs,
- merchant_pub,
- exchange_pub,
- exchange_sig,
- master_pub,
- ep_start,
- ep_expire,
- ep_end,
- master_sig))
- {
- GNUNET_break_op (0);
- return NULL;
- }
- jcoin_sigs = json_array ();
- GNUNET_assert (NULL != jcoin_sigs);
- jcoin_pubs = json_array ();
- GNUNET_assert (NULL != jcoin_pubs);
- for (unsigned int i = 0; i<num_coins; i++)
- {
- GNUNET_assert (0 ==
- json_array_append_new (jcoin_sigs,
- GNUNET_JSON_from_data_auto (
- coin_sigs[i])));
- GNUNET_assert (0 ==
- json_array_append_new (jcoin_pubs,
- GNUNET_JSON_from_data_auto (
- coin_pubs[i])));
- }
- deposit_confirmation_obj
- = GNUNET_JSON_PACK (
- GNUNET_JSON_pack_data_auto ("h_wire",
- h_wire),
- GNUNET_JSON_pack_data_auto ("h_policy",
- h_policy),
- GNUNET_JSON_pack_data_auto ("h_contract_terms",
- h_contract_terms),
- GNUNET_JSON_pack_timestamp ("exchange_timestamp",
- exchange_timestamp),
- GNUNET_JSON_pack_allow_null (
- GNUNET_JSON_pack_timestamp ("refund_deadline",
- refund_deadline)),
- GNUNET_JSON_pack_timestamp ("wire_deadline",
- wire_deadline),
- TALER_JSON_pack_amount ("total_without_fee",
- total_without_fee),
- GNUNET_JSON_pack_array_steal ("coin_pubs",
- jcoin_pubs),
- GNUNET_JSON_pack_array_steal ("coin_sigs",
- jcoin_sigs),
- GNUNET_JSON_pack_data_auto ("merchant_pub",
- merchant_pub),
- GNUNET_JSON_pack_data_auto ("exchange_sig",
- exchange_sig),
- GNUNET_JSON_pack_data_auto ("master_pub",
- master_pub),
- GNUNET_JSON_pack_timestamp ("ep_start",
- ep_start),
- GNUNET_JSON_pack_timestamp ("ep_expire",
- ep_expire),
- GNUNET_JSON_pack_timestamp ("ep_end",
- ep_end),
- GNUNET_JSON_pack_data_auto ("master_sig",
- master_sig),
- GNUNET_JSON_pack_data_auto ("exchange_pub",
- exchange_pub));
- dh = GNUNET_new (struct TALER_AUDITOR_DepositConfirmationHandle);
- dh->cb = cb;
- dh->cb_cls = cb_cls;
- dh->url = TALER_url_join (url,
- "deposit-confirmation",
- NULL);
- if (NULL == dh->url)
- {
- GNUNET_free (dh);
- return NULL;
- }
- eh = TALER_AUDITOR_curl_easy_get_ (dh->url);
- if ( (NULL == eh) ||
- (CURLE_OK !=
- curl_easy_setopt (eh,
- CURLOPT_CUSTOMREQUEST,
- "PUT")) ||
- (GNUNET_OK !=
- TALER_curl_easy_post (&dh->ctx,
- eh,
- deposit_confirmation_obj)) )
- {
- GNUNET_break (0);
- if (NULL != eh)
- curl_easy_cleanup (eh);
- json_decref (deposit_confirmation_obj);
- GNUNET_free (dh->url);
- GNUNET_free (dh);
- return NULL;
- }
- json_decref (deposit_confirmation_obj);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "URL for deposit-confirmation: `%s'\n",
- dh->url);
- dh->job = GNUNET_CURL_job_add2 (ctx,
- eh,
- dh->ctx.headers,
- &handle_deposit_confirmation_finished,
- dh);
- {
- /* Disable 100 continue processing */
- struct curl_slist *x_headers;
-
- x_headers = curl_slist_append (NULL,
- "Expect:");
- GNUNET_CURL_extend_headers (dh->job,
- x_headers);
- curl_slist_free_all (x_headers);
- }
- return dh;
-}
-
-
-void
-TALER_AUDITOR_deposit_confirmation_cancel (
- struct TALER_AUDITOR_DepositConfirmationHandle *deposit_confirmation)
-{
- if (NULL != deposit_confirmation->job)
- {
- GNUNET_CURL_job_cancel (deposit_confirmation->job);
- deposit_confirmation->job = NULL;
- }
- GNUNET_free (deposit_confirmation->url);
- TALER_curl_easy_post_finished (&deposit_confirmation->ctx);
- GNUNET_free (deposit_confirmation);
-}
-
-
-/* end of auditor_api_deposit_confirmation.c */
diff --git a/src/lib/auditor_api_exchanges.c b/src/lib/auditor_api_exchanges.c
deleted file mode 100644
index 897dfe60f..000000000
--- a/src/lib/auditor_api_exchanges.c
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2014-2018 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software
- Foundation; either version 3, or (at your option) any later version.
-
- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- TALER; see the file COPYING. If not, see
- <http://www.gnu.org/licenses/>
-*/
-/**
- * @file lib/auditor_api_exchanges.c
- * @brief Implementation of the /exchanges request of the auditor's HTTP API
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include <jansson.h>
-#include <microhttpd.h> /* just for HTTP status codes */
-#include <gnunet/gnunet_util_lib.h>
-#include <gnunet/gnunet_json_lib.h>
-#include <gnunet/gnunet_curl_lib.h>
-#include "taler_json_lib.h"
-#include "taler_auditor_service.h"
-#include "taler_util.h"
-#include "taler_curl_lib.h"
-#include "taler_signatures.h"
-#include "auditor_api_curl_defaults.h"
-
-/**
- * How many exchanges do we allow a single auditor to
- * audit at most?
- */
-#define MAX_EXCHANGES 1024
-
-
-/**
- * @brief A ListExchanges Handle
- */
-struct TALER_AUDITOR_ListExchangesHandle
-{
-
- /**
- * The url for this request.
- */
- char *url;
-
- /**
- * Handle for the request.
- */
- struct GNUNET_CURL_Job *job;
-
- /**
- * Function to call with the result.
- */
- TALER_AUDITOR_ListExchangesResultCallback cb;
-
- /**
- * Closure for @a cb.
- */
- void *cb_cls;
-
-};
-
-
-/**
- * Function called when we're done processing the
- * HTTP /exchanges request.
- *
- * @param cls the `struct TALER_AUDITOR_ListExchangesHandle`
- * @param response_code HTTP response code, 0 on error
- * @param djson parsed JSON result, NULL on error
- */
-static void
-handle_exchanges_finished (void *cls,
- long response_code,
- const void *djson)
-{
- const json_t *json = djson;
- const json_t *ja;
- unsigned int ja_len;
- struct TALER_AUDITOR_ListExchangesHandle *leh = cls;
- struct TALER_AUDITOR_ListExchangesResponse ler = {
- .hr.reply = json,
- .hr.http_status = (unsigned int) response_code
- };
-
- leh->job = NULL;
- switch (response_code)
- {
- case 0:
- ler.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
- break;
- case MHD_HTTP_OK:
- ja = json_object_get (json,
- "exchanges");
- if ( (NULL == ja) ||
- (! json_is_array (ja)) )
- {
- GNUNET_break (0);
- ler.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
- ler.hr.http_status = 0;
- break;
- }
-
- ja_len = json_array_size (ja);
- if (ja_len > MAX_EXCHANGES)
- {
- GNUNET_break (0);
- ler.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
- ler.hr.http_status = 0;
- break;
- }
- {
- struct TALER_AUDITOR_ExchangeInfo ei[GNUNET_NZL (ja_len)];
- bool ok = true;
-
- for (unsigned int i = 0; i<ja_len; i++)
- {
- struct GNUNET_JSON_Specification spec[] = {
- GNUNET_JSON_spec_fixed_auto ("master_pub",
- &ei[i].master_pub),
- GNUNET_JSON_spec_string ("exchange_url",
- &ei[i].exchange_url),
- GNUNET_JSON_spec_end ()
- };
-
- if (GNUNET_OK !=
- GNUNET_JSON_parse (json_array_get (ja,
- i),
- spec,
- NULL, NULL))
- {
- GNUNET_break_op (0);
- ok = false;
- ler.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
- ler.hr.http_status = 0;
- break;
- }
- }
- if (! ok)
- break;
- ler.details.ok.ei = ei;
- ler.details.ok.num_exchanges = ja_len;
- leh->cb (leh->cb_cls,
- &ler);
- TALER_AUDITOR_list_exchanges_cancel (leh);
- return;
- }
- case MHD_HTTP_BAD_REQUEST:
- /* This should never happen, either us or the auditor is buggy
- (or API version conflict); just pass JSON reply to the application */
- ler.hr.ec = TALER_JSON_get_error_code (json);
- ler.hr.hint = TALER_JSON_get_error_hint (json);
- break;
- case MHD_HTTP_NOT_FOUND:
- /* Nothing really to verify, this should never
- happen, we should pass the JSON reply to the application */
- ler.hr.ec = TALER_JSON_get_error_code (json);
- ler.hr.hint = TALER_JSON_get_error_hint (json);
- break;
- case MHD_HTTP_INTERNAL_SERVER_ERROR:
- /* Server had an internal issue; we should retry, but this API
- leaves this to the application */
- ler.hr.ec = TALER_JSON_get_error_code (json);
- ler.hr.hint = TALER_JSON_get_error_hint (json);
- break;
- default:
- /* unexpected response code */
- ler.hr.ec = TALER_JSON_get_error_code (json);
- ler.hr.hint = TALER_JSON_get_error_hint (json);
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Unexpected response code %u/%d for auditor list-exchanges request\n",
- (unsigned int) response_code,
- (int) ler.hr.ec);
- GNUNET_break_op (0);
- break;
- }
- if (NULL != leh->cb)
- leh->cb (leh->cb_cls,
- &ler);
- TALER_AUDITOR_list_exchanges_cancel (leh);
-}
-
-
-struct TALER_AUDITOR_ListExchangesHandle *
-TALER_AUDITOR_list_exchanges (struct GNUNET_CURL_Context *ctx,
- const char *url,
- TALER_AUDITOR_ListExchangesResultCallback cb,
- void *cb_cls)
-{
- struct TALER_AUDITOR_ListExchangesHandle *leh;
- CURL *eh;
-
- leh = GNUNET_new (struct TALER_AUDITOR_ListExchangesHandle);
- leh->cb = cb;
- leh->cb_cls = cb_cls;
- leh->url = TALER_url_join (url,
- "exchanges",
- NULL);
- if (NULL == leh->url)
- {
- GNUNET_free (leh);
- return NULL;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "URL for list-exchanges: `%s'\n",
- leh->url);
- eh = TALER_AUDITOR_curl_easy_get_ (leh->url);
- if (NULL == eh)
- {
- GNUNET_break (0);
- GNUNET_free (leh->url);
- GNUNET_free (leh);
- return NULL;
- }
- leh->job = GNUNET_CURL_job_add (ctx,
- eh,
- &handle_exchanges_finished,
- leh);
- return leh;
-}
-
-
-void
-TALER_AUDITOR_list_exchanges_cancel (
- struct TALER_AUDITOR_ListExchangesHandle *leh)
-{
- if (NULL != leh->job)
- {
- GNUNET_CURL_job_cancel (leh->job);
- leh->job = NULL;
- }
- GNUNET_free (leh->url);
- GNUNET_free (leh);
-}
-
-
-/* end of auditor_api_exchanges.c */
diff --git a/src/lib/auditor_api_get_config.c b/src/lib/auditor_api_get_config.c
deleted file mode 100644
index c9f366568..000000000
--- a/src/lib/auditor_api_get_config.c
+++ /dev/null
@@ -1,288 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2014-2023 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software
- Foundation; either version 3, or (at your option) any later version.
-
- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- TALER; see the file COPYING. If not, see
- <http://www.gnu.org/licenses/>
-*/
-/**
- * @file lib/auditor_api_get_config.c
- * @brief Implementation of /config for the auditor's HTTP API
- * @author Sree Harsha Totakura <sreeharsha@totakura.in>
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include <microhttpd.h>
-#include <gnunet/gnunet_curl_lib.h>
-#include "taler_json_lib.h"
-#include "taler_auditor_service.h"
-#include "taler_signatures.h"
-#include "auditor_api_curl_defaults.h"
-
-
-/**
- * Which revision of the Taler auditor protocol is implemented
- * by this library? Used to determine compatibility.
- */
-#define TALER_PROTOCOL_CURRENT 0
-
-/**
- * How many revisions back are we compatible to?
- */
-#define TALER_PROTOCOL_AGE 0
-
-
-/**
- * Log error related to CURL operations.
- *
- * @param type log level
- * @param function which function failed to run
- * @param code what was the curl error code
- */
-#define CURL_STRERROR(type, function, code) \
- GNUNET_log (type, "Curl function `%s' has failed at `%s:%d' with error: %s", \
- function, __FILE__, __LINE__, curl_easy_strerror (code));
-
-
-/**
- * Handle for the get config request.
- */
-struct TALER_AUDITOR_GetConfigHandle
-{
- /**
- * The context of this handle
- */
- struct GNUNET_CURL_Context *ctx;
-
- /**
- * Function to call with the auditor's certification data,
- * NULL if this has already been done.
- */
- TALER_AUDITOR_ConfigCallback config_cb;
-
- /**
- * Closure to pass to @e config_cb.
- */
- void *config_cb_cls;
-
- /**
- * Data for the request to get the /config of a auditor,
- * NULL once we are past stage #MHS_INIT.
- */
- struct GNUNET_CURL_Job *vr;
-
- /**
- * The url for the @e vr job.
- */
- char *vr_url;
-
-};
-
-
-/* ***************** Internal /config fetching ************* */
-
-/**
- * Decode the JSON in @a resp_obj from the /config response and store the data
- * in the @a key_data.
- *
- * @param[in] resp_obj JSON object to parse
- * @param[in,out] vi where to store the results we decoded
- * @param[out] vc where to store config compatibility data
- * @return #TALER_EC_NONE on success
- */
-static enum TALER_ErrorCode
-decode_config_json (const json_t *resp_obj,
- struct TALER_AUDITOR_ConfigInformation *vi,
- enum TALER_AUDITOR_VersionCompatibility *vc)
-{
- unsigned int age;
- unsigned int revision;
- unsigned int current;
- char dummy;
- const char *ver;
- struct GNUNET_JSON_Specification spec[] = {
- GNUNET_JSON_spec_string ("version",
- &ver),
- GNUNET_JSON_spec_fixed_auto ("auditor_public_key",
- &vi->auditor_pub),
- GNUNET_JSON_spec_end ()
- };
-
- if (JSON_OBJECT != json_typeof (resp_obj))
- {
- GNUNET_break_op (0);
- return TALER_EC_GENERIC_JSON_INVALID;
- }
- /* check the config */
- if (GNUNET_OK !=
- GNUNET_JSON_parse (resp_obj,
- spec,
- NULL, NULL))
- {
- GNUNET_break_op (0);
- return TALER_EC_GENERIC_JSON_INVALID;
- }
- if (3 != sscanf (ver,
- "%u:%u:%u%c",
- &current,
- &revision,
- &age,
- &dummy))
- {
- GNUNET_break_op (0);
- return TALER_EC_GENERIC_VERSION_MALFORMED;
- }
- vi->version = ver;
- *vc = TALER_AUDITOR_VC_MATCH;
- if (TALER_PROTOCOL_CURRENT < current)
- {
- *vc |= TALER_AUDITOR_VC_NEWER;
- if (TALER_PROTOCOL_CURRENT < current - age)
- *vc |= TALER_AUDITOR_VC_INCOMPATIBLE;
- }
- if (TALER_PROTOCOL_CURRENT > current)
- {
- *vc |= TALER_AUDITOR_VC_OLDER;
- if (TALER_PROTOCOL_CURRENT - TALER_PROTOCOL_AGE > current)
- *vc |= TALER_AUDITOR_VC_INCOMPATIBLE;
- }
- return TALER_EC_NONE;
-}
-
-
-/**
- * Callback used when downloading the reply to a /config request
- * is complete.
- *
- * @param cls the `struct TALER_AUDITOR_GetConfigHandle`
- * @param response_code HTTP response code, 0 on error
- * @param gresp_obj parsed JSON result, NULL on error, must be a `const json_t *`
- */
-static void
-config_completed_cb (void *cls,
- long response_code,
- const void *gresp_obj)
-{
- struct TALER_AUDITOR_GetConfigHandle *auditor = cls;
- const json_t *resp_obj = gresp_obj;
- struct TALER_AUDITOR_ConfigResponse vr = {
- .hr.reply = resp_obj,
- .hr.http_status = (unsigned int) response_code
- };
-
- auditor->vr = NULL;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Received config from URL `%s' with status %ld.\n",
- auditor->vr_url,
- response_code);
- switch (response_code)
- {
- case 0:
- GNUNET_break_op (0);
- vr.hr.ec = TALER_EC_INVALID;
- break;
- case MHD_HTTP_OK:
- if (NULL == resp_obj)
- {
- GNUNET_break_op (0);
- vr.hr.http_status = 0;
- vr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
- break;
- }
- vr.hr.ec = decode_config_json (resp_obj,
- &vr.details.ok.vi,
- &vr.details.ok.compat);
- if (TALER_EC_NONE != vr.hr.ec)
- {
- GNUNET_break_op (0);
- vr.hr.http_status = 0;
- break;
- }
- break;
- case MHD_HTTP_INTERNAL_SERVER_ERROR:
- vr.hr.ec = TALER_JSON_get_error_code (resp_obj);
- vr.hr.hint = TALER_JSON_get_error_hint (resp_obj);
- break;
- default:
- vr.hr.ec = TALER_JSON_get_error_code (resp_obj);
- vr.hr.hint = TALER_JSON_get_error_hint (resp_obj);
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Unexpected response code %u/%d\n",
- (unsigned int) response_code,
- (int) vr.hr.ec);
- break;
- }
- auditor->config_cb (auditor->config_cb_cls,
- &vr);
- TALER_AUDITOR_get_config_cancel (auditor);
-}
-
-
-struct TALER_AUDITOR_GetConfigHandle *
-TALER_AUDITOR_get_config (struct GNUNET_CURL_Context *ctx,
- const char *url,
- TALER_AUDITOR_ConfigCallback config_cb,
- void *config_cb_cls)
-{
- struct TALER_AUDITOR_GetConfigHandle *auditor;
- CURL *eh;
-
- auditor = GNUNET_new (struct TALER_AUDITOR_GetConfigHandle);
- auditor->config_cb = config_cb;
- auditor->config_cb_cls = config_cb_cls;
- auditor->ctx = ctx;
- auditor->vr_url = TALER_url_join (url,
- "config",
- NULL);
- if (NULL == auditor->vr_url)
- {
- GNUNET_break (0);
- GNUNET_free (auditor->vr_url);
- GNUNET_free (auditor);
- return NULL;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Requesting auditor config with URL `%s'.\n",
- auditor->vr_url);
- eh = TALER_AUDITOR_curl_easy_get_ (auditor->vr_url);
- if (NULL == eh)
- {
- GNUNET_break (0);
- TALER_AUDITOR_get_config_cancel (auditor);
- return NULL;
- }
- GNUNET_break (CURLE_OK ==
- curl_easy_setopt (eh,
- CURLOPT_TIMEOUT,
- (long) 300));
- auditor->vr = GNUNET_CURL_job_add (auditor->ctx,
- eh,
- &config_completed_cb,
- auditor);
- return auditor;
-}
-
-
-void
-TALER_AUDITOR_get_config_cancel (struct TALER_AUDITOR_GetConfigHandle *auditor)
-{
- if (NULL != auditor->vr)
- {
- GNUNET_CURL_job_cancel (auditor->vr);
- auditor->vr = NULL;
- }
- GNUNET_free (auditor->vr_url);
- GNUNET_free (auditor);
-}
-
-
-/* end of auditor_api_get_config.c */
diff --git a/src/lib/exchange_api_age_withdraw.c b/src/lib/exchange_api_age_withdraw.c
deleted file mode 100644
index ea9c0371e..000000000
--- a/src/lib/exchange_api_age_withdraw.c
+++ /dev/null
@@ -1,1117 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2023 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software
- Foundation; either version 3, or (at your option) any later version.
-
- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- TALER; see the file COPYING. If not, see
- <http://www.gnu.org/licenses/>
-*/
-/**
- * @file lib/exchange_api_age_withdraw.c
- * @brief Implementation of /reserves/$RESERVE_PUB/age-withdraw requests
- * @author Ă–zgĂĽr Kesim
- */
-
-#include "platform.h"
-#include <gnunet/gnunet_common.h>
-#include <jansson.h>
-#include <microhttpd.h> /* just for HTTP status codes */
-#include <gnunet/gnunet_util_lib.h>
-#include <gnunet/gnunet_json_lib.h>
-#include <gnunet/gnunet_curl_lib.h>
-#include <sys/wait.h>
-#include "taler_curl_lib.h"
-#include "taler_error_codes.h"
-#include "taler_json_lib.h"
-#include "taler_exchange_service.h"
-#include "exchange_api_common.h"
-#include "exchange_api_handle.h"
-#include "taler_signatures.h"
-#include "exchange_api_curl_defaults.h"
-#include "taler_util.h"
-
-/**
- * A CoinCandidate is populated from a master secret
- */
-struct CoinCandidate
-{
- /**
- * Master key material for the coin candidates.
- */
- struct TALER_PlanchetMasterSecretP secret;
-
- /**
- * The details derived form the master secrets
- */
- struct TALER_EXCHANGE_AgeWithdrawCoinPrivateDetails details;
-
- /**
- * Blinded hash of the coin
- **/
- struct TALER_BlindedCoinHashP blinded_coin_h;
-
-};
-
-
-/**
- * Closure for a call to /csr-withdraw, contains data that is needed to process
- * the result.
- */
-struct CSRClosure
-{
- /* Points to the actual candidate in CoinData.coin_candidates, to continue
- * to build its contents based on the results from /csr-withdraw */
- struct CoinCandidate *candidate;
-
- /* The planchet to finally generate. Points to the corresponding candidate
- * in CoindData.planchet_details */
- struct TALER_PlanchetDetail *planchet;
-
- /* Handler to the originating call to /age-withdraw, needed to either
- * cancel the running age-withdraw request (on failure of the current call
- * to /csr-withdraw), or to eventually perform the protocol, once all
- * csr-withdraw requests have successfully finished. */
- struct TALER_EXCHANGE_AgeWithdrawHandle *age_withdraw_handle;
-
- /* Denomination information, needed for CS coins for the
- * step after /csr-withdraw */
- const struct TALER_EXCHANGE_DenomPublicKey *denom_pub;
-
- /* Handler for the CS R request */
- struct TALER_EXCHANGE_CsRWithdrawHandle *csr_withdraw_handle;
-};
-
-/**
- * Data we keep per coin in the batch.
- */
-struct CoinData
-{
- /**
- * The denomination of the coin. Must support age restriction, i.e
- * its .keys.age_mask MUST not be 0
- */
- struct TALER_EXCHANGE_DenomPublicKey denom_pub;
-
- /**
- * The Candidates for the coin
- */
- struct CoinCandidate coin_candidates[TALER_CNC_KAPPA];
-
- /**
- * Details of the planchet(s).
- */
- struct TALER_PlanchetDetail planchet_details[TALER_CNC_KAPPA];
-
- /**
- * Closure for each candidate of type CS for the preflight request to
- * /csr-withdraw
- */
- struct CSRClosure csr_cls[TALER_CNC_KAPPA];
-};
-
-/**
- * A /reserves/$RESERVE_PUB/age-withdraw request-handle for calls with
- * pre-blinded planchets. Returned by TALER_EXCHANGE_age_withdraw_blinded.
- */
-struct TALER_EXCHANGE_AgeWithdrawBlindedHandle
-{
-
- /**
- * Reserve private key.
- */
- const struct TALER_ReservePrivateKeyP *reserve_priv;
-
- /**
- * Reserve public key, calculated
- */
- struct TALER_ReservePublicKeyP reserve_pub;
-
- /**
- * Signature of the reserve for the request, calculated after all
- * parameters for the coins are collected.
- */
- struct TALER_ReserveSignatureP reserve_sig;
-
- /*
- * The denomination keys of the exchange
- */
- struct TALER_EXCHANGE_Keys *keys;
-
- /**
- * The age mask, extacted from the denominations.
- * MUST be the same for all denominations
- *
- */
- struct TALER_AgeMask age_mask;
-
- /**
- * Maximum age to commit to.
- */
- uint8_t max_age;
-
- /**
- * The commitment calculated as SHA512 hash over all blinded_coin_h
- */
- struct TALER_AgeWithdrawCommitmentHashP h_commitment;
-
- /**
- * Total amount requested (value plus withdraw fee).
- */
- struct TALER_Amount amount_with_fee;
-
- /**
- * Length of the @e blinded_input Array
- */
- size_t num_input;
-
- /**
- * The blinded planchet input for the call to /age-withdraw via
- * TALER_EXCHANGE_age_withdraw_blinded
- */
- const struct TALER_EXCHANGE_AgeWithdrawBlindedInput *blinded_input;
-
- /**
- * The url for this request.
- */
- char *request_url;
-
- /**
- * Context for curl.
- */
- struct GNUNET_CURL_Context *curl_ctx;
-
- /**
- * CURL handle for the request job.
- */
- struct GNUNET_CURL_Job *job;
-
- /**
- * Post Context
- */
- struct TALER_CURL_PostContext post_ctx;
-
- /**
- * Function to call with age-withdraw response results.
- */
- TALER_EXCHANGE_AgeWithdrawBlindedCallback callback;
-
- /**
- * Closure for @e blinded_callback
- */
- void *callback_cls;
-};
-
-/**
- * A /reserves/$RESERVE_PUB/age-withdraw request-handle for calls from
- * a wallet, i. e. when blinding data is available.
- */
-struct TALER_EXCHANGE_AgeWithdrawHandle
-{
-
- /**
- * Length of the @e coin_data Array
- */
- size_t num_coins;
-
- /**
- * The base-URL of the exchange.
- */
- const char *exchange_url;
-
- /**
- * Reserve private key.
- */
- const struct TALER_ReservePrivateKeyP *reserve_priv;
-
- /**
- * Reserve public key, calculated
- */
- struct TALER_ReservePublicKeyP reserve_pub;
-
- /**
- * Signature of the reserve for the request, calculated after all
- * parameters for the coins are collected.
- */
- struct TALER_ReserveSignatureP reserve_sig;
-
- /*
- * The denomination keys of the exchange
- */
- struct TALER_EXCHANGE_Keys *keys;
-
- /**
- * The age mask, extacted from the denominations.
- * MUST be the same for all denominations
- *
- */
- struct TALER_AgeMask age_mask;
-
- /**
- * Maximum age to commit to.
- */
- uint8_t max_age;
-
- /**
- * Array of per-coin data
- */
- struct CoinData *coin_data;
-
- /**
- * Context for curl.
- */
- struct GNUNET_CURL_Context *curl_ctx;
-
- struct
- {
- /**
- * Number of /csr-withdraw requests still pending.
- */
- unsigned int pending;
-
- /**
- * CURL handle for the request job.
- */
- struct GNUNET_CURL_Job *job;
- } csr;
-
-
- /**
- * Function to call with age-withdraw response results.
- */
- TALER_EXCHANGE_AgeWithdrawCallback callback;
-
- /**
- * Closure for @e age_withdraw_cb
- */
- void *callback_cls;
-
- /* The Handler for the actual call to the exchange */
- struct TALER_EXCHANGE_AgeWithdrawBlindedHandle *procotol_handle;
-};
-
-/**
- * We got a 200 OK response for the /reserves/$RESERVE_PUB/age-withdraw operation.
- * Extract the noreveal_index and return it to the caller.
- *
- * @param awbh operation handle
- * @param j_response reply from the exchange
- * @return #GNUNET_OK on success, #GNUNET_SYSERR on errors
- */
-static enum GNUNET_GenericReturnValue
-reserve_age_withdraw_ok (
- struct TALER_EXCHANGE_AgeWithdrawBlindedHandle *awbh,
- const json_t *j_response)
-{
- struct TALER_EXCHANGE_AgeWithdrawBlindedResponse response = {
- .hr.reply = j_response,
- .hr.http_status = MHD_HTTP_OK,
- .details.ok.h_commitment = awbh->h_commitment
- };
- struct TALER_ExchangeSignatureP exchange_sig;
- struct GNUNET_JSON_Specification spec[] = {
- GNUNET_JSON_spec_uint8 ("noreveal_index",
- &response.details.ok.noreveal_index),
- GNUNET_JSON_spec_fixed_auto ("exchange_sig",
- &exchange_sig),
- GNUNET_JSON_spec_fixed_auto ("exchange_pub",
- &response.details.ok.exchange_pub),
- GNUNET_JSON_spec_end ()
- };
-
- if (GNUNET_OK!=
- GNUNET_JSON_parse (j_response,
- spec,
- NULL, NULL))
- {
- GNUNET_break_op (0);
- return GNUNET_SYSERR;
- }
-
- if (GNUNET_OK !=
- TALER_exchange_online_age_withdraw_confirmation_verify (
- &awbh->h_commitment,
- response.details.ok.noreveal_index,
- &response.details.ok.exchange_pub,
- &exchange_sig))
- {
- GNUNET_break_op (0);
- return GNUNET_SYSERR;
-
- }
-
- awbh->callback (awbh->callback_cls,
- &response);
- /* make sure the callback isn't called again */
- awbh->callback = NULL;
-
- return GNUNET_OK;
-}
-
-
-/**
- * Function called when we're done processing the
- * HTTP /reserves/$RESERVE_PUB/age-withdraw request.
- *
- * @param cls the `struct TALER_EXCHANGE_AgeWithdrawHandle`
- * @param response_code The HTTP response code
- * @param response response data
- */
-static void
-handle_reserve_age_withdraw_blinded_finished (
- void *cls,
- long response_code,
- const void *response)
-{
- struct TALER_EXCHANGE_AgeWithdrawBlindedHandle *awbh = cls;
- const json_t *j_response = response;
- struct TALER_EXCHANGE_AgeWithdrawBlindedResponse awbr = {
- .hr.reply = j_response,
- .hr.http_status = (unsigned int) response_code
- };
-
- awbh->job = NULL;
- switch (response_code)
- {
- case 0:
- awbr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
- break;
- case MHD_HTTP_OK:
- if (GNUNET_OK !=
- reserve_age_withdraw_ok (awbh,
- j_response))
- {
- GNUNET_break_op (0);
- awbr.hr.http_status = 0;
- awbr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
- break;
- }
- GNUNET_assert (NULL == awbh->callback);
- TALER_EXCHANGE_age_withdraw_blinded_cancel (awbh);
- return;
- case MHD_HTTP_BAD_REQUEST:
- /* This should never happen, either us or the exchange is buggy
- (or API version conflict); just pass JSON reply to the application */
- awbr.hr.ec = TALER_JSON_get_error_code (j_response);
- awbr.hr.hint = TALER_JSON_get_error_hint (j_response);
- break;
- case MHD_HTTP_FORBIDDEN:
- GNUNET_break_op (0);
- /* Nothing really to verify, exchange says one of the signatures is
- invalid; as we checked them, this should never happen, we
- should pass the JSON reply to the application */
- awbr.hr.ec = TALER_JSON_get_error_code (j_response);
- awbr.hr.hint = TALER_JSON_get_error_hint (j_response);
- break;
- case MHD_HTTP_NOT_FOUND:
- /* Nothing really to verify, the exchange basically just says
- that it doesn't know this reserve. Can happen if we
- query before the wire transfer went through.
- We should simply pass the JSON reply to the application. */
- awbr.hr.ec = TALER_JSON_get_error_code (j_response);
- awbr.hr.hint = TALER_JSON_get_error_hint (j_response);
- break;
- case MHD_HTTP_CONFLICT:
- /* The age requirements might not have been met */
- awbr.hr.ec = TALER_JSON_get_error_code (j_response);
- awbr.hr.hint = TALER_JSON_get_error_hint (j_response);
- break;
- case MHD_HTTP_GONE:
- /* could happen if denomination was revoked */
- /* Note: one might want to check /keys for revocation
- signature here, alas tricky in case our /keys
- is outdated => left to clients */
- awbr.hr.ec = TALER_JSON_get_error_code (j_response);
- awbr.hr.hint = TALER_JSON_get_error_hint (j_response);
- break;
- case MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS:
- /* only validate reply is well-formed */
- {
- uint64_t ptu;
- struct GNUNET_JSON_Specification spec[] = {
- GNUNET_JSON_spec_uint64 ("requirement_row",
- &ptu),
- GNUNET_JSON_spec_end ()
- };
-
- if (GNUNET_OK !=
- GNUNET_JSON_parse (j_response,
- spec,
- NULL, NULL))
- {
- GNUNET_break_op (0);
- awbr.hr.http_status = 0;
- awbr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
- break;
- }
- }
- case MHD_HTTP_INTERNAL_SERVER_ERROR:
- /* Server had an internal issue; we should retry, but this API
- leaves this to the application */
- awbr.hr.ec = TALER_JSON_get_error_code (j_response);
- awbr.hr.hint = TALER_JSON_get_error_hint (j_response);
- break;
- default:
- /* unexpected response code */
- GNUNET_break_op (0);
- awbr.hr.ec = TALER_JSON_get_error_code (j_response);
- awbr.hr.hint = TALER_JSON_get_error_hint (j_response);
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Unexpected response code %u/%d for exchange age-withdraw\n",
- (unsigned int) response_code,
- (int) awbr.hr.ec);
- break;
- }
- awbh->callback (awbh->callback_cls,
- &awbr);
- TALER_EXCHANGE_age_withdraw_blinded_cancel (awbh);
-}
-
-
-/**
- * Runs the actual age-withdraw operation with the blinded planchets.
- *
- * @param[in,out] awbh age withdraw handler
- */
-static void
-perform_protocol (
- struct TALER_EXCHANGE_AgeWithdrawBlindedHandle *awbh)
-{
-#define FAIL_IF(cond) \
- do { \
- if ((cond)) \
- { \
- GNUNET_break (! (cond)); \
- goto ERROR; \
- } \
- } while(0)
-
- struct GNUNET_HashContext *coins_hctx;
- json_t *j_denoms = NULL;
- json_t *j_array_candidates = NULL;
- json_t *j_request_body = NULL;
- CURL *curlh = NULL;
-
- GNUNET_assert (0 < awbh->num_input);
- awbh->age_mask = awbh->blinded_input[0].denom_pub->key.age_mask;
-
- FAIL_IF (GNUNET_OK !=
- TALER_amount_set_zero (awbh->keys->currency,
- &awbh->amount_with_fee));
- /* Accumulate total value with fees */
- for (size_t i = 0; i < awbh->num_input; i++)
- {
- struct TALER_Amount coin_total;
- const struct TALER_EXCHANGE_DenomPublicKey *dpub =
- awbh->blinded_input[i].denom_pub;
-
- FAIL_IF (0 >
- TALER_amount_add (&coin_total,
- &dpub->fees.withdraw,
- &dpub->value));
- FAIL_IF (0 >
- TALER_amount_add (&awbh->amount_with_fee,
- &awbh->amount_with_fee,
- &coin_total));
- }
-
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Attempting to age-withdraw from reserve %s with maximum age %d\n",
- TALER_B2S (&awbh->reserve_pub),
- awbh->max_age);
-
- coins_hctx = GNUNET_CRYPTO_hash_context_start ();
- FAIL_IF (NULL == coins_hctx);
-
-
- j_denoms = json_array ();
- j_array_candidates = json_array ();
- FAIL_IF ((NULL == j_denoms) ||
- (NULL == j_array_candidates));
-
- for (size_t i = 0; i< awbh->num_input; i++)
- {
- /* Build the denomination array */
- {
- const struct TALER_EXCHANGE_DenomPublicKey *denom_pub =
- awbh->blinded_input[i].denom_pub;
- const struct TALER_DenominationHashP *denom_h = &denom_pub->h_key;
- json_t *jdenom;
-
- /* The mask must be the same for all coins */
- FAIL_IF (awbh->age_mask.bits != denom_pub->key.age_mask.bits);
-
- jdenom = GNUNET_JSON_PACK (
- GNUNET_JSON_pack_data_auto (NULL,
- denom_h));
- FAIL_IF (NULL == jdenom);
- FAIL_IF (0 < json_array_append_new (j_denoms,
- jdenom));
-
- /* Build the candidate array */
- {
- json_t *j_can = json_array ();
- FAIL_IF (NULL == j_can);
-
- for (size_t k = 0; k < TALER_CNC_KAPPA; k++)
- {
- struct TALER_BlindedCoinHashP bch;
- const struct TALER_PlanchetDetail *planchet =
- &awbh->blinded_input[i].planchet_details[k];
- json_t *jc = GNUNET_JSON_PACK (
- TALER_JSON_pack_blinded_planchet (
- NULL,
- &planchet->blinded_planchet));
-
- FAIL_IF (NULL == jc);
- FAIL_IF (0 < json_array_append_new (j_can,
- jc));
-
- TALER_coin_ev_hash (&planchet->blinded_planchet,
- &planchet->denom_pub_hash,
- &bch);
-
- GNUNET_CRYPTO_hash_context_read (coins_hctx,
- &bch,
- sizeof(bch));
- }
-
- FAIL_IF (0 < json_array_append_new (j_array_candidates,
- j_can));
- }
- }
- }
-
- /* Build the hash of the commitment */
- GNUNET_CRYPTO_hash_context_finish (coins_hctx,
- &awbh->h_commitment.hash);
-
- /* Sign the request */
- TALER_wallet_age_withdraw_sign (&awbh->h_commitment,
- &awbh->amount_with_fee,
- &awbh->age_mask,
- awbh->max_age,
- awbh->reserve_priv,
- &awbh->reserve_sig);
-
- /* Initiate the POST-request */
- j_request_body = GNUNET_JSON_PACK (
- GNUNET_JSON_pack_array_steal ("denom_hs", j_denoms),
- GNUNET_JSON_pack_array_steal ("blinded_coin_evs", j_array_candidates),
- GNUNET_JSON_pack_uint64 ("max_age", awbh->max_age),
- GNUNET_JSON_pack_data_auto ("reserve_sig", &awbh->reserve_sig));
- FAIL_IF (NULL == j_request_body);
-
- curlh = TALER_EXCHANGE_curl_easy_get_ (awbh->request_url);
- FAIL_IF (NULL == curlh);
- FAIL_IF (GNUNET_OK !=
- TALER_curl_easy_post (&awbh->post_ctx,
- curlh,
- j_request_body));
- json_decref (j_request_body);
- j_request_body = NULL;
-
- awbh->job = GNUNET_CURL_job_add2 (
- awbh->curl_ctx,
- curlh,
- awbh->post_ctx.headers,
- &handle_reserve_age_withdraw_blinded_finished,
- awbh);
- FAIL_IF (NULL == awbh->job);
-
- /* No errors, return */
- return;
-
-ERROR:
- if (NULL != j_denoms)
- json_decref (j_denoms);
- if (NULL != j_array_candidates)
- json_decref (j_array_candidates);
- if (NULL != j_request_body)
- json_decref (j_request_body);
- if (NULL != curlh)
- curl_easy_cleanup (curlh);
- TALER_EXCHANGE_age_withdraw_blinded_cancel (awbh);
- return;
-#undef FAIL_IF
-}
-
-
-/**
- * @brief Callback to copy the results from the call to TALER_age_withdraw_blinded
- * to the result for the originating call from TALER_age_withdraw.
- *
- * @param cls struct TALER_AgeWithdrawHandle
- * @param awbr The response
- */
-static void
-copy_results (
- void *cls,
- const struct TALER_EXCHANGE_AgeWithdrawBlindedResponse *awbr)
-{
- struct TALER_EXCHANGE_AgeWithdrawHandle *awh = cls;
- uint8_t k = awbr->details.ok.noreveal_index;
- struct TALER_EXCHANGE_AgeWithdrawCoinPrivateDetails details[awh->num_coins];
- struct TALER_BlindedCoinHashP blinded_coin_hs[awh->num_coins];
- struct TALER_EXCHANGE_AgeWithdrawResponse resp = {
- .hr = awbr->hr,
- .details = {
- .ok = { .noreveal_index = awbr->details.ok.noreveal_index,
- .h_commitment = awbr->details.ok.h_commitment,
- .exchange_pub = awbr->details.ok.exchange_pub,
- .num_coins = awh->num_coins,
- .coin_details = details,
- .blinded_coin_hs = blinded_coin_hs},
- },
- };
-
- for (size_t n = 0; n< awh->num_coins; n++)
- {
- details[n] = awh->coin_data[n].coin_candidates[k].details;
- details[n].planchet = awh->coin_data[n].planchet_details[k];
- blinded_coin_hs[n] = awh->coin_data[n].coin_candidates[k].blinded_coin_h;
- }
-
- awh->callback (awh->callback_cls,
- &resp);
-
- awh->callback = NULL;
-}
-
-
-/**
- * @brief Prepares and executes TALER_EXCHANGE_age_withdraw_blinded.
- * If there were CS-denominations involved, started once the all calls
- * to /csr-withdraw are done.
- */
-static void
-call_age_withdraw_blinded (
- struct TALER_EXCHANGE_AgeWithdrawHandle *awh)
-{
- struct TALER_EXCHANGE_AgeWithdrawBlindedInput blinded_input[awh->num_coins];
-
- /* Prepare the blinded planchets as input */
- for (size_t n = 0; n < awh->num_coins; n++)
- {
- blinded_input[n].denom_pub = &awh->coin_data[n].denom_pub;
- for (uint8_t k = 0; k < TALER_CNC_KAPPA; k++)
- blinded_input[n].planchet_details[k] =
- awh->coin_data[n].planchet_details[k];
- }
-
- awh->procotol_handle =
- TALER_EXCHANGE_age_withdraw_blinded (
- awh->curl_ctx,
- awh->keys,
- awh->exchange_url,
- awh->reserve_priv,
- awh->max_age,
- awh->num_coins,
- blinded_input,
- copy_results,
- awh);
-}
-
-
-/**
- * Prepares the request URL for the age-withdraw request
- *
- * @param awbh The handler
- * @param exchange_url The base-URL to the exchange
- */
-static
-enum GNUNET_GenericReturnValue
-prepare_url (
- struct TALER_EXCHANGE_AgeWithdrawBlindedHandle *awbh,
- const char *exchange_url)
-{
- char arg_str[sizeof (struct TALER_ReservePublicKeyP) * 2 + 32];
- char pub_str[sizeof (struct TALER_ReservePublicKeyP) * 2];
- char *end;
-
- end = GNUNET_STRINGS_data_to_string (
- &awbh->reserve_pub,
- sizeof (awbh->reserve_pub),
- pub_str,
- sizeof (pub_str));
- *end = '\0';
- GNUNET_snprintf (arg_str,
- sizeof (arg_str),
- "reserves/%s/age-withdraw",
- pub_str);
-
- awbh->request_url = TALER_url_join (exchange_url,
- arg_str,
- NULL);
- if (NULL == awbh->request_url)
- {
- GNUNET_break (0);
- TALER_EXCHANGE_age_withdraw_blinded_cancel (awbh);
- return GNUNET_SYSERR;
- }
-
- return GNUNET_OK;
-}
-
-
-/**
- * @brief Function called when CSR withdraw retrieval is finished
- *
- * @param cls the `struct CSRClosure *`
- * @param csrr replies from the /csr-withdraw request
- */
-static void
-csr_withdraw_done (
- void *cls,
- const struct TALER_EXCHANGE_CsRWithdrawResponse *csrr)
-{
- struct CSRClosure *csr = cls;
- struct CoinCandidate *can;
- struct TALER_PlanchetDetail *planchet;
- struct TALER_EXCHANGE_AgeWithdrawHandle *awh;
-
- GNUNET_assert (NULL != csr);
- awh = csr->age_withdraw_handle;
- planchet = csr->planchet;
- can = csr->candidate;
-
- GNUNET_assert (NULL != can);
- GNUNET_assert (NULL != planchet);
- GNUNET_assert (NULL != awh);
-
- csr->csr_withdraw_handle = NULL;
-
- switch (csrr->hr.http_status)
- {
- case MHD_HTTP_OK:
- {
- bool success = false;
- /* Complete the initialization of the coin with CS denomination */
- can->details.alg_values = csrr->details.ok.alg_values;
- GNUNET_assert (can->details.alg_values.cipher
- == TALER_DENOMINATION_CS);
- TALER_planchet_setup_coin_priv (&can->secret,
- &can->details.alg_values,
- &can->details.coin_priv);
- TALER_planchet_blinding_secret_create (&can->secret,
- &can->details.alg_values,
- &can->details.blinding_key);
- /* This initializes the 2nd half of the
- can->planchet_detail.blinded_planchet! */
- do {
- if (GNUNET_OK !=
- TALER_planchet_prepare (&csr->denom_pub->key,
- &can->details.alg_values,
- &can->details.blinding_key,
- &can->details.coin_priv,
- &can->details.h_age_commitment,
- &can->details.h_coin_pub,
- planchet))
- {
- GNUNET_break (0);
- TALER_EXCHANGE_age_withdraw_cancel (awh);
- break;
- }
-
- if (GNUNET_OK !=
- TALER_coin_ev_hash (&planchet->blinded_planchet,
- &planchet->denom_pub_hash,
- &can->blinded_coin_h))
- {
- GNUNET_break (0);
- TALER_EXCHANGE_age_withdraw_cancel (awh);
- break;
- }
- success = true;
- } while(0);
-
- awh->csr.pending--;
-
- /* No more pending requests to /csr-withdraw, we can now perform the
- * actual age-withdraw operation */
- if (0 == awh->csr.pending && success)
- call_age_withdraw_blinded (awh);
- return;
- }
- default:
- break;
- }
-
- TALER_EXCHANGE_age_withdraw_cancel (awh);
-}
-
-
-/**
- * @brief Prepare the coins for the call to age-withdraw and calculates
- * the total amount with fees.
- *
- * For denomination with CS as cipher, initiates the preflight to retrieve the
- * csr-parameter via /csr-withdraw.
- *
- * @param awh The handler to the age-withdraw
- * @param num_coins The number of coins in @e coin_inputs
- * @param coin_inputs The input for the individual coin(-candidates)
- * @return GNUNET_OK on success, GNUNET_SYSERR on failure
- */
-static
-enum GNUNET_GenericReturnValue
-prepare_coins (
- struct TALER_EXCHANGE_AgeWithdrawHandle *awh,
- size_t num_coins,
- const struct TALER_EXCHANGE_AgeWithdrawCoinInput coin_inputs[
- static num_coins])
-{
-#define FAIL_IF(cond) \
- do { \
- if ((cond)) \
- { \
- GNUNET_break (! (cond)); \
- goto ERROR; \
- } \
- } while(0)
-
- GNUNET_assert (0 < num_coins);
- awh->age_mask = coin_inputs[0].denom_pub->key.age_mask;
-
- awh->coin_data = GNUNET_new_array (awh->num_coins,
- struct CoinData);
-
- for (size_t i = 0; i < num_coins; i++)
- {
- struct CoinData *cd = &awh->coin_data[i];
- const struct TALER_EXCHANGE_AgeWithdrawCoinInput *input = &coin_inputs[i];
- cd->denom_pub = *input->denom_pub;
-
- /* The mask must be the same for all coins */
- FAIL_IF (awh->age_mask.bits != input->denom_pub->key.age_mask.bits);
-
- TALER_denom_pub_deep_copy (&cd->denom_pub.key,
- &input->denom_pub->key);
-
- for (uint8_t k = 0; k < TALER_CNC_KAPPA; k++)
- {
- struct CoinCandidate *can = &cd->coin_candidates[k];
- struct TALER_PlanchetDetail *planchet = &cd->planchet_details[k];
-
- can->secret = input->secrets[k];
- /* Derive the age restriction from the given secret and
- * the maximum age */
- TALER_age_restriction_from_secret (
- &can->secret,
- &input->denom_pub->key.age_mask,
- awh->max_age,
- &can->details.age_commitment_proof);
-
- TALER_age_commitment_hash (&can->details.age_commitment_proof.commitment,
- &can->details.h_age_commitment);
-
- switch (input->denom_pub->key.cipher)
- {
- case TALER_DENOMINATION_RSA:
- {
- can->details.alg_values.cipher = TALER_DENOMINATION_RSA;
- TALER_planchet_setup_coin_priv (&can->secret,
- &can->details.alg_values,
- &can->details.coin_priv);
- TALER_planchet_blinding_secret_create (&can->secret,
- &can->details.alg_values,
- &can->details.blinding_key);
- FAIL_IF (GNUNET_OK !=
- TALER_planchet_prepare (&cd->denom_pub.key,
- &can->details.alg_values,
- &can->details.blinding_key,
- &can->details.coin_priv,
- &can->details.h_age_commitment,
- &can->details.h_coin_pub,
- planchet));
- FAIL_IF (GNUNET_OK !=
- TALER_coin_ev_hash (&planchet->blinded_planchet,
- &planchet->denom_pub_hash,
- &can->blinded_coin_h));
- break;
- }
- case TALER_DENOMINATION_CS:
- {
- can->details.alg_values.cipher = TALER_DENOMINATION_CS;
-
- struct CSRClosure *cls = &cd->csr_cls[k];
- /**
- * Save the handler and the denomination for the callback
- * after the call to csr-withdraw */
- cls->age_withdraw_handle = awh;
- cls->candidate = can;
- cls->planchet = planchet;
- cls->denom_pub = &cd->denom_pub;
-
- TALER_cs_withdraw_nonce_derive (
- &can->secret,
- &planchet->blinded_planchet.details.cs_blinded_planchet.nonce);
-
- /* Note that we only initialize the first half
- of the blinded_planchet here; the other part
- will be done after the /csr-withdraw request! */
- planchet->blinded_planchet.cipher = TALER_DENOMINATION_CS;
- cls->csr_withdraw_handle =
- TALER_EXCHANGE_csr_withdraw (
- awh->curl_ctx,
- awh->exchange_url,
- &cd->denom_pub,
- &planchet->blinded_planchet.details.cs_blinded_planchet.nonce,
- &csr_withdraw_done,
- cls);
- FAIL_IF (NULL == cls->csr_withdraw_handle);
-
- awh->csr.pending++;
- break;
- }
- default:
- FAIL_IF (1);
- }
- }
- }
- return GNUNET_OK;
-
-ERROR:
- TALER_EXCHANGE_age_withdraw_cancel (awh);
- return GNUNET_SYSERR;
-#undef FAIL_IF
-};
-
-struct TALER_EXCHANGE_AgeWithdrawHandle *
-TALER_EXCHANGE_age_withdraw (
- struct GNUNET_CURL_Context *curl_ctx,
- struct TALER_EXCHANGE_Keys *keys,
- const char *exchange_url,
- const struct TALER_ReservePrivateKeyP *reserve_priv,
- size_t num_coins,
- const struct TALER_EXCHANGE_AgeWithdrawCoinInput coin_inputs[const static
- num_coins],
- uint8_t max_age,
- TALER_EXCHANGE_AgeWithdrawCallback res_cb,
- void *res_cb_cls)
-{
- struct TALER_EXCHANGE_AgeWithdrawHandle *awh;
-
- awh = GNUNET_new (struct TALER_EXCHANGE_AgeWithdrawHandle);
- awh->exchange_url = exchange_url;
- awh->keys = TALER_EXCHANGE_keys_incref (keys);
- awh->curl_ctx = curl_ctx;
- awh->reserve_priv = reserve_priv;
- awh->callback = res_cb;
- awh->callback_cls = res_cb_cls;
- awh->num_coins = num_coins;
- awh->max_age = max_age;
-
-
- if (GNUNET_OK != prepare_coins (awh,
- num_coins,
- coin_inputs))
- return NULL;
-
- /* If there were no CS denominations, we can now perform the actual
- * age-withdraw protocol. Otherwise, there are calls to /csr-withdraw
- * in flight and once they finish, the age-withdraw-protocol will be
- * called from within the csr_withdraw_done-function.
- */
- if (0 == awh->csr.pending)
- call_age_withdraw_blinded (awh);
-
- return awh;
-}
-
-
-void
-TALER_EXCHANGE_age_withdraw_cancel (
- struct TALER_EXCHANGE_AgeWithdrawHandle *awh)
-{
- /* Cleanup coin data */
- for (unsigned int i = 0; i<awh->num_coins; i++)
- {
- struct CoinData *cd = &awh->coin_data[i];
-
- for (uint8_t k = 0; k < TALER_CNC_KAPPA; k++)
- {
- struct TALER_PlanchetDetail *planchet = &cd->planchet_details[k];
- struct CSRClosure *cls = &cd->csr_cls[k];
-
- if (NULL != cls->csr_withdraw_handle)
- {
- TALER_EXCHANGE_csr_withdraw_cancel (cls->csr_withdraw_handle);
- cls->csr_withdraw_handle = NULL;
- }
- TALER_blinded_planchet_free (&planchet->blinded_planchet);
- }
- TALER_denom_pub_free (&cd->denom_pub.key);
- }
- GNUNET_free (awh->coin_data);
- TALER_EXCHANGE_keys_decref (awh->keys);
- TALER_EXCHANGE_age_withdraw_blinded_cancel (awh->procotol_handle);
- awh->procotol_handle = NULL;
- GNUNET_free (awh);
-}
-
-
-struct TALER_EXCHANGE_AgeWithdrawBlindedHandle *
-TALER_EXCHANGE_age_withdraw_blinded (
- struct GNUNET_CURL_Context *curl_ctx,
- struct TALER_EXCHANGE_Keys *keys,
- const char *exchange_url,
- const struct TALER_ReservePrivateKeyP *reserve_priv,
- uint8_t max_age,
- unsigned int num_input,
- const struct TALER_EXCHANGE_AgeWithdrawBlindedInput blinded_input[static
- num_input],
- TALER_EXCHANGE_AgeWithdrawBlindedCallback res_cb,
- void *res_cb_cls)
-{
- struct TALER_EXCHANGE_AgeWithdrawBlindedHandle *awbh =
- GNUNET_new (struct TALER_EXCHANGE_AgeWithdrawBlindedHandle);
-
- awbh->num_input = num_input;
- awbh->blinded_input = blinded_input;
- awbh->keys = TALER_EXCHANGE_keys_incref (keys);
- awbh->curl_ctx = curl_ctx;
- awbh->reserve_priv = reserve_priv;
- awbh->callback = res_cb;
- awbh->callback_cls = res_cb_cls;
- awbh->max_age = max_age;
-
- GNUNET_CRYPTO_eddsa_key_get_public (&awbh->reserve_priv->eddsa_priv,
- &awbh->reserve_pub.eddsa_pub);
-
- if (GNUNET_OK != prepare_url (awbh,
- exchange_url))
- return NULL;
-
- perform_protocol (awbh);
- return awbh;
-}
-
-
-void
-TALER_EXCHANGE_age_withdraw_blinded_cancel (
- struct TALER_EXCHANGE_AgeWithdrawBlindedHandle *awbh)
-{
- if (NULL == awbh)
- return;
-
- if (NULL != awbh->job)
- {
- GNUNET_CURL_job_cancel (awbh->job);
- awbh->job = NULL;
- }
- GNUNET_free (awbh->request_url);
- TALER_EXCHANGE_keys_decref (awbh->keys);
- TALER_curl_easy_post_finished (&awbh->post_ctx);
- GNUNET_free (awbh);
-}
-
-
-/* exchange_api_age_withdraw.c */
diff --git a/src/lib/exchange_api_age_withdraw_reveal.c b/src/lib/exchange_api_age_withdraw_reveal.c
deleted file mode 100644
index a448d109d..000000000
--- a/src/lib/exchange_api_age_withdraw_reveal.c
+++ /dev/null
@@ -1,471 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2023 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software
- Foundation; either version 3, or (at your option) any later version.
-
- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- TALER; see the file COPYING. If not, see
- <http://www.gnu.org/licenses/>
-*/
-/**
- * @file lib/exchange_api_age_withdraw_reveal.c
- * @brief Implementation of /age-withdraw/$ACH/reveal requests
- * @author Ă–zgĂĽr Kesim
- */
-
-#include "platform.h"
-#include <gnunet/gnunet_common.h>
-#include <jansson.h>
-#include <microhttpd.h> /* just for HTTP status codes */
-#include <gnunet/gnunet_util_lib.h>
-#include <gnunet/gnunet_json_lib.h>
-#include <gnunet/gnunet_curl_lib.h>
-#include "taler_curl_lib.h"
-#include "taler_json_lib.h"
-#include "taler_exchange_service.h"
-#include "exchange_api_common.h"
-#include "exchange_api_handle.h"
-#include "taler_signatures.h"
-#include "exchange_api_curl_defaults.h"
-
-/**
- * Handler for a running age-withdraw-reveal request
- */
-struct TALER_EXCHANGE_AgeWithdrawRevealHandle
-{
-
- /* The index not to be disclosed */
- uint8_t noreveal_index;
-
- /* The age-withdraw commitment */
- struct TALER_AgeWithdrawCommitmentHashP h_commitment;
-
- /* The reserve's public key */
- const struct TALER_ReservePublicKeyP *reserve_pub;
-
- /* Number of coins */
- size_t num_coins;
-
- /* The @e num_coins * kappa coin secrets from the age-withdraw commitment */
- const struct TALER_EXCHANGE_AgeWithdrawCoinInput *coins_input;
-
- /* The url for the reveal request */
- const char *request_url;
-
- /**
- * CURL handle for the request job.
- */
- struct GNUNET_CURL_Job *job;
-
- /**
- * Post Context
- */
- struct TALER_CURL_PostContext post_ctx;
-
- /* Callback */
- TALER_EXCHANGE_AgeWithdrawRevealCallback callback;
-
- /* Reveal */
- void *callback_cls;
-};
-
-
-/**
- * We got a 200 OK response for the /age-withdraw/$ACH/reveal operation.
- * Extract the signed blindedcoins and return it to the caller.
- *
- * @param awrh operation handle
- * @param j_response reply from the exchange
- * @return #GNUNET_OK on success, #GNUNET_SYSERR on errors
- */
-static enum GNUNET_GenericReturnValue
-age_withdraw_reveal_ok (
- struct TALER_EXCHANGE_AgeWithdrawRevealHandle *awrh,
- const json_t *j_response)
-{
- struct TALER_EXCHANGE_AgeWithdrawRevealResponse response = {
- .hr.reply = j_response,
- .hr.http_status = MHD_HTTP_OK,
- };
- const json_t *j_sigs;
- struct GNUNET_JSON_Specification spec[] = {
- GNUNET_JSON_spec_array_const ("ev_sigs",
- &j_sigs),
- GNUNET_JSON_spec_end ()
- };
-
- if (GNUNET_OK != GNUNET_JSON_parse (j_response,
- spec,
- NULL, NULL))
- {
- GNUNET_break_op (0);
- return GNUNET_SYSERR;
- }
-
- if (awrh->num_coins != json_array_size (j_sigs))
- {
- /* Number of coins generated does not match our expectation */
- GNUNET_break_op (0);
- return GNUNET_SYSERR;
- }
-
- {
- struct TALER_BlindedDenominationSignature denom_sigs[awrh->num_coins];
- json_t *j_sig;
- size_t n;
-
- /* Reconstruct the coins and unblind the signatures */
- json_array_foreach (j_sigs, n, j_sig)
- {
- struct GNUNET_JSON_Specification spec[] = {
- TALER_JSON_spec_blinded_denom_sig (NULL,
- &denom_sigs[n]),
- GNUNET_JSON_spec_end ()
- };
-
- if (GNUNET_OK != GNUNET_JSON_parse (j_sig,
- spec,
- NULL, NULL))
- {
- GNUNET_break_op (0);
- return GNUNET_SYSERR;
- }
-
- }
-
- response.details.ok.num_sigs = awrh->num_coins;
- response.details.ok.blinded_denom_sigs = denom_sigs;
- awrh->callback (awrh->callback_cls,
- &response);
- /* Make sure the callback isn't called again */
- awrh->callback = NULL;
- }
-
- return GNUNET_OK;
-}
-
-
-/**
- * Function called when we're done processing the
- * HTTP /age-withdraw/$ACH/reveal request.
- *
- * @param cls the `struct TALER_EXCHANGE_AgeWithdrawRevealHandle`
- * @param response_code The HTTP response code
- * @param response response data
- */
-static void
-handle_age_withdraw_reveal_finished (
- void *cls,
- long response_code,
- const void *response)
-{
- struct TALER_EXCHANGE_AgeWithdrawRevealHandle *awrh = cls;
- const json_t *j_response = response;
- struct TALER_EXCHANGE_AgeWithdrawRevealResponse awr = {
- .hr.reply = j_response,
- .hr.http_status = (unsigned int) response_code
- };
-
- awrh->job = NULL;
- /* FIXME[oec]: Only handle response-codes that are in the spec */
- switch (response_code)
- {
- case 0:
- awr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
- break;
- case MHD_HTTP_OK:
- {
- enum GNUNET_GenericReturnValue ret;
-
- ret = age_withdraw_reveal_ok (awrh,
- j_response);
- if (GNUNET_OK != ret)
- {
- GNUNET_break_op (0);
- awr.hr.http_status = 0;
- awr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
- break;
- }
- GNUNET_assert (NULL == awrh->callback);
- TALER_EXCHANGE_age_withdraw_reveal_cancel (awrh);
- return;
- }
- case MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS:
- /* only validate reply is well-formed */
- {
- uint64_t ptu;
- struct GNUNET_JSON_Specification spec[] = {
- GNUNET_JSON_spec_uint64 ("legitimization_uuid",
- &ptu),
- GNUNET_JSON_spec_end ()
- };
-
- if (GNUNET_OK !=
- GNUNET_JSON_parse (j_response,
- spec,
- NULL, NULL))
- {
- GNUNET_break_op (0);
- awr.hr.http_status = 0;
- awr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
- break;
- }
- }
- case MHD_HTTP_BAD_REQUEST:
- /* This should never happen, either us or the exchange is buggy
- (or API version conflict); just pass JSON reply to the application */
- awr.hr.ec = TALER_JSON_get_error_code (j_response);
- awr.hr.hint = TALER_JSON_get_error_hint (j_response);
- break;
- case MHD_HTTP_FORBIDDEN:
- GNUNET_break_op (0);
- /**
- * This should never happen, as we don't sent any signatures
- * to the exchange to verify. We should simply pass the JSON reply
- * to the application
- **/
- awr.hr.ec = TALER_JSON_get_error_code (j_response);
- awr.hr.hint = TALER_JSON_get_error_hint (j_response);
- break;
- case MHD_HTTP_NOT_FOUND:
- /* Nothing really to verify, the exchange basically just says
- that it doesn't know this age-withdraw commitment. */
- awr.hr.ec = TALER_JSON_get_error_code (j_response);
- awr.hr.hint = TALER_JSON_get_error_hint (j_response);
- break;
- case MHD_HTTP_CONFLICT:
- /* An age commitment for one of the coins did not fulfill
- * the required maximum age requirement of the corresponding
- * reserve.
- * Error code: TALER_EC_EXCHANGE_GENERIC_COIN_AGE_REQUIREMENT_FAILURE.
- */
- awr.hr.ec = TALER_JSON_get_error_code (j_response);
- awr.hr.hint = TALER_JSON_get_error_hint (j_response);
- break;
- case MHD_HTTP_GONE:
- /* could happen if denomination was revoked */
- /* Note: one might want to check /keys for revocation
- signature here, alas tricky in case our /keys
- is outdated => left to clients */
- awr.hr.ec = TALER_JSON_get_error_code (j_response);
- awr.hr.hint = TALER_JSON_get_error_hint (j_response);
- break;
- case MHD_HTTP_INTERNAL_SERVER_ERROR:
- /* Server had an internal issue; we should retry, but this API
- leaves this to the application */
- awr.hr.ec = TALER_JSON_get_error_code (j_response);
- awr.hr.hint = TALER_JSON_get_error_hint (j_response);
- break;
- default:
- /* unexpected response code */
- GNUNET_break_op (0);
- awr.hr.ec = TALER_JSON_get_error_code (j_response);
- awr.hr.hint = TALER_JSON_get_error_hint (j_response);
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Unexpected response code %u/%d for exchange age-withdraw\n",
- (unsigned int) response_code,
- (int) awr.hr.ec);
- break;
- }
- awrh->callback (awrh->callback_cls,
- &awr);
- TALER_EXCHANGE_age_withdraw_reveal_cancel (awrh);
-}
-
-
-/**
- * Prepares the request URL for the age-withdraw-reveal request
- *
- * @param exchange_url The base-URL to the exchange
- * @param[in,out] awrh The handler
- * @return GNUNET_OK on success, GNUNET_SYSERR otherwise
- */
-static
-enum GNUNET_GenericReturnValue
-prepare_url (
- const char *exchange_url,
- struct TALER_EXCHANGE_AgeWithdrawRevealHandle *awrh)
-{
- char arg_str[sizeof (struct TALER_AgeWithdrawCommitmentHashP) * 2 + 32];
- char pub_str[sizeof (struct TALER_AgeWithdrawCommitmentHashP) * 2];
- char *end;
-
- end = GNUNET_STRINGS_data_to_string (&awrh->h_commitment,
- sizeof (awrh->h_commitment),
- pub_str,
- sizeof (pub_str));
- *end = '\0';
- GNUNET_snprintf (arg_str,
- sizeof (arg_str),
- "age-withdraw/%s/reveal",
- pub_str);
-
- awrh->request_url = TALER_url_join (exchange_url,
- arg_str,
- NULL);
- if (NULL == awrh->request_url)
- {
- GNUNET_break (0);
- TALER_EXCHANGE_age_withdraw_reveal_cancel (awrh);
- return GNUNET_SYSERR;
- }
-
- return GNUNET_OK;
-}
-
-
-/**
- * Call /age-withdraw/$ACH/reveal
- *
- * @param curl_ctx The context for CURL
- * @param awrh The handler
- */
-static
-void
-perform_protocol (
- struct GNUNET_CURL_Context *curl_ctx,
- struct TALER_EXCHANGE_AgeWithdrawRevealHandle *awrh)
-{
- CURL *curlh = NULL;
- json_t *j_request_body = NULL;
- json_t *j_array_of_secrets = NULL;
- json_t *j_secrets = NULL;
- json_t *j_sec = NULL;
-
-#define FAIL_IF(cond) \
- do { \
- if ((cond)) \
- { \
- GNUNET_break (! (cond)); \
- goto ERROR; \
- } \
- } while(0)
-
- j_array_of_secrets = json_array ();
- FAIL_IF (NULL == j_array_of_secrets);
-
- for (size_t n = 0; n < awrh->num_coins; n++)
- {
- const struct TALER_PlanchetMasterSecretP *secrets =
- awrh->coins_input[n].secrets;
-
- j_secrets = json_array ();
- FAIL_IF (NULL == j_secrets);
-
- for (uint8_t k = 0; k < TALER_CNC_KAPPA; k++)
- {
- const struct TALER_PlanchetMasterSecretP *secret = &secrets[k];
- if (awrh->noreveal_index == k)
- continue;
-
- j_sec = GNUNET_JSON_PACK (
- GNUNET_JSON_pack_data_auto (NULL, secret));
-
- FAIL_IF (NULL == j_sec);
- FAIL_IF (0 < json_array_append_new (j_secrets,
- j_sec));
- }
-
- FAIL_IF (0 < json_array_append_new (j_array_of_secrets,
- j_secrets));
- }
- j_request_body = GNUNET_JSON_PACK (
- GNUNET_JSON_pack_data_auto ("reserve_pub",
- awrh->reserve_pub),
- GNUNET_JSON_pack_array_steal ("disclosed_coin_secrets",
- j_array_of_secrets));
- FAIL_IF (NULL == j_request_body);
-
- curlh = TALER_EXCHANGE_curl_easy_get_ (awrh->request_url);
- FAIL_IF (NULL == curlh);
- FAIL_IF (GNUNET_OK !=
- TALER_curl_easy_post (&awrh->post_ctx,
- curlh,
- j_request_body));
- json_decref (j_request_body);
- j_request_body = NULL;
-
- awrh->job = GNUNET_CURL_job_add2 (curl_ctx,
- curlh,
- awrh->post_ctx.headers,
- &handle_age_withdraw_reveal_finished,
- awrh);
- FAIL_IF (NULL == awrh->job);
-
- /* No error, return */
- return;
-
-ERROR:
- if (NULL != j_sec)
- json_decref (j_sec);
- if (NULL != j_secrets)
- json_decref (j_secrets);
- if (NULL != j_array_of_secrets)
- json_decref (j_array_of_secrets);
- if (NULL != j_request_body)
- json_decref (j_request_body);
- if (NULL != curlh)
- curl_easy_cleanup (curlh);
- TALER_EXCHANGE_age_withdraw_reveal_cancel (awrh);
- return;
-#undef FAIL_IF
-}
-
-
-struct TALER_EXCHANGE_AgeWithdrawRevealHandle *
-TALER_EXCHANGE_age_withdraw_reveal (
- struct GNUNET_CURL_Context *curl_ctx,
- const char *exchange_url,
- size_t num_coins,
- const struct TALER_EXCHANGE_AgeWithdrawCoinInput coins_input[static
- num_coins],
- uint8_t noreveal_index,
- const struct TALER_AgeWithdrawCommitmentHashP *h_commitment,
- const struct TALER_ReservePublicKeyP *reserve_pub,
- TALER_EXCHANGE_AgeWithdrawRevealCallback reveal_cb,
- void *reveal_cb_cls)
-{
- struct TALER_EXCHANGE_AgeWithdrawRevealHandle *awrh =
- GNUNET_new (struct TALER_EXCHANGE_AgeWithdrawRevealHandle);
- awrh->noreveal_index = noreveal_index;
- awrh->h_commitment = *h_commitment;
- awrh->num_coins = num_coins;
- awrh->coins_input = coins_input;
- awrh->callback = reveal_cb;
- awrh->callback_cls = reveal_cb_cls;
- awrh->reserve_pub = reserve_pub;
-
- if (GNUNET_OK !=
- prepare_url (exchange_url,
- awrh))
- return NULL;
-
- perform_protocol (curl_ctx, awrh);
-
- return awrh;
-}
-
-
-void
-TALER_EXCHANGE_age_withdraw_reveal_cancel (
- struct TALER_EXCHANGE_AgeWithdrawRevealHandle *awrh)
-{
- if (NULL != awrh->job)
- {
- GNUNET_CURL_job_cancel (awrh->job);
- awrh->job = NULL;
- }
- TALER_curl_easy_post_finished (&awrh->post_ctx);
- /* FIXME[oec]: anything else left to cleanup!? */
- GNUNET_free (awrh);
-}
-
-
-/* exchange_api_age_withdraw_reveal.c */
diff --git a/src/lib/exchange_api_auditor_add_denomination.c b/src/lib/exchange_api_auditor_add_denomination.c
deleted file mode 100644
index 89de0d7f1..000000000
--- a/src/lib/exchange_api_auditor_add_denomination.c
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2015-2021 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software
- Foundation; either version 3, or (at your option) any later version.
-
- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- TALER; see the file COPYING. If not, see
- <http://www.gnu.org/licenses/>
-*/
-/**
- * @file lib/exchange_api_auditor_add_denomination.c
- * @brief functions for the auditor to add its signature for denomination at the exchange
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include "taler_json_lib.h"
-#include <gnunet/gnunet_curl_lib.h>
-#include "taler_exchange_service.h"
-#include "auditor_api_curl_defaults.h"
-#include "taler_signatures.h"
-#include "taler_curl_lib.h"
-#include "taler_json_lib.h"
-
-
-struct TALER_EXCHANGE_AuditorAddDenominationHandle
-{
-
- /**
- * The url for this request.
- */
- char *url;
-
- /**
- * Minor context that holds body and headers.
- */
- struct TALER_CURL_PostContext post_ctx;
-
- /**
- * Handle for the request.
- */
- struct GNUNET_CURL_Job *job;
-
- /**
- * Function to call with the result.
- */
- TALER_EXCHANGE_AuditorAddDenominationCallback cb;
-
- /**
- * Closure for @a cb.
- */
- void *cb_cls;
-
- /**
- * Reference to the execution context.
- */
- struct GNUNET_CURL_Context *ctx;
-};
-
-
-/**
- * Function called when we're done processing the
- * HTTP POST /auditor/$AUDITOR_PUB/$H_DENOM_PUB request.
- *
- * @param cls the `struct TALER_EXCHANGE_AuditorAddDenominationHandle *`
- * @param response_code HTTP response code, 0 on error
- * @param response response body, NULL if not in JSON
- */
-static void
-handle_auditor_add_denomination_finished (void *cls,
- long response_code,
- const void *response)
-{
- struct TALER_EXCHANGE_AuditorAddDenominationHandle *ah = cls;
- const json_t *json = response;
- struct TALER_EXCHANGE_AuditorAddDenominationResponse adr = {
- .hr.http_status = (unsigned int) response_code,
- .hr.reply = json
- };
-
- ah->job = NULL;
- switch (response_code)
- {
- case MHD_HTTP_NO_CONTENT:
- break;
- case MHD_HTTP_FORBIDDEN:
- adr.hr.ec = TALER_JSON_get_error_code (json);
- adr.hr.hint = TALER_JSON_get_error_hint (json);
- break;
- case MHD_HTTP_NOT_FOUND:
- adr.hr.ec = TALER_JSON_get_error_code (json);
- adr.hr.hint = TALER_JSON_get_error_hint (json);
- break;
- case MHD_HTTP_GONE:
- adr.hr.ec = TALER_JSON_get_error_code (json);
- adr.hr.hint = TALER_JSON_get_error_hint (json);
- break;
- case MHD_HTTP_PRECONDITION_FAILED:
- adr.hr.ec = TALER_JSON_get_error_code (json);
- adr.hr.hint = TALER_JSON_get_error_hint (json);
- break;
- default:
- /* unexpected response code */
- if (NULL != json)
- {
- adr.hr.ec = TALER_JSON_get_error_code (json);
- adr.hr.hint = TALER_JSON_get_error_hint (json);
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Unexpected response code %u/%d for exchange auditor-add-denomination at URL `%s'\n",
- (unsigned int) response_code,
- (int) adr.hr.ec,
- ah->url);
- }
- else
- {
- adr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
- adr.hr.hint = NULL;
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Unexpected HTTP response code %u (no JSON returned) at URL `%s'\n",
- (unsigned int) response_code,
- ah->url);
- }
- break;
- }
- if (NULL != ah->cb)
- {
- ah->cb (ah->cb_cls,
- &adr);
- ah->cb = NULL;
- }
- TALER_EXCHANGE_add_auditor_denomination_cancel (ah);
-}
-
-
-struct TALER_EXCHANGE_AuditorAddDenominationHandle *
-TALER_EXCHANGE_add_auditor_denomination (
- struct GNUNET_CURL_Context *ctx,
- const char *url,
- const struct TALER_DenominationHashP *h_denom_pub,
- const struct TALER_AuditorPublicKeyP *auditor_pub,
- const struct TALER_AuditorSignatureP *auditor_sig,
- TALER_EXCHANGE_AuditorAddDenominationCallback cb,
- void *cb_cls)
-{
- struct TALER_EXCHANGE_AuditorAddDenominationHandle *ah;
- CURL *eh;
- json_t *body;
-
- ah = GNUNET_new (struct TALER_EXCHANGE_AuditorAddDenominationHandle);
- ah->cb = cb;
- ah->cb_cls = cb_cls;
- ah->ctx = ctx;
- {
- char apub_str[sizeof (*auditor_pub) * 2];
- char denom_str[sizeof (*h_denom_pub) * 2];
- char arg_str[sizeof (apub_str) + sizeof (denom_str) + 32];
- char *end;
-
- end = GNUNET_STRINGS_data_to_string (auditor_pub,
- sizeof (*auditor_pub),
- apub_str,
- sizeof (apub_str));
- *end = '\0';
- end = GNUNET_STRINGS_data_to_string (h_denom_pub,
- sizeof (*h_denom_pub),
- denom_str,
- sizeof (denom_str));
- *end = '\0';
- GNUNET_snprintf (arg_str,
- sizeof (arg_str),
- "auditors/%s/%s",
- apub_str,
- denom_str);
- ah->url = TALER_url_join (url,
- arg_str,
- NULL);
- }
- if (NULL == ah->url)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Could not construct request URL.\n");
- GNUNET_free (ah);
- return NULL;
- }
- body = GNUNET_JSON_PACK (
- GNUNET_JSON_pack_data_auto ("auditor_sig",
- auditor_sig));
- eh = TALER_AUDITOR_curl_easy_get_ (ah->url);
- if ( (NULL == eh) ||
- (GNUNET_OK !=
- TALER_curl_easy_post (&ah->post_ctx,
- eh,
- body)) )
- {
- GNUNET_break (0);
- if (NULL != eh)
- curl_easy_cleanup (eh);
- json_decref (body);
- GNUNET_free (ah->url);
- return NULL;
- }
- json_decref (body);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Requesting URL '%s'\n",
- ah->url);
- ah->job = GNUNET_CURL_job_add2 (ctx,
- eh,
- ah->post_ctx.headers,
- &handle_auditor_add_denomination_finished,
- ah);
- if (NULL == ah->job)
- {
- TALER_EXCHANGE_add_auditor_denomination_cancel (ah);
- return NULL;
- }
- return ah;
-}
-
-
-void
-TALER_EXCHANGE_add_auditor_denomination_cancel (
- struct TALER_EXCHANGE_AuditorAddDenominationHandle *ah)
-{
- if (NULL != ah->job)
- {
- GNUNET_CURL_job_cancel (ah->job);
- ah->job = NULL;
- }
- TALER_curl_easy_post_finished (&ah->post_ctx);
- GNUNET_free (ah->url);
- GNUNET_free (ah);
-}
diff --git a/src/lib/exchange_api_csr_melt.c b/src/lib/exchange_api_csr_melt.c
deleted file mode 100644
index f59995af3..000000000
--- a/src/lib/exchange_api_csr_melt.c
+++ /dev/null
@@ -1,317 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2014-2022 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software
- Foundation; either version 3, or (at your option) any later version.
-
- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- TALER; see the file COPYING. If not, see
- <http://www.gnu.org/licenses/>
-*/
-/**
- * @file lib/exchange_api_csr_melt.c
- * @brief Implementation of /csr-melt requests (get R in exchange used for Clause Schnorr refresh)
- * @author Lucien Heuzeveldt
- * @author Gian Demarmels
- */
-#include "platform.h"
-#include <jansson.h>
-#include <microhttpd.h> /* just for HTTP status codes */
-#include <gnunet/gnunet_util_lib.h>
-#include <gnunet/gnunet_json_lib.h>
-#include <gnunet/gnunet_curl_lib.h>
-#include "taler_exchange_service.h"
-#include "taler_json_lib.h"
-#include "exchange_api_handle.h"
-#include "taler_signatures.h"
-#include "exchange_api_curl_defaults.h"
-
-
-/**
- * @brief A Clause Schnorr R Handle
- */
-struct TALER_EXCHANGE_CsRMeltHandle
-{
-
- /**
- * Function to call with the result.
- */
- TALER_EXCHANGE_CsRMeltCallback cb;
-
- /**
- * Closure for @a cb.
- */
- void *cb_cls;
-
- /**
- * The url for this request.
- */
- char *url;
-
- /**
- * Handle for the request.
- */
- struct GNUNET_CURL_Job *job;
-
- /**
- * Context for #TEH_curl_easy_post(). Keeps the data that must
- * persist for Curl to make the upload.
- */
- struct TALER_CURL_PostContext post_ctx;
-};
-
-
-/**
- * We got a 200 OK response for the /reserves/$RESERVE_PUB/withdraw operation.
- * Extract the coin's signature and return it to the caller. The signature we
- * get from the exchange is for the blinded value. Thus, we first must
- * unblind it and then should verify its validity against our coin's hash.
- *
- * If everything checks out, we return the unblinded signature
- * to the application via the callback.
- *
- * @param csrh operation handle
- * @param arr reply from the exchange
- * @param hr http response details
- * @return #GNUNET_OK on success, #GNUNET_SYSERR on errors
- */
-static enum GNUNET_GenericReturnValue
-csr_ok (struct TALER_EXCHANGE_CsRMeltHandle *csrh,
- const json_t *arr,
- struct TALER_EXCHANGE_HttpResponse *hr)
-{
- unsigned int alen = json_array_size (arr);
- struct TALER_ExchangeWithdrawValues alg_values[GNUNET_NZL (alen)];
- struct TALER_EXCHANGE_CsRMeltResponse csrr = {
- .hr = *hr,
- .details.ok.alg_values_len = alen,
- .details.ok.alg_values = alg_values
- };
-
- for (unsigned int i = 0; i<alen; i++)
- {
- json_t *av = json_array_get (arr,
- i);
- struct GNUNET_JSON_Specification spec[] = {
- TALER_JSON_spec_exchange_withdraw_values (
- "ewv",
- &alg_values[i]),
- GNUNET_JSON_spec_end ()
- };
-
- if (GNUNET_OK !=
- GNUNET_JSON_parse (av,
- spec,
- NULL, NULL))
- {
- GNUNET_break_op (0);
- return GNUNET_SYSERR;
- }
- }
- csrh->cb (csrh->cb_cls,
- &csrr);
- return GNUNET_OK;
-}
-
-
-/**
- * Function called when we're done processing the HTTP /csr request.
- *
- * @param cls the `struct TALER_EXCHANGE_CsRMeltHandle`
- * @param response_code HTTP response code, 0 on error
- * @param response parsed JSON result, NULL on error
- */
-static void
-handle_csr_finished (void *cls,
- long response_code,
- const void *response)
-{
- struct TALER_EXCHANGE_CsRMeltHandle *csrh = cls;
- const json_t *j = response;
- struct TALER_EXCHANGE_HttpResponse hr = {
- .reply = j,
- .http_status = (unsigned int) response_code
- };
- struct TALER_EXCHANGE_CsRMeltResponse csrr = {
- .hr = hr
- };
-
- csrh->job = NULL;
- switch (response_code)
- {
- case 0:
- csrr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
- break;
- case MHD_HTTP_OK:
- {
- json_t *arr;
-
- arr = json_object_get (j,
- "ewvs");
- if ( (NULL == arr) ||
- (0 == json_array_size (arr)) ||
- (GNUNET_OK !=
- csr_ok (csrh,
- arr,
- &hr)) )
- {
- GNUNET_break_op (0);
- csrr.hr.http_status = 0;
- csrr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
- break;
- }
- }
- TALER_EXCHANGE_csr_melt_cancel (csrh);
- return;
- case MHD_HTTP_BAD_REQUEST:
- /* This should never happen, either us or the exchange is buggy
- (or API version conflict); just pass JSON reply to the application */
- csrr.hr.ec = TALER_JSON_get_error_code (j);
- csrr.hr.hint = TALER_JSON_get_error_hint (j);
- break;
- case MHD_HTTP_NOT_FOUND:
- /* Nothing really to verify, the exchange basically just says
- that it doesn't know the /csr endpoint or denomination.
- Can happen if the exchange doesn't support Clause Schnorr.
- We should simply pass the JSON reply to the application. */
- csrr.hr.ec = TALER_JSON_get_error_code (j);
- csrr.hr.hint = TALER_JSON_get_error_hint (j);
- break;
- case MHD_HTTP_GONE:
- /* could happen if denomination was revoked */
- /* Note: one might want to check /keys for revocation
- signature here, alas tricky in case our /keys
- is outdated => left to clients */
- csrr.hr.ec = TALER_JSON_get_error_code (j);
- csrr.hr.hint = TALER_JSON_get_error_hint (j);
- break;
- case MHD_HTTP_INTERNAL_SERVER_ERROR:
- /* Server had an internal issue; we should retry, but this API
- leaves this to the application */
- csrr.hr.ec = TALER_JSON_get_error_code (j);
- csrr.hr.hint = TALER_JSON_get_error_hint (j);
- break;
- default:
- /* unexpected response code */
- GNUNET_break_op (0);
- csrr.hr.ec = TALER_JSON_get_error_code (j);
- csrr.hr.hint = TALER_JSON_get_error_hint (j);
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Unexpected response code %u/%d for CS R request\n",
- (unsigned int) response_code,
- (int) hr.ec);
- break;
- }
- csrh->cb (csrh->cb_cls,
- &csrr);
- csrh->cb = NULL;
- TALER_EXCHANGE_csr_melt_cancel (csrh);
-}
-
-
-struct TALER_EXCHANGE_CsRMeltHandle *
-TALER_EXCHANGE_csr_melt (
- struct GNUNET_CURL_Context *ctx,
- const char *url,
- const struct TALER_RefreshMasterSecretP *rms,
- unsigned int nks_len,
- struct TALER_EXCHANGE_NonceKey nks[static nks_len],
- TALER_EXCHANGE_CsRMeltCallback res_cb,
- void *res_cb_cls)
-{
- struct TALER_EXCHANGE_CsRMeltHandle *csrh;
- json_t *csr_arr;
-
- if (0 == nks_len)
- {
- GNUNET_break (0);
- return NULL;
- }
- for (unsigned int i = 0; i<nks_len; i++)
- if (TALER_DENOMINATION_CS != nks[i].pk->key.cipher)
- {
- GNUNET_break (0);
- return NULL;
- }
- csrh = GNUNET_new (struct TALER_EXCHANGE_CsRMeltHandle);
- csrh->cb = res_cb;
- csrh->cb_cls = res_cb_cls;
- csr_arr = json_array ();
- GNUNET_assert (NULL != csr_arr);
- for (unsigned int i = 0; i<nks_len; i++)
- {
- const struct TALER_EXCHANGE_NonceKey *nk = &nks[i];
- json_t *csr_obj;
-
- csr_obj = GNUNET_JSON_PACK (
- GNUNET_JSON_pack_uint64 ("coin_offset",
- nk->cnc_num),
- GNUNET_JSON_pack_data_auto ("denom_pub_hash",
- &nk->pk->h_key));
- GNUNET_assert (NULL != csr_obj);
- GNUNET_assert (0 ==
- json_array_append_new (csr_arr,
- csr_obj));
- }
- csrh->url = TALER_url_join (url,
- "csr-melt",
- NULL);
- if (NULL == csrh->url)
- {
- json_decref (csr_arr);
- GNUNET_free (csrh);
- return NULL;
- }
- {
- CURL *eh;
- json_t *req;
-
- req = GNUNET_JSON_PACK (
- GNUNET_JSON_pack_data_auto ("rms",
- rms),
- GNUNET_JSON_pack_array_steal ("nks",
- csr_arr));
- eh = TALER_EXCHANGE_curl_easy_get_ (csrh->url);
- if ( (NULL == eh) ||
- (GNUNET_OK !=
- TALER_curl_easy_post (&csrh->post_ctx,
- eh,
- req)) )
- {
- GNUNET_break (0);
- if (NULL != eh)
- curl_easy_cleanup (eh);
- json_decref (req);
- GNUNET_free (csrh->url);
- GNUNET_free (csrh);
- return NULL;
- }
- json_decref (req);
- csrh->job = GNUNET_CURL_job_add2 (ctx,
- eh,
- csrh->post_ctx.headers,
- &handle_csr_finished,
- csrh);
- }
- return csrh;
-}
-
-
-void
-TALER_EXCHANGE_csr_melt_cancel (struct TALER_EXCHANGE_CsRMeltHandle *csrh)
-{
- if (NULL != csrh->job)
- {
- GNUNET_CURL_job_cancel (csrh->job);
- csrh->job = NULL;
- }
- GNUNET_free (csrh->url);
- TALER_curl_easy_post_finished (&csrh->post_ctx);
- GNUNET_free (csrh);
-}
diff --git a/src/lib/exchange_api_kyc_check.c b/src/lib/exchange_api_kyc_check.c
deleted file mode 100644
index 373dd89a7..000000000
--- a/src/lib/exchange_api_kyc_check.c
+++ /dev/null
@@ -1,329 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2021-2023 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software
- Foundation; either version 3, or (at your option) any later version.
-
- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- TALER; see the file COPYING. If not, see
- <http://www.gnu.org/licenses/>
-*/
-/**
- * @file lib/exchange_api_kyc_check.c
- * @brief Implementation of the /kyc-check request
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include <microhttpd.h> /* just for HTTP check codes */
-#include <gnunet/gnunet_util_lib.h>
-#include <gnunet/gnunet_curl_lib.h>
-#include "taler_exchange_service.h"
-#include "taler_json_lib.h"
-#include "exchange_api_handle.h"
-#include "taler_signatures.h"
-#include "exchange_api_curl_defaults.h"
-
-
-/**
- * @brief A ``/kyc-check`` handle
- */
-struct TALER_EXCHANGE_KycCheckHandle
-{
-
- /**
- * The url for this request.
- */
- char *url;
-
- /**
- * Keys of the exchange.
- */
- struct TALER_EXCHANGE_Keys *keys;
-
- /**
- * Handle for the request.
- */
- struct GNUNET_CURL_Job *job;
-
- /**
- * Function to call with the result.
- */
- TALER_EXCHANGE_KycStatusCallback cb;
-
- /**
- * Closure for @e cb.
- */
- void *cb_cls;
-
- /**
- * Hash of the payto:// URL that is being KYC'ed.
- */
- struct TALER_PaytoHashP h_payto;
-
-};
-
-
-/**
- * Function called when we're done processing the
- * HTTP /kyc-check request.
- *
- * @param cls the `struct TALER_EXCHANGE_KycCheckHandle`
- * @param response_code HTTP response code, 0 on error
- * @param response parsed JSON result, NULL on error
- */
-static void
-handle_kyc_check_finished (void *cls,
- long response_code,
- const void *response)
-{
- struct TALER_EXCHANGE_KycCheckHandle *kch = cls;
- const json_t *j = response;
- struct TALER_EXCHANGE_KycStatus ks = {
- .http_status = (unsigned int) response_code
- };
-
- kch->job = NULL;
- switch (response_code)
- {
- case 0:
- ks.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
- break;
- case MHD_HTTP_OK:
- {
- const json_t *kyc_details;
- uint32_t status;
- struct GNUNET_JSON_Specification spec[] = {
- GNUNET_JSON_spec_fixed_auto ("exchange_sig",
- &ks.details.ok.exchange_sig),
- GNUNET_JSON_spec_fixed_auto ("exchange_pub",
- &ks.details.ok.exchange_pub),
- GNUNET_JSON_spec_timestamp ("now",
- &ks.details.ok.timestamp),
- GNUNET_JSON_spec_object_const ("kyc_details",
- &kyc_details),
- GNUNET_JSON_spec_uint32 ("aml_status",
- &status),
- GNUNET_JSON_spec_end ()
- };
-
- if (GNUNET_OK !=
- GNUNET_JSON_parse (j,
- spec,
- NULL, NULL))
- {
- GNUNET_break_op (0);
- ks.http_status = 0;
- ks.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
- break;
- }
- ks.details.ok.kyc_details = kyc_details;
- ks.details.ok.aml_status
- = (enum TALER_AmlDecisionState) status;
- if (GNUNET_OK !=
- TALER_EXCHANGE_test_signing_key (kch->keys,
- &ks.details.ok.exchange_pub))
- {
- GNUNET_break_op (0);
- ks.http_status = 0;
- ks.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
- GNUNET_JSON_parse_free (spec);
- break;
- }
-
- if (GNUNET_OK !=
- TALER_exchange_online_account_setup_success_verify (
- &kch->h_payto,
- ks.details.ok.kyc_details,
- ks.details.ok.timestamp,
- &ks.details.ok.exchange_pub,
- &ks.details.ok.exchange_sig))
- {
- GNUNET_break_op (0);
- ks.http_status = 0;
- ks.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
- GNUNET_JSON_parse_free (spec);
- break;
- }
- kch->cb (kch->cb_cls,
- &ks);
- GNUNET_JSON_parse_free (spec);
- TALER_EXCHANGE_kyc_check_cancel (kch);
- return;
- }
- case MHD_HTTP_ACCEPTED:
- {
- uint32_t status;
- struct GNUNET_JSON_Specification spec[] = {
- GNUNET_JSON_spec_string ("kyc_url",
- &ks.details.accepted.kyc_url),
- GNUNET_JSON_spec_uint32 ("aml_status",
- &status),
- GNUNET_JSON_spec_end ()
- };
-
- if (GNUNET_OK !=
- GNUNET_JSON_parse (j,
- spec,
- NULL, NULL))
- {
- GNUNET_break_op (0);
- ks.http_status = 0;
- ks.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
- break;
- }
- ks.details.accepted.aml_status
- = (enum TALER_AmlDecisionState) status;
- kch->cb (kch->cb_cls,
- &ks);
- GNUNET_JSON_parse_free (spec);
- TALER_EXCHANGE_kyc_check_cancel (kch);
- return;
- }
- case MHD_HTTP_NO_CONTENT:
- break;
- case MHD_HTTP_BAD_REQUEST:
- ks.ec = TALER_JSON_get_error_code (j);
- /* 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_FORBIDDEN:
- ks.ec = TALER_JSON_get_error_code (j);
- break;
- case MHD_HTTP_NOT_FOUND:
- ks.ec = TALER_JSON_get_error_code (j);
- break;
- case MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS:
- {
- uint32_t status;
- struct GNUNET_JSON_Specification spec[] = {
- GNUNET_JSON_spec_uint32 ("aml_status",
- &status),
- GNUNET_JSON_spec_end ()
- };
-
- if (GNUNET_OK !=
- GNUNET_JSON_parse (j,
- spec,
- NULL, NULL))
- {
- GNUNET_break_op (0);
- ks.http_status = 0;
- ks.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
- break;
- }
- ks.details.unavailable_for_legal_reasons.aml_status
- = (enum TALER_AmlDecisionState) status;
- kch->cb (kch->cb_cls,
- &ks);
- GNUNET_JSON_parse_free (spec);
- TALER_EXCHANGE_kyc_check_cancel (kch);
- return;
- }
- case MHD_HTTP_INTERNAL_SERVER_ERROR:
- ks.ec = TALER_JSON_get_error_code (j);
- /* Server had an internal issue; we should retry, but this API
- leaves this to the application */
- break;
- default:
- /* unexpected response code */
- GNUNET_break_op (0);
- ks.ec = TALER_JSON_get_error_code (j);
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Unexpected response code %u/%d for exchange kyc_check\n",
- (unsigned int) response_code,
- (int) ks.ec);
- break;
- }
- kch->cb (kch->cb_cls,
- &ks);
- TALER_EXCHANGE_kyc_check_cancel (kch);
-}
-
-
-struct TALER_EXCHANGE_KycCheckHandle *
-TALER_EXCHANGE_kyc_check (
- struct GNUNET_CURL_Context *ctx,
- const char *url,
- struct TALER_EXCHANGE_Keys *keys,
- uint64_t requirement_row,
- const struct TALER_PaytoHashP *h_payto,
- enum TALER_KYCLOGIC_KycUserType ut,
- struct GNUNET_TIME_Relative timeout,
- TALER_EXCHANGE_KycStatusCallback cb,
- void *cb_cls)
-{
- struct TALER_EXCHANGE_KycCheckHandle *kch;
- CURL *eh;
- char *arg_str;
-
- {
- char payto_str[sizeof (*h_payto) * 2];
- char *end;
- unsigned long long timeout_ms;
-
- end = GNUNET_STRINGS_data_to_string (
- h_payto,
- sizeof (*h_payto),
- payto_str,
- sizeof (payto_str) - 1);
- *end = '\0';
- timeout_ms = timeout.rel_value_us
- / GNUNET_TIME_UNIT_MILLISECONDS.rel_value_us;
- GNUNET_asprintf (&arg_str,
- "kyc-check/%llu/%s/%s?timeout_ms=%llu",
- (unsigned long long) requirement_row,
- payto_str,
- TALER_KYCLOGIC_kyc_user_type2s (ut),
- timeout_ms);
- }
- kch = GNUNET_new (struct TALER_EXCHANGE_KycCheckHandle);
- kch->h_payto = *h_payto;
- kch->cb = cb;
- kch->cb_cls = cb_cls;
- kch->url = TALER_url_join (url,
- arg_str,
- NULL);
- GNUNET_free (arg_str);
- if (NULL == kch->url)
- {
- GNUNET_free (kch);
- return NULL;
- }
- eh = TALER_EXCHANGE_curl_easy_get_ (kch->url);
- if (NULL == eh)
- {
- GNUNET_break (0);
- GNUNET_free (kch->url);
- GNUNET_free (kch);
- return NULL;
- }
- kch->keys = TALER_EXCHANGE_keys_incref (keys);
- kch->job = GNUNET_CURL_job_add_with_ct_json (ctx,
- eh,
- &handle_kyc_check_finished,
- kch);
- return kch;
-}
-
-
-void
-TALER_EXCHANGE_kyc_check_cancel (struct TALER_EXCHANGE_KycCheckHandle *kch)
-{
- if (NULL != kch->job)
- {
- GNUNET_CURL_job_cancel (kch->job);
- kch->job = NULL;
- }
- TALER_EXCHANGE_keys_decref (kch->keys);
- GNUNET_free (kch->url);
- GNUNET_free (kch);
-}
-
-
-/* end of exchange_api_kyc_check.c */
diff --git a/src/lib/exchange_api_kyc_proof.c b/src/lib/exchange_api_kyc_proof.c
deleted file mode 100644
index e7cc9c4cf..000000000
--- a/src/lib/exchange_api_kyc_proof.c
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2021, 2022 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software
- Foundation; either version 3, or (at your option) any later version.
-
- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- TALER; see the file COPYING. If not, see
- <http://www.gnu.org/licenses/>
-*/
-/**
- * @file lib/exchange_api_kyc_proof.c
- * @brief Implementation of the /kyc-proof request
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include <microhttpd.h> /* just for HTTP proof codes */
-#include <gnunet/gnunet_util_lib.h>
-#include <gnunet/gnunet_curl_lib.h>
-#include "taler_exchange_service.h"
-#include "taler_json_lib.h"
-#include "exchange_api_handle.h"
-#include "taler_signatures.h"
-#include "exchange_api_curl_defaults.h"
-
-
-/**
- * @brief A ``/kyc-proof`` handle
- */
-struct TALER_EXCHANGE_KycProofHandle
-{
-
- /**
- * The url for this request.
- */
- char *url;
-
- /**
- * Handle to our CURL request.
- */
- CURL *eh;
-
- /**
- * Handle for the request.
- */
- struct GNUNET_CURL_Job *job;
-
- /**
- * Function to call with the result.
- */
- TALER_EXCHANGE_KycProofCallback cb;
-
- /**
- * Closure for @e cb.
- */
- void *cb_cls;
-
-};
-
-
-/**
- * Function called when we're done processing the
- * HTTP /kyc-proof request.
- *
- * @param cls the `struct TALER_EXCHANGE_KycProofHandle`
- * @param response_code HTTP response code, 0 on error
- * @param body response body
- * @param body_size number of bytes in @a body
- */
-static void
-handle_kyc_proof_finished (void *cls,
- long response_code,
- const void *body,
- size_t body_size)
-{
- struct TALER_EXCHANGE_KycProofHandle *kph = cls;
- struct TALER_EXCHANGE_KycProofResponse kpr = {
- .http_status = (unsigned int) response_code
- };
-
- (void) body;
- (void) body_size;
- kph->job = NULL;
- switch (response_code)
- {
- case 0:
- break;
- case MHD_HTTP_SEE_OTHER:
- {
- char *redirect_url;
-
- GNUNET_assert (CURLE_OK ==
- curl_easy_getinfo (kph->eh,
- CURLINFO_REDIRECT_URL,
- &redirect_url));
- kpr.details.found.redirect_url = redirect_url;
- break;
- }
- case MHD_HTTP_BAD_REQUEST:
- /* 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_UNAUTHORIZED:
- break;
- case MHD_HTTP_FORBIDDEN:
- break;
- case MHD_HTTP_NOT_FOUND:
- break;
- case MHD_HTTP_BAD_GATEWAY:
- /* Server had an internal issue; we should retry, but this API
- leaves this to the application */
- break;
- case MHD_HTTP_GATEWAY_TIMEOUT:
- /* Server had an internal issue; we should retry, but this API
- leaves this to the application */
- break;
- default:
- /* unexpected response code */
- GNUNET_break_op (0);
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Unexpected response code %u for exchange kyc_proof\n",
- (unsigned int) response_code);
- break;
- }
- kph->cb (kph->cb_cls,
- &kpr);
- TALER_EXCHANGE_kyc_proof_cancel (kph);
-}
-
-
-struct TALER_EXCHANGE_KycProofHandle *
-TALER_EXCHANGE_kyc_proof (
- struct GNUNET_CURL_Context *ctx,
- const char *url,
- const struct TALER_PaytoHashP *h_payto,
- const char *logic,
- const char *args,
- TALER_EXCHANGE_KycProofCallback cb,
- void *cb_cls)
-{
- struct TALER_EXCHANGE_KycProofHandle *kph;
- char *arg_str;
-
- if (NULL == args)
- args = "";
- else
- GNUNET_assert (args[0] == '&');
- {
- char hstr[sizeof (struct TALER_PaytoHashP) * 2];
- char *end;
-
- end = GNUNET_STRINGS_data_to_string (h_payto,
- sizeof (*h_payto),
- hstr,
- sizeof (hstr));
- *end = '\0';
- GNUNET_asprintf (&arg_str,
- "kyc-proof/%s?state=%s%s",
- logic,
- hstr,
- args);
- }
- kph = GNUNET_new (struct TALER_EXCHANGE_KycProofHandle);
- kph->cb = cb;
- kph->cb_cls = cb_cls;
- kph->url = TALER_url_join (url,
- arg_str,
- NULL);
- GNUNET_free (arg_str);
- if (NULL == kph->url)
- {
- GNUNET_free (kph);
- return NULL;
- }
- kph->eh = TALER_EXCHANGE_curl_easy_get_ (kph->url);
- if (NULL == kph->eh)
- {
- GNUNET_break (0);
- GNUNET_free (kph->url);
- GNUNET_free (kph);
- return NULL;
- }
- /* disable location following, we want to learn the
- result of a 303 redirect! */
- GNUNET_assert (CURLE_OK ==
- curl_easy_setopt (kph->eh,
- CURLOPT_FOLLOWLOCATION,
- 0L));
- kph->job = GNUNET_CURL_job_add_raw (ctx,
- kph->eh,
- NULL,
- &handle_kyc_proof_finished,
- kph);
- return kph;
-}
-
-
-void
-TALER_EXCHANGE_kyc_proof_cancel (struct TALER_EXCHANGE_KycProofHandle *kph)
-{
- if (NULL != kph->job)
- {
- GNUNET_CURL_job_cancel (kph->job);
- kph->job = NULL;
- }
- GNUNET_free (kph->url);
- GNUNET_free (kph);
-}
-
-
-/* end of exchange_api_kyc_proof.c */
diff --git a/src/lib/exchange_api_kyc_wallet.c b/src/lib/exchange_api_kyc_wallet.c
deleted file mode 100644
index 7197694ae..000000000
--- a/src/lib/exchange_api_kyc_wallet.c
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2021 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software
- Foundation; either version 3, or (at your option) any later version.
-
- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- TALER; see the file COPYING. If not, see
- <http://www.gnu.org/licenses/>
-*/
-/**
- * @file lib/exchange_api_kyc_wallet.c
- * @brief Implementation of the /kyc-wallet request
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include <microhttpd.h> /* just for HTTP wallet codes */
-#include <gnunet/gnunet_util_lib.h>
-#include <gnunet/gnunet_curl_lib.h>
-#include "taler_exchange_service.h"
-#include "taler_json_lib.h"
-#include "exchange_api_handle.h"
-#include "taler_signatures.h"
-#include "exchange_api_curl_defaults.h"
-
-
-/**
- * @brief A ``/kyc-wallet`` handle
- */
-struct TALER_EXCHANGE_KycWalletHandle
-{
-
- /**
- * Context for #TEH_curl_easy_post(). Keeps the data that must
- * persist for Curl to make the upload.
- */
- struct TALER_CURL_PostContext ctx;
-
- /**
- * The url for this request.
- */
- char *url;
-
- /**
- * Handle for the request.
- */
- struct GNUNET_CURL_Job *job;
-
- /**
- * Function to call with the result.
- */
- TALER_EXCHANGE_KycWalletCallback cb;
-
- /**
- * Closure for @e cb.
- */
- void *cb_cls;
-
-};
-
-
-/**
- * Function called when we're done processing the
- * HTTP /kyc-wallet request.
- *
- * @param cls the `struct TALER_EXCHANGE_KycWalletHandle`
- * @param response_code HTTP response code, 0 on error
- * @param response parsed JSON result, NULL on error
- */
-static void
-handle_kyc_wallet_finished (void *cls,
- long response_code,
- const void *response)
-{
- struct TALER_EXCHANGE_KycWalletHandle *kwh = cls;
- const json_t *j = response;
- struct TALER_EXCHANGE_WalletKycResponse ks = {
- .http_status = (unsigned int) response_code
- };
-
- kwh->job = NULL;
- switch (response_code)
- {
- case 0:
- ks.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
- break;
- case MHD_HTTP_NO_CONTENT:
- break;
- case MHD_HTTP_BAD_REQUEST:
- ks.ec = TALER_JSON_get_error_code (j);
- /* 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_FORBIDDEN:
- ks.ec = TALER_JSON_get_error_code (j);
- break;
- case MHD_HTTP_NOT_FOUND:
- ks.ec = TALER_JSON_get_error_code (j);
- break;
- case MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS:
- {
- struct GNUNET_JSON_Specification spec[] = {
- GNUNET_JSON_spec_fixed_auto (
- "h_payto",
- &ks.details.unavailable_for_legal_reasons.h_payto),
- GNUNET_JSON_spec_uint64 (
- "requirement_row",
- &ks.details.unavailable_for_legal_reasons.requirement_row),
- GNUNET_JSON_spec_end ()
- };
-
- if (GNUNET_OK !=
- GNUNET_JSON_parse (j,
- spec,
- NULL, NULL))
- {
- GNUNET_break_op (0);
- ks.http_status = 0;
- ks.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
- break;
- }
- break;
- }
- case MHD_HTTP_INTERNAL_SERVER_ERROR:
- ks.ec = TALER_JSON_get_error_code (j);
- /* Server had an internal issue; we should retry, but this API
- leaves this to the application */
- break;
- default:
- /* unexpected response code */
- GNUNET_break_op (0);
- ks.ec = TALER_JSON_get_error_code (j);
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Unexpected response code %u/%d for exchange /kyc-wallet\n",
- (unsigned int) response_code,
- (int) ks.ec);
- break;
- }
- kwh->cb (kwh->cb_cls,
- &ks);
- TALER_EXCHANGE_kyc_wallet_cancel (kwh);
-}
-
-
-struct TALER_EXCHANGE_KycWalletHandle *
-TALER_EXCHANGE_kyc_wallet (
- struct GNUNET_CURL_Context *ctx,
- const char *url,
- const struct TALER_ReservePrivateKeyP *reserve_priv,
- const struct TALER_Amount *balance,
- TALER_EXCHANGE_KycWalletCallback cb,
- void *cb_cls)
-{
- struct TALER_EXCHANGE_KycWalletHandle *kwh;
- CURL *eh;
- json_t *req;
- struct TALER_ReservePublicKeyP reserve_pub;
- struct TALER_ReserveSignatureP reserve_sig;
-
- GNUNET_CRYPTO_eddsa_key_get_public (&reserve_priv->eddsa_priv,
- &reserve_pub.eddsa_pub);
- TALER_wallet_account_setup_sign (reserve_priv,
- balance,
- &reserve_sig);
- req = GNUNET_JSON_PACK (
- TALER_JSON_pack_amount ("balance",
- balance),
- GNUNET_JSON_pack_data_auto ("reserve_pub",
- &reserve_pub),
- GNUNET_JSON_pack_data_auto ("reserve_sig",
- &reserve_sig));
- GNUNET_assert (NULL != req);
- kwh = GNUNET_new (struct TALER_EXCHANGE_KycWalletHandle);
- kwh->cb = cb;
- kwh->cb_cls = cb_cls;
- kwh->url = TALER_url_join (url,
- "kyc-wallet",
- NULL);
- if (NULL == kwh->url)
- {
- json_decref (req);
- GNUNET_free (kwh);
- return NULL;
- }
- eh = TALER_EXCHANGE_curl_easy_get_ (kwh->url);
- if ( (NULL == eh) ||
- (GNUNET_OK !=
- TALER_curl_easy_post (&kwh->ctx,
- eh,
- req)) )
- {
- GNUNET_break (0);
- if (NULL != eh)
- curl_easy_cleanup (eh);
- json_decref (req);
- GNUNET_free (kwh->url);
- GNUNET_free (kwh);
- return NULL;
- }
- json_decref (req);
- kwh->job = GNUNET_CURL_job_add2 (ctx,
- eh,
- kwh->ctx.headers,
- &handle_kyc_wallet_finished,
- kwh);
- return kwh;
-}
-
-
-void
-TALER_EXCHANGE_kyc_wallet_cancel (struct TALER_EXCHANGE_KycWalletHandle *kwh)
-{
- if (NULL != kwh->job)
- {
- GNUNET_CURL_job_cancel (kwh->job);
- kwh->job = NULL;
- }
- GNUNET_free (kwh->url);
- TALER_curl_easy_post_finished (&kwh->ctx);
- GNUNET_free (kwh);
-}
-
-
-/* end of exchange_api_kyc_wallet.c */
diff --git a/src/lib/exchange_api_lookup_aml_decision.c b/src/lib/exchange_api_lookup_aml_decision.c
deleted file mode 100644
index 01e98213b..000000000
--- a/src/lib/exchange_api_lookup_aml_decision.c
+++ /dev/null
@@ -1,419 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2023 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software
- Foundation; either version 3, or (at your option) any later version.
-
- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- TALER; see the file COPYING. If not, see
- <http://www.gnu.org/licenses/>
-*/
-/**
- * @file lib/exchange_api_lookup_aml_decision.c
- * @brief Implementation of the /aml/$OFFICER_PUB/decision request
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include <microhttpd.h> /* just for HTTP status codes */
-#include <gnunet/gnunet_util_lib.h>
-#include <gnunet/gnunet_curl_lib.h>
-#include "taler_exchange_service.h"
-#include "taler_json_lib.h"
-#include "exchange_api_handle.h"
-#include "taler_signatures.h"
-#include "exchange_api_curl_defaults.h"
-
-
-/**
- * @brief A /coins/$COIN_PUB/link Handle
- */
-struct TALER_EXCHANGE_LookupAmlDecision
-{
-
- /**
- * The url for this request.
- */
- char *url;
-
- /**
- * Handle for the request.
- */
- struct GNUNET_CURL_Job *job;
-
- /**
- * Function to call with the result.
- */
- TALER_EXCHANGE_LookupAmlDecisionCallback decision_cb;
-
- /**
- * Closure for @e cb.
- */
- void *decision_cb_cls;
-
- /**
- * HTTP headers for the job.
- */
- struct curl_slist *job_headers;
-};
-
-
-/**
- * Parse AML decision history.
- *
- * @param aml_history JSON array with AML history
- * @param[out] aml_history_ar where to write the result
- * @return #GNUNET_OK on success
- */
-static enum GNUNET_GenericReturnValue
-parse_aml_history (const json_t *aml_history,
- struct TALER_EXCHANGE_AmlDecisionDetail *aml_history_ar)
-{
- json_t *obj;
- size_t idx;
-
- json_array_foreach (aml_history, idx, obj)
- {
- struct TALER_EXCHANGE_AmlDecisionDetail *aml = &aml_history_ar[idx];
- uint32_t state32;
- struct GNUNET_JSON_Specification spec[] = {
- GNUNET_JSON_spec_timestamp ("decision_time",
- &aml->decision_time),
- GNUNET_JSON_spec_string ("justification",
- &aml->justification),
- TALER_JSON_spec_amount_any ("new_threshold",
- &aml->new_threshold),
- GNUNET_JSON_spec_uint32 ("new_state",
- &state32),
- GNUNET_JSON_spec_fixed_auto ("decider_pub",
- &aml->decider_pub),
- GNUNET_JSON_spec_end ()
- };
-
- if (GNUNET_OK !=
- GNUNET_JSON_parse (obj,
- spec,
- NULL,
- NULL))
- {
- GNUNET_break_op (0);
- return GNUNET_SYSERR;
- }
- aml->new_state = (enum TALER_AmlDecisionState) state32;
- }
- return GNUNET_OK;
-}
-
-
-/**
- * Parse KYC response array.
- *
- * @param kyc_attributes JSON array with KYC details
- * @param[out] kyc_attributes_ar where to write the result
- * @return #GNUNET_OK on success
- */
-static enum GNUNET_GenericReturnValue
-parse_kyc_attributes (const json_t *kyc_attributes,
- struct TALER_EXCHANGE_KycHistoryDetail *kyc_attributes_ar)
-{
- json_t *obj;
- size_t idx;
-
- json_array_foreach (kyc_attributes, idx, obj)
- {
- struct TALER_EXCHANGE_KycHistoryDetail *kyc = &kyc_attributes_ar[idx];
- struct GNUNET_JSON_Specification spec[] = {
- GNUNET_JSON_spec_timestamp ("collection_time",
- &kyc->collection_time),
- GNUNET_JSON_spec_mark_optional (
- GNUNET_JSON_spec_object_const ("attributes",
- &kyc->attributes),
- NULL),
- GNUNET_JSON_spec_string ("provider_section",
- &kyc->provider_section),
- GNUNET_JSON_spec_end ()
- };
-
- if (GNUNET_OK !=
- GNUNET_JSON_parse (obj,
- spec,
- NULL,
- NULL))
- {
- GNUNET_break_op (0);
- return GNUNET_SYSERR;
- }
- }
- return GNUNET_OK;
-}
-
-
-/**
- * Parse the provided decision data from the "200 OK" response.
- *
- * @param[in,out] lh handle (callback may be zero'ed out)
- * @param json json reply with the data for one coin
- * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
- */
-static enum GNUNET_GenericReturnValue
-parse_decision_ok (struct TALER_EXCHANGE_LookupAmlDecision *lh,
- const json_t *json)
-{
- struct TALER_EXCHANGE_AmlDecisionResponse lr = {
- .hr.reply = json,
- .hr.http_status = MHD_HTTP_OK
- };
- const json_t *aml_history;
- const json_t *kyc_attributes;
- struct GNUNET_JSON_Specification spec[] = {
- GNUNET_JSON_spec_array_const ("aml_history",
- &aml_history),
- GNUNET_JSON_spec_array_const ("kyc_attributes",
- &kyc_attributes),
- GNUNET_JSON_spec_end ()
- };
-
- if (GNUNET_OK !=
- GNUNET_JSON_parse (json,
- spec,
- NULL,
- NULL))
- {
- GNUNET_break_op (0);
- return GNUNET_SYSERR;
- }
- lr.details.ok.aml_history_length = json_array_size (aml_history);
- lr.details.ok.kyc_attributes_length = json_array_size (kyc_attributes);
- {
- struct TALER_EXCHANGE_AmlDecisionDetail aml_history_ar[
- GNUNET_NZL (lr.details.ok.aml_history_length)];
- struct TALER_EXCHANGE_KycHistoryDetail kyc_attributes_ar[
- GNUNET_NZL (lr.details.ok.kyc_attributes_length)];
- enum GNUNET_GenericReturnValue ret = GNUNET_SYSERR;
-
- memset (aml_history_ar,
- 0,
- sizeof (aml_history_ar));
- memset (kyc_attributes_ar,
- 0,
- sizeof (kyc_attributes_ar));
- lr.details.ok.aml_history = aml_history_ar;
- lr.details.ok.kyc_attributes = kyc_attributes_ar;
- ret = parse_aml_history (aml_history,
- aml_history_ar);
- if (GNUNET_OK == ret)
- ret = parse_kyc_attributes (kyc_attributes,
- kyc_attributes_ar);
- if (GNUNET_OK == ret)
- {
- lh->decision_cb (lh->decision_cb_cls,
- &lr);
- lh->decision_cb = NULL;
- }
- return ret;
- }
-}
-
-
-/**
- * Function called when we're done processing the
- * HTTP /aml/$OFFICER_PUB/decision request.
- *
- * @param cls the `struct TALER_EXCHANGE_LookupAmlDecision`
- * @param response_code HTTP response code, 0 on error
- * @param response parsed JSON result, NULL on error
- */
-static void
-handle_lookup_finished (void *cls,
- long response_code,
- const void *response)
-{
- struct TALER_EXCHANGE_LookupAmlDecision *lh = cls;
- const json_t *j = response;
- struct TALER_EXCHANGE_AmlDecisionResponse lr = {
- .hr.reply = j,
- .hr.http_status = (unsigned int) response_code
- };
-
- lh->job = NULL;
- switch (response_code)
- {
- case 0:
- lr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
- break;
- case MHD_HTTP_OK:
- if (GNUNET_OK !=
- parse_decision_ok (lh,
- j))
- {
- GNUNET_break_op (0);
- lr.hr.http_status = 0;
- lr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
- break;
- }
- GNUNET_assert (NULL == lh->decision_cb);
- TALER_EXCHANGE_lookup_aml_decision_cancel (lh);
- return;
- case MHD_HTTP_NO_CONTENT:
- break;
- case MHD_HTTP_BAD_REQUEST:
- lr.hr.ec = TALER_JSON_get_error_code (j);
- lr.hr.hint = TALER_JSON_get_error_hint (j);
- /* 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_FORBIDDEN:
- lr.hr.ec = TALER_JSON_get_error_code (j);
- lr.hr.hint = TALER_JSON_get_error_hint (j);
- /* Nothing really to verify, exchange says this coin was not melted; we
- should pass the JSON reply to the application */
- break;
- case MHD_HTTP_NOT_FOUND:
- lr.hr.ec = TALER_JSON_get_error_code (j);
- lr.hr.hint = TALER_JSON_get_error_hint (j);
- /* Nothing really to verify, exchange says this coin was not melted; we
- should pass the JSON reply to the application */
- break;
- case MHD_HTTP_INTERNAL_SERVER_ERROR:
- lr.hr.ec = TALER_JSON_get_error_code (j);
- lr.hr.hint = TALER_JSON_get_error_hint (j);
- /* Server had an internal issue; we should retry, but this API
- leaves this to the application */
- break;
- default:
- /* unexpected response code */
- GNUNET_break_op (0);
- lr.hr.ec = TALER_JSON_get_error_code (j);
- lr.hr.hint = TALER_JSON_get_error_hint (j);
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Unexpected response code %u/%d for exchange lookup AML decision\n",
- (unsigned int) response_code,
- (int) lr.hr.ec);
- break;
- }
- if (NULL != lh->decision_cb)
- lh->decision_cb (lh->decision_cb_cls,
- &lr);
- TALER_EXCHANGE_lookup_aml_decision_cancel (lh);
-}
-
-
-struct TALER_EXCHANGE_LookupAmlDecision *
-TALER_EXCHANGE_lookup_aml_decision (
- struct GNUNET_CURL_Context *ctx,
- const char *exchange_url,
- const struct TALER_PaytoHashP *h_payto,
- const struct TALER_AmlOfficerPrivateKeyP *officer_priv,
- bool history,
- TALER_EXCHANGE_LookupAmlDecisionCallback cb,
- void *cb_cls)
-{
- struct TALER_EXCHANGE_LookupAmlDecision *lh;
- CURL *eh;
- struct TALER_AmlOfficerPublicKeyP officer_pub;
- struct TALER_AmlOfficerSignatureP officer_sig;
- char arg_str[sizeof (officer_pub) * 2
- + sizeof (*h_payto) * 2 + 32];
-
- GNUNET_CRYPTO_eddsa_key_get_public (&officer_priv->eddsa_priv,
- &officer_pub.eddsa_pub);
- TALER_officer_aml_query_sign (officer_priv,
- &officer_sig);
- {
- char pub_str[sizeof (officer_pub) * 2];
- char pt_str[sizeof (*h_payto) * 2];
- char *end;
-
- end = GNUNET_STRINGS_data_to_string (
- &officer_pub,
- sizeof (officer_pub),
- pub_str,
- sizeof (pub_str));
- *end = '\0';
- end = GNUNET_STRINGS_data_to_string (
- h_payto,
- sizeof (*h_payto),
- pt_str,
- sizeof (pt_str));
- *end = '\0';
- GNUNET_snprintf (arg_str,
- sizeof (arg_str),
- "aml/%s/decision/%s",
- pub_str,
- pt_str);
- }
- lh = GNUNET_new (struct TALER_EXCHANGE_LookupAmlDecision);
- lh->decision_cb = cb;
- lh->decision_cb_cls = cb_cls;
- lh->url = TALER_url_join (exchange_url,
- arg_str,
- "history",
- history
- ? "true"
- : NULL,
- NULL);
- if (NULL == lh->url)
- {
- GNUNET_free (lh);
- return NULL;
- }
- eh = TALER_EXCHANGE_curl_easy_get_ (lh->url);
- if (NULL == eh)
- {
- GNUNET_break (0);
- GNUNET_free (lh->url);
- GNUNET_free (lh);
- return NULL;
- }
- {
- char *hdr;
- char sig_str[sizeof (officer_sig) * 2];
- char *end;
-
- end = GNUNET_STRINGS_data_to_string (
- &officer_sig,
- sizeof (officer_sig),
- sig_str,
- sizeof (sig_str));
- *end = '\0';
-
- GNUNET_asprintf (&hdr,
- "%s: %s",
- TALER_AML_OFFICER_SIGNATURE_HEADER,
- sig_str);
- lh->job_headers = curl_slist_append (NULL,
- hdr);
- GNUNET_free (hdr);
- lh->job_headers = curl_slist_append (lh->job_headers,
- "Content-type: application/json");
- lh->job = GNUNET_CURL_job_add2 (ctx,
- eh,
- lh->job_headers,
- &handle_lookup_finished,
- lh);
- }
- return lh;
-}
-
-
-void
-TALER_EXCHANGE_lookup_aml_decision_cancel (
- struct TALER_EXCHANGE_LookupAmlDecision *lh)
-{
- if (NULL != lh->job)
- {
- GNUNET_CURL_job_cancel (lh->job);
- lh->job = NULL;
- }
- curl_slist_free_all (lh->job_headers);
- GNUNET_free (lh->url);
- GNUNET_free (lh);
-}
-
-
-/* end of exchange_api_lookup_aml_decision.c */
diff --git a/src/lib/exchange_api_lookup_aml_decisions.c b/src/lib/exchange_api_lookup_aml_decisions.c
deleted file mode 100644
index 22222b1e4..000000000
--- a/src/lib/exchange_api_lookup_aml_decisions.c
+++ /dev/null
@@ -1,378 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2023 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software
- Foundation; either version 3, or (at your option) any later version.
-
- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- TALER; see the file COPYING. If not, see
- <http://www.gnu.org/licenses/>
-*/
-/**
- * @file lib/exchange_api_lookup_aml_decisions.c
- * @brief Implementation of the /aml/$OFFICER_PUB/decisions request
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include <microhttpd.h> /* just for HTTP status codes */
-#include <gnunet/gnunet_util_lib.h>
-#include <gnunet/gnunet_curl_lib.h>
-#include "taler_exchange_service.h"
-#include "taler_json_lib.h"
-#include "exchange_api_handle.h"
-#include "taler_signatures.h"
-#include "exchange_api_curl_defaults.h"
-
-
-/**
- * @brief A /coins/$COIN_PUB/link Handle
- */
-struct TALER_EXCHANGE_LookupAmlDecisions
-{
-
- /**
- * The url for this request.
- */
- char *url;
-
- /**
- * Handle for the request.
- */
- struct GNUNET_CURL_Job *job;
-
- /**
- * Function to call with the result.
- */
- TALER_EXCHANGE_LookupAmlDecisionsCallback decisions_cb;
-
- /**
- * Closure for @e cb.
- */
- void *decisions_cb_cls;
-
- /**
- * HTTP headers for the job.
- */
- struct curl_slist *job_headers;
-};
-
-
-/**
- * Parse AML decision summary array.
- *
- * @param decisions JSON array with AML decision summaries
- * @param[out] decision_ar where to write the result
- * @return #GNUNET_OK on success
- */
-static enum GNUNET_GenericReturnValue
-parse_aml_decisions (const json_t *decisions,
- struct TALER_EXCHANGE_AmlDecisionSummary *decision_ar)
-{
- json_t *obj;
- size_t idx;
-
- json_array_foreach (decisions, idx, obj)
- {
- struct TALER_EXCHANGE_AmlDecisionSummary *decision = &decision_ar[idx];
- uint32_t state32;
- struct GNUNET_JSON_Specification spec[] = {
- GNUNET_JSON_spec_fixed_auto ("h_payto",
- &decision->h_payto),
- GNUNET_JSON_spec_uint32 ("current_state",
- &state32),
- TALER_JSON_spec_amount_any ("threshold",
- &decision->threshold),
- GNUNET_JSON_spec_uint64 ("rowid",
- &decision->rowid),
- GNUNET_JSON_spec_end ()
- };
-
- if (GNUNET_OK !=
- GNUNET_JSON_parse (obj,
- spec,
- NULL,
- NULL))
- {
- GNUNET_break_op (0);
- return GNUNET_SYSERR;
- }
- decision->current_state = (enum TALER_AmlDecisionState) state32;
- }
- return GNUNET_OK;
-}
-
-
-/**
- * Parse the provided decision data from the "200 OK" response.
- *
- * @param[in,out] lh handle (callback may be zero'ed out)
- * @param json json reply with the data for one coin
- * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
- */
-static enum GNUNET_GenericReturnValue
-parse_decisions_ok (struct TALER_EXCHANGE_LookupAmlDecisions *lh,
- const json_t *json)
-{
- struct TALER_EXCHANGE_AmlDecisionsResponse lr = {
- .hr.reply = json,
- .hr.http_status = MHD_HTTP_OK
- };
- const json_t *records;
- struct GNUNET_JSON_Specification spec[] = {
- GNUNET_JSON_spec_array_const ("records",
- &records),
- GNUNET_JSON_spec_end ()
- };
-
- if (GNUNET_OK !=
- GNUNET_JSON_parse (json,
- spec,
- NULL,
- NULL))
- {
- GNUNET_break_op (0);
- return GNUNET_SYSERR;
- }
- lr.details.ok.decisions_length = json_array_size (records);
- {
- struct TALER_EXCHANGE_AmlDecisionSummary decisions[
- GNUNET_NZL (lr.details.ok.decisions_length)];
- enum GNUNET_GenericReturnValue ret = GNUNET_SYSERR;
-
- lr.details.ok.decisions = decisions;
- ret = parse_aml_decisions (records,
- decisions);
- if (GNUNET_OK == ret)
- {
- lh->decisions_cb (lh->decisions_cb_cls,
- &lr);
- lh->decisions_cb = NULL;
- }
- return ret;
- }
-}
-
-
-/**
- * Function called when we're done processing the
- * HTTP /aml/$OFFICER_PUB/decisions request.
- *
- * @param cls the `struct TALER_EXCHANGE_LookupAmlDecisions`
- * @param response_code HTTP response code, 0 on error
- * @param response parsed JSON result, NULL on error
- */
-static void
-handle_lookup_finished (void *cls,
- long response_code,
- const void *response)
-{
- struct TALER_EXCHANGE_LookupAmlDecisions *lh = cls;
- const json_t *j = response;
- struct TALER_EXCHANGE_AmlDecisionsResponse lr = {
- .hr.reply = j,
- .hr.http_status = (unsigned int) response_code
- };
-
- lh->job = NULL;
- switch (response_code)
- {
- case 0:
- lr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
- break;
- case MHD_HTTP_OK:
- if (GNUNET_OK !=
- parse_decisions_ok (lh,
- j))
- {
- GNUNET_break_op (0);
- lr.hr.http_status = 0;
- lr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
- break;
- }
- GNUNET_assert (NULL == lh->decisions_cb);
- TALER_EXCHANGE_lookup_aml_decisions_cancel (lh);
- return;
- case MHD_HTTP_NO_CONTENT:
- break;
- case MHD_HTTP_BAD_REQUEST:
- lr.hr.ec = TALER_JSON_get_error_code (j);
- lr.hr.hint = TALER_JSON_get_error_hint (j);
- /* 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_FORBIDDEN:
- lr.hr.ec = TALER_JSON_get_error_code (j);
- lr.hr.hint = TALER_JSON_get_error_hint (j);
- /* Nothing really to verify, exchange says this coin was not melted; we
- should pass the JSON reply to the application */
- break;
- case MHD_HTTP_NOT_FOUND:
- lr.hr.ec = TALER_JSON_get_error_code (j);
- lr.hr.hint = TALER_JSON_get_error_hint (j);
- /* Nothing really to verify, exchange says this coin was not melted; we
- should pass the JSON reply to the application */
- break;
- case MHD_HTTP_INTERNAL_SERVER_ERROR:
- lr.hr.ec = TALER_JSON_get_error_code (j);
- lr.hr.hint = TALER_JSON_get_error_hint (j);
- /* Server had an internal issue; we should retry, but this API
- leaves this to the application */
- break;
- default:
- /* unexpected response code */
- GNUNET_break_op (0);
- lr.hr.ec = TALER_JSON_get_error_code (j);
- lr.hr.hint = TALER_JSON_get_error_hint (j);
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Unexpected response code %u/%d for lookup AML decisions\n",
- (unsigned int) response_code,
- (int) lr.hr.ec);
- break;
- }
- if (NULL != lh->decisions_cb)
- lh->decisions_cb (lh->decisions_cb_cls,
- &lr);
- TALER_EXCHANGE_lookup_aml_decisions_cancel (lh);
-}
-
-
-struct TALER_EXCHANGE_LookupAmlDecisions *
-TALER_EXCHANGE_lookup_aml_decisions (
- struct GNUNET_CURL_Context *ctx,
- const char *exchange_url,
- uint64_t start,
- int delta,
- enum TALER_AmlDecisionState state,
- const struct TALER_AmlOfficerPrivateKeyP *officer_priv,
- TALER_EXCHANGE_LookupAmlDecisionsCallback cb,
- void *cb_cls)
-{
- struct TALER_EXCHANGE_LookupAmlDecisions *lh;
- CURL *eh;
- struct TALER_AmlOfficerPublicKeyP officer_pub;
- struct TALER_AmlOfficerSignatureP officer_sig;
- char arg_str[sizeof (struct TALER_AmlOfficerPublicKeyP) * 2 + 32];
- const char *state_str = NULL;
-
- switch (state)
- {
- case TALER_AML_NORMAL:
- state_str = "normal";
- break;
- case TALER_AML_PENDING:
- state_str = "pending";
- break;
- case TALER_AML_FROZEN:
- state_str = "frozen";
- break;
- }
- GNUNET_assert (NULL != state_str);
- GNUNET_CRYPTO_eddsa_key_get_public (&officer_priv->eddsa_priv,
- &officer_pub.eddsa_pub);
- TALER_officer_aml_query_sign (officer_priv,
- &officer_sig);
- {
- char pub_str[sizeof (officer_pub) * 2];
- char *end;
-
- end = GNUNET_STRINGS_data_to_string (
- &officer_pub,
- sizeof (officer_pub),
- pub_str,
- sizeof (pub_str));
- *end = '\0';
- GNUNET_snprintf (arg_str,
- sizeof (arg_str),
- "aml/%s/decisions/%s",
- pub_str,
- state_str);
- }
- lh = GNUNET_new (struct TALER_EXCHANGE_LookupAmlDecisions);
- lh->decisions_cb = cb;
- lh->decisions_cb_cls = cb_cls;
- {
- char delta_s[24];
- char start_s[24];
-
- GNUNET_snprintf (delta_s,
- sizeof (delta_s),
- "%d",
- delta);
- GNUNET_snprintf (start_s,
- sizeof (start_s),
- "%llu",
- (unsigned long long) start);
- lh->url = TALER_url_join (exchange_url,
- arg_str,
- "delta",
- delta_s,
- "start",
- start_s,
- NULL);
- }
- if (NULL == lh->url)
- {
- GNUNET_free (lh);
- return NULL;
- }
- eh = TALER_EXCHANGE_curl_easy_get_ (lh->url);
- if (NULL == eh)
- {
- GNUNET_break (0);
- GNUNET_free (lh->url);
- GNUNET_free (lh);
- return NULL;
- }
- {
- char *hdr;
- char sig_str[sizeof (officer_sig) * 2];
- char *end;
-
- end = GNUNET_STRINGS_data_to_string (
- &officer_sig,
- sizeof (officer_sig),
- sig_str,
- sizeof (sig_str));
- *end = '\0';
-
- GNUNET_asprintf (&hdr,
- "%s: %s",
- TALER_AML_OFFICER_SIGNATURE_HEADER,
- sig_str);
- lh->job_headers = curl_slist_append (NULL,
- hdr);
- GNUNET_free (hdr);
- lh->job_headers = curl_slist_append (lh->job_headers,
- "Content-type: application/json");
- lh->job = GNUNET_CURL_job_add2 (ctx,
- eh,
- lh->job_headers,
- &handle_lookup_finished,
- lh);
- }
- return lh;
-}
-
-
-void
-TALER_EXCHANGE_lookup_aml_decisions_cancel (
- struct TALER_EXCHANGE_LookupAmlDecisions *lh)
-{
- if (NULL != lh->job)
- {
- GNUNET_CURL_job_cancel (lh->job);
- lh->job = NULL;
- }
- curl_slist_free_all (lh->job_headers);
- GNUNET_free (lh->url);
- GNUNET_free (lh);
-}
-
-
-/* end of exchange_api_lookup_aml_decisions.c */
diff --git a/src/lib/exchange_api_management_add_partner.c b/src/lib/exchange_api_management_add_partner.c
deleted file mode 100644
index fec66c567..000000000
--- a/src/lib/exchange_api_management_add_partner.c
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2023 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software
- Foundation; either version 3, or (at your option) any later version.
-
- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- TALER; see the file COPYING. If not, see
- <http://www.gnu.org/licenses/>
-*/
-/**
- * @file lib/exchange_api_management_add_partner.c
- * @brief functions to add an partner by an AML officer
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include "taler_json_lib.h"
-#include <gnunet/gnunet_curl_lib.h>
-#include "taler_exchange_service.h"
-#include "exchange_api_curl_defaults.h"
-#include "taler_signatures.h"
-#include "taler_curl_lib.h"
-#include "taler_json_lib.h"
-
-
-struct TALER_EXCHANGE_ManagementAddPartner
-{
-
- /**
- * The url for this request.
- */
- char *url;
-
- /**
- * Minor context that holds body and headers.
- */
- struct TALER_CURL_PostContext post_ctx;
-
- /**
- * Handle for the request.
- */
- struct GNUNET_CURL_Job *job;
-
- /**
- * Function to call with the result.
- */
- TALER_EXCHANGE_ManagementAddPartnerCallback cb;
-
- /**
- * Closure for @a cb.
- */
- void *cb_cls;
-
- /**
- * Reference to the execution context.
- */
- struct GNUNET_CURL_Context *ctx;
-};
-
-
-/**
- * Function called when we're done processing the
- * HTTP POST /management/partners request.
- *
- * @param cls the `struct TALER_EXCHANGE_ManagementAddPartner *`
- * @param response_code HTTP response code, 0 on error
- * @param response response body, NULL if not in JSON
- */
-static void
-handle_add_partner_finished (void *cls,
- long response_code,
- const void *response)
-{
- struct TALER_EXCHANGE_ManagementAddPartner *wh = cls;
- const json_t *json = response;
- struct TALER_EXCHANGE_ManagementAddPartnerResponse apr = {
- .hr.http_status = (unsigned int) response_code,
- .hr.reply = json
- };
-
- wh->job = NULL;
- switch (response_code)
- {
- case 0:
- /* no reply */
- apr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
- apr.hr.hint = "server offline?";
- break;
- case MHD_HTTP_NO_CONTENT:
- break;
- case MHD_HTTP_FORBIDDEN:
- apr.hr.ec = TALER_JSON_get_error_code (json);
- apr.hr.hint = TALER_JSON_get_error_hint (json);
- break;
- case MHD_HTTP_CONFLICT:
- apr.hr.ec = TALER_JSON_get_error_code (json);
- apr.hr.hint = TALER_JSON_get_error_hint (json);
- break;
- default:
- /* unexpected response code */
- GNUNET_break_op (0);
- apr.hr.ec = TALER_JSON_get_error_code (json);
- apr.hr.hint = TALER_JSON_get_error_hint (json);
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Unexpected response code %u/%d for adding exchange partner\n",
- (unsigned int) response_code,
- (int) apr.hr.ec);
- break;
- }
- if (NULL != wh->cb)
- {
- wh->cb (wh->cb_cls,
- &apr);
- wh->cb = NULL;
- }
- TALER_EXCHANGE_management_add_partner_cancel (wh);
-}
-
-
-struct TALER_EXCHANGE_ManagementAddPartner *
-TALER_EXCHANGE_management_add_partner (
- struct GNUNET_CURL_Context *ctx,
- const char *url,
- const struct TALER_MasterPublicKeyP *partner_pub,
- struct GNUNET_TIME_Timestamp start_date,
- struct GNUNET_TIME_Timestamp end_date,
- struct GNUNET_TIME_Relative wad_frequency,
- const struct TALER_Amount *wad_fee,
- const char *partner_base_url,
- const struct TALER_MasterSignatureP *master_sig,
- TALER_EXCHANGE_ManagementAddPartnerCallback cb,
- void *cb_cls)
-{
- struct TALER_EXCHANGE_ManagementAddPartner *wh;
- CURL *eh;
- json_t *body;
-
- wh = GNUNET_new (struct TALER_EXCHANGE_ManagementAddPartner);
- wh->cb = cb;
- wh->cb_cls = cb_cls;
- wh->ctx = ctx;
- wh->url = TALER_url_join (url,
- "management/partners",
- NULL);
- if (NULL == wh->url)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Could not construct request URL.\n");
- GNUNET_free (wh);
- return NULL;
- }
- body = GNUNET_JSON_PACK (
- GNUNET_JSON_pack_string ("partner_base_url",
- partner_base_url),
- GNUNET_JSON_pack_timestamp ("start_date",
- start_date),
- GNUNET_JSON_pack_timestamp ("end_date",
- end_date),
- GNUNET_JSON_pack_time_rel ("wad_frequency",
- wad_frequency),
- GNUNET_JSON_pack_data_auto ("partner_pub",
- &partner_pub),
- GNUNET_JSON_pack_data_auto ("master_sig",
- &master_sig),
- TALER_JSON_pack_amount ("wad_fee",
- wad_fee)
- );
- eh = TALER_EXCHANGE_curl_easy_get_ (wh->url);
- if ( (NULL == eh) ||
- (GNUNET_OK !=
- TALER_curl_easy_post (&wh->post_ctx,
- eh,
- body)) )
- {
- GNUNET_break (0);
- if (NULL != eh)
- curl_easy_cleanup (eh);
- json_decref (body);
- GNUNET_free (wh->url);
- return NULL;
- }
- json_decref (body);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Requesting URL '%s'\n",
- wh->url);
- wh->job = GNUNET_CURL_job_add2 (ctx,
- eh,
- wh->post_ctx.headers,
- &handle_add_partner_finished,
- wh);
- if (NULL == wh->job)
- {
- TALER_EXCHANGE_management_add_partner_cancel (wh);
- return NULL;
- }
- return wh;
-}
-
-
-void
-TALER_EXCHANGE_management_add_partner_cancel (
- struct TALER_EXCHANGE_ManagementAddPartner *wh)
-{
- if (NULL != wh->job)
- {
- GNUNET_CURL_job_cancel (wh->job);
- wh->job = NULL;
- }
- TALER_curl_easy_post_finished (&wh->post_ctx);
- GNUNET_free (wh->url);
- GNUNET_free (wh);
-}
diff --git a/src/lib/exchange_api_management_auditor_disable.c b/src/lib/exchange_api_management_auditor_disable.c
deleted file mode 100644
index 8bce7f74f..000000000
--- a/src/lib/exchange_api_management_auditor_disable.c
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2015-2021 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software
- Foundation; either version 3, or (at your option) any later version.
-
- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- TALER; see the file COPYING. If not, see
- <http://www.gnu.org/licenses/>
-*/
-/**
- * @file lib/exchange_api_management_auditor_disable.c
- * @brief functions to disable an auditor
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include "taler_json_lib.h"
-#include <gnunet/gnunet_curl_lib.h>
-#include "taler_exchange_service.h"
-#include "exchange_api_curl_defaults.h"
-#include "taler_signatures.h"
-#include "taler_curl_lib.h"
-#include "taler_json_lib.h"
-
-/**
- * @brief Handle for a POST /management/auditors/$AUDITOR_PUB/disable request.
- */
-struct TALER_EXCHANGE_ManagementAuditorDisableHandle
-{
-
- /**
- * The url for this request.
- */
- char *url;
-
- /**
- * Minor context that holds body and headers.
- */
- struct TALER_CURL_PostContext post_ctx;
-
- /**
- * Handle for the request.
- */
- struct GNUNET_CURL_Job *job;
-
- /**
- * Function to call with the result.
- */
- TALER_EXCHANGE_ManagementAuditorDisableCallback cb;
-
- /**
- * Closure for @a cb.
- */
- void *cb_cls;
-
- /**
- * Reference to the execution context.
- */
- struct GNUNET_CURL_Context *ctx;
-};
-
-
-/**
- * Function called when we're done processing the
- * HTTP /management/auditors/%s/disable request.
- *
- * @param cls the `struct TALER_EXCHANGE_ManagementAuditorDisableHandle *`
- * @param response_code HTTP response code, 0 on error
- * @param response response body, NULL if not in JSON
- */
-static void
-handle_auditor_disable_finished (void *cls,
- long response_code,
- const void *response)
-{
- struct TALER_EXCHANGE_ManagementAuditorDisableHandle *ah = cls;
- const json_t *json = response;
- struct TALER_EXCHANGE_ManagementAuditorDisableResponse adr = {
- .hr.http_status = (unsigned int) response_code,
- .hr.reply = json
- };
-
- ah->job = NULL;
- switch (response_code)
- {
- case MHD_HTTP_NO_CONTENT:
- break;
- case MHD_HTTP_FORBIDDEN:
- adr.hr.ec = TALER_JSON_get_error_code (json);
- adr.hr.hint = TALER_JSON_get_error_hint (json);
- break;
- case MHD_HTTP_NOT_FOUND:
- adr.hr.ec = TALER_JSON_get_error_code (json);
- adr.hr.hint = TALER_JSON_get_error_hint (json);
- break;
- case MHD_HTTP_CONFLICT:
- adr.hr.ec = TALER_JSON_get_error_code (json);
- adr.hr.hint = TALER_JSON_get_error_hint (json);
- break;
- default:
- /* unexpected response code */
- GNUNET_break_op (0);
- adr.hr.ec = TALER_JSON_get_error_code (json);
- adr.hr.hint = TALER_JSON_get_error_hint (json);
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Unexpected response code %u/%d for exchange management auditor disable\n",
- (unsigned int) response_code,
- (int) adr.hr.ec);
- break;
- }
- if (NULL != ah->cb)
- {
- ah->cb (ah->cb_cls,
- &adr);
- ah->cb = NULL;
- }
- TALER_EXCHANGE_management_disable_auditor_cancel (ah);
-}
-
-
-struct TALER_EXCHANGE_ManagementAuditorDisableHandle *
-TALER_EXCHANGE_management_disable_auditor (
- struct GNUNET_CURL_Context *ctx,
- const char *url,
- const struct TALER_AuditorPublicKeyP *auditor_pub,
- struct GNUNET_TIME_Timestamp validity_end,
- const struct TALER_MasterSignatureP *master_sig,
- TALER_EXCHANGE_ManagementAuditorDisableCallback cb,
- void *cb_cls)
-{
- struct TALER_EXCHANGE_ManagementAuditorDisableHandle *ah;
- CURL *eh;
- json_t *body;
-
- ah = GNUNET_new (struct TALER_EXCHANGE_ManagementAuditorDisableHandle);
- ah->cb = cb;
- ah->cb_cls = cb_cls;
- ah->ctx = ctx;
- {
- char epub_str[sizeof (*auditor_pub) * 2];
- char arg_str[sizeof (epub_str) + 64];
- char *end;
-
- end = GNUNET_STRINGS_data_to_string (auditor_pub,
- sizeof (*auditor_pub),
- epub_str,
- sizeof (epub_str));
- *end = '\0';
- GNUNET_snprintf (arg_str,
- sizeof (arg_str),
- "management/auditors/%s/disable",
- epub_str);
- ah->url = TALER_url_join (url,
- arg_str,
- NULL);
- }
- if (NULL == ah->url)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Could not construct request URL.\n");
- GNUNET_free (ah);
- return NULL;
- }
- body = GNUNET_JSON_PACK (
- GNUNET_JSON_pack_data_auto ("master_sig",
- master_sig),
- GNUNET_JSON_pack_timestamp ("validity_end",
- validity_end));
- eh = TALER_EXCHANGE_curl_easy_get_ (ah->url);
- if ( (NULL == eh) ||
- (GNUNET_OK !=
- TALER_curl_easy_post (&ah->post_ctx,
- eh,
- body)))
- {
- GNUNET_break (0);
- if (NULL != eh)
- curl_easy_cleanup (eh);
- json_decref (body);
- GNUNET_free (ah->url);
- return NULL;
- }
- json_decref (body);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Requesting URL '%s'\n",
- ah->url);
- ah->job = GNUNET_CURL_job_add2 (ctx,
- eh,
- ah->post_ctx.headers,
- &handle_auditor_disable_finished,
- ah);
- if (NULL == ah->job)
- {
- TALER_EXCHANGE_management_disable_auditor_cancel (ah);
- return NULL;
- }
- return ah;
-}
-
-
-void
-TALER_EXCHANGE_management_disable_auditor_cancel (
- struct TALER_EXCHANGE_ManagementAuditorDisableHandle *ah)
-{
- if (NULL != ah->job)
- {
- GNUNET_CURL_job_cancel (ah->job);
- ah->job = NULL;
- }
- TALER_curl_easy_post_finished (&ah->post_ctx);
- GNUNET_free (ah->url);
- GNUNET_free (ah);
-}
diff --git a/src/lib/exchange_api_management_auditor_enable.c b/src/lib/exchange_api_management_auditor_enable.c
deleted file mode 100644
index 41c5049c2..000000000
--- a/src/lib/exchange_api_management_auditor_enable.c
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2015-2021 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software
- Foundation; either version 3, or (at your option) any later version.
-
- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- TALER; see the file COPYING. If not, see
- <http://www.gnu.org/licenses/>
-*/
-/**
- * @file lib/exchange_api_management_auditor_enable.c
- * @brief functions to enable an auditor
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include "taler_json_lib.h"
-#include <gnunet/gnunet_curl_lib.h>
-#include "taler_exchange_service.h"
-#include "exchange_api_curl_defaults.h"
-#include "taler_signatures.h"
-#include "taler_curl_lib.h"
-#include "taler_json_lib.h"
-
-
-/**
- * @brief Handle for a POST /management/auditors request.
- */
-struct TALER_EXCHANGE_ManagementAuditorEnableHandle
-{
-
- /**
- * The url for this request.
- */
- char *url;
-
- /**
- * Minor context that holds body and headers.
- */
- struct TALER_CURL_PostContext post_ctx;
-
- /**
- * Handle for the request.
- */
- struct GNUNET_CURL_Job *job;
-
- /**
- * Function to call with the result.
- */
- TALER_EXCHANGE_ManagementAuditorEnableCallback cb;
-
- /**
- * Closure for @a cb.
- */
- void *cb_cls;
-
- /**
- * Reference to the execution context.
- */
- struct GNUNET_CURL_Context *ctx;
-};
-
-
-/**
- * Function called when we're done processing the
- * HTTP POST /management/auditors request.
- *
- * @param cls the `struct TALER_EXCHANGE_ManagementAuditorEnableHandle *`
- * @param response_code HTTP response code, 0 on error
- * @param response response body, NULL if not in JSON
- */
-static void
-handle_auditor_enable_finished (void *cls,
- long response_code,
- const void *response)
-{
- struct TALER_EXCHANGE_ManagementAuditorEnableHandle *ah = cls;
- const json_t *json = response;
- struct TALER_EXCHANGE_ManagementAuditorEnableResponse aer = {
- .hr.http_status = (unsigned int) response_code,
- .hr.reply = json
- };
-
- ah->job = NULL;
- switch (response_code)
- {
- case MHD_HTTP_NO_CONTENT:
- break;
- case MHD_HTTP_FORBIDDEN:
- aer.hr.ec = TALER_JSON_get_error_code (json);
- aer.hr.hint = TALER_JSON_get_error_hint (json);
- break;
- case MHD_HTTP_NOT_FOUND:
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Server did not find handler at `%s'. Did you configure the correct exchange base URL?\n",
- ah->url);
- if (NULL != json)
- {
- aer.hr.ec = TALER_JSON_get_error_code (json);
- aer.hr.hint = TALER_JSON_get_error_hint (json);
- }
- else
- {
- aer.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
- aer.hr.hint = TALER_ErrorCode_get_hint (aer.hr.ec);
- }
- break;
- case MHD_HTTP_CONFLICT:
- aer.hr.ec = TALER_JSON_get_error_code (json);
- aer.hr.hint = TALER_JSON_get_error_hint (json);
- break;
- default:
- /* unexpected response code */
- GNUNET_break_op (0);
- aer.hr.ec = TALER_JSON_get_error_code (json);
- aer.hr.hint = TALER_JSON_get_error_hint (json);
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Unexpected response code %u/%d for exchange management auditor enable\n",
- (unsigned int) response_code,
- (int) aer.hr.ec);
- break;
- }
- if (NULL != ah->cb)
- {
- ah->cb (ah->cb_cls,
- &aer);
- ah->cb = NULL;
- }
- TALER_EXCHANGE_management_enable_auditor_cancel (ah);
-}
-
-
-struct TALER_EXCHANGE_ManagementAuditorEnableHandle *
-TALER_EXCHANGE_management_enable_auditor (
- struct GNUNET_CURL_Context *ctx,
- const char *url,
- const struct TALER_AuditorPublicKeyP *auditor_pub,
- const char *auditor_url,
- const char *auditor_name,
- struct GNUNET_TIME_Timestamp validity_start,
- const struct TALER_MasterSignatureP *master_sig,
- TALER_EXCHANGE_ManagementAuditorEnableCallback cb,
- void *cb_cls)
-{
- struct TALER_EXCHANGE_ManagementAuditorEnableHandle *ah;
- CURL *eh;
- json_t *body;
-
- ah = GNUNET_new (struct TALER_EXCHANGE_ManagementAuditorEnableHandle);
- ah->cb = cb;
- ah->cb_cls = cb_cls;
- ah->ctx = ctx;
- ah->url = TALER_url_join (url,
- "management/auditors",
- NULL);
- if (NULL == ah->url)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Could not construct request URL.\n");
- GNUNET_free (ah);
- return NULL;
- }
- body = GNUNET_JSON_PACK (
- GNUNET_JSON_pack_string ("auditor_url",
- auditor_url),
- GNUNET_JSON_pack_string ("auditor_name",
- auditor_name),
- GNUNET_JSON_pack_data_auto ("auditor_pub",
- auditor_pub),
- GNUNET_JSON_pack_data_auto ("master_sig",
- master_sig),
- GNUNET_JSON_pack_timestamp ("validity_start",
- validity_start));
- eh = TALER_EXCHANGE_curl_easy_get_ (ah->url);
- if ( (NULL == eh) ||
- (GNUNET_OK !=
- TALER_curl_easy_post (&ah->post_ctx,
- eh,
- body)) )
- {
- GNUNET_break (0);
- json_decref (body);
- if (NULL != eh)
- curl_easy_cleanup (eh);
- GNUNET_free (ah->url);
- return NULL;
- }
- json_decref (body);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Requesting URL '%s'\n",
- ah->url);
- ah->job = GNUNET_CURL_job_add2 (ctx,
- eh,
- ah->post_ctx.headers,
- &handle_auditor_enable_finished,
- ah);
- if (NULL == ah->job)
- {
- TALER_EXCHANGE_management_enable_auditor_cancel (ah);
- return NULL;
- }
- return ah;
-}
-
-
-void
-TALER_EXCHANGE_management_enable_auditor_cancel (
- struct TALER_EXCHANGE_ManagementAuditorEnableHandle *ah)
-{
- if (NULL != ah->job)
- {
- GNUNET_CURL_job_cancel (ah->job);
- ah->job = NULL;
- }
- TALER_curl_easy_post_finished (&ah->post_ctx);
- GNUNET_free (ah->url);
- GNUNET_free (ah);
-}
diff --git a/src/lib/exchange_api_management_drain_profits.c b/src/lib/exchange_api_management_drain_profits.c
deleted file mode 100644
index bc7232b87..000000000
--- a/src/lib/exchange_api_management_drain_profits.c
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2020-2023 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software
- Foundation; either version 3, or (at your option) any later version.
-
- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- TALER; see the file COPYING. If not, see
- <http://www.gnu.org/licenses/>
-*/
-/**
- * @file lib/exchange_api_management_drain_profits.c
- * @brief functions to set wire fees at an exchange
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include "taler_json_lib.h"
-#include <gnunet/gnunet_curl_lib.h>
-#include "exchange_api_curl_defaults.h"
-#include "taler_exchange_service.h"
-#include "taler_signatures.h"
-#include "taler_curl_lib.h"
-#include "taler_json_lib.h"
-
-
-struct TALER_EXCHANGE_ManagementDrainProfitsHandle
-{
-
- /**
- * The url for this request.
- */
- char *url;
-
- /**
- * Minor context that holds body and headers.
- */
- struct TALER_CURL_PostContext post_ctx;
-
- /**
- * Handle for the request.
- */
- struct GNUNET_CURL_Job *job;
-
- /**
- * Function to call with the result.
- */
- TALER_EXCHANGE_ManagementDrainProfitsCallback cb;
-
- /**
- * Closure for @a cb.
- */
- void *cb_cls;
-
- /**
- * Reference to the execution context.
- */
- struct GNUNET_CURL_Context *ctx;
-};
-
-
-/**
- * Function called when we're done processing the
- * HTTP /management/drain request.
- *
- * @param cls the `struct TALER_EXCHANGE_ManagementDrainProfitsHandle *`
- * @param response_code HTTP response code, 0 on error
- * @param response response body, NULL if not in JSON
- */
-static void
-handle_drain_profits_finished (void *cls,
- long response_code,
- const void *response)
-{
- struct TALER_EXCHANGE_ManagementDrainProfitsHandle *dp = cls;
- const json_t *json = response;
- struct TALER_EXCHANGE_ManagementDrainResponse dr = {
- .hr.http_status = (unsigned int) response_code,
- .hr.reply = json
- };
-
- dp->job = NULL;
- switch (response_code)
- {
- case MHD_HTTP_NO_CONTENT:
- break;
- case MHD_HTTP_FORBIDDEN:
- dr.hr.ec = TALER_JSON_get_error_code (json);
- dr.hr.hint = TALER_JSON_get_error_hint (json);
- break;
- case MHD_HTTP_CONFLICT:
- dr.hr.ec = TALER_JSON_get_error_code (json);
- dr.hr.hint = TALER_JSON_get_error_hint (json);
- break;
- case MHD_HTTP_PRECONDITION_FAILED:
- dr.hr.ec = TALER_JSON_get_error_code (json);
- dr.hr.hint = TALER_JSON_get_error_hint (json);
- break;
- default:
- /* unexpected response code */
- GNUNET_break_op (0);
- dr.hr.ec = TALER_JSON_get_error_code (json);
- dr.hr.hint = TALER_JSON_get_error_hint (json);
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Unexpected response code %u/%d for exchange management drain profits\n",
- (unsigned int) response_code,
- (int) dr.hr.ec);
- break;
- }
- if (NULL != dp->cb)
- {
- dp->cb (dp->cb_cls,
- &dr);
- dp->cb = NULL;
- }
- TALER_EXCHANGE_management_drain_profits_cancel (dp);
-}
-
-
-struct TALER_EXCHANGE_ManagementDrainProfitsHandle *
-TALER_EXCHANGE_management_drain_profits (
- struct GNUNET_CURL_Context *ctx,
- const char *url,
- const struct TALER_WireTransferIdentifierRawP *wtid,
- const struct TALER_Amount *amount,
- struct GNUNET_TIME_Timestamp date,
- const char *account_section,
- const char *payto_uri,
- const struct TALER_MasterSignatureP *master_sig,
- TALER_EXCHANGE_ManagementDrainProfitsCallback cb,
- void *cb_cls)
-{
- struct TALER_EXCHANGE_ManagementDrainProfitsHandle *dp;
- CURL *eh;
- json_t *body;
-
- dp = GNUNET_new (struct TALER_EXCHANGE_ManagementDrainProfitsHandle);
- dp->cb = cb;
- dp->cb_cls = cb_cls;
- dp->ctx = ctx;
- dp->url = TALER_url_join (url,
- "management/drain",
- NULL);
- if (NULL == dp->url)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Could not construct request URL.\n");
- GNUNET_free (dp);
- return NULL;
- }
- body = GNUNET_JSON_PACK (
- GNUNET_JSON_pack_string ("debit_account_section",
- account_section),
- GNUNET_JSON_pack_string ("credit_payto_uri",
- payto_uri),
- GNUNET_JSON_pack_data_auto ("wtid",
- wtid),
- GNUNET_JSON_pack_data_auto ("master_sig",
- master_sig),
- GNUNET_JSON_pack_timestamp ("date",
- date),
- TALER_JSON_pack_amount ("amount",
- amount));
- eh = TALER_EXCHANGE_curl_easy_get_ (dp->url);
- if ( (NULL == eh) ||
- (GNUNET_OK !=
- TALER_curl_easy_post (&dp->post_ctx,
- eh,
- body)) )
- {
- GNUNET_break (0);
- if (NULL != eh)
- curl_easy_cleanup (eh);
- json_decref (body);
- GNUNET_free (dp->url);
- return NULL;
- }
- json_decref (body);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Requesting URL '%s'\n",
- dp->url);
- dp->job = GNUNET_CURL_job_add2 (ctx,
- eh,
- dp->post_ctx.headers,
- &handle_drain_profits_finished,
- dp);
- if (NULL == dp->job)
- {
- TALER_EXCHANGE_management_drain_profits_cancel (dp);
- return NULL;
- }
- return dp;
-}
-
-
-void
-TALER_EXCHANGE_management_drain_profits_cancel (
- struct TALER_EXCHANGE_ManagementDrainProfitsHandle *dp)
-{
- if (NULL != dp->job)
- {
- GNUNET_CURL_job_cancel (dp->job);
- dp->job = NULL;
- }
- TALER_curl_easy_post_finished (&dp->post_ctx);
- GNUNET_free (dp->url);
- GNUNET_free (dp);
-}
diff --git a/src/lib/exchange_api_management_post_extensions.c b/src/lib/exchange_api_management_post_extensions.c
deleted file mode 100644
index 00d1c5e3f..000000000
--- a/src/lib/exchange_api_management_post_extensions.c
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2015-2023 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software
- Foundation; either version 3, or (at your option) any later version.
-
- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- TALER; see the file COPYING. If not, see
- <http://www.gnu.org/licenses/>
- */
-/**
- * @file lib/exchange_api_management_post_extensions.c
- * @brief functions to handle the settings for extensions (p2p and age restriction)
- * @author Ă–zgĂĽr Kesim
- */
-#include "platform.h"
-#include "taler_json_lib.h"
-#include <gnunet/gnunet_curl_lib.h>
-#include "taler_extensions.h"
-#include "exchange_api_curl_defaults.h"
-#include "taler_exchange_service.h"
-#include "taler_signatures.h"
-#include "taler_curl_lib.h"
-#include "taler_json_lib.h"
-
-
-/**
- * @brief Handle for a POST /management/extensions request.
- */
-struct TALER_EXCHANGE_ManagementPostExtensionsHandle
-{
-
- /**
- * The url for this request.
- */
- char *url;
-
- /**
- * Minor context that holds body and headers.
- */
- struct TALER_CURL_PostContext post_ctx;
-
- /**
- * Handle for the request.
- */
- struct GNUNET_CURL_Job *job;
-
- /**
- * Function to call with the result.
- */
- TALER_EXCHANGE_ManagementPostExtensionsCallback cb;
-
- /**
- * Closure for @a cb.
- */
- void *cb_cls;
-
- /**
- * Reference to the execution context.
- */
- struct GNUNET_CURL_Context *ctx;
-};
-
-
-/**
- * Function called when we're done processing the
- * HTTP POST /management/extensions request.
- *
- * @param cls the `struct TALER_EXCHANGE_ManagementPostExtensionsHandle *`
- * @param response_code HTTP response code, 0 on error
- * @param response response body, NULL if not in JSON
- */
-static void
-handle_post_extensions_finished (void *cls,
- long response_code,
- const void *response)
-{
- struct TALER_EXCHANGE_ManagementPostExtensionsHandle *ph = cls;
- const json_t *json = response;
- struct TALER_EXCHANGE_ManagementPostExtensionsResponse per = {
- .hr.http_status = (unsigned int) response_code,
- .hr.reply = json
- };
-
- ph->job = NULL;
- switch (response_code)
- {
- case MHD_HTTP_NO_CONTENT:
- break;
- case MHD_HTTP_FORBIDDEN:
- per.hr.ec = TALER_JSON_get_error_code (json);
- per.hr.hint = TALER_JSON_get_error_hint (json);
- break;
- case MHD_HTTP_NOT_FOUND:
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Server did not find handler at `%s'. Did you configure the correct exchange base URL?\n",
- ph->url);
- if (NULL != json)
- {
- per.hr.ec = TALER_JSON_get_error_code (json);
- per.hr.hint = TALER_JSON_get_error_hint (json);
- }
- else
- {
- per.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
- per.hr.hint = TALER_ErrorCode_get_hint (per.hr.ec);
- }
- break;
- default:
- /* unexpected response code */
- GNUNET_break_op (0);
- per.hr.ec = TALER_JSON_get_error_code (json);
- per.hr.hint = TALER_JSON_get_error_hint (json);
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Unexpected response code %u/%d for exchange management post extensions\n",
- (unsigned int) response_code,
- (int) per.hr.ec);
- break;
- }
- if (NULL != ph->cb)
- {
- ph->cb (ph->cb_cls,
- &per);
- ph->cb = NULL;
- }
- TALER_EXCHANGE_management_post_extensions_cancel (ph);
-}
-
-
-struct TALER_EXCHANGE_ManagementPostExtensionsHandle *
-TALER_EXCHANGE_management_post_extensions (
- struct GNUNET_CURL_Context *ctx,
- const char *url,
- const struct TALER_EXCHANGE_ManagementPostExtensionsData *ped,
- TALER_EXCHANGE_ManagementPostExtensionsCallback cb,
- void *cb_cls)
-{
- struct TALER_EXCHANGE_ManagementPostExtensionsHandle *ph;
- CURL *eh = NULL;
- json_t *body = NULL;
-
- ph = GNUNET_new (struct TALER_EXCHANGE_ManagementPostExtensionsHandle);
- ph->cb = cb;
- ph->cb_cls = cb_cls;
- ph->ctx = ctx;
- ph->url = TALER_url_join (url,
- "management/extensions",
- NULL);
- if (NULL == ph->url)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Could not construct request URL.\n");
- GNUNET_free (ph);
- return NULL;
- }
-
- body = GNUNET_JSON_PACK (
- GNUNET_JSON_pack_object_steal ("extensions",
- (json_t *) ped->extensions),
- GNUNET_JSON_pack_data_auto ("extensions_sig",
- &ped->extensions_sig));
-
- eh = TALER_EXCHANGE_curl_easy_get_ (ph->url);
- if ( (NULL == eh) ||
- (GNUNET_OK !=
- TALER_curl_easy_post (&ph->post_ctx,
- eh,
- body)) )
- {
- GNUNET_break (0);
- if (NULL != eh)
- curl_easy_cleanup (eh);
- json_decref (body);
- GNUNET_free (ph->url);
- return NULL;
- }
- json_decref (body);
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Requesting URL '%s'\n",
- ph->url);
- ph->job = GNUNET_CURL_job_add2 (ctx,
- eh,
- ph->post_ctx.headers,
- &handle_post_extensions_finished,
- ph);
- if (NULL == ph->job)
- {
- TALER_EXCHANGE_management_post_extensions_cancel (ph);
- return NULL;
- }
- return ph;
-}
-
-
-void
-TALER_EXCHANGE_management_post_extensions_cancel (
- struct TALER_EXCHANGE_ManagementPostExtensionsHandle *ph)
-{
- if (NULL != ph->job)
- {
- GNUNET_CURL_job_cancel (ph->job);
- ph->job = NULL;
- }
- TALER_curl_easy_post_finished (&ph->post_ctx);
- GNUNET_free (ph->url);
- GNUNET_free (ph);
-}
diff --git a/src/lib/exchange_api_management_post_keys.c b/src/lib/exchange_api_management_post_keys.c
deleted file mode 100644
index a46124d90..000000000
--- a/src/lib/exchange_api_management_post_keys.c
+++ /dev/null
@@ -1,237 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2015-2021 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software
- Foundation; either version 3, or (at your option) any later version.
-
- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- TALER; see the file COPYING. If not, see
- <http://www.gnu.org/licenses/>
-*/
-/**
- * @file lib/exchange_api_management_post_keys.c
- * @brief functions to affirm the validity of exchange keys using the master private key
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include "taler_json_lib.h"
-#include <gnunet/gnunet_curl_lib.h>
-#include "taler_exchange_service.h"
-#include "exchange_api_curl_defaults.h"
-#include "taler_signatures.h"
-#include "taler_curl_lib.h"
-#include "taler_json_lib.h"
-
-
-/**
- * @brief Handle for a POST /management/keys request.
- */
-struct TALER_EXCHANGE_ManagementPostKeysHandle
-{
-
- /**
- * The url for this request.
- */
- char *url;
-
- /**
- * Minor context that holds body and headers.
- */
- struct TALER_CURL_PostContext post_ctx;
-
- /**
- * Handle for the request.
- */
- struct GNUNET_CURL_Job *job;
-
- /**
- * Function to call with the result.
- */
- TALER_EXCHANGE_ManagementPostKeysCallback cb;
-
- /**
- * Closure for @a cb.
- */
- void *cb_cls;
-
- /**
- * Reference to the execution context.
- */
- struct GNUNET_CURL_Context *ctx;
-};
-
-
-/**
- * Function called when we're done processing the
- * HTTP POST /management/keys request.
- *
- * @param cls the `struct TALER_EXCHANGE_ManagementPostKeysHandle *`
- * @param response_code HTTP response code, 0 on error
- * @param response response body, NULL if not in JSON
- */
-static void
-handle_post_keys_finished (void *cls,
- long response_code,
- const void *response)
-{
- struct TALER_EXCHANGE_ManagementPostKeysHandle *ph = cls;
- const json_t *json = response;
- struct TALER_EXCHANGE_ManagementPostKeysResponse pkr = {
- .hr.http_status = (unsigned int) response_code,
- .hr.reply = json
- };
-
- ph->job = NULL;
- switch (response_code)
- {
- case MHD_HTTP_NO_CONTENT:
- break;
- case MHD_HTTP_FORBIDDEN:
- pkr.hr.ec = TALER_JSON_get_error_code (json);
- pkr.hr.hint = TALER_JSON_get_error_hint (json);
- break;
- case MHD_HTTP_NOT_FOUND:
- pkr.hr.ec = TALER_JSON_get_error_code (json);
- pkr.hr.hint = TALER_JSON_get_error_hint (json);
- break;
- case MHD_HTTP_REQUEST_ENTITY_TOO_LARGE:
- pkr.hr.ec = TALER_JSON_get_error_code (json);
- pkr.hr.hint = TALER_JSON_get_error_hint (json);
- break;
- default:
- /* unexpected response code */
- GNUNET_break_op (0);
- pkr.hr.ec = TALER_JSON_get_error_code (json);
- pkr.hr.hint = TALER_JSON_get_error_hint (json);
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Unexpected response code %u/%d for exchange management post keys\n",
- (unsigned int) response_code,
- (int) pkr.hr.ec);
- break;
- }
- if (NULL != ph->cb)
- {
- ph->cb (ph->cb_cls,
- &pkr);
- ph->cb = NULL;
- }
- TALER_EXCHANGE_post_management_keys_cancel (ph);
-}
-
-
-struct TALER_EXCHANGE_ManagementPostKeysHandle *
-TALER_EXCHANGE_post_management_keys (
- struct GNUNET_CURL_Context *ctx,
- const char *url,
- const struct TALER_EXCHANGE_ManagementPostKeysData *pkd,
- TALER_EXCHANGE_ManagementPostKeysCallback cb,
- void *cb_cls)
-{
- struct TALER_EXCHANGE_ManagementPostKeysHandle *ph;
- CURL *eh;
- json_t *body;
- json_t *denom_sigs;
- json_t *signkey_sigs;
-
- ph = GNUNET_new (struct TALER_EXCHANGE_ManagementPostKeysHandle);
- ph->cb = cb;
- ph->cb_cls = cb_cls;
- ph->ctx = ctx;
- ph->url = TALER_url_join (url,
- "management/keys",
- NULL);
- if (NULL == ph->url)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Could not construct request URL.\n");
- GNUNET_free (ph);
- return NULL;
- }
- denom_sigs = json_array ();
- GNUNET_assert (NULL != denom_sigs);
- for (unsigned int i = 0; i<pkd->num_denom_sigs; i++)
- {
- const struct TALER_EXCHANGE_DenominationKeySignature *dks
- = &pkd->denom_sigs[i];
-
- GNUNET_assert (0 ==
- json_array_append_new (
- denom_sigs,
- GNUNET_JSON_PACK (
- GNUNET_JSON_pack_data_auto ("h_denom_pub",
- &dks->h_denom_pub),
- GNUNET_JSON_pack_data_auto ("master_sig",
- &dks->master_sig))));
- }
- signkey_sigs = json_array ();
- GNUNET_assert (NULL != signkey_sigs);
- for (unsigned int i = 0; i<pkd->num_sign_sigs; i++)
- {
- const struct TALER_EXCHANGE_SigningKeySignature *sks
- = &pkd->sign_sigs[i];
-
- GNUNET_assert (0 ==
- json_array_append_new (
- signkey_sigs,
- GNUNET_JSON_PACK (
- GNUNET_JSON_pack_data_auto ("exchange_pub",
- &sks->exchange_pub),
- GNUNET_JSON_pack_data_auto ("master_sig",
- &sks->master_sig))));
- }
- body = GNUNET_JSON_PACK (
- GNUNET_JSON_pack_array_steal ("denom_sigs",
- denom_sigs),
- GNUNET_JSON_pack_array_steal ("signkey_sigs",
- signkey_sigs));
- eh = TALER_EXCHANGE_curl_easy_get_ (ph->url);
- if ( (NULL == eh) ||
- (GNUNET_OK !=
- TALER_curl_easy_post (&ph->post_ctx,
- eh,
- body)) )
- {
- GNUNET_break (0);
- if (NULL != eh)
- curl_easy_cleanup (eh);
- json_decref (body);
- GNUNET_free (ph->url);
- return NULL;
- }
- json_decref (body);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Requesting URL '%s'\n",
- ph->url);
- ph->job = GNUNET_CURL_job_add2 (ctx,
- eh,
- ph->post_ctx.headers,
- &handle_post_keys_finished,
- ph);
- if (NULL == ph->job)
- {
- TALER_EXCHANGE_post_management_keys_cancel (ph);
- return NULL;
- }
- return ph;
-}
-
-
-void
-TALER_EXCHANGE_post_management_keys_cancel (
- struct TALER_EXCHANGE_ManagementPostKeysHandle *ph)
-{
- if (NULL != ph->job)
- {
- GNUNET_CURL_job_cancel (ph->job);
- ph->job = NULL;
- }
- TALER_curl_easy_post_finished (&ph->post_ctx);
- GNUNET_free (ph->url);
- GNUNET_free (ph);
-}
diff --git a/src/lib/exchange_api_management_revoke_denomination_key.c b/src/lib/exchange_api_management_revoke_denomination_key.c
deleted file mode 100644
index aa4d527a7..000000000
--- a/src/lib/exchange_api_management_revoke_denomination_key.c
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2015-2020 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software
- Foundation; either version 3, or (at your option) any later version.
-
- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- TALER; see the file COPYING. If not, see
- <http://www.gnu.org/licenses/>
-*/
-/**
- * @file lib/exchange_api_management_revoke_denomination_key.c
- * @brief functions to revoke an exchange denomination key
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include "taler_json_lib.h"
-#include <gnunet/gnunet_curl_lib.h>
-#include "taler_exchange_service.h"
-#include "exchange_api_curl_defaults.h"
-#include "taler_signatures.h"
-#include "taler_curl_lib.h"
-#include "taler_json_lib.h"
-
-
-/**
- * @brief Handle for a POST /management/denominations/$H_DENOM_PUB/revoke request.
- */
-struct TALER_EXCHANGE_ManagementRevokeDenominationKeyHandle
-{
-
- /**
- * The url for this request.
- */
- char *url;
-
- /**
- * Minor context that holds body and headers.
- */
- struct TALER_CURL_PostContext post_ctx;
-
- /**
- * Handle for the request.
- */
- struct GNUNET_CURL_Job *job;
-
- /**
- * Function to call with the result.
- */
- TALER_EXCHANGE_ManagementRevokeDenominationKeyCallback cb;
-
- /**
- * Closure for @a cb.
- */
- void *cb_cls;
-
- /**
- * Reference to the execution context.
- */
- struct GNUNET_CURL_Context *ctx;
-};
-
-
-/**
- * Function called when we're done processing the
- * HTTP /management/denominations/$H_DENOM_PUB/revoke request.
- *
- * @param cls the `struct TALER_EXCHANGE_ManagementRevokeDenominationKeyHandle *`
- * @param response_code HTTP response code, 0 on error
- * @param response response body, NULL if not in JSON
- */
-static void
-handle_revoke_denomination_finished (void *cls,
- long response_code,
- const void *response)
-{
- struct TALER_EXCHANGE_ManagementRevokeDenominationKeyHandle *rh = cls;
- const json_t *json = response;
- struct TALER_EXCHANGE_ManagementRevokeDenominationResponse rdr = {
- .hr.http_status = (unsigned int) response_code,
- .hr.reply = json
- };
-
- rh->job = NULL;
- switch (response_code)
- {
- case 0:
- /* no reply */
- rdr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
- rdr.hr.hint = "server offline?";
- break;
- case MHD_HTTP_NO_CONTENT:
- break;
- case MHD_HTTP_FORBIDDEN:
- rdr.hr.ec = TALER_JSON_get_error_code (json);
- rdr.hr.hint = TALER_JSON_get_error_hint (json);
- break;
- default:
- /* unexpected response code */
- GNUNET_break_op (0);
- rdr.hr.ec = TALER_JSON_get_error_code (json);
- rdr.hr.hint = TALER_JSON_get_error_hint (json);
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Unexpected response code %u/%d for exchange management revoke denomination\n",
- (unsigned int) response_code,
- (int) rdr.hr.ec);
- break;
- }
- if (NULL != rh->cb)
- {
- rh->cb (rh->cb_cls,
- &rdr);
- rh->cb = NULL;
- }
- TALER_EXCHANGE_management_revoke_denomination_key_cancel (rh);
-}
-
-
-struct TALER_EXCHANGE_ManagementRevokeDenominationKeyHandle *
-TALER_EXCHANGE_management_revoke_denomination_key (
- struct GNUNET_CURL_Context *ctx,
- const char *url,
- const struct TALER_DenominationHashP *h_denom_pub,
- const struct TALER_MasterSignatureP *master_sig,
- TALER_EXCHANGE_ManagementRevokeDenominationKeyCallback cb,
- void *cb_cls)
-{
- struct TALER_EXCHANGE_ManagementRevokeDenominationKeyHandle *rh;
- CURL *eh;
- json_t *body;
-
- rh = GNUNET_new (struct TALER_EXCHANGE_ManagementRevokeDenominationKeyHandle);
- rh->cb = cb;
- rh->cb_cls = cb_cls;
- rh->ctx = ctx;
- {
- char epub_str[sizeof (*h_denom_pub) * 2];
- char arg_str[sizeof (epub_str) + 64];
- char *end;
-
- end = GNUNET_STRINGS_data_to_string (h_denom_pub,
- sizeof (*h_denom_pub),
- epub_str,
- sizeof (epub_str));
- *end = '\0';
- GNUNET_snprintf (arg_str,
- sizeof (arg_str),
- "management/denominations/%s/revoke",
- epub_str);
- rh->url = TALER_url_join (url,
- arg_str,
- NULL);
- }
- if (NULL == rh->url)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Could not construct request URL.\n");
- GNUNET_free (rh);
- return NULL;
- }
- body = GNUNET_JSON_PACK (
- GNUNET_JSON_pack_data_auto ("master_sig",
- master_sig));
- if (NULL == body)
- {
- GNUNET_break (0);
- GNUNET_free (rh->url);
- GNUNET_free (rh);
- return NULL;
- }
- eh = TALER_EXCHANGE_curl_easy_get_ (rh->url);
- if ( (NULL == eh) ||
- (GNUNET_OK !=
- TALER_curl_easy_post (&rh->post_ctx,
- eh,
- body)) )
- {
- GNUNET_break (0);
- if (NULL != eh)
- curl_easy_cleanup (eh);
- json_decref (body);
- GNUNET_free (rh->url);
- return NULL;
- }
- json_decref (body);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Requesting URL '%s'\n",
- rh->url);
- rh->job = GNUNET_CURL_job_add2 (ctx,
- eh,
- rh->post_ctx.headers,
- &handle_revoke_denomination_finished,
- rh);
- if (NULL == rh->job)
- {
- TALER_EXCHANGE_management_revoke_denomination_key_cancel (rh);
- return NULL;
- }
- return rh;
-}
-
-
-void
-TALER_EXCHANGE_management_revoke_denomination_key_cancel (
- struct TALER_EXCHANGE_ManagementRevokeDenominationKeyHandle *rh)
-{
- if (NULL != rh->job)
- {
- GNUNET_CURL_job_cancel (rh->job);
- rh->job = NULL;
- }
- TALER_curl_easy_post_finished (&rh->post_ctx);
- GNUNET_free (rh->url);
- GNUNET_free (rh);
-}
diff --git a/src/lib/exchange_api_management_revoke_signing_key.c b/src/lib/exchange_api_management_revoke_signing_key.c
deleted file mode 100644
index c4d634248..000000000
--- a/src/lib/exchange_api_management_revoke_signing_key.c
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2015-2021 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software
- Foundation; either version 3, or (at your option) any later version.
-
- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- TALER; see the file COPYING. If not, see
- <http://www.gnu.org/licenses/>
-*/
-/**
- * @file lib/exchange_api_management_revoke_signing_key.c
- * @brief functions to revoke an exchange online signing key
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include "taler_json_lib.h"
-#include <gnunet/gnunet_curl_lib.h>
-#include "taler_exchange_service.h"
-#include "exchange_api_curl_defaults.h"
-#include "taler_signatures.h"
-#include "taler_curl_lib.h"
-#include "taler_json_lib.h"
-
-
-struct TALER_EXCHANGE_ManagementRevokeSigningKeyHandle
-{
-
- /**
- * The url for this request.
- */
- char *url;
-
- /**
- * Minor context that holds body and headers.
- */
- struct TALER_CURL_PostContext post_ctx;
-
- /**
- * Handle for the request.
- */
- struct GNUNET_CURL_Job *job;
-
- /**
- * Function to call with the result.
- */
- TALER_EXCHANGE_ManagementRevokeSigningKeyCallback cb;
-
- /**
- * Closure for @a cb.
- */
- void *cb_cls;
-
- /**
- * Reference to the execution context.
- */
- struct GNUNET_CURL_Context *ctx;
-};
-
-
-/**
- * Function called when we're done processing the
- * HTTP /management/signkeys/%s/revoke request.
- *
- * @param cls the `struct TALER_EXCHANGE_ManagementRevokeSigningKeyHandle *`
- * @param response_code HTTP response code, 0 on error
- * @param response response body, NULL if not in JSON
- */
-static void
-handle_revoke_signing_finished (void *cls,
- long response_code,
- const void *response)
-{
- struct TALER_EXCHANGE_ManagementRevokeSigningKeyHandle *rh = cls;
- const json_t *json = response;
- struct TALER_EXCHANGE_ManagementRevokeSigningKeyResponse rsr = {
- .hr.http_status = (unsigned int) response_code,
- .hr.reply = json
- };
-
- rh->job = NULL;
- switch (response_code)
- {
- case 0:
- /* no reply */
- rsr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
- rsr.hr.hint = "server offline?";
- break;
- case MHD_HTTP_NO_CONTENT:
- break;
- case MHD_HTTP_FORBIDDEN:
- rsr.hr.ec = TALER_JSON_get_error_code (json);
- rsr.hr.hint = TALER_JSON_get_error_hint (json);
- break;
- default:
- /* unexpected response code */
- GNUNET_break_op (0);
- rsr.hr.ec = TALER_JSON_get_error_code (json);
- rsr.hr.hint = TALER_JSON_get_error_hint (json);
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Unexpected response code %u/%d for exchange management revoke signkey\n",
- (unsigned int) response_code,
- (int) rsr.hr.ec);
- break;
- }
- if (NULL != rh->cb)
- {
- rh->cb (rh->cb_cls,
- &rsr);
- rh->cb = NULL;
- }
- TALER_EXCHANGE_management_revoke_signing_key_cancel (rh);
-}
-
-
-struct TALER_EXCHANGE_ManagementRevokeSigningKeyHandle *
-TALER_EXCHANGE_management_revoke_signing_key (
- struct GNUNET_CURL_Context *ctx,
- const char *url,
- const struct TALER_ExchangePublicKeyP *exchange_pub,
- const struct TALER_MasterSignatureP *master_sig,
- TALER_EXCHANGE_ManagementRevokeSigningKeyCallback cb,
- void *cb_cls)
-{
- struct TALER_EXCHANGE_ManagementRevokeSigningKeyHandle *rh;
- CURL *eh;
- json_t *body;
-
- rh = GNUNET_new (struct TALER_EXCHANGE_ManagementRevokeSigningKeyHandle);
- rh->cb = cb;
- rh->cb_cls = cb_cls;
- rh->ctx = ctx;
- {
- char epub_str[sizeof (*exchange_pub) * 2];
- char arg_str[sizeof (epub_str) + 64];
- char *end;
-
- end = GNUNET_STRINGS_data_to_string (exchange_pub,
- sizeof (*exchange_pub),
- epub_str,
- sizeof (epub_str));
- *end = '\0';
- GNUNET_snprintf (arg_str,
- sizeof (arg_str),
- "management/signkeys/%s/revoke",
- epub_str);
- rh->url = TALER_url_join (url,
- arg_str,
- NULL);
- }
- if (NULL == rh->url)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Could not construct request URL.\n");
- GNUNET_free (rh);
- return NULL;
- }
- body = GNUNET_JSON_PACK (
- GNUNET_JSON_pack_data_auto ("master_sig",
- master_sig));
- eh = TALER_EXCHANGE_curl_easy_get_ (rh->url);
- if ( (NULL == eh) ||
- (GNUNET_OK !=
- TALER_curl_easy_post (&rh->post_ctx,
- eh,
- body)) )
- {
- GNUNET_break (0);
- if (NULL != eh)
- curl_easy_cleanup (eh);
- json_decref (body);
- GNUNET_free (rh->url);
- return NULL;
- }
- json_decref (body);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Requesting URL '%s'\n",
- rh->url);
- rh->job = GNUNET_CURL_job_add2 (ctx,
- eh,
- rh->post_ctx.headers,
- &handle_revoke_signing_finished,
- rh);
- if (NULL == rh->job)
- {
- TALER_EXCHANGE_management_revoke_signing_key_cancel (rh);
- return NULL;
- }
- return rh;
-}
-
-
-void
-TALER_EXCHANGE_management_revoke_signing_key_cancel (
- struct TALER_EXCHANGE_ManagementRevokeSigningKeyHandle *rh)
-{
- if (NULL != rh->job)
- {
- GNUNET_CURL_job_cancel (rh->job);
- rh->job = NULL;
- }
- TALER_curl_easy_post_finished (&rh->post_ctx);
- GNUNET_free (rh->url);
- GNUNET_free (rh);
-}
diff --git a/src/lib/exchange_api_management_set_global_fee.c b/src/lib/exchange_api_management_set_global_fee.c
deleted file mode 100644
index 54c37fd64..000000000
--- a/src/lib/exchange_api_management_set_global_fee.c
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2020-2022 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software
- Foundation; either version 3, or (at your option) any later version.
-
- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- TALER; see the file COPYING. If not, see
- <http://www.gnu.org/licenses/>
-*/
-/**
- * @file lib/exchange_api_management_set_global_fee.c
- * @brief functions to set global fees at an exchange
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include "taler_json_lib.h"
-#include <gnunet/gnunet_curl_lib.h>
-#include "exchange_api_curl_defaults.h"
-#include "taler_exchange_service.h"
-#include "taler_signatures.h"
-#include "taler_curl_lib.h"
-#include "taler_json_lib.h"
-
-
-struct TALER_EXCHANGE_ManagementSetGlobalFeeHandle
-{
-
- /**
- * The url for this request.
- */
- char *url;
-
- /**
- * Minor context that holds body and headers.
- */
- struct TALER_CURL_PostContext post_ctx;
-
- /**
- * Handle for the request.
- */
- struct GNUNET_CURL_Job *job;
-
- /**
- * Function to call with the result.
- */
- TALER_EXCHANGE_ManagementSetGlobalFeeCallback cb;
-
- /**
- * Closure for @a cb.
- */
- void *cb_cls;
-
- /**
- * Reference to the execution context.
- */
- struct GNUNET_CURL_Context *ctx;
-};
-
-
-/**
- * Function called when we're done processing the
- * HTTP /management/global request.
- *
- * @param cls the `struct TALER_EXCHANGE_ManagementAuditorEnableHandle *`
- * @param response_code HTTP response code, 0 on error
- * @param response response body, NULL if not in JSON
- */
-static void
-handle_set_global_fee_finished (void *cls,
- long response_code,
- const void *response)
-{
- struct TALER_EXCHANGE_ManagementSetGlobalFeeHandle *sgfh = cls;
- const json_t *json = response;
- struct TALER_EXCHANGE_ManagementSetGlobalFeeResponse sfr = {
- .hr.http_status = (unsigned int) response_code,
- .hr.reply = json
- };
-
- sgfh->job = NULL;
- switch (response_code)
- {
- case MHD_HTTP_NO_CONTENT:
- break;
- case MHD_HTTP_FORBIDDEN:
- sfr.hr.ec = TALER_JSON_get_error_code (json);
- sfr.hr.hint = TALER_JSON_get_error_hint (json);
- break;
- case MHD_HTTP_NOT_FOUND:
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Server did not find handler at `%s'. Did you configure the correct exchange base URL?\n",
- sgfh->url);
- if (NULL != json)
- {
- sfr.hr.ec = TALER_JSON_get_error_code (json);
- sfr.hr.hint = TALER_JSON_get_error_hint (json);
- }
- else
- {
- sfr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
- sfr.hr.hint = TALER_ErrorCode_get_hint (sfr.hr.ec);
- }
- break;
- case MHD_HTTP_CONFLICT:
- sfr.hr.ec = TALER_JSON_get_error_code (json);
- sfr.hr.hint = TALER_JSON_get_error_hint (json);
- break;
- case MHD_HTTP_PRECONDITION_FAILED:
- sfr.hr.ec = TALER_JSON_get_error_code (json);
- sfr.hr.hint = TALER_JSON_get_error_hint (json);
- break;
- default:
- /* unexpected response code */
- GNUNET_break_op (0);
- sfr.hr.ec = TALER_JSON_get_error_code (json);
- sfr.hr.hint = TALER_JSON_get_error_hint (json);
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Unexpected response code %u/%d for exchange management set global fee\n",
- (unsigned int) response_code,
- (int) sfr.hr.ec);
- break;
- }
- if (NULL != sgfh->cb)
- {
- sgfh->cb (sgfh->cb_cls,
- &sfr);
- sgfh->cb = NULL;
- }
- TALER_EXCHANGE_management_set_global_fees_cancel (sgfh);
-}
-
-
-struct TALER_EXCHANGE_ManagementSetGlobalFeeHandle *
-TALER_EXCHANGE_management_set_global_fees (
- struct GNUNET_CURL_Context *ctx,
- const char *exchange_base_url,
- struct GNUNET_TIME_Timestamp validity_start,
- struct GNUNET_TIME_Timestamp validity_end,
- const struct TALER_GlobalFeeSet *fees,
- struct GNUNET_TIME_Relative purse_timeout,
- struct GNUNET_TIME_Relative history_expiration,
- uint32_t purse_account_limit,
- const struct TALER_MasterSignatureP *master_sig,
- TALER_EXCHANGE_ManagementSetGlobalFeeCallback cb,
- void *cb_cls)
-{
- struct TALER_EXCHANGE_ManagementSetGlobalFeeHandle *sgfh;
- CURL *eh;
- json_t *body;
-
- sgfh = GNUNET_new (struct TALER_EXCHANGE_ManagementSetGlobalFeeHandle);
- sgfh->cb = cb;
- sgfh->cb_cls = cb_cls;
- sgfh->ctx = ctx;
- sgfh->url = TALER_url_join (exchange_base_url,
- "management/global-fee",
- NULL);
- if (NULL == sgfh->url)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Could not construct request URL.\n");
- GNUNET_free (sgfh);
- return NULL;
- }
- body = GNUNET_JSON_PACK (
- GNUNET_JSON_pack_data_auto ("master_sig",
- master_sig),
- GNUNET_JSON_pack_timestamp ("fee_start",
- validity_start),
- GNUNET_JSON_pack_timestamp ("fee_end",
- validity_end),
- TALER_JSON_pack_amount ("history_fee",
- &fees->history),
- TALER_JSON_pack_amount ("account_fee",
- &fees->account),
- TALER_JSON_pack_amount ("purse_fee",
- &fees->purse),
- GNUNET_JSON_pack_time_rel ("purse_timeout",
- purse_timeout),
- GNUNET_JSON_pack_time_rel ("history_expiration",
- history_expiration),
- GNUNET_JSON_pack_uint64 ("purse_account_limit",
- purse_account_limit));
- eh = TALER_EXCHANGE_curl_easy_get_ (sgfh->url);
- if ( (NULL == eh) ||
- (GNUNET_OK !=
- TALER_curl_easy_post (&sgfh->post_ctx,
- eh,
- body)) )
- {
- GNUNET_break (0);
- if (NULL != eh)
- curl_easy_cleanup (eh);
- json_decref (body);
- GNUNET_free (sgfh->url);
- return NULL;
- }
- json_decref (body);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Requesting URL '%s'\n",
- sgfh->url);
- sgfh->job = GNUNET_CURL_job_add2 (ctx,
- eh,
- sgfh->post_ctx.headers,
- &handle_set_global_fee_finished,
- sgfh);
- if (NULL == sgfh->job)
- {
- TALER_EXCHANGE_management_set_global_fees_cancel (sgfh);
- return NULL;
- }
- return sgfh;
-}
-
-
-void
-TALER_EXCHANGE_management_set_global_fees_cancel (
- struct TALER_EXCHANGE_ManagementSetGlobalFeeHandle *sgfh)
-{
- if (NULL != sgfh->job)
- {
- GNUNET_CURL_job_cancel (sgfh->job);
- sgfh->job = NULL;
- }
- TALER_curl_easy_post_finished (&sgfh->post_ctx);
- GNUNET_free (sgfh->url);
- GNUNET_free (sgfh);
-}
diff --git a/src/lib/exchange_api_management_set_wire_fee.c b/src/lib/exchange_api_management_set_wire_fee.c
deleted file mode 100644
index 03cab8c99..000000000
--- a/src/lib/exchange_api_management_set_wire_fee.c
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2020-2022 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software
- Foundation; either version 3, or (at your option) any later version.
-
- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- TALER; see the file COPYING. If not, see
- <http://www.gnu.org/licenses/>
-*/
-/**
- * @file lib/exchange_api_management_set_wire_fee.c
- * @brief functions to set wire fees at an exchange
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include "taler_json_lib.h"
-#include <gnunet/gnunet_curl_lib.h>
-#include "exchange_api_curl_defaults.h"
-#include "taler_exchange_service.h"
-#include "taler_signatures.h"
-#include "taler_curl_lib.h"
-#include "taler_json_lib.h"
-
-
-struct TALER_EXCHANGE_ManagementSetWireFeeHandle
-{
-
- /**
- * The url for this request.
- */
- char *url;
-
- /**
- * Minor context that holds body and headers.
- */
- struct TALER_CURL_PostContext post_ctx;
-
- /**
- * Handle for the request.
- */
- struct GNUNET_CURL_Job *job;
-
- /**
- * Function to call with the result.
- */
- TALER_EXCHANGE_ManagementSetWireFeeCallback cb;
-
- /**
- * Closure for @a cb.
- */
- void *cb_cls;
-
- /**
- * Reference to the execution context.
- */
- struct GNUNET_CURL_Context *ctx;
-};
-
-
-/**
- * Function called when we're done processing the
- * HTTP /management/wire request.
- *
- * @param cls the `struct TALER_EXCHANGE_ManagementAuditorEnableHandle *`
- * @param response_code HTTP response code, 0 on error
- * @param response response body, NULL if not in JSON
- */
-static void
-handle_set_wire_fee_finished (void *cls,
- long response_code,
- const void *response)
-{
- struct TALER_EXCHANGE_ManagementSetWireFeeHandle *swfh = cls;
- const json_t *json = response;
- struct TALER_EXCHANGE_ManagementSetWireFeeResponse swr = {
- .hr.http_status = (unsigned int) response_code,
- .hr.reply = json
- };
-
- swfh->job = NULL;
- switch (response_code)
- {
- case MHD_HTTP_NO_CONTENT:
- break;
- case MHD_HTTP_FORBIDDEN:
- swr.hr.ec = TALER_JSON_get_error_code (json);
- swr.hr.hint = TALER_JSON_get_error_hint (json);
- break;
- case MHD_HTTP_NOT_FOUND:
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Server did not find handler at `%s'. Did you configure the correct exchange base URL?\n",
- swfh->url);
- if (NULL != json)
- {
- swr.hr.ec = TALER_JSON_get_error_code (json);
- swr.hr.hint = TALER_JSON_get_error_hint (json);
- }
- else
- {
- swr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
- swr.hr.hint = TALER_ErrorCode_get_hint (swr.hr.ec);
- }
- break;
- case MHD_HTTP_CONFLICT:
- swr.hr.ec = TALER_JSON_get_error_code (json);
- swr.hr.hint = TALER_JSON_get_error_hint (json);
- break;
- case MHD_HTTP_PRECONDITION_FAILED:
- swr.hr.ec = TALER_JSON_get_error_code (json);
- swr.hr.hint = TALER_JSON_get_error_hint (json);
- break;
- default:
- /* unexpected response code */
- GNUNET_break_op (0);
- swr.hr.ec = TALER_JSON_get_error_code (json);
- swr.hr.hint = TALER_JSON_get_error_hint (json);
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Unexpected response code %u/%d for exchange management set wire fee\n",
- (unsigned int) response_code,
- (int) swr.hr.ec);
- break;
- }
- if (NULL != swfh->cb)
- {
- swfh->cb (swfh->cb_cls,
- &swr);
- swfh->cb = NULL;
- }
- TALER_EXCHANGE_management_set_wire_fees_cancel (swfh);
-}
-
-
-struct TALER_EXCHANGE_ManagementSetWireFeeHandle *
-TALER_EXCHANGE_management_set_wire_fees (
- struct GNUNET_CURL_Context *ctx,
- const char *exchange_base_url,
- const char *wire_method,
- struct GNUNET_TIME_Timestamp validity_start,
- struct GNUNET_TIME_Timestamp validity_end,
- const struct TALER_WireFeeSet *fees,
- const struct TALER_MasterSignatureP *master_sig,
- TALER_EXCHANGE_ManagementSetWireFeeCallback cb,
- void *cb_cls)
-{
- struct TALER_EXCHANGE_ManagementSetWireFeeHandle *swfh;
- CURL *eh;
- json_t *body;
-
- swfh = GNUNET_new (struct TALER_EXCHANGE_ManagementSetWireFeeHandle);
- swfh->cb = cb;
- swfh->cb_cls = cb_cls;
- swfh->ctx = ctx;
- swfh->url = TALER_url_join (exchange_base_url,
- "management/wire-fee",
- NULL);
- if (NULL == swfh->url)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Could not construct request URL.\n");
- GNUNET_free (swfh);
- return NULL;
- }
- body = GNUNET_JSON_PACK (
- GNUNET_JSON_pack_string ("wire_method",
- wire_method),
- GNUNET_JSON_pack_data_auto ("master_sig",
- master_sig),
- GNUNET_JSON_pack_timestamp ("fee_start",
- validity_start),
- GNUNET_JSON_pack_timestamp ("fee_end",
- validity_end),
- TALER_JSON_pack_amount ("closing_fee",
- &fees->closing),
- TALER_JSON_pack_amount ("wire_fee",
- &fees->wire));
- eh = TALER_EXCHANGE_curl_easy_get_ (swfh->url);
- if ( (NULL == eh) ||
- (GNUNET_OK !=
- TALER_curl_easy_post (&swfh->post_ctx,
- eh,
- body)) )
- {
- GNUNET_break (0);
- if (NULL != eh)
- curl_easy_cleanup (eh);
- json_decref (body);
- GNUNET_free (swfh->url);
- return NULL;
- }
- json_decref (body);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Requesting URL '%s'\n",
- swfh->url);
- swfh->job = GNUNET_CURL_job_add2 (ctx,
- eh,
- swfh->post_ctx.headers,
- &handle_set_wire_fee_finished,
- swfh);
- if (NULL == swfh->job)
- {
- TALER_EXCHANGE_management_set_wire_fees_cancel (swfh);
- return NULL;
- }
- return swfh;
-}
-
-
-void
-TALER_EXCHANGE_management_set_wire_fees_cancel (
- struct TALER_EXCHANGE_ManagementSetWireFeeHandle *swfh)
-{
- if (NULL != swfh->job)
- {
- GNUNET_CURL_job_cancel (swfh->job);
- swfh->job = NULL;
- }
- TALER_curl_easy_post_finished (&swfh->post_ctx);
- GNUNET_free (swfh->url);
- GNUNET_free (swfh);
-}
diff --git a/src/lib/exchange_api_management_update_aml_officer.c b/src/lib/exchange_api_management_update_aml_officer.c
deleted file mode 100644
index 76cbc7e8d..000000000
--- a/src/lib/exchange_api_management_update_aml_officer.c
+++ /dev/null
@@ -1,229 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2023 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software
- Foundation; either version 3, or (at your option) any later version.
-
- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- TALER; see the file COPYING. If not, see
- <http://www.gnu.org/licenses/>
-*/
-/**
- * @file lib/exchange_api_management_update_aml_officer.c
- * @brief functions to update AML officer status
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include "taler_json_lib.h"
-#include <gnunet/gnunet_curl_lib.h>
-#include "taler_exchange_service.h"
-#include "exchange_api_curl_defaults.h"
-#include "taler_signatures.h"
-#include "taler_curl_lib.h"
-#include "taler_json_lib.h"
-
-
-struct TALER_EXCHANGE_ManagementUpdateAmlOfficer
-{
-
- /**
- * The url for this request.
- */
- char *url;
-
- /**
- * Minor context that holds body and headers.
- */
- struct TALER_CURL_PostContext post_ctx;
-
- /**
- * Handle for the request.
- */
- struct GNUNET_CURL_Job *job;
-
- /**
- * Function to call with the result.
- */
- TALER_EXCHANGE_ManagementUpdateAmlOfficerCallback cb;
-
- /**
- * Closure for @a cb.
- */
- void *cb_cls;
-
- /**
- * Reference to the execution context.
- */
- struct GNUNET_CURL_Context *ctx;
-};
-
-
-/**
- * Function called when we're done processing the
- * HTTP /management/wire request.
- *
- * @param cls the `struct TALER_EXCHANGE_ManagementAuditorEnableHandle *`
- * @param response_code HTTP response code, 0 on error
- * @param response response body, NULL if not in JSON
- */
-static void
-handle_update_aml_officer_finished (void *cls,
- long response_code,
- const void *response)
-{
- struct TALER_EXCHANGE_ManagementUpdateAmlOfficer *wh = cls;
- const json_t *json = response;
- struct TALER_EXCHANGE_ManagementUpdateAmlOfficerResponse uar = {
- .hr.http_status = (unsigned int) response_code,
- .hr.reply = json
- };
-
- wh->job = NULL;
- switch (response_code)
- {
- case 0:
- /* no reply */
- uar.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
- uar.hr.hint = "server offline?";
- break;
- case MHD_HTTP_NO_CONTENT:
- break;
- case MHD_HTTP_FORBIDDEN:
- uar.hr.ec = TALER_JSON_get_error_code (json);
- uar.hr.hint = TALER_JSON_get_error_hint (json);
- break;
- case MHD_HTTP_NOT_FOUND:
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Server did not find handler at `%s'. Did you configure the correct exchange base URL?\n",
- wh->url);
- if (NULL != json)
- {
- uar.hr.ec = TALER_JSON_get_error_code (json);
- uar.hr.hint = TALER_JSON_get_error_hint (json);
- }
- else
- {
- uar.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
- uar.hr.hint = TALER_ErrorCode_get_hint (uar.hr.ec);
- }
- break;
- case MHD_HTTP_CONFLICT:
- uar.hr.ec = TALER_JSON_get_error_code (json);
- uar.hr.hint = TALER_JSON_get_error_hint (json);
- break;
- default:
- /* unexpected response code */
- GNUNET_break_op (0);
- uar.hr.ec = TALER_JSON_get_error_code (json);
- uar.hr.hint = TALER_JSON_get_error_hint (json);
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Unexpected response code %u/%d for exchange management update AML officer\n",
- (unsigned int) response_code,
- (int) uar.hr.ec);
- break;
- }
- if (NULL != wh->cb)
- {
- wh->cb (wh->cb_cls,
- &uar);
- wh->cb = NULL;
- }
- TALER_EXCHANGE_management_update_aml_officer_cancel (wh);
-}
-
-
-struct TALER_EXCHANGE_ManagementUpdateAmlOfficer *
-TALER_EXCHANGE_management_update_aml_officer (
- struct GNUNET_CURL_Context *ctx,
- const char *url,
- const struct TALER_AmlOfficerPublicKeyP *officer_pub,
- const char *officer_name,
- struct GNUNET_TIME_Timestamp change_date,
- bool is_active,
- bool read_only,
- const struct TALER_MasterSignatureP *master_sig,
- TALER_EXCHANGE_ManagementUpdateAmlOfficerCallback cb,
- void *cb_cls)
-{
- struct TALER_EXCHANGE_ManagementUpdateAmlOfficer *wh;
- CURL *eh;
- json_t *body;
-
- wh = GNUNET_new (struct TALER_EXCHANGE_ManagementUpdateAmlOfficer);
- wh->cb = cb;
- wh->cb_cls = cb_cls;
- wh->ctx = ctx;
- wh->url = TALER_url_join (url,
- "management/aml-officers",
- NULL);
- if (NULL == wh->url)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Could not construct request URL.\n");
- GNUNET_free (wh);
- return NULL;
- }
- body = GNUNET_JSON_PACK (
- GNUNET_JSON_pack_string ("officer_name",
- officer_name),
- GNUNET_JSON_pack_data_auto ("officer_pub",
- officer_pub),
- GNUNET_JSON_pack_data_auto ("master_sig",
- master_sig),
- GNUNET_JSON_pack_bool ("is_active",
- is_active),
- GNUNET_JSON_pack_bool ("read_only",
- read_only),
- GNUNET_JSON_pack_timestamp ("change_date",
- change_date));
- eh = TALER_EXCHANGE_curl_easy_get_ (wh->url);
- if ( (NULL == eh) ||
- (GNUNET_OK !=
- TALER_curl_easy_post (&wh->post_ctx,
- eh,
- body)) )
- {
- GNUNET_break (0);
- if (NULL != eh)
- curl_easy_cleanup (eh);
- json_decref (body);
- GNUNET_free (wh->url);
- return NULL;
- }
- json_decref (body);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Requesting URL '%s'\n",
- wh->url);
- wh->job = GNUNET_CURL_job_add2 (ctx,
- eh,
- wh->post_ctx.headers,
- &handle_update_aml_officer_finished,
- wh);
- if (NULL == wh->job)
- {
- TALER_EXCHANGE_management_update_aml_officer_cancel (wh);
- return NULL;
- }
- return wh;
-}
-
-
-void
-TALER_EXCHANGE_management_update_aml_officer_cancel (
- struct TALER_EXCHANGE_ManagementUpdateAmlOfficer *wh)
-{
- if (NULL != wh->job)
- {
- GNUNET_CURL_job_cancel (wh->job);
- wh->job = NULL;
- }
- TALER_curl_easy_post_finished (&wh->post_ctx);
- GNUNET_free (wh->url);
- GNUNET_free (wh);
-}
diff --git a/src/lib/exchange_api_management_wire_disable.c b/src/lib/exchange_api_management_wire_disable.c
deleted file mode 100644
index 30749b0e4..000000000
--- a/src/lib/exchange_api_management_wire_disable.c
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2015-2023 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software
- Foundation; either version 3, or (at your option) any later version.
-
- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- TALER; see the file COPYING. If not, see
- <http://www.gnu.org/licenses/>
-*/
-/**
- * @file lib/exchange_api_management_wire_disable.c
- * @brief functions to disable an exchange wire method / bank account
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include "taler_json_lib.h"
-#include <gnunet/gnunet_curl_lib.h>
-#include "taler_exchange_service.h"
-#include "exchange_api_curl_defaults.h"
-#include "taler_signatures.h"
-#include "taler_curl_lib.h"
-#include "taler_json_lib.h"
-
-
-struct TALER_EXCHANGE_ManagementWireDisableHandle
-{
-
- /**
- * The url for this request.
- */
- char *url;
-
- /**
- * Minor context that holds body and headers.
- */
- struct TALER_CURL_PostContext post_ctx;
-
- /**
- * Handle for the request.
- */
- struct GNUNET_CURL_Job *job;
-
- /**
- * Function to call with the result.
- */
- TALER_EXCHANGE_ManagementWireDisableCallback cb;
-
- /**
- * Closure for @a cb.
- */
- void *cb_cls;
-
- /**
- * Reference to the execution context.
- */
- struct GNUNET_CURL_Context *ctx;
-};
-
-
-/**
- * Function called when we're done processing the
- * HTTP /management/wire/disable request.
- *
- * @param cls the `struct TALER_EXCHANGE_ManagementAuditorDisableHandle *`
- * @param response_code HTTP response code, 0 on error
- * @param response response body, NULL if not in JSON
- */
-static void
-handle_auditor_disable_finished (void *cls,
- long response_code,
- const void *response)
-{
- struct TALER_EXCHANGE_ManagementWireDisableHandle *wh = cls;
- const json_t *json = response;
- struct TALER_EXCHANGE_ManagementWireDisableResponse wdr = {
- .hr.http_status = (unsigned int) response_code,
- .hr.reply = json
- };
-
- wh->job = NULL;
- switch (response_code)
- {
- case 0:
- /* no reply */
- wdr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
- wdr.hr.hint = "server offline?";
- break;
- case MHD_HTTP_NO_CONTENT:
- break;
- case MHD_HTTP_FORBIDDEN:
- wdr.hr.ec = TALER_JSON_get_error_code (json);
- wdr.hr.hint = TALER_JSON_get_error_hint (json);
- break;
- case MHD_HTTP_NOT_FOUND:
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Server did not find handler at `%s'. Did you configure the correct exchange base URL?\n",
- wh->url);
- if (NULL != json)
- {
- wdr.hr.ec = TALER_JSON_get_error_code (json);
- wdr.hr.hint = TALER_JSON_get_error_hint (json);
- }
- else
- {
- wdr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
- wdr.hr.hint = TALER_ErrorCode_get_hint (wdr.hr.ec);
- }
- break;
- case MHD_HTTP_CONFLICT:
- wdr.hr.ec = TALER_JSON_get_error_code (json);
- wdr.hr.hint = TALER_JSON_get_error_hint (json);
- break;
- default:
- /* unexpected response code */
- GNUNET_break_op (0);
- wdr.hr.ec = TALER_JSON_get_error_code (json);
- wdr.hr.hint = TALER_JSON_get_error_hint (json);
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Unexpected response code %u/%d exchange management disable wire\n",
- (unsigned int) response_code,
- (int) wdr.hr.ec);
- break;
- }
- if (NULL != wh->cb)
- {
- wh->cb (wh->cb_cls,
- &wdr);
- wh->cb = NULL;
- }
- TALER_EXCHANGE_management_disable_wire_cancel (wh);
-}
-
-
-struct TALER_EXCHANGE_ManagementWireDisableHandle *
-TALER_EXCHANGE_management_disable_wire (
- struct GNUNET_CURL_Context *ctx,
- const char *url,
- const char *payto_uri,
- struct GNUNET_TIME_Timestamp validity_end,
- const struct TALER_MasterSignatureP *master_sig,
- TALER_EXCHANGE_ManagementWireDisableCallback cb,
- void *cb_cls)
-{
- struct TALER_EXCHANGE_ManagementWireDisableHandle *wh;
- CURL *eh;
- json_t *body;
-
- wh = GNUNET_new (struct TALER_EXCHANGE_ManagementWireDisableHandle);
- wh->cb = cb;
- wh->cb_cls = cb_cls;
- wh->ctx = ctx;
- wh->url = TALER_url_join (url,
- "management/wire/disable",
- NULL);
- if (NULL == wh->url)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Could not construct request URL.\n");
- GNUNET_free (wh);
- return NULL;
- }
- body = GNUNET_JSON_PACK (
- GNUNET_JSON_pack_string ("payto_uri",
- payto_uri),
- GNUNET_JSON_pack_data_auto ("master_sig_del",
- master_sig),
- GNUNET_JSON_pack_timestamp ("validity_end",
- validity_end));
- eh = TALER_EXCHANGE_curl_easy_get_ (wh->url);
- if ( (NULL == eh) ||
- (GNUNET_OK !=
- TALER_curl_easy_post (&wh->post_ctx,
- eh,
- body)) )
- {
- GNUNET_break (0);
- if (NULL != eh)
- curl_easy_cleanup (eh);
- json_decref (body);
- GNUNET_free (wh->url);
- return NULL;
- }
- json_decref (body);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Requesting URL '%s'\n",
- wh->url);
- wh->job = GNUNET_CURL_job_add2 (ctx,
- eh,
- wh->post_ctx.headers,
- &handle_auditor_disable_finished,
- wh);
- if (NULL == wh->job)
- {
- TALER_EXCHANGE_management_disable_wire_cancel (wh);
- return NULL;
- }
- return wh;
-}
-
-
-void
-TALER_EXCHANGE_management_disable_wire_cancel (
- struct TALER_EXCHANGE_ManagementWireDisableHandle *wh)
-{
- if (NULL != wh->job)
- {
- GNUNET_CURL_job_cancel (wh->job);
- wh->job = NULL;
- }
- TALER_curl_easy_post_finished (&wh->post_ctx);
- GNUNET_free (wh->url);
- GNUNET_free (wh);
-}
diff --git a/src/lib/exchange_api_management_wire_enable.c b/src/lib/exchange_api_management_wire_enable.c
deleted file mode 100644
index 5add3e0b0..000000000
--- a/src/lib/exchange_api_management_wire_enable.c
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2015-2023 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software
- Foundation; either version 3, or (at your option) any later version.
-
- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- TALER; see the file COPYING. If not, see
- <http://www.gnu.org/licenses/>
-*/
-/**
- * @file lib/exchange_api_management_wire_enable.c
- * @brief functions to enable an exchange wire method / bank account
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include "taler_json_lib.h"
-#include <gnunet/gnunet_curl_lib.h>
-#include "taler_exchange_service.h"
-#include "exchange_api_curl_defaults.h"
-#include "taler_signatures.h"
-#include "taler_curl_lib.h"
-#include "taler_json_lib.h"
-
-
-struct TALER_EXCHANGE_ManagementWireEnableHandle
-{
-
- /**
- * The url for this request.
- */
- char *url;
-
- /**
- * Minor context that holds body and headers.
- */
- struct TALER_CURL_PostContext post_ctx;
-
- /**
- * Handle for the request.
- */
- struct GNUNET_CURL_Job *job;
-
- /**
- * Function to call with the result.
- */
- TALER_EXCHANGE_ManagementWireEnableCallback cb;
-
- /**
- * Closure for @a cb.
- */
- void *cb_cls;
-
- /**
- * Reference to the execution context.
- */
- struct GNUNET_CURL_Context *ctx;
-};
-
-
-/**
- * Function called when we're done processing the
- * HTTP /management/wire request.
- *
- * @param cls the `struct TALER_EXCHANGE_ManagementAuditorEnableHandle *`
- * @param response_code HTTP response code, 0 on error
- * @param response response body, NULL if not in JSON
- */
-static void
-handle_auditor_enable_finished (void *cls,
- long response_code,
- const void *response)
-{
- struct TALER_EXCHANGE_ManagementWireEnableHandle *wh = cls;
- const json_t *json = response;
- struct TALER_EXCHANGE_ManagementWireEnableResponse wer = {
- .hr.http_status = (unsigned int) response_code,
- .hr.reply = json
- };
-
- wh->job = NULL;
- switch (response_code)
- {
- case 0:
- /* no reply */
- wer.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
- wer.hr.hint = "server offline?";
- break;
- case MHD_HTTP_NO_CONTENT:
- break;
- case MHD_HTTP_FORBIDDEN:
- wer.hr.ec = TALER_JSON_get_error_code (json);
- wer.hr.hint = TALER_JSON_get_error_hint (json);
- break;
- case MHD_HTTP_NOT_FOUND:
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Server did not find handler at `%s'. Did you configure the correct exchange base URL?\n",
- wh->url);
- if (NULL != json)
- {
- wer.hr.ec = TALER_JSON_get_error_code (json);
- wer.hr.hint = TALER_JSON_get_error_hint (json);
- }
- else
- {
- wer.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
- wer.hr.hint = TALER_ErrorCode_get_hint (wer.hr.ec);
- }
- break;
- case MHD_HTTP_CONFLICT:
- wer.hr.ec = TALER_JSON_get_error_code (json);
- wer.hr.hint = TALER_JSON_get_error_hint (json);
- break;
- default:
- /* unexpected response code */
- GNUNET_break_op (0);
- wer.hr.ec = TALER_JSON_get_error_code (json);
- wer.hr.hint = TALER_JSON_get_error_hint (json);
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Unexpected response code %u/%d for exchange management enable wire\n",
- (unsigned int) response_code,
- (int) wer.hr.ec);
- break;
- }
- if (NULL != wh->cb)
- {
- wh->cb (wh->cb_cls,
- &wer);
- wh->cb = NULL;
- }
- TALER_EXCHANGE_management_enable_wire_cancel (wh);
-}
-
-
-struct TALER_EXCHANGE_ManagementWireEnableHandle *
-TALER_EXCHANGE_management_enable_wire (
- struct GNUNET_CURL_Context *ctx,
- const char *url,
- const char *payto_uri,
- const char *conversion_url,
- const json_t *debit_restrictions,
- const json_t *credit_restrictions,
- struct GNUNET_TIME_Timestamp validity_start,
- const struct TALER_MasterSignatureP *master_sig1,
- const struct TALER_MasterSignatureP *master_sig2,
- TALER_EXCHANGE_ManagementWireEnableCallback cb,
- void *cb_cls)
-{
- struct TALER_EXCHANGE_ManagementWireEnableHandle *wh;
- CURL *eh;
- json_t *body;
-
- {
- char *msg = TALER_payto_validate (payto_uri);
-
- if (NULL != msg)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "payto URI is malformed: %s\n",
- msg);
- GNUNET_free (msg);
- return NULL;
- }
- }
- wh = GNUNET_new (struct TALER_EXCHANGE_ManagementWireEnableHandle);
- wh->cb = cb;
- wh->cb_cls = cb_cls;
- wh->ctx = ctx;
- wh->url = TALER_url_join (url,
- "management/wire",
- NULL);
- if (NULL == wh->url)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Could not construct request URL.\n");
- GNUNET_free (wh);
- return NULL;
- }
- body = GNUNET_JSON_PACK (
- GNUNET_JSON_pack_string ("payto_uri",
- payto_uri),
- GNUNET_JSON_pack_array_incref ("debit_restrictions",
- (json_t *) debit_restrictions),
- GNUNET_JSON_pack_array_incref ("credit_restrictions",
- (json_t *) credit_restrictions),
- GNUNET_JSON_pack_allow_null (
- GNUNET_JSON_pack_string ("conversion_url",
- conversion_url)),
- GNUNET_JSON_pack_data_auto ("master_sig_add",
- master_sig1),
- GNUNET_JSON_pack_data_auto ("master_sig_wire",
- master_sig2),
- GNUNET_JSON_pack_timestamp ("validity_start",
- validity_start));
- eh = TALER_EXCHANGE_curl_easy_get_ (wh->url);
- if ( (NULL == eh) ||
- (GNUNET_OK !=
- TALER_curl_easy_post (&wh->post_ctx,
- eh,
- body)) )
- {
- GNUNET_break (0);
- if (NULL != eh)
- curl_easy_cleanup (eh);
- json_decref (body);
- GNUNET_free (wh->url);
- return NULL;
- }
- json_decref (body);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Requesting URL '%s'\n",
- wh->url);
- wh->job = GNUNET_CURL_job_add2 (ctx,
- eh,
- wh->post_ctx.headers,
- &handle_auditor_enable_finished,
- wh);
- if (NULL == wh->job)
- {
- TALER_EXCHANGE_management_enable_wire_cancel (wh);
- return NULL;
- }
- return wh;
-}
-
-
-void
-TALER_EXCHANGE_management_enable_wire_cancel (
- struct TALER_EXCHANGE_ManagementWireEnableHandle *wh)
-{
- if (NULL != wh->job)
- {
- GNUNET_CURL_job_cancel (wh->job);
- wh->job = NULL;
- }
- TALER_curl_easy_post_finished (&wh->post_ctx);
- GNUNET_free (wh->url);
- GNUNET_free (wh);
-}
diff --git a/src/lib/exchange_api_melt.c b/src/lib/exchange_api_melt.c
deleted file mode 100644
index ba4241dab..000000000
--- a/src/lib/exchange_api_melt.c
+++ /dev/null
@@ -1,596 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2015-2023 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software
- Foundation; either version 3, or (at your option) any later version.
-
- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- TALER; see the file COPYING. If not, see
- <http://www.gnu.org/licenses/>
-*/
-/**
- * @file lib/exchange_api_melt.c
- * @brief Implementation of the /coins/$COIN_PUB/melt request
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include <jansson.h>
-#include <microhttpd.h> /* just for HTTP status codes */
-#include <gnunet/gnunet_util_lib.h>
-#include <gnunet/gnunet_json_lib.h>
-#include <gnunet/gnunet_curl_lib.h>
-#include "taler_json_lib.h"
-#include "taler_exchange_service.h"
-#include "exchange_api_common.h"
-#include "exchange_api_handle.h"
-#include "taler_signatures.h"
-#include "exchange_api_curl_defaults.h"
-#include "exchange_api_refresh_common.h"
-
-
-/**
- * @brief A /coins/$COIN_PUB/melt Handle
- */
-struct TALER_EXCHANGE_MeltHandle
-{
-
- /**
- * The keys of the this request handle will use
- */
- struct TALER_EXCHANGE_Keys *keys;
-
- /**
- * The url for this request.
- */
- char *url;
-
- /**
- * The exchange base url.
- */
- char *exchange_url;
-
- /**
- * Curl context.
- */
- struct GNUNET_CURL_Context *cctx;
-
- /**
- * Context for #TEH_curl_easy_post(). Keeps the data that must
- * persist for Curl to make the upload.
- */
- struct TALER_CURL_PostContext ctx;
-
- /**
- * Handle for the request.
- */
- struct GNUNET_CURL_Job *job;
-
- /**
- * Function to call with refresh melt failure results.
- */
- TALER_EXCHANGE_MeltCallback melt_cb;
-
- /**
- * Closure for @e result_cb and @e melt_failure_cb.
- */
- void *melt_cb_cls;
-
- /**
- * Actual information about the melt operation.
- */
- struct MeltData md;
-
- /**
- * The secret the entire melt operation is seeded from.
- */
- struct TALER_RefreshMasterSecretP rms;
-
- /**
- * Details about the characteristics of the requested melt operation.
- */
- const struct TALER_EXCHANGE_RefreshData *rd;
-
- /**
- * Array of `num_fresh_coins` per-coin values
- * returned from melt operation.
- */
- struct TALER_EXCHANGE_MeltBlindingDetail *mbds;
-
- /**
- * Handle for the preflight request, or NULL.
- */
- struct TALER_EXCHANGE_CsRMeltHandle *csr;
-
- /**
- * Public key of the coin being melted.
- */
- struct TALER_CoinSpendPublicKeyP coin_pub;
-
- /**
- * Signature affirming the melt.
- */
- struct TALER_CoinSpendSignatureP coin_sig;
-
- /**
- * @brief Public information about the coin's denomination key
- */
- const struct TALER_EXCHANGE_DenomPublicKey *dki;
-
- /**
- * Gamma value chosen by the exchange during melt.
- */
- uint32_t noreveal_index;
-
- /**
- * True if we need to include @e rms in our melt request.
- */
- bool send_rms;
-};
-
-
-/**
- * Verify that the signature on the "200 OK" response
- * from the exchange is valid.
- *
- * @param[in,out] mh melt handle
- * @param json json reply with the signature
- * @param[out] exchange_pub public key of the exchange used for the signature
- * @return #GNUNET_OK if the signature is valid, #GNUNET_SYSERR if not
- */
-static enum GNUNET_GenericReturnValue
-verify_melt_signature_ok (struct TALER_EXCHANGE_MeltHandle *mh,
- const json_t *json,
- struct TALER_ExchangePublicKeyP *exchange_pub)
-{
- struct TALER_ExchangeSignatureP exchange_sig;
- const struct TALER_EXCHANGE_Keys *key_state;
- struct GNUNET_JSON_Specification spec[] = {
- GNUNET_JSON_spec_fixed_auto ("exchange_sig",
- &exchange_sig),
- GNUNET_JSON_spec_fixed_auto ("exchange_pub",
- exchange_pub),
- GNUNET_JSON_spec_uint32 ("noreveal_index",
- &mh->noreveal_index),
- GNUNET_JSON_spec_end ()
- };
-
- if (GNUNET_OK !=
- GNUNET_JSON_parse (json,
- spec,
- NULL, NULL))
- {
- GNUNET_break_op (0);
- return GNUNET_SYSERR;
- }
- /* check that exchange signing key is permitted */
- key_state = mh->keys;
- if (GNUNET_OK !=
- TALER_EXCHANGE_test_signing_key (key_state,
- exchange_pub))
- {
- GNUNET_break_op (0);
- return GNUNET_SYSERR;
- }
-
- /* check that noreveal index is in permitted range */
- if (TALER_CNC_KAPPA <= mh->noreveal_index)
- {
- GNUNET_break_op (0);
- return GNUNET_SYSERR;
- }
-
- if (GNUNET_OK !=
- TALER_exchange_online_melt_confirmation_verify (
- &mh->md.rc,
- mh->noreveal_index,
- exchange_pub,
- &exchange_sig))
- {
- GNUNET_break_op (0);
- return GNUNET_SYSERR;
- }
- return GNUNET_OK;
-}
-
-
-/**
- * Function called when we're done processing the
- * HTTP /coins/$COIN_PUB/melt request.
- *
- * @param cls the `struct TALER_EXCHANGE_MeltHandle`
- * @param response_code HTTP response code, 0 on error
- * @param response parsed JSON result, NULL on error
- */
-static void
-handle_melt_finished (void *cls,
- long response_code,
- const void *response)
-{
- struct TALER_EXCHANGE_MeltHandle *mh = cls;
- const json_t *j = response;
- struct TALER_EXCHANGE_MeltResponse mr = {
- .hr.reply = j,
- .hr.http_status = (unsigned int) response_code
- };
-
- mh->job = NULL;
- switch (response_code)
- {
- case 0:
- mr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
- break;
- case MHD_HTTP_OK:
- if (GNUNET_OK !=
- verify_melt_signature_ok (mh,
- j,
- &mr.details.ok.sign_key))
- {
- GNUNET_break_op (0);
- mr.hr.http_status = 0;
- mr.hr.ec = TALER_EC_EXCHANGE_MELT_INVALID_SIGNATURE_BY_EXCHANGE;
- break;
- }
- mr.details.ok.noreveal_index = mh->noreveal_index;
- mr.details.ok.num_mbds = mh->rd->fresh_pks_len;
- mr.details.ok.mbds = mh->mbds;
- mh->melt_cb (mh->melt_cb_cls,
- &mr);
- mh->melt_cb = NULL;
- break;
- case MHD_HTTP_BAD_REQUEST:
- /* This should never happen, either us or the exchange is buggy
- (or API version conflict); just pass JSON reply to the application */
- mr.hr.ec = TALER_JSON_get_error_code (j);
- mr.hr.hint = TALER_JSON_get_error_hint (j);
- break;
- case MHD_HTTP_CONFLICT:
- mr.hr.ec = TALER_JSON_get_error_code (j);
- mr.hr.hint = TALER_JSON_get_error_hint (j);
- break;
- case MHD_HTTP_FORBIDDEN:
- /* Nothing really to verify, exchange says one of the signatures is
- invalid; assuming we checked them, this should never happen, we
- should pass the JSON reply to the application */
- mr.hr.ec = TALER_JSON_get_error_code (j);
- mr.hr.hint = TALER_JSON_get_error_hint (j);
- break;
- case MHD_HTTP_NOT_FOUND:
- /* Nothing really to verify, this should never
- happen, we should pass the JSON reply to the application */
- mr.hr.ec = TALER_JSON_get_error_code (j);
- mr.hr.hint = TALER_JSON_get_error_hint (j);
- break;
- case MHD_HTTP_INTERNAL_SERVER_ERROR:
- /* Server had an internal issue; we should retry, but this API
- leaves this to the application */
- mr.hr.ec = TALER_JSON_get_error_code (j);
- mr.hr.hint = TALER_JSON_get_error_hint (j);
- break;
- default:
- /* unexpected response code */
- mr.hr.ec = TALER_JSON_get_error_code (j);
- mr.hr.hint = TALER_JSON_get_error_hint (j);
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Unexpected response code %u/%d for exchange melt\n",
- (unsigned int) response_code,
- mr.hr.ec);
- GNUNET_break_op (0);
- break;
- }
- if (NULL != mh->melt_cb)
- mh->melt_cb (mh->melt_cb_cls,
- &mr);
- TALER_EXCHANGE_melt_cancel (mh);
-}
-
-
-/**
- * Start the actual melt operation, now that we have
- * the exchange's input values.
- *
- * @param[in,out] mh melt operation to run
- * @return #GNUNET_OK if we could start the operation
- */
-static enum GNUNET_GenericReturnValue
-start_melt (struct TALER_EXCHANGE_MeltHandle *mh)
-{
- const struct TALER_EXCHANGE_Keys *key_state;
- json_t *melt_obj;
- CURL *eh;
- char arg_str[sizeof (struct TALER_CoinSpendPublicKeyP) * 2 + 32];
- struct TALER_DenominationHashP h_denom_pub;
- struct TALER_ExchangeWithdrawValues alg_values[mh->rd->fresh_pks_len];
-
- for (unsigned int i = 0; i<mh->rd->fresh_pks_len; i++)
- alg_values[i] = mh->mbds[i].alg_value;
- if (GNUNET_OK !=
- TALER_EXCHANGE_get_melt_data_ (&mh->rms,
- mh->rd,
- alg_values,
- &mh->md))
- {
- GNUNET_break (0);
- return GNUNET_SYSERR;
- }
- TALER_denom_pub_hash (&mh->md.melted_coin.pub_key,
- &h_denom_pub);
- TALER_wallet_melt_sign (
- &mh->md.melted_coin.melt_amount_with_fee,
- &mh->md.melted_coin.fee_melt,
- &mh->md.rc,
- &h_denom_pub,
- mh->md.melted_coin.h_age_commitment,
- &mh->md.melted_coin.coin_priv,
- &mh->coin_sig);
- GNUNET_CRYPTO_eddsa_key_get_public (&mh->md.melted_coin.coin_priv.eddsa_priv,
- &mh->coin_pub.eddsa_pub);
- melt_obj = GNUNET_JSON_PACK (
- GNUNET_JSON_pack_data_auto ("denom_pub_hash",
- &h_denom_pub),
- TALER_JSON_pack_denom_sig ("denom_sig",
- &mh->md.melted_coin.sig),
- GNUNET_JSON_pack_data_auto ("confirm_sig",
- &mh->coin_sig),
- TALER_JSON_pack_amount ("value_with_fee",
- &mh->md.melted_coin.melt_amount_with_fee),
- GNUNET_JSON_pack_data_auto ("rc",
- &mh->md.rc),
- GNUNET_JSON_pack_allow_null (
- (NULL != mh->md.melted_coin.h_age_commitment)
- ? GNUNET_JSON_pack_data_auto ("age_commitment_hash",
- mh->md.melted_coin.h_age_commitment)
- : GNUNET_JSON_pack_string ("age_commitment_hash",
- NULL)),
- GNUNET_JSON_pack_allow_null (
- mh->send_rms
- ? GNUNET_JSON_pack_data_auto ("rms",
- &mh->rms)
- : GNUNET_JSON_pack_string ("rms",
- NULL)));
- {
- char pub_str[sizeof (struct TALER_CoinSpendPublicKeyP) * 2];
- char *end;
-
- end = GNUNET_STRINGS_data_to_string (
- &mh->coin_pub,
- sizeof (struct TALER_CoinSpendPublicKeyP),
- pub_str,
- sizeof (pub_str));
- *end = '\0';
- GNUNET_snprintf (arg_str,
- sizeof (arg_str),
- "coins/%s/melt",
- pub_str);
- }
-
- key_state = mh->keys;
- mh->dki = TALER_EXCHANGE_get_denomination_key (key_state,
- &mh->md.melted_coin.pub_key);
-
- /* and now we can at last begin the actual request handling */
-
- mh->url = TALER_url_join (mh->exchange_url,
- arg_str,
- NULL);
- if (NULL == mh->url)
- {
- json_decref (melt_obj);
- return GNUNET_SYSERR;
- }
- eh = TALER_EXCHANGE_curl_easy_get_ (mh->url);
- if ( (NULL == eh) ||
- (GNUNET_OK !=
- TALER_curl_easy_post (&mh->ctx,
- eh,
- melt_obj)) )
- {
- GNUNET_break (0);
- if (NULL != eh)
- curl_easy_cleanup (eh);
- json_decref (melt_obj);
- return GNUNET_SYSERR;
- }
- json_decref (melt_obj);
- mh->job = GNUNET_CURL_job_add2 (mh->cctx,
- eh,
- mh->ctx.headers,
- &handle_melt_finished,
- mh);
- return GNUNET_OK;
-}
-
-
-/**
- * The melt request @a mh failed, return an error to
- * the application and cancel the operation.
- *
- * @param[in] mh melt request that failed
- * @param ec error code to fail with
- */
-static void
-fail_mh (struct TALER_EXCHANGE_MeltHandle *mh,
- enum TALER_ErrorCode ec)
-{
- struct TALER_EXCHANGE_MeltResponse mr = {
- .hr.ec = ec
- };
-
- mh->melt_cb (mh->melt_cb_cls,
- &mr);
- TALER_EXCHANGE_melt_cancel (mh);
-}
-
-
-/**
- * Callbacks of this type are used to serve the result of submitting a
- * CS R request to a exchange.
- *
- * @param cls closure with our `struct TALER_EXCHANGE_MeltHandle *`
- * @param csrr response details
- */
-static void
-csr_cb (void *cls,
- const struct TALER_EXCHANGE_CsRMeltResponse *csrr)
-{
- struct TALER_EXCHANGE_MeltHandle *mh = cls;
- unsigned int nks_off = 0;
-
- mh->csr = NULL;
- if (MHD_HTTP_OK != csrr->hr.http_status)
- {
- struct TALER_EXCHANGE_MeltResponse mr = {
- .hr = csrr->hr
- };
-
- mr.hr.hint = "/csr-melt failed";
- mh->melt_cb (mh->melt_cb_cls,
- &mr);
- TALER_EXCHANGE_melt_cancel (mh);
- return;
- }
- for (unsigned int i = 0; i<mh->rd->fresh_pks_len; i++)
- {
- const struct TALER_EXCHANGE_DenomPublicKey *fresh_pk =
- &mh->rd->fresh_pks[i];
- struct TALER_ExchangeWithdrawValues *wv = &mh->mbds[i].alg_value;
-
- switch (fresh_pk->key.cipher)
- {
- case TALER_DENOMINATION_INVALID:
- GNUNET_break (0);
- fail_mh (mh,
- TALER_EC_GENERIC_CLIENT_INTERNAL_ERROR);
- return;
- case TALER_DENOMINATION_RSA:
- GNUNET_assert (TALER_DENOMINATION_RSA == wv->cipher);
- break;
- case TALER_DENOMINATION_CS:
- GNUNET_assert (TALER_DENOMINATION_CS == wv->cipher);
- *wv = csrr->details.ok.alg_values[nks_off];
- nks_off++;
- break;
- }
- }
- mh->send_rms = true;
- if (GNUNET_OK !=
- start_melt (mh))
- {
- GNUNET_break (0);
- fail_mh (mh,
- TALER_EC_GENERIC_CLIENT_INTERNAL_ERROR);
- return;
- }
-}
-
-
-struct TALER_EXCHANGE_MeltHandle *
-TALER_EXCHANGE_melt (
- struct GNUNET_CURL_Context *ctx,
- const char *url,
- struct TALER_EXCHANGE_Keys *keys,
- const struct TALER_RefreshMasterSecretP *rms,
- const struct TALER_EXCHANGE_RefreshData *rd,
- TALER_EXCHANGE_MeltCallback melt_cb,
- void *melt_cb_cls)
-{
- struct TALER_EXCHANGE_NonceKey nks[GNUNET_NZL (rd->fresh_pks_len)];
- unsigned int nks_off = 0;
- struct TALER_EXCHANGE_MeltHandle *mh;
-
- if (0 == rd->fresh_pks_len)
- {
- GNUNET_break (0);
- return NULL;
- }
- mh = GNUNET_new (struct TALER_EXCHANGE_MeltHandle);
- mh->noreveal_index = TALER_CNC_KAPPA; /* invalid value */
- mh->cctx = ctx;
- mh->exchange_url = GNUNET_strdup (url);
- mh->rd = rd;
- mh->rms = *rms;
- mh->melt_cb = melt_cb;
- mh->melt_cb_cls = melt_cb_cls;
- mh->mbds = GNUNET_new_array (rd->fresh_pks_len,
- struct TALER_EXCHANGE_MeltBlindingDetail);
- for (unsigned int i = 0; i<rd->fresh_pks_len; i++)
- {
- const struct TALER_EXCHANGE_DenomPublicKey *fresh_pk = &rd->fresh_pks[i];
- struct TALER_ExchangeWithdrawValues *wv = &mh->mbds[i].alg_value;
-
- switch (fresh_pk->key.cipher)
- {
- case TALER_DENOMINATION_INVALID:
- GNUNET_break (0);
- GNUNET_free (mh->mbds);
- GNUNET_free (mh);
- return NULL;
- case TALER_DENOMINATION_RSA:
- wv->cipher = TALER_DENOMINATION_RSA;
- break;
- case TALER_DENOMINATION_CS:
- wv->cipher = TALER_DENOMINATION_CS;
- nks[nks_off].pk = fresh_pk;
- nks[nks_off].cnc_num = nks_off;
- nks_off++;
- break;
- }
- }
- mh->keys = TALER_EXCHANGE_keys_incref (keys);
- if (0 != nks_off)
- {
- mh->csr = TALER_EXCHANGE_csr_melt (ctx,
- url,
- rms,
- nks_off,
- nks,
- &csr_cb,
- mh);
- if (NULL == mh->csr)
- {
- GNUNET_break (0);
- TALER_EXCHANGE_melt_cancel (mh);
- return NULL;
- }
- return mh;
- }
- if (GNUNET_OK !=
- start_melt (mh))
- {
- GNUNET_break (0);
- TALER_EXCHANGE_melt_cancel (mh);
- return NULL;
- }
- return mh;
-}
-
-
-void
-TALER_EXCHANGE_melt_cancel (struct TALER_EXCHANGE_MeltHandle *mh)
-{
- if (NULL != mh->job)
- {
- GNUNET_CURL_job_cancel (mh->job);
- mh->job = NULL;
- }
- if (NULL != mh->csr)
- {
- TALER_EXCHANGE_csr_melt_cancel (mh->csr);
- mh->csr = NULL;
- }
- TALER_EXCHANGE_free_melt_data_ (&mh->md); /* does not free 'md' itself */
- GNUNET_free (mh->mbds);
- GNUNET_free (mh->url);
- GNUNET_free (mh->exchange_url);
- TALER_curl_easy_post_finished (&mh->ctx);
- TALER_EXCHANGE_keys_decref (mh->keys);
- GNUNET_free (mh);
-}
-
-
-/* end of exchange_api_melt.c */
diff --git a/src/lib/exchange_api_recoup.c b/src/lib/exchange_api_recoup.c
deleted file mode 100644
index cfd265f04..000000000
--- a/src/lib/exchange_api_recoup.c
+++ /dev/null
@@ -1,369 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2017-2023 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software
- Foundation; either version 3, or (at your option) any later version.
-
- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- TALER; see the file COPYING. If not, see
- <http://www.gnu.org/licenses/>
-*/
-/**
- * @file lib/exchange_api_recoup.c
- * @brief Implementation of the /recoup request of the exchange's HTTP API
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include <jansson.h>
-#include <microhttpd.h> /* just for HTTP status codes */
-#include <gnunet/gnunet_util_lib.h>
-#include <gnunet/gnunet_json_lib.h>
-#include <gnunet/gnunet_curl_lib.h>
-#include "taler_json_lib.h"
-#include "taler_exchange_service.h"
-#include "exchange_api_common.h"
-#include "exchange_api_handle.h"
-#include "taler_signatures.h"
-#include "exchange_api_curl_defaults.h"
-
-
-/**
- * @brief A Recoup Handle
- */
-struct TALER_EXCHANGE_RecoupHandle
-{
-
- /**
- * The keys of the exchange this request handle will use
- */
- struct TALER_EXCHANGE_Keys *keys;
-
- /**
- * The url for this request.
- */
- char *url;
-
- /**
- * Context for #TEH_curl_easy_post(). Keeps the data that must
- * persist for Curl to make the upload.
- */
- struct TALER_CURL_PostContext ctx;
-
- /**
- * Denomination key of the coin.
- */
- struct TALER_EXCHANGE_DenomPublicKey pk;
-
- /**
- * Our signature requesting the recoup.
- */
- struct TALER_CoinSpendSignatureP coin_sig;
-
- /**
- * Handle for the request.
- */
- struct GNUNET_CURL_Job *job;
-
- /**
- * Function to call with the result.
- */
- TALER_EXCHANGE_RecoupResultCallback cb;
-
- /**
- * Closure for @a cb.
- */
- void *cb_cls;
-
- /**
- * Public key of the coin we are trying to get paid back.
- */
- struct TALER_CoinSpendPublicKeyP coin_pub;
-
-};
-
-
-/**
- * Parse a recoup response. If it is valid, call the callback.
- *
- * @param ph recoup handle
- * @param json json reply with the signature
- * @return #GNUNET_OK if the signature is valid and we called the callback;
- * #GNUNET_SYSERR if not (callback must still be called)
- */
-static enum GNUNET_GenericReturnValue
-process_recoup_response (const struct TALER_EXCHANGE_RecoupHandle *ph,
- const json_t *json)
-{
- struct TALER_EXCHANGE_RecoupResponse rr = {
- .hr.reply = json,
- .hr.http_status = MHD_HTTP_OK
- };
- struct GNUNET_JSON_Specification spec_withdraw[] = {
- GNUNET_JSON_spec_fixed_auto ("reserve_pub",
- &rr.details.ok.reserve_pub),
- GNUNET_JSON_spec_end ()
- };
-
- if (GNUNET_OK !=
- GNUNET_JSON_parse (json,
- spec_withdraw,
- NULL, NULL))
- {
- GNUNET_break_op (0);
- return GNUNET_SYSERR;
- }
- ph->cb (ph->cb_cls,
- &rr);
- return GNUNET_OK;
-}
-
-
-/**
- * Function called when we're done processing the
- * HTTP /recoup request.
- *
- * @param cls the `struct TALER_EXCHANGE_RecoupHandle`
- * @param response_code HTTP response code, 0 on error
- * @param response parsed JSON result, NULL on error
- */
-static void
-handle_recoup_finished (void *cls,
- long response_code,
- const void *response)
-{
- struct TALER_EXCHANGE_RecoupHandle *ph = cls;
- const json_t *j = response;
- struct TALER_EXCHANGE_RecoupResponse rr = {
- .hr.reply = j,
- .hr.http_status = (unsigned int) response_code
- };
-
- ph->job = NULL;
- switch (response_code)
- {
- case 0:
- rr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
- break;
- case MHD_HTTP_OK:
- if (GNUNET_OK !=
- process_recoup_response (ph,
- j))
- {
- GNUNET_break_op (0);
- rr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
- rr.hr.http_status = 0;
- break;
- }
- TALER_EXCHANGE_recoup_cancel (ph);
- return;
- case MHD_HTTP_BAD_REQUEST:
- /* This should never happen, either us or the exchange is buggy
- (or API version conflict); just pass JSON reply to the application */
- rr.hr.ec = TALER_JSON_get_error_code (j);
- rr.hr.hint = TALER_JSON_get_error_hint (j);
- break;
- case MHD_HTTP_CONFLICT:
- {
- struct TALER_Amount min_key;
-
- rr.hr.ec = TALER_JSON_get_error_code (j);
- rr.hr.hint = TALER_JSON_get_error_hint (j);
- if (GNUNET_OK !=
- TALER_EXCHANGE_get_min_denomination_ (ph->keys,
- &min_key))
- {
- GNUNET_break (0);
- rr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
- rr.hr.http_status = 0;
- break;
- }
- break;
- }
- case MHD_HTTP_FORBIDDEN:
- /* Nothing really to verify, exchange says one of the signatures is
- invalid; as we checked them, this should never happen, we
- should pass the JSON reply to the application */
- rr.hr.ec = TALER_JSON_get_error_code (j);
- rr.hr.hint = TALER_JSON_get_error_hint (j);
- break;
- case MHD_HTTP_NOT_FOUND:
- /* Nothing really to verify, this should never
- happen, we should pass the JSON reply to the application */
- rr.hr.ec = TALER_JSON_get_error_code (j);
- rr.hr.hint = TALER_JSON_get_error_hint (j);
- break;
- case MHD_HTTP_GONE:
- /* Kind of normal: the money was already sent to the merchant
- (it was too late for the refund). */
- rr.hr.ec = TALER_JSON_get_error_code (j);
- rr.hr.hint = TALER_JSON_get_error_hint (j);
- break;
- case MHD_HTTP_INTERNAL_SERVER_ERROR:
- /* Server had an internal issue; we should retry, but this API
- leaves this to the application */
- rr.hr.ec = TALER_JSON_get_error_code (j);
- rr.hr.hint = TALER_JSON_get_error_hint (j);
- break;
- default:
- /* unexpected response code */
- rr.hr.ec = TALER_JSON_get_error_code (j);
- rr.hr.hint = TALER_JSON_get_error_hint (j);
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Unexpected response code %u/%d for exchange recoup\n",
- (unsigned int) response_code,
- (int) rr.hr.ec);
- GNUNET_break (0);
- break;
- }
- ph->cb (ph->cb_cls,
- &rr);
- TALER_EXCHANGE_recoup_cancel (ph);
-}
-
-
-struct TALER_EXCHANGE_RecoupHandle *
-TALER_EXCHANGE_recoup (
- struct GNUNET_CURL_Context *ctx,
- const char *url,
- struct TALER_EXCHANGE_Keys *keys,
- const struct TALER_EXCHANGE_DenomPublicKey *pk,
- const struct TALER_DenominationSignature *denom_sig,
- const struct TALER_ExchangeWithdrawValues *exchange_vals,
- const struct TALER_PlanchetMasterSecretP *ps,
- TALER_EXCHANGE_RecoupResultCallback recoup_cb,
- void *recoup_cb_cls)
-{
- struct TALER_EXCHANGE_RecoupHandle *ph;
- struct TALER_DenominationHashP h_denom_pub;
- json_t *recoup_obj;
- CURL *eh;
- char arg_str[sizeof (struct TALER_CoinSpendPublicKeyP) * 2 + 32];
- struct TALER_CoinSpendPrivateKeyP coin_priv;
- union TALER_DenominationBlindingKeyP bks;
-
- ph = GNUNET_new (struct TALER_EXCHANGE_RecoupHandle);
- TALER_planchet_setup_coin_priv (ps,
- exchange_vals,
- &coin_priv);
- TALER_planchet_blinding_secret_create (ps,
- exchange_vals,
- &bks);
- GNUNET_CRYPTO_eddsa_key_get_public (&coin_priv.eddsa_priv,
- &ph->coin_pub.eddsa_pub);
- TALER_denom_pub_hash (&pk->key,
- &h_denom_pub);
- TALER_wallet_recoup_sign (&h_denom_pub,
- &bks,
- &coin_priv,
- &ph->coin_sig);
- recoup_obj = GNUNET_JSON_PACK (
- GNUNET_JSON_pack_data_auto ("denom_pub_hash",
- &h_denom_pub),
- TALER_JSON_pack_denom_sig ("denom_sig",
- denom_sig),
- TALER_JSON_pack_exchange_withdraw_values ("ewv",
- exchange_vals),
- GNUNET_JSON_pack_data_auto ("coin_sig",
- &ph->coin_sig),
- GNUNET_JSON_pack_data_auto ("coin_blind_key_secret",
- &bks));
- if (TALER_DENOMINATION_CS == denom_sig->cipher)
- {
- struct TALER_CsNonce nonce;
-
- /* NOTE: this is not elegant, and as per the note in TALER_coin_ev_hash()
- it is not strictly clear that the nonce is needed. Best case would be
- to find a way to include it more 'naturally' somehow, for example with
- the variant union version of bks! */
- TALER_cs_withdraw_nonce_derive (ps,
- &nonce);
- GNUNET_assert (
- 0 ==
- json_object_set_new (recoup_obj,
- "cs_nonce",
- GNUNET_JSON_from_data_auto (
- &nonce)));
- }
-
- {
- char pub_str[sizeof (struct TALER_CoinSpendPublicKeyP) * 2];
- char *end;
-
- end = GNUNET_STRINGS_data_to_string (
- &ph->coin_pub,
- sizeof (struct TALER_CoinSpendPublicKeyP),
- pub_str,
- sizeof (pub_str));
- *end = '\0';
- GNUNET_snprintf (arg_str,
- sizeof (arg_str),
- "coins/%s/recoup",
- pub_str);
- }
-
- ph->pk = *pk;
- memset (&ph->pk.key,
- 0,
- sizeof (ph->pk.key)); /* zero out, as lifetime cannot be warranted */
- ph->cb = recoup_cb;
- ph->cb_cls = recoup_cb_cls;
- ph->url = TALER_url_join (url,
- arg_str,
- NULL);
- if (NULL == ph->url)
- {
- json_decref (recoup_obj);
- GNUNET_free (ph);
- return NULL;
- }
- eh = TALER_EXCHANGE_curl_easy_get_ (ph->url);
- if ( (NULL == eh) ||
- (GNUNET_OK !=
- TALER_curl_easy_post (&ph->ctx,
- eh,
- recoup_obj)) )
- {
- GNUNET_break (0);
- if (NULL != eh)
- curl_easy_cleanup (eh);
- json_decref (recoup_obj);
- GNUNET_free (ph->url);
- GNUNET_free (ph);
- return NULL;
- }
- json_decref (recoup_obj);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "URL for recoup: `%s'\n",
- ph->url);
- ph->keys = TALER_EXCHANGE_keys_incref (keys);
- ph->job = GNUNET_CURL_job_add2 (ctx,
- eh,
- ph->ctx.headers,
- &handle_recoup_finished,
- ph);
- return ph;
-}
-
-
-void
-TALER_EXCHANGE_recoup_cancel (struct TALER_EXCHANGE_RecoupHandle *ph)
-{
- if (NULL != ph->job)
- {
- GNUNET_CURL_job_cancel (ph->job);
- ph->job = NULL;
- }
- GNUNET_free (ph->url);
- TALER_curl_easy_post_finished (&ph->ctx);
- TALER_EXCHANGE_keys_decref (ph->keys);
- GNUNET_free (ph);
-}
-
-
-/* end of exchange_api_recoup.c */
diff --git a/src/lib/exchange_api_recoup_refresh.c b/src/lib/exchange_api_recoup_refresh.c
deleted file mode 100644
index 0bcd44dec..000000000
--- a/src/lib/exchange_api_recoup_refresh.c
+++ /dev/null
@@ -1,363 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2017-2023 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software
- Foundation; either version 3, or (at your option) any later version.
-
- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- TALER; see the file COPYING. If not, see
- <http://www.gnu.org/licenses/>
-*/
-/**
- * @file lib/exchange_api_recoup_refresh.c
- * @brief Implementation of the /recoup-refresh request of the exchange's HTTP API
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include <jansson.h>
-#include <microhttpd.h> /* just for HTTP status codes */
-#include <gnunet/gnunet_util_lib.h>
-#include <gnunet/gnunet_json_lib.h>
-#include <gnunet/gnunet_curl_lib.h>
-#include "taler_json_lib.h"
-#include "taler_exchange_service.h"
-#include "exchange_api_common.h"
-#include "exchange_api_handle.h"
-#include "taler_signatures.h"
-#include "exchange_api_curl_defaults.h"
-
-
-/**
- * @brief A Recoup Handle
- */
-struct TALER_EXCHANGE_RecoupRefreshHandle
-{
-
- /**
- * The keys of the exchange this request handle will use
- */
- struct TALER_EXCHANGE_Keys *keys;
-
- /**
- * The url for this request.
- */
- char *url;
-
- /**
- * Context for #TEH_curl_easy_post(). Keeps the data that must
- * persist for Curl to make the upload.
- */
- struct TALER_CURL_PostContext ctx;
-
- /**
- * Denomination key of the coin.
- */
- struct TALER_EXCHANGE_DenomPublicKey pk;
-
- /**
- * Handle for the request.
- */
- struct GNUNET_CURL_Job *job;
-
- /**
- * Function to call with the result.
- */
- TALER_EXCHANGE_RecoupRefreshResultCallback cb;
-
- /**
- * Closure for @a cb.
- */
- void *cb_cls;
-
- /**
- * Public key of the coin we are trying to get paid back.
- */
- struct TALER_CoinSpendPublicKeyP coin_pub;
-
- /**
- * Signature affirming the recoup-refresh operation.
- */
- struct TALER_CoinSpendSignatureP coin_sig;
-
-};
-
-
-/**
- * Parse a recoup-refresh response. If it is valid, call the callback.
- *
- * @param ph recoup handle
- * @param json json reply with the signature
- * @return #GNUNET_OK if the signature is valid and we called the callback;
- * #GNUNET_SYSERR if not (callback must still be called)
- */
-static enum GNUNET_GenericReturnValue
-process_recoup_response (
- const struct TALER_EXCHANGE_RecoupRefreshHandle *ph,
- const json_t *json)
-{
- struct TALER_EXCHANGE_RecoupRefreshResponse rrr = {
- .hr.reply = json,
- .hr.http_status = MHD_HTTP_OK
- };
- struct GNUNET_JSON_Specification spec_refresh[] = {
- GNUNET_JSON_spec_fixed_auto ("old_coin_pub",
- &rrr.details.ok.old_coin_pub),
- GNUNET_JSON_spec_end ()
- };
-
- if (GNUNET_OK !=
- GNUNET_JSON_parse (json,
- spec_refresh,
- NULL, NULL))
- {
- GNUNET_break_op (0);
- return GNUNET_SYSERR;
- }
- ph->cb (ph->cb_cls,
- &rrr);
- return GNUNET_OK;
-}
-
-
-/**
- * Function called when we're done processing the
- * HTTP /recoup-refresh request.
- *
- * @param cls the `struct TALER_EXCHANGE_RecoupRefreshHandle`
- * @param response_code HTTP response code, 0 on error
- * @param response parsed JSON result, NULL on error
- */
-static void
-handle_recoup_refresh_finished (void *cls,
- long response_code,
- const void *response)
-{
- struct TALER_EXCHANGE_RecoupRefreshHandle *ph = cls;
- const json_t *j = response;
- struct TALER_EXCHANGE_RecoupRefreshResponse rrr = {
- .hr.reply = j,
- .hr.http_status = (unsigned int) response_code
- };
-
- ph->job = NULL;
- switch (response_code)
- {
- case 0:
- rrr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
- break;
- case MHD_HTTP_OK:
- if (GNUNET_OK !=
- process_recoup_response (ph,
- j))
- {
- GNUNET_break_op (0);
- rrr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
- rrr.hr.http_status = 0;
- break;
- }
- TALER_EXCHANGE_recoup_refresh_cancel (ph);
- return;
- case MHD_HTTP_BAD_REQUEST:
- /* This should never happen, either us or the exchange is buggy
- (or API version conflict); just pass JSON reply to the application */
- rrr.hr.ec = TALER_JSON_get_error_code (j);
- rrr.hr.hint = TALER_JSON_get_error_hint (j);
- break;
- case MHD_HTTP_FORBIDDEN:
- /* Nothing really to verify, exchange says one of the signatures is
- invalid; as we checked them, this should never happen, we
- should pass the JSON reply to the application */
- rrr.hr.ec = TALER_JSON_get_error_code (j);
- rrr.hr.hint = TALER_JSON_get_error_hint (j);
- break;
- case MHD_HTTP_NOT_FOUND:
- /* Nothing really to verify, this should never
- happen, we should pass the JSON reply to the application */
- rrr.hr.ec = TALER_JSON_get_error_code (j);
- rrr.hr.hint = TALER_JSON_get_error_hint (j);
- break;
- case MHD_HTTP_CONFLICT:
- rrr.hr.ec = TALER_JSON_get_error_code (j);
- rrr.hr.hint = TALER_JSON_get_error_hint (j);
- break;
- case MHD_HTTP_GONE:
- /* Kind of normal: the money was already sent to the merchant
- (it was too late for the refund). */
- rrr.hr.ec = TALER_JSON_get_error_code (j);
- rrr.hr.hint = TALER_JSON_get_error_hint (j);
- break;
- case MHD_HTTP_INTERNAL_SERVER_ERROR:
- /* Server had an internal issue; we should retry, but this API
- leaves this to the application */
- rrr.hr.ec = TALER_JSON_get_error_code (j);
- rrr.hr.hint = TALER_JSON_get_error_hint (j);
- break;
- default:
- /* unexpected response code */
- rrr.hr.ec = TALER_JSON_get_error_code (j);
- rrr.hr.hint = TALER_JSON_get_error_hint (j);
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Unexpected response code %u/%d for exchange recoup\n",
- (unsigned int) response_code,
- (int) rrr.hr.ec);
- GNUNET_break (0);
- break;
- }
- ph->cb (ph->cb_cls,
- &rrr);
- TALER_EXCHANGE_recoup_refresh_cancel (ph);
-}
-
-
-struct TALER_EXCHANGE_RecoupRefreshHandle *
-TALER_EXCHANGE_recoup_refresh (
- struct GNUNET_CURL_Context *ctx,
- const char *url,
- struct TALER_EXCHANGE_Keys *keys,
- const struct TALER_EXCHANGE_DenomPublicKey *pk,
- const struct TALER_DenominationSignature *denom_sig,
- const struct TALER_ExchangeWithdrawValues *exchange_vals,
- const struct TALER_RefreshMasterSecretP *rms,
- const struct TALER_PlanchetMasterSecretP *ps,
- unsigned int idx,
- TALER_EXCHANGE_RecoupRefreshResultCallback recoup_cb,
- void *recoup_cb_cls)
-{
- struct TALER_EXCHANGE_RecoupRefreshHandle *ph;
- struct TALER_DenominationHashP h_denom_pub;
- json_t *recoup_obj;
- CURL *eh;
- char arg_str[sizeof (struct TALER_CoinSpendPublicKeyP) * 2 + 32];
- struct TALER_CoinSpendPrivateKeyP coin_priv;
- union TALER_DenominationBlindingKeyP bks;
-
- GNUNET_assert (NULL != recoup_cb);
- ph = GNUNET_new (struct TALER_EXCHANGE_RecoupRefreshHandle);
- ph->pk = *pk;
- memset (&ph->pk.key,
- 0,
- sizeof (ph->pk.key)); /* zero out, as lifetime cannot be warranted */
- ph->cb = recoup_cb;
- ph->cb_cls = recoup_cb_cls;
- TALER_planchet_setup_coin_priv (ps,
- exchange_vals,
- &coin_priv);
- TALER_planchet_blinding_secret_create (ps,
- exchange_vals,
- &bks);
- GNUNET_CRYPTO_eddsa_key_get_public (&coin_priv.eddsa_priv,
- &ph->coin_pub.eddsa_pub);
- TALER_denom_pub_hash (&pk->key,
- &h_denom_pub);
- TALER_wallet_recoup_refresh_sign (&h_denom_pub,
- &bks,
- &coin_priv,
- &ph->coin_sig);
- recoup_obj = GNUNET_JSON_PACK (
- GNUNET_JSON_pack_data_auto ("denom_pub_hash",
- &h_denom_pub),
- TALER_JSON_pack_denom_sig ("denom_sig",
- denom_sig),
- TALER_JSON_pack_exchange_withdraw_values ("ewv",
- exchange_vals),
- GNUNET_JSON_pack_data_auto ("coin_sig",
- &ph->coin_sig),
- GNUNET_JSON_pack_data_auto ("coin_blind_key_secret",
- &bks));
-
- if (TALER_DENOMINATION_CS == denom_sig->cipher)
- {
- struct TALER_CsNonce nonce;
-
- /* NOTE: this is not elegant, and as per the note in TALER_coin_ev_hash()
- it is not strictly clear that the nonce is needed. Best case would be
- to find a way to include it more 'naturally' somehow, for example with
- the variant union version of bks! */
- TALER_cs_refresh_nonce_derive (rms,
- idx,
- &nonce);
- GNUNET_assert (
- 0 ==
- json_object_set_new (recoup_obj,
- "cs_nonce",
- GNUNET_JSON_from_data_auto (
- &nonce)));
- }
-
- {
- char pub_str[sizeof (struct TALER_CoinSpendPublicKeyP) * 2];
- char *end;
-
- end = GNUNET_STRINGS_data_to_string (
- &ph->coin_pub,
- sizeof (struct TALER_CoinSpendPublicKeyP),
- pub_str,
- sizeof (pub_str));
- *end = '\0';
- GNUNET_snprintf (arg_str,
- sizeof (arg_str),
- "coins/%s/recoup-refresh",
- pub_str);
- }
-
- ph->url = TALER_url_join (url,
- arg_str,
- NULL);
- if (NULL == ph->url)
- {
- json_decref (recoup_obj);
- GNUNET_free (ph);
- return NULL;
- }
- eh = TALER_EXCHANGE_curl_easy_get_ (ph->url);
- if ( (NULL == eh) ||
- (GNUNET_OK !=
- TALER_curl_easy_post (&ph->ctx,
- eh,
- recoup_obj)) )
- {
- GNUNET_break (0);
- if (NULL != eh)
- curl_easy_cleanup (eh);
- json_decref (recoup_obj);
- GNUNET_free (ph->url);
- GNUNET_free (ph);
- return NULL;
- }
- json_decref (recoup_obj);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "URL for recoup-refresh: `%s'\n",
- ph->url);
- ph->keys = TALER_EXCHANGE_keys_incref (keys);
- ph->job = GNUNET_CURL_job_add2 (ctx,
- eh,
- ph->ctx.headers,
- &handle_recoup_refresh_finished,
- ph);
- return ph;
-}
-
-
-void
-TALER_EXCHANGE_recoup_refresh_cancel (
- struct TALER_EXCHANGE_RecoupRefreshHandle *ph)
-{
- if (NULL != ph->job)
- {
- GNUNET_CURL_job_cancel (ph->job);
- ph->job = NULL;
- }
- GNUNET_free (ph->url);
- TALER_curl_easy_post_finished (&ph->ctx);
- TALER_EXCHANGE_keys_decref (ph->keys);
- GNUNET_free (ph);
-}
-
-
-/* end of exchange_api_recoup_refresh.c */
diff --git a/src/lib/exchange_api_refresh_common.c b/src/lib/exchange_api_refresh_common.c
deleted file mode 100644
index 0a6665b55..000000000
--- a/src/lib/exchange_api_refresh_common.c
+++ /dev/null
@@ -1,249 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2015-2022 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software
- Foundation; either version 3, or (at your option) any later version.
-
- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- TALER; see the file COPYING. If not, see
- <http://www.gnu.org/licenses/>
-*/
-/**
- * @file lib/exchange_api_refresh_common.c
- * @brief Serialization logic shared between melt and reveal steps during refreshing
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include "exchange_api_refresh_common.h"
-
-
-void
-TALER_EXCHANGE_free_melt_data_ (struct MeltData *md)
-{
- for (unsigned int i = 0; i < TALER_CNC_KAPPA; i++)
- {
- struct TALER_RefreshCoinData *rcds = md->rcd[i];
-
- if (NULL == rcds)
- continue;
- for (unsigned int j = 0; j < md->num_fresh_coins; j++)
- TALER_blinded_planchet_free (&rcds[j].blinded_planchet);
- GNUNET_free (rcds);
- }
- TALER_denom_pub_free (&md->melted_coin.pub_key);
- TALER_denom_sig_free (&md->melted_coin.sig);
- if (NULL != md->fcds)
- {
- for (unsigned int j = 0; j<md->num_fresh_coins; j++)
- {
- struct FreshCoinData *fcd = &md->fcds[j];
-
- TALER_denom_pub_free (&fcd->fresh_pk);
- for (size_t i = 0; i < TALER_CNC_KAPPA; i++)
- {
- TALER_age_commitment_proof_free (fcd->age_commitment_proofs[i]);
- GNUNET_free (fcd->age_commitment_proofs[i]);
- }
- }
- GNUNET_free (md->fcds);
- }
- /* Finally, clean up a bit... */
- GNUNET_CRYPTO_zero_keys (md,
- sizeof (struct MeltData));
-}
-
-
-enum GNUNET_GenericReturnValue
-TALER_EXCHANGE_get_melt_data_ (
- const struct TALER_RefreshMasterSecretP *rms,
- const struct TALER_EXCHANGE_RefreshData *rd,
- const struct TALER_ExchangeWithdrawValues *alg_values,
- struct MeltData *md)
-{
- struct TALER_Amount total;
- struct TALER_CoinSpendPublicKeyP coin_pub;
- struct TALER_CsNonce nonces[rd->fresh_pks_len];
- bool uses_cs = false;
-
- GNUNET_CRYPTO_eddsa_key_get_public (&rd->melt_priv.eddsa_priv,
- &coin_pub.eddsa_pub);
- /* build up melt data structure */
- memset (md,
- 0,
- sizeof (*md));
- md->num_fresh_coins = rd->fresh_pks_len;
- md->melted_coin.coin_priv = rd->melt_priv;
- md->melted_coin.melt_amount_with_fee = rd->melt_amount;
- md->melted_coin.fee_melt = rd->melt_pk.fees.refresh;
- md->melted_coin.original_value = rd->melt_pk.value;
- md->melted_coin.expire_deposit = rd->melt_pk.expire_deposit;
- md->melted_coin.age_commitment_proof = rd->melt_age_commitment_proof;
- md->melted_coin.h_age_commitment = rd->melt_h_age_commitment;
-
- GNUNET_assert (GNUNET_OK ==
- TALER_amount_set_zero (rd->melt_amount.currency,
- &total));
- TALER_denom_pub_deep_copy (&md->melted_coin.pub_key,
- &rd->melt_pk.key);
- TALER_denom_sig_deep_copy (&md->melted_coin.sig,
- &rd->melt_sig);
- md->fcds = GNUNET_new_array (md->num_fresh_coins,
- struct FreshCoinData);
- for (unsigned int j = 0; j<rd->fresh_pks_len; j++)
- {
- struct FreshCoinData *fcd = &md->fcds[j];
-
- if (alg_values[j].cipher != rd->fresh_pks[j].key.cipher)
- {
- GNUNET_break (0);
- TALER_EXCHANGE_free_melt_data_ (md);
- return GNUNET_SYSERR;
- }
- if (TALER_DENOMINATION_CS == alg_values[j].cipher)
- {
- uses_cs = true;
- TALER_cs_refresh_nonce_derive (
- rms,
- j,
- &nonces[j]);
- }
- TALER_denom_pub_deep_copy (&fcd->fresh_pk,
- &rd->fresh_pks[j].key);
- if ( (0 >
- TALER_amount_add (&total,
- &total,
- &rd->fresh_pks[j].value)) ||
- (0 >
- TALER_amount_add (&total,
- &total,
- &rd->fresh_pks[j].fees.withdraw)) )
- {
- GNUNET_break (0);
- TALER_EXCHANGE_free_melt_data_ (md);
- return GNUNET_SYSERR;
- }
- }
-
- /* verify that melt_amount is above total cost */
- if (1 ==
- TALER_amount_cmp (&total,
- &rd->melt_amount) )
- {
- /* Eh, this operation is more expensive than the
- @a melt_amount. This is not OK. */
- GNUNET_break (0);
- TALER_EXCHANGE_free_melt_data_ (md);
- return GNUNET_SYSERR;
- }
-
- /* build up coins */
- for (unsigned int i = 0; i<TALER_CNC_KAPPA; i++)
- {
- struct TALER_TransferSecretP trans_sec;
-
- TALER_planchet_secret_to_transfer_priv (
- rms,
- &rd->melt_priv,
- i,
- &md->transfer_priv[i]);
-
- GNUNET_CRYPTO_ecdhe_key_get_public (
- &md->transfer_priv[i].ecdhe_priv,
- &md->transfer_pub[i].ecdhe_pub);
-
- TALER_link_derive_transfer_secret (&rd->melt_priv,
- &md->transfer_priv[i],
- &trans_sec);
-
- md->rcd[i] = GNUNET_new_array (rd->fresh_pks_len,
- struct TALER_RefreshCoinData);
-
- for (unsigned int j = 0; j<rd->fresh_pks_len; j++)
- {
- struct FreshCoinData *fcd = &md->fcds[j];
- struct TALER_CoinSpendPrivateKeyP *coin_priv = &fcd->coin_priv;
- struct TALER_PlanchetMasterSecretP *ps = &fcd->ps[i];
- struct TALER_RefreshCoinData *rcd = &md->rcd[i][j];
- union TALER_DenominationBlindingKeyP *bks = &fcd->bks[i];
- struct TALER_PlanchetDetail pd;
- struct TALER_CoinPubHashP c_hash;
- struct TALER_AgeCommitmentHash ach;
- struct TALER_AgeCommitmentHash *pah = NULL;
-
- TALER_transfer_secret_to_planchet_secret (&trans_sec,
- j,
- ps);
-
- TALER_planchet_setup_coin_priv (ps,
- &alg_values[j],
- coin_priv);
-
- TALER_planchet_blinding_secret_create (ps,
- &alg_values[j],
- bks);
-
- if (NULL != rd->melt_age_commitment_proof)
- {
- fcd->age_commitment_proofs[i] = GNUNET_new (struct
- TALER_AgeCommitmentProof);
-
- GNUNET_assert (GNUNET_OK ==
- TALER_age_commitment_derive (
- md->melted_coin.age_commitment_proof,
- &trans_sec.key,
- fcd->age_commitment_proofs[i]));
-
- TALER_age_commitment_hash (
- &fcd->age_commitment_proofs[i]->commitment,
- &ach);
- pah = &ach;
- }
-
- if (TALER_DENOMINATION_CS == alg_values[j].cipher)
- pd.blinded_planchet.details.cs_blinded_planchet.nonce = nonces[j];
-
- if (GNUNET_OK !=
- TALER_planchet_prepare (&fcd->fresh_pk,
- &alg_values[j],
- bks,
- coin_priv,
- pah,
- &c_hash,
- &pd))
- {
- GNUNET_break_op (0);
- TALER_EXCHANGE_free_melt_data_ (md);
- return GNUNET_SYSERR;
- }
- rcd->blinded_planchet = pd.blinded_planchet;
- rcd->dk = &fcd->fresh_pk;
- }
- }
-
- /* Finally, compute refresh commitment */
- {
- struct TALER_RefreshCommitmentEntry rce[TALER_CNC_KAPPA];
-
- for (unsigned int i = 0; i<TALER_CNC_KAPPA; i++)
- {
- rce[i].transfer_pub = md->transfer_pub[i];
- rce[i].new_coins = md->rcd[i];
- }
- TALER_refresh_get_commitment (&md->rc,
- TALER_CNC_KAPPA,
- uses_cs
- ? rms
- : NULL,
- rd->fresh_pks_len,
- rce,
- &coin_pub,
- &rd->melt_amount);
- }
- return GNUNET_OK;
-}
diff --git a/src/lib/exchange_api_refresh_common.h b/src/lib/exchange_api_refresh_common.h
deleted file mode 100644
index 0cb80f17e..000000000
--- a/src/lib/exchange_api_refresh_common.h
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2015-2022 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software
- Foundation; either version 3, or (at your option) any later version.
-
- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- TALER; see the file COPYING. If not, see
- <http://www.gnu.org/licenses/>
-*/
-/**
- * @file lib/exchange_api_refresh_common.h
- * @brief shared (serialization) logic for refresh protocol
- * @author Christian Grothoff
- */
-#ifndef REFRESH_COMMON_H
-#define REFRESH_COMMON_H
-#include <jansson.h>
-#include "taler_json_lib.h"
-#include "taler_exchange_service.h"
-#include "taler_signatures.h"
-
-
-/**
- * Information about a coin we are melting.
- */
-struct MeltedCoin
-{
- /**
- * Private key of the coin.
- */
- struct TALER_CoinSpendPrivateKeyP coin_priv;
-
- /**
- * Amount this coin contributes to the melt, including fee.
- */
- struct TALER_Amount melt_amount_with_fee;
-
- /**
- * The applicable fee for melting a coin of this denomination
- */
- struct TALER_Amount fee_melt;
-
- /**
- * The original value of the coin.
- */
- struct TALER_Amount original_value;
-
- /**
- * The original age commitment, its proof and its hash. MUST be NULL if no
- * age commitment was set.
- */
- const struct TALER_AgeCommitmentProof *age_commitment_proof;
- const struct TALER_AgeCommitmentHash *h_age_commitment;
-
- /**
- * Timestamp indicating when coins of this denomination become invalid.
- */
- struct GNUNET_TIME_Timestamp expire_deposit;
-
- /**
- * Denomination key of the original coin.
- */
- struct TALER_DenominationPublicKey pub_key;
-
- /**
- * Exchange's signature over the coin.
- */
- struct TALER_DenominationSignature sig;
-
-};
-
-
-/**
- * Data we keep for each fresh coin created in the
- * melt process.
- */
-struct FreshCoinData
-{
- /**
- * Denomination public key of the coin.
- */
- struct TALER_DenominationPublicKey fresh_pk;
-
- /**
- * Array of planchet secrets for the coins, depending
- * on the cut-and-choose.
- */
- struct TALER_PlanchetMasterSecretP ps[TALER_CNC_KAPPA];
-
- /**
- * Private key of the coin.
- */
- struct TALER_CoinSpendPrivateKeyP coin_priv;
-
- /**
- * Arrays of age commitments and proofs to be created, one for each
- * cut-and-choose dimension. NULL if age restriction is not applicable.
- */
- struct TALER_AgeCommitmentProof *age_commitment_proofs[TALER_CNC_KAPPA];
-
- /**
- * Blinding key secrets for the coins, depending on the
- * cut-and-choose.
- */
- union TALER_DenominationBlindingKeyP bks[TALER_CNC_KAPPA];
-
-};
-
-
-/**
- * Melt data in non-serialized format for convenient processing.
- */
-struct MeltData
-{
-
- /**
- * Hash over the committed data during refresh operation.
- */
- struct TALER_RefreshCommitmentP rc;
-
- /**
- * Information about the melted coin.
- */
- struct MeltedCoin melted_coin;
-
- /**
- * Array of length @e num_fresh_coins with information
- * about each fresh coin.
- */
- struct FreshCoinData *fcds;
-
- /**
- * Transfer secrets, one per cut and choose.
- */
- struct TALER_TransferSecretP trans_sec[TALER_CNC_KAPPA];
-
- /**
- * Transfer private keys for each cut-and-choose dimension.
- */
- struct TALER_TransferPrivateKeyP transfer_priv[TALER_CNC_KAPPA];
-
- /**
- * Transfer public key of this commitment.
- */
- struct TALER_TransferPublicKeyP transfer_pub[TALER_CNC_KAPPA];
-
- /**
- * Transfer secrets, one per cut and choose.
- */
- struct TALER_RefreshCommitmentEntry rce[TALER_CNC_KAPPA];
-
- /**
- * Blinded planchets and denominations of the fresh coins, depending on the cut-and-choose. Array of length
- * @e num_fresh_coins.
- */
- struct TALER_RefreshCoinData *rcd[TALER_CNC_KAPPA];
-
- /**
- * Number of coins we are creating
- */
- uint16_t num_fresh_coins;
-
-};
-
-
-/**
- * Compute the melt data from the refresh data and secret.
- *
- * @param rms secret internals of the refresh-reveal operation
- * @param rd refresh data with the characteristics of the operation
- * @param alg_values contributions from the exchange into the melt
- * @param[out] md where to write the derived melt data
- */
-enum GNUNET_GenericReturnValue
-TALER_EXCHANGE_get_melt_data_ (
- const struct TALER_RefreshMasterSecretP *rms,
- const struct TALER_EXCHANGE_RefreshData *rd,
- const struct TALER_ExchangeWithdrawValues *alg_values,
- struct MeltData *md);
-
-
-/**
- * Free all information associated with a melting session. Note
- * that we allow the melting session to be only partially initialized,
- * as we use this function also when freeing melt data that was not
- * fully initialized.
- *
- * @param[in] md melting data to release, the pointer itself is NOT
- * freed (as it is typically not allocated by itself)
- */
-void
-TALER_EXCHANGE_free_melt_data_ (struct MeltData *md);
-
-#endif
diff --git a/src/lib/exchange_api_refreshes_reveal.c b/src/lib/exchange_api_refreshes_reveal.c
deleted file mode 100644
index 220682992..000000000
--- a/src/lib/exchange_api_refreshes_reveal.c
+++ /dev/null
@@ -1,531 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2015-2023 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software
- Foundation; either version 3, or (at your option) any later version.
-
- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- TALER; see the file COPYING. If not, see
- <http://www.gnu.org/licenses/>
-*/
-/**
- * @file lib/exchange_api_refreshes_reveal.c
- * @brief Implementation of the /refreshes/$RCH/reveal requests
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include <jansson.h>
-#include <microhttpd.h> /* just for HTTP status codes */
-#include <gnunet/gnunet_util_lib.h>
-#include <gnunet/gnunet_json_lib.h>
-#include <gnunet/gnunet_curl_lib.h>
-#include "taler_json_lib.h"
-#include "taler_exchange_service.h"
-#include "exchange_api_handle.h"
-#include "taler_signatures.h"
-#include "exchange_api_curl_defaults.h"
-#include "exchange_api_refresh_common.h"
-
-
-/**
- * @brief A /refreshes/$RCH/reveal Handle
- */
-struct TALER_EXCHANGE_RefreshesRevealHandle
-{
-
- /**
- * The url for this request.
- */
- char *url;
-
- /**
- * Context for #TEH_curl_easy_post(). Keeps the data that must
- * persist for Curl to make the upload.
- */
- struct TALER_CURL_PostContext ctx;
-
- /**
- * Handle for the request.
- */
- struct GNUNET_CURL_Job *job;
-
- /**
- * Exchange-contributed values to the operation.
- */
- struct TALER_ExchangeWithdrawValues *alg_values;
-
- /**
- * Function to call with the result.
- */
- TALER_EXCHANGE_RefreshesRevealCallback reveal_cb;
-
- /**
- * Closure for @e reveal_cb.
- */
- void *reveal_cb_cls;
-
- /**
- * Actual information about the melt operation.
- */
- struct MeltData md;
-
- /**
- * The index selected by the exchange in cut-and-choose to not be revealed.
- */
- uint16_t noreveal_index;
-
-};
-
-
-/**
- * We got a 200 OK response for the /refreshes/$RCH/reveal operation. Extract
- * the coin signatures and return them to the caller. The signatures we get
- * from the exchange is for the blinded value. Thus, we first must unblind
- * them and then should verify their validity.
- *
- * If everything checks out, we return the unblinded signatures
- * to the application via the callback.
- *
- * @param rrh operation handle
- * @param json reply from the exchange
- * @param[out] rcis array of length `num_fresh_coins`, initialized to contain the coin data
- * @return #GNUNET_OK on success, #GNUNET_SYSERR on errors
- */
-static enum GNUNET_GenericReturnValue
-refresh_reveal_ok (struct TALER_EXCHANGE_RefreshesRevealHandle *rrh,
- const json_t *json,
- struct TALER_EXCHANGE_RevealedCoinInfo *rcis)
-{
- const json_t *jsona;
- struct GNUNET_JSON_Specification outer_spec[] = {
- GNUNET_JSON_spec_array_const ("ev_sigs",
- &jsona),
- GNUNET_JSON_spec_end ()
- };
-
- if (GNUNET_OK !=
- GNUNET_JSON_parse (json,
- outer_spec,
- NULL, NULL))
- {
- GNUNET_break_op (0);
- return GNUNET_SYSERR;
- }
- if (rrh->md.num_fresh_coins != json_array_size (jsona))
- {
- /* Number of coins generated does not match our expectation */
- GNUNET_break_op (0);
- return GNUNET_SYSERR;
- }
- for (unsigned int i = 0; i<rrh->md.num_fresh_coins; i++)
- {
- struct TALER_EXCHANGE_RevealedCoinInfo *rci = &rcis[i];
- const struct FreshCoinData *fcd = &rrh->md.fcds[i];
- const struct TALER_DenominationPublicKey *pk;
- json_t *jsonai;
- struct TALER_BlindedDenominationSignature blind_sig;
- struct TALER_CoinSpendPublicKeyP coin_pub;
- struct TALER_CoinPubHashP coin_hash;
- struct GNUNET_JSON_Specification spec[] = {
- TALER_JSON_spec_blinded_denom_sig ("ev_sig",
- &blind_sig),
- GNUNET_JSON_spec_end ()
- };
- struct TALER_FreshCoin coin;
- union TALER_DenominationBlindingKeyP bks;
- const struct TALER_AgeCommitmentHash *pah = NULL;
-
- rci->ps = fcd->ps[rrh->noreveal_index];
- rci->bks = fcd->bks[rrh->noreveal_index];
- rci->age_commitment_proof = NULL;
-
- pk = &fcd->fresh_pk;
- jsonai = json_array_get (jsona, i);
-
- GNUNET_assert (NULL != jsonai);
-
- if (NULL != rrh->md.melted_coin.age_commitment_proof)
- {
- rci->age_commitment_proof =
- fcd->age_commitment_proofs[rrh->noreveal_index];
-
- TALER_age_commitment_hash (&rci->age_commitment_proof->commitment,
- &rci->h_age_commitment);
- pah = &rci->h_age_commitment;
- }
-
- if (GNUNET_OK !=
- GNUNET_JSON_parse (jsonai,
- spec,
- NULL, NULL))
- {
- GNUNET_break_op (0);
- return GNUNET_SYSERR;
- }
-
- TALER_planchet_setup_coin_priv (&rci->ps,
- &rrh->alg_values[i],
- &rci->coin_priv);
- TALER_planchet_blinding_secret_create (&rci->ps,
- &rrh->alg_values[i],
- &bks);
- /* needed to verify the signature, and we didn't store it earlier,
- hence recomputing it here... */
- GNUNET_CRYPTO_eddsa_key_get_public (&rci->coin_priv.eddsa_priv,
- &coin_pub.eddsa_pub);
- TALER_coin_pub_hash (
- &coin_pub,
- pah,
- &coin_hash);
- if (GNUNET_OK !=
- TALER_planchet_to_coin (
- pk,
- &blind_sig,
- &bks,
- &rci->coin_priv,
- pah,
- &coin_hash,
- &rrh->alg_values[i],
- &coin))
- {
- GNUNET_break_op (0);
- GNUNET_JSON_parse_free (spec);
- return GNUNET_SYSERR;
- }
- GNUNET_JSON_parse_free (spec);
- rci->sig = coin.sig;
- }
- return GNUNET_OK;
-}
-
-
-/**
- * Function called when we're done processing the
- * HTTP /refreshes/$RCH/reveal request.
- *
- * @param cls the `struct TALER_EXCHANGE_RefreshHandle`
- * @param response_code HTTP response code, 0 on error
- * @param response parsed JSON result, NULL on error
- */
-static void
-handle_refresh_reveal_finished (void *cls,
- long response_code,
- const void *response)
-{
- struct TALER_EXCHANGE_RefreshesRevealHandle *rrh = cls;
- const json_t *j = response;
- struct TALER_EXCHANGE_RevealResult rr = {
- .hr.reply = j,
- .hr.http_status = (unsigned int) response_code
- };
-
- rrh->job = NULL;
- switch (response_code)
- {
- case 0:
- rr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
- break;
- case MHD_HTTP_OK:
- {
- struct TALER_EXCHANGE_RevealedCoinInfo rcis[rrh->md.num_fresh_coins];
- enum GNUNET_GenericReturnValue ret;
-
- memset (rcis,
- 0,
- sizeof (rcis));
- ret = refresh_reveal_ok (rrh,
- j,
- rcis);
- if (GNUNET_OK != ret)
- {
- rr.hr.http_status = 0;
- rr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
- break;
- }
- else
- {
- GNUNET_assert (rrh->noreveal_index < TALER_CNC_KAPPA);
- rr.details.ok.num_coins = rrh->md.num_fresh_coins;
- rr.details.ok.coins = rcis;
- rrh->reveal_cb (rrh->reveal_cb_cls,
- &rr);
- rrh->reveal_cb = NULL;
- }
- for (unsigned int i = 0; i<rrh->md.num_fresh_coins; i++)
- {
- TALER_denom_sig_free (&rcis[i].sig);
- TALER_age_commitment_proof_free (rcis[i].age_commitment_proof);
- }
- TALER_EXCHANGE_refreshes_reveal_cancel (rrh);
- return;
- }
- case MHD_HTTP_BAD_REQUEST:
- /* This should never happen, either us or the exchange is buggy
- (or API version conflict); just pass JSON reply to the application */
- rr.hr.ec = TALER_JSON_get_error_code (j);
- rr.hr.hint = TALER_JSON_get_error_hint (j);
- break;
- case MHD_HTTP_CONFLICT:
- /* Nothing really to verify, exchange says our reveal is inconsistent
- with our commitment, so either side is buggy; we
- should pass the JSON reply to the application */
- rr.hr.ec = TALER_JSON_get_error_code (j);
- rr.hr.hint = TALER_JSON_get_error_hint (j);
- break;
- case MHD_HTTP_GONE:
- /* Server claims key expired or has been revoked */
- rr.hr.ec = TALER_JSON_get_error_code (j);
- rr.hr.hint = TALER_JSON_get_error_hint (j);
- break;
- case MHD_HTTP_INTERNAL_SERVER_ERROR:
- /* Server had an internal issue; we should retry, but this API
- leaves this to the application */
- rr.hr.ec = TALER_JSON_get_error_code (j);
- rr.hr.hint = TALER_JSON_get_error_hint (j);
- break;
- default:
- /* unexpected response code */
- GNUNET_break_op (0);
- rr.hr.ec = TALER_JSON_get_error_code (j);
- rr.hr.hint = TALER_JSON_get_error_hint (j);
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Unexpected response code %u/%d for exchange refreshes reveal\n",
- (unsigned int) response_code,
- (int) rr.hr.ec);
- break;
- }
- if (NULL != rrh->reveal_cb)
- rrh->reveal_cb (rrh->reveal_cb_cls,
- &rr);
- TALER_EXCHANGE_refreshes_reveal_cancel (rrh);
-}
-
-
-struct TALER_EXCHANGE_RefreshesRevealHandle *
-TALER_EXCHANGE_refreshes_reveal (
- struct GNUNET_CURL_Context *ctx,
- const char *url,
- const struct TALER_RefreshMasterSecretP *rms,
- const struct TALER_EXCHANGE_RefreshData *rd,
- unsigned int num_coins,
- const struct TALER_ExchangeWithdrawValues alg_values[static num_coins],
- uint32_t noreveal_index,
- TALER_EXCHANGE_RefreshesRevealCallback reveal_cb,
- void *reveal_cb_cls)
-{
- struct TALER_EXCHANGE_RefreshesRevealHandle *rrh;
- json_t *transfer_privs;
- json_t *new_denoms_h;
- json_t *coin_evs;
- json_t *reveal_obj;
- json_t *link_sigs;
- json_t *old_age_commitment = NULL;
- CURL *eh;
- struct MeltData md;
- char arg_str[sizeof (struct TALER_RefreshCommitmentP) * 2 + 32];
- bool send_rms = false;
-
- GNUNET_assert (num_coins == rd->fresh_pks_len);
- if (noreveal_index >= TALER_CNC_KAPPA)
- {
- /* We check this here, as it would be really bad to below just
- disclose all the transfer keys. Note that this error should
- have been caught way earlier when the exchange replied, but maybe
- we had some internal corruption that changed the value... */
- GNUNET_break (0);
- return NULL;
- }
- if (GNUNET_OK !=
- TALER_EXCHANGE_get_melt_data_ (rms,
- rd,
- alg_values,
- &md))
- {
- GNUNET_break (0);
- return NULL;
- }
-
- /* now new_denoms */
- GNUNET_assert (NULL != (new_denoms_h = json_array ()));
- GNUNET_assert (NULL != (coin_evs = json_array ()));
- GNUNET_assert (NULL != (link_sigs = json_array ()));
- for (unsigned int i = 0; i<md.num_fresh_coins; i++)
- {
- const struct TALER_RefreshCoinData *rcd = &md.rcd[noreveal_index][i];
- struct TALER_DenominationHashP denom_hash;
-
- if (TALER_DENOMINATION_CS == md.fcds[i].fresh_pk.cipher)
- send_rms = true;
- TALER_denom_pub_hash (&md.fcds[i].fresh_pk,
- &denom_hash);
- GNUNET_assert (0 ==
- json_array_append_new (new_denoms_h,
- GNUNET_JSON_from_data_auto (
- &denom_hash)));
- GNUNET_assert (0 ==
- json_array_append_new (
- coin_evs,
- GNUNET_JSON_PACK (
- TALER_JSON_pack_blinded_planchet (
- NULL,
- &rcd->blinded_planchet))));
- {
- struct TALER_CoinSpendSignatureP link_sig;
- struct TALER_BlindedCoinHashP bch;
-
- TALER_coin_ev_hash (&rcd->blinded_planchet,
- &denom_hash,
- &bch);
- TALER_wallet_link_sign (
- &denom_hash,
- &md.transfer_pub[noreveal_index],
- &bch,
- &md.melted_coin.coin_priv,
- &link_sig);
- GNUNET_assert (0 ==
- json_array_append_new (
- link_sigs,
- GNUNET_JSON_from_data_auto (&link_sig)));
- }
- }
-
- /* build array of transfer private keys */
- GNUNET_assert (NULL != (transfer_privs = json_array ()));
- for (unsigned int j = 0; j<TALER_CNC_KAPPA; j++)
- {
- if (j == noreveal_index)
- {
- /* This is crucial: exclude the transfer key for the noreval index! */
- continue;
- }
- GNUNET_assert (0 ==
- json_array_append_new (transfer_privs,
- GNUNET_JSON_from_data_auto (
- &md.transfer_priv[j])));
- }
-
- /* build array of old age commitment, if applicable */
- if (NULL != rd->melt_age_commitment_proof)
- {
- GNUNET_assert (NULL != rd->melt_h_age_commitment);
- GNUNET_assert (NULL != (old_age_commitment = json_array ()));
-
- for (size_t i = 0; i < rd->melt_age_commitment_proof->commitment.num; i++)
- {
- enum GNUNET_GenericReturnValue ret;
- ret = json_array_append_new (
- old_age_commitment,
- GNUNET_JSON_from_data_auto (
- &rd->melt_age_commitment_proof->commitment.keys[i]));
- GNUNET_assert (0 == ret);
- }
- }
-
- /* build main JSON request */
- reveal_obj = GNUNET_JSON_PACK (
- GNUNET_JSON_pack_data_auto ("transfer_pub",
- &md.transfer_pub[noreveal_index]),
- GNUNET_JSON_pack_allow_null (
- send_rms
- ? GNUNET_JSON_pack_data_auto ("rms",
- rms)
- : GNUNET_JSON_pack_string ("rms",
- NULL)),
- GNUNET_JSON_pack_allow_null (
- GNUNET_JSON_pack_array_steal ("old_age_commitment",
- old_age_commitment)),
- GNUNET_JSON_pack_array_steal ("transfer_privs",
- transfer_privs),
- GNUNET_JSON_pack_array_steal ("link_sigs",
- link_sigs),
- GNUNET_JSON_pack_array_steal ("new_denoms_h",
- new_denoms_h),
- GNUNET_JSON_pack_array_steal ("coin_evs",
- coin_evs));
- {
- char pub_str[sizeof (struct TALER_RefreshCommitmentP) * 2];
- char *end;
-
- end = GNUNET_STRINGS_data_to_string (&md.rc,
- sizeof (md.rc),
- pub_str,
- sizeof (pub_str));
- *end = '\0';
- GNUNET_snprintf (arg_str,
- sizeof (arg_str),
- "refreshes/%s/reveal",
- pub_str);
- }
- /* finally, we can actually issue the request */
- rrh = GNUNET_new (struct TALER_EXCHANGE_RefreshesRevealHandle);
- rrh->noreveal_index = noreveal_index;
- rrh->reveal_cb = reveal_cb;
- rrh->reveal_cb_cls = reveal_cb_cls;
- rrh->md = md;
- rrh->alg_values
- = GNUNET_memdup (alg_values,
- md.num_fresh_coins
- * sizeof (struct TALER_ExchangeWithdrawValues));
- rrh->url = TALER_url_join (url,
- arg_str,
- NULL);
- if (NULL == rrh->url)
- {
- json_decref (reveal_obj);
- TALER_EXCHANGE_free_melt_data_ (&md);
- GNUNET_free (rrh->alg_values);
- GNUNET_free (rrh);
- return NULL;
- }
-
- eh = TALER_EXCHANGE_curl_easy_get_ (rrh->url);
- if ( (NULL == eh) ||
- (GNUNET_OK !=
- TALER_curl_easy_post (&rrh->ctx,
- eh,
- reveal_obj)) )
- {
- GNUNET_break (0);
- if (NULL != eh)
- curl_easy_cleanup (eh);
- json_decref (reveal_obj);
- TALER_EXCHANGE_free_melt_data_ (&md);
- GNUNET_free (rrh->alg_values);
- GNUNET_free (rrh->url);
- GNUNET_free (rrh);
- return NULL;
- }
- json_decref (reveal_obj);
- rrh->job = GNUNET_CURL_job_add2 (ctx,
- eh,
- rrh->ctx.headers,
- &handle_refresh_reveal_finished,
- rrh);
- return rrh;
-}
-
-
-void
-TALER_EXCHANGE_refreshes_reveal_cancel (
- struct TALER_EXCHANGE_RefreshesRevealHandle *rrh)
-{
- if (NULL != rrh->job)
- {
- GNUNET_CURL_job_cancel (rrh->job);
- rrh->job = NULL;
- }
- GNUNET_free (rrh->alg_values);
- GNUNET_free (rrh->url);
- TALER_curl_easy_post_finished (&rrh->ctx);
- TALER_EXCHANGE_free_melt_data_ (&rrh->md);
- GNUNET_free (rrh);
-}
-
-
-/* exchange_api_refreshes_reveal.c */
diff --git a/src/lib/exchange_api_refund.c b/src/lib/exchange_api_refund.c
deleted file mode 100644
index 7401bfe4f..000000000
--- a/src/lib/exchange_api_refund.c
+++ /dev/null
@@ -1,480 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2014-2023 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software
- Foundation; either version 3, or (at your option) any later version.
-
- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- TALER; see the file COPYING. If not, see
- <http://www.gnu.org/licenses/>
-*/
-/**
- * @file lib/exchange_api_refund.c
- * @brief Implementation of the /refund request of the exchange's HTTP API
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include <jansson.h>
-#include <microhttpd.h> /* just for HTTP status codes */
-#include <gnunet/gnunet_util_lib.h>
-#include <gnunet/gnunet_json_lib.h>
-#include <gnunet/gnunet_curl_lib.h>
-#include "taler_json_lib.h"
-#include "taler_exchange_service.h"
-#include "exchange_api_handle.h"
-#include "taler_signatures.h"
-#include "exchange_api_curl_defaults.h"
-
-
-/**
- * @brief A Refund Handle
- */
-struct TALER_EXCHANGE_RefundHandle
-{
-
- /**
- * The keys of the exchange this request handle will use
- */
- struct TALER_EXCHANGE_Keys *keys;
-
- /**
- * The url for this request.
- */
- char *url;
-
- /**
- * Context for #TEH_curl_easy_post(). Keeps the data that must
- * persist for Curl to make the upload.
- */
- struct TALER_CURL_PostContext ctx;
-
- /**
- * Handle for the request.
- */
- struct GNUNET_CURL_Job *job;
-
- /**
- * Function to call with the result.
- */
- TALER_EXCHANGE_RefundCallback cb;
-
- /**
- * Closure for @a cb.
- */
- void *cb_cls;
-
- /**
- * Hash over the proposal data to identify the contract
- * which is being refunded.
- */
- struct TALER_PrivateContractHashP h_contract_terms;
-
- /**
- * The coin's public key. This is the value that must have been
- * signed (blindly) by the Exchange.
- */
- struct TALER_CoinSpendPublicKeyP coin_pub;
-
- /**
- * The Merchant's public key. Allows the merchant to later refund
- * the transaction or to inquire about the wire transfer identifier.
- */
- struct TALER_MerchantPublicKeyP merchant;
-
- /**
- * Merchant-generated transaction ID for the refund.
- */
- uint64_t rtransaction_id;
-
- /**
- * Amount to be refunded, including refund fee charged by the
- * exchange to the customer.
- */
- struct TALER_Amount refund_amount;
-
-};
-
-
-/**
- * Verify that the signature on the "200 OK" response
- * from the exchange is valid.
- *
- * @param[in,out] rh refund handle (refund fee added)
- * @param json json reply with the signature
- * @param[out] exchange_pub set to the exchange's public key
- * @param[out] exchange_sig set to the exchange's signature
- * @return #GNUNET_OK if the signature is valid, #GNUNET_SYSERR if not
- */
-static enum GNUNET_GenericReturnValue
-verify_refund_signature_ok (struct TALER_EXCHANGE_RefundHandle *rh,
- const json_t *json,
- struct TALER_ExchangePublicKeyP *exchange_pub,
- struct TALER_ExchangeSignatureP *exchange_sig)
-{
- struct GNUNET_JSON_Specification spec[] = {
- GNUNET_JSON_spec_fixed_auto ("exchange_sig",
- exchange_sig),
- GNUNET_JSON_spec_fixed_auto ("exchange_pub",
- exchange_pub),
- GNUNET_JSON_spec_end ()
- };
-
- if (GNUNET_OK !=
- GNUNET_JSON_parse (json,
- spec,
- NULL, NULL))
- {
- GNUNET_break_op (0);
- return GNUNET_SYSERR;
- }
- if (GNUNET_OK !=
- TALER_EXCHANGE_test_signing_key (rh->keys,
- exchange_pub))
- {
- GNUNET_break_op (0);
- return GNUNET_SYSERR;
- }
- if (GNUNET_OK !=
- TALER_exchange_online_refund_confirmation_verify (
- &rh->h_contract_terms,
- &rh->coin_pub,
- &rh->merchant,
- rh->rtransaction_id,
- &rh->refund_amount,
- exchange_pub,
- exchange_sig))
- {
- GNUNET_break_op (0);
- return GNUNET_SYSERR;
- }
- return GNUNET_OK;
-}
-
-
-/**
- * Verify that the information on the "412 Dependency Failed" response
- * from the exchange is valid and indeed shows that there is a refund
- * transaction ID reuse going on.
- *
- * @param[in,out] rh refund handle (refund fee added)
- * @param json json reply with the signature
- * @return #GNUNET_OK if the signature is valid, #GNUNET_SYSERR if not
- */
-static enum GNUNET_GenericReturnValue
-verify_failed_dependency_ok (struct TALER_EXCHANGE_RefundHandle *rh,
- const json_t *json)
-{
- const json_t *h;
- json_t *e;
- struct GNUNET_JSON_Specification spec[] = {
- GNUNET_JSON_spec_array_const ("history",
- &h),
- GNUNET_JSON_spec_end ()
- };
-
- if (GNUNET_OK !=
- GNUNET_JSON_parse (json,
- spec,
- NULL, NULL))
- {
- GNUNET_break_op (0);
- return GNUNET_SYSERR;
- }
- if (1 != json_array_size (h))
- {
- GNUNET_break_op (0);
- return GNUNET_SYSERR;
- }
- e = json_array_get (h, 0);
- {
- struct TALER_Amount amount;
- const char *type;
- struct TALER_MerchantSignatureP sig;
- struct TALER_Amount refund_fee;
- struct TALER_PrivateContractHashP h_contract_terms;
- uint64_t rtransaction_id;
- struct TALER_MerchantPublicKeyP merchant_pub;
- struct GNUNET_JSON_Specification ispec[] = {
- TALER_JSON_spec_amount_any ("amount",
- &amount),
- GNUNET_JSON_spec_string ("type",
- &type),
- TALER_JSON_spec_amount_any ("refund_fee",
- &refund_fee),
- GNUNET_JSON_spec_fixed_auto ("merchant_sig",
- &sig),
- GNUNET_JSON_spec_fixed_auto ("h_contract_terms",
- &h_contract_terms),
- GNUNET_JSON_spec_fixed_auto ("merchant_pub",
- &merchant_pub),
- GNUNET_JSON_spec_uint64 ("rtransaction_id",
- &rtransaction_id),
- GNUNET_JSON_spec_end ()
- };
-
- if (GNUNET_OK !=
- GNUNET_JSON_parse (e,
- ispec,
- NULL, NULL))
- {
- GNUNET_break_op (0);
- return GNUNET_SYSERR;
- }
- if (GNUNET_OK !=
- TALER_merchant_refund_verify (&rh->coin_pub,
- &h_contract_terms,
- rtransaction_id,
- &amount,
- &merchant_pub,
- &sig))
- {
- GNUNET_break_op (0);
- return GNUNET_SYSERR;
- }
- if ( (rtransaction_id != rh->rtransaction_id) ||
- (0 != GNUNET_memcmp (&rh->h_contract_terms,
- &h_contract_terms)) ||
- (0 != GNUNET_memcmp (&rh->merchant,
- &merchant_pub)) ||
- (0 == TALER_amount_cmp (&rh->refund_amount,
- &amount)) )
- {
- GNUNET_break_op (0);
- return GNUNET_SYSERR;
- }
- }
- return GNUNET_OK;
-}
-
-
-/**
- * Function called when we're done processing the
- * HTTP /refund request.
- *
- * @param cls the `struct TALER_EXCHANGE_RefundHandle`
- * @param response_code HTTP response code, 0 on error
- * @param response parsed JSON result, NULL on error
- */
-static void
-handle_refund_finished (void *cls,
- long response_code,
- const void *response)
-{
- struct TALER_EXCHANGE_RefundHandle *rh = cls;
- const json_t *j = response;
- struct TALER_EXCHANGE_RefundResponse rr = {
- .hr.reply = j,
- .hr.http_status = (unsigned int) response_code
- };
-
- rh->job = NULL;
- switch (response_code)
- {
- case 0:
- rr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
- break;
- case MHD_HTTP_OK:
- if (GNUNET_OK !=
- verify_refund_signature_ok (rh,
- j,
- &rr.details.ok.exchange_pub,
- &rr.details.ok.exchange_sig))
- {
- GNUNET_break_op (0);
- rr.hr.http_status = 0;
- rr.hr.ec = TALER_EC_EXCHANGE_REFUND_INVALID_SIGNATURE_BY_EXCHANGE;
- }
- break;
- case MHD_HTTP_BAD_REQUEST:
- /* This should never happen, either us or the exchange is buggy
- (or API version conflict); also can happen if the currency
- differs (which we should obviously never support).
- Just pass JSON reply to the application */
- rr.hr.ec = TALER_JSON_get_error_code (j);
- rr.hr.hint = TALER_JSON_get_error_hint (j);
- break;
- case MHD_HTTP_FORBIDDEN:
- /* Nothing really to verify, exchange says one of the signatures is
- invalid; as we checked them, this should never happen, we
- should pass the JSON reply to the application */
- rr.hr.ec = TALER_JSON_get_error_code (j);
- rr.hr.hint = TALER_JSON_get_error_hint (j);
- break;
- case MHD_HTTP_NOT_FOUND:
- /* Nothing really to verify, this should never
- happen, we should pass the JSON reply to the application */
- rr.hr.ec = TALER_JSON_get_error_code (j);
- rr.hr.hint = TALER_JSON_get_error_hint (j);
- break;
- case MHD_HTTP_CONFLICT:
- /* Requested total refunds exceed deposited amount */
- rr.hr.ec = TALER_JSON_get_error_code (j);
- rr.hr.hint = TALER_JSON_get_error_hint (j);
- break;
- case MHD_HTTP_GONE:
- /* Kind of normal: the money was already sent to the merchant
- (it was too late for the refund). */
- rr.hr.ec = TALER_JSON_get_error_code (j);
- rr.hr.hint = TALER_JSON_get_error_hint (j);
- break;
- case MHD_HTTP_PRECONDITION_FAILED:
- if (GNUNET_OK !=
- verify_failed_dependency_ok (rh,
- j))
- {
- GNUNET_break (0);
- rr.hr.http_status = 0;
- rr.hr.ec = TALER_EC_EXCHANGE_REFUND_INVALID_FAILURE_PROOF_BY_EXCHANGE;
- rr.hr.hint = "failed precondition proof returned by exchange is invalid";
- break;
- }
- /* Two different refund requests were made about the same deposit, but
- carrying identical refund transaction ids. */
- rr.hr.ec = TALER_JSON_get_error_code (j);
- rr.hr.hint = TALER_JSON_get_error_hint (j);
- break;
- case MHD_HTTP_INTERNAL_SERVER_ERROR:
- /* Server had an internal issue; we should retry, but this API
- leaves this to the application */
- rr.hr.ec = TALER_JSON_get_error_code (j);
- rr.hr.hint = TALER_JSON_get_error_hint (j);
- break;
- default:
- /* unexpected response code */
- GNUNET_break_op (0);
- rr.hr.ec = TALER_JSON_get_error_code (j);
- rr.hr.hint = TALER_JSON_get_error_hint (j);
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Unexpected response code %u/%d for exchange refund\n",
- (unsigned int) response_code,
- rr.hr.ec);
- break;
- }
- rh->cb (rh->cb_cls,
- &rr);
- TALER_EXCHANGE_refund_cancel (rh);
-}
-
-
-struct TALER_EXCHANGE_RefundHandle *
-TALER_EXCHANGE_refund (
- struct GNUNET_CURL_Context *ctx,
- const char *url,
- struct TALER_EXCHANGE_Keys *keys,
- const struct TALER_Amount *amount,
- const struct TALER_PrivateContractHashP *h_contract_terms,
- const struct TALER_CoinSpendPublicKeyP *coin_pub,
- uint64_t rtransaction_id,
- const struct TALER_MerchantPrivateKeyP *merchant_priv,
- TALER_EXCHANGE_RefundCallback cb,
- void *cb_cls)
-{
- struct TALER_MerchantPublicKeyP merchant_pub;
- struct TALER_MerchantSignatureP merchant_sig;
- struct TALER_EXCHANGE_RefundHandle *rh;
- json_t *refund_obj;
- CURL *eh;
- char arg_str[sizeof (struct TALER_CoinSpendPublicKeyP) * 2 + 32];
-
- GNUNET_CRYPTO_eddsa_key_get_public (&merchant_priv->eddsa_priv,
- &merchant_pub.eddsa_pub);
- TALER_merchant_refund_sign (coin_pub,
- h_contract_terms,
- rtransaction_id,
- amount,
- merchant_priv,
- &merchant_sig);
- {
- char pub_str[sizeof (struct TALER_CoinSpendPublicKeyP) * 2];
- char *end;
-
- end = GNUNET_STRINGS_data_to_string (
- coin_pub,
- sizeof (struct TALER_CoinSpendPublicKeyP),
- pub_str,
- sizeof (pub_str));
- *end = '\0';
- GNUNET_snprintf (arg_str,
- sizeof (arg_str),
- "coins/%s/refund",
- pub_str);
- }
- refund_obj = GNUNET_JSON_PACK (
- TALER_JSON_pack_amount ("refund_amount",
- amount),
- GNUNET_JSON_pack_data_auto ("h_contract_terms",
- h_contract_terms),
- GNUNET_JSON_pack_uint64 ("rtransaction_id",
- rtransaction_id),
- GNUNET_JSON_pack_data_auto ("merchant_pub",
- &merchant_pub),
- GNUNET_JSON_pack_data_auto ("merchant_sig",
- &merchant_sig));
- rh = GNUNET_new (struct TALER_EXCHANGE_RefundHandle);
- rh->cb = cb;
- rh->cb_cls = cb_cls;
- rh->url = TALER_url_join (url,
- arg_str,
- NULL);
- if (NULL == rh->url)
- {
- json_decref (refund_obj);
- GNUNET_free (rh);
- return NULL;
- }
- rh->h_contract_terms = *h_contract_terms;
- rh->coin_pub = *coin_pub;
- rh->merchant = merchant_pub;
- rh->rtransaction_id = rtransaction_id;
- rh->refund_amount = *amount;
- eh = TALER_EXCHANGE_curl_easy_get_ (rh->url);
- if ( (NULL == eh) ||
- (GNUNET_OK !=
- TALER_curl_easy_post (&rh->ctx,
- eh,
- refund_obj)) )
- {
- GNUNET_break (0);
- if (NULL != eh)
- curl_easy_cleanup (eh);
- json_decref (refund_obj);
- GNUNET_free (rh->url);
- GNUNET_free (rh);
- return NULL;
- }
- json_decref (refund_obj);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "URL for refund: `%s'\n",
- rh->url);
- rh->keys = TALER_EXCHANGE_keys_incref (keys);
- rh->job = GNUNET_CURL_job_add2 (ctx,
- eh,
- rh->ctx.headers,
- &handle_refund_finished,
- rh);
- return rh;
-}
-
-
-void
-TALER_EXCHANGE_refund_cancel (struct TALER_EXCHANGE_RefundHandle *refund)
-{
- if (NULL != refund->job)
- {
- GNUNET_CURL_job_cancel (refund->job);
- refund->job = NULL;
- }
- GNUNET_free (refund->url);
- TALER_curl_easy_post_finished (&refund->ctx);
- TALER_EXCHANGE_keys_decref (refund->keys);
- GNUNET_free (refund);
-}
-
-
-/* end of exchange_api_refund.c */
diff --git a/src/lib/exchange_api_stefan.c b/src/lib/exchange_api_stefan.c
deleted file mode 100644
index c3576cd73..000000000
--- a/src/lib/exchange_api_stefan.c
+++ /dev/null
@@ -1,320 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2023 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software
- Foundation; either version 3, or (at your option) any later version.
-
- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- TALER; see the file COPYING. If not, see
- <http://www.gnu.org/licenses/>
-*/
-/**
- * @file lib/exchange_api_stefan.c
- * @brief calculations on the STEFAN curve
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include "taler_json_lib.h"
-#include <gnunet/gnunet_curl_lib.h>
-#include "exchange_api_handle.h"
-#include <math.h>
-
-
-/**
- * Determine smallest denomination in @a keys.
- *
- * @param keys exchange response to evaluate
- * @return NULL on error (no denominations)
- */
-static const struct TALER_Amount *
-get_unit (const struct TALER_EXCHANGE_Keys *keys)
-{
- const struct TALER_Amount *min = NULL;
-
- for (unsigned int i = 0; i<keys->num_denom_keys; i++)
- {
- const struct TALER_EXCHANGE_DenomPublicKey *dk
- = &keys->denom_keys[i];
-
- if ( (NULL == min) ||
- (1 == TALER_amount_cmp (min,
- /* > */
- &dk->value)) )
- min = &dk->value;
- }
- GNUNET_break (NULL != min);
- return min;
-}
-
-
-/**
- * Convert amount to double for STEFAN curve evaluation.
- *
- * @param a input amount
- * @return (rounded) amount as a double
- */
-static double
-amount_to_double (const struct TALER_Amount *a)
-{
- double d = (double) a->value;
-
- d += a->fraction / ((double) TALER_AMOUNT_FRAC_BASE);
- return d;
-}
-
-
-/**
- * Convert double to amount for STEFAN curve evaluation.
- *
- * @param dv input amount
- * @param currency deisred currency
- * @param[out] rval (rounded) amount as a double
- */
-static void
-double_to_amount (double dv,
- const char *currency,
- struct TALER_Amount *rval)
-{
- double rem;
-
- GNUNET_assert (GNUNET_OK ==
- TALER_amount_set_zero (currency,
- rval));
- rval->value = floorl (dv);
- rem = dv - ((double) rval->value);
- if (rem < 0.0)
- rem = 0.0;
- rem *= TALER_AMOUNT_FRAC_BASE;
- rval->fraction = floorl (rem);
- if (rval->fraction >= TALER_AMOUNT_FRAC_BASE)
- {
- /* Strange, multiplication overflowed our range,
- round up value instead */
- rval->fraction = 0;
- rval->value += 1;
- }
-}
-
-
-enum GNUNET_GenericReturnValue
-TALER_EXCHANGE_keys_stefan_b2n (
- const struct TALER_EXCHANGE_Keys *keys,
- const struct TALER_Amount *brut,
- struct TALER_Amount *net)
-{
- const struct TALER_Amount *min;
- double log_d = amount_to_double (&keys->stefan_log);
- double lin_d = keys->stefan_lin;
- double abs_d = amount_to_double (&keys->stefan_abs);
- double bru_d = amount_to_double (brut);
- double min_d;
- double fee_d;
- double net_d;
-
- if (TALER_amount_is_zero (brut))
- {
- *net = *brut;
- return GNUNET_NO;
- }
- min = get_unit (keys);
- if (NULL == min)
- return GNUNET_SYSERR;
- if (1.0f <= keys->stefan_lin)
- {
- /* This cannot work, linear STEFAN fee estimate always
- exceed any gross amount. */
- GNUNET_break_op (0);
- return GNUNET_SYSERR;
- }
- min_d = amount_to_double (min);
- fee_d = abs_d
- + log_d * log2 (bru_d / min_d)
- + lin_d * bru_d;
- if (fee_d > bru_d)
- {
- GNUNET_assert (GNUNET_OK ==
- TALER_amount_set_zero (brut->currency,
- net));
- return GNUNET_NO;
- }
- net_d = bru_d - fee_d;
- double_to_amount (net_d,
- brut->currency,
- net);
- return GNUNET_OK;
-}
-
-
-/**
- * Our function
- * f(x) := ne + ab + lo * log2(x/mi) + li * x - x
- * for #newton().
- */
-static double
-eval_f (double mi,
- double ab,
- double lo,
- double li,
- double ne,
- double x)
-{
- return ne + ab + lo * log2 (x / mi) + li * x - x;
-}
-
-
-/**
- * Our function
- * f'(x) := lo / log(2) / x + li - 1
- * for #newton().
- */
-static double
-eval_fp (double mi,
- double lo,
- double li,
- double ne,
- double x)
-{
- return lo / log (2) / x + li - 1;
-}
-
-
-/**
- * Use Newton's method to find x where f(x)=0.
- *
- * @return x where "eval_f(x)==0".
- */
-static double
-newton (double mi,
- double ab,
- double lo,
- double li,
- double ne)
-{
- const double eps = 0.00000001; /* max error allowed */
- double min_ab = ne + ab; /* result cannot be smaller than this! */
- /* compute lower bounds by various heuristics */
- double min_ab_li = min_ab + min_ab * li;
- double min_ab_li_lo = min_ab_li + log2 (min_ab_li / mi) * lo;
- double min_ab_lo = min_ab + log2 (min_ab / mi) * lo;
- double min_ab_lo_li = min_ab_lo + min_ab_lo * li;
- /* take global lower bound */
- double x_min = GNUNET_MAX (min_ab_lo_li,
- min_ab_li_lo);
- double x = x_min; /* use lower bound as starting point */
-
- /* Objective: invert
- ne := br - ab - lo * log2 (br/mi) - li * br
- to find 'br'.
- Method: use Newton's method to find root of:
- f(x) := ne + ab + lo * log2 (x/mi) + li * x - x
- using also
- f'(x) := lo / log(2) / x + li - 1
- */
- /* Loop to abort in case of divergence;
- 100 is already very high, 2-4 is normal! */
- for (unsigned int i = 0; i<100; i++)
- {
- double fx = eval_f (mi, ab, lo, li, ne, x);
- double fxp = eval_fp (mi, lo, li, ne, x);
- double x_new = x - fx / fxp;
-
- if (fabs (x - x_new) <= eps)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Needed %u rounds from %f to result BRUT %f => NET: %f\n",
- i,
- x_min,
- x_new,
- x_new - ab - li * x_new - lo * log2 (x / mi));
- return x_new;
- }
- if (x_new < x_min)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "Divergence, obtained very bad estimate %f after %u rounds!\n",
- x_new,
- i);
- return x_min;
- }
- x = x_new;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "Slow convergence, returning bad estimate %f!\n",
- x);
- return x;
-}
-
-
-enum GNUNET_GenericReturnValue
-TALER_EXCHANGE_keys_stefan_n2b (
- const struct TALER_EXCHANGE_Keys *keys,
- const struct TALER_Amount *net,
- struct TALER_Amount *brut)
-{
- const struct TALER_Amount *min;
- double lin_d = keys->stefan_lin;
- double log_d = amount_to_double (&keys->stefan_log);
- double abs_d = amount_to_double (&keys->stefan_abs);
- double net_d = amount_to_double (net);
- double min_d;
- double brut_d;
-
- if (TALER_amount_is_zero (net))
- {
- *brut = *net;
- return GNUNET_NO;
- }
- min = get_unit (keys);
- if (NULL == min)
- return GNUNET_SYSERR;
- if (1.0f <= keys->stefan_lin)
- {
- /* This cannot work, linear STEFAN fee estimate always
- exceed any gross amount. */
- GNUNET_break_op (0);
- return GNUNET_SYSERR;
- }
- min_d = amount_to_double (min);
- brut_d = newton (min_d,
- abs_d,
- log_d,
- lin_d,
- net_d);
- double_to_amount (brut_d,
- net->currency,
- brut);
- return GNUNET_OK;
-}
-
-
-void
-TALER_EXCHANGE_keys_stefan_round (
- const struct TALER_EXCHANGE_Keys *keys,
- struct TALER_Amount *val)
-{
- const struct TALER_Amount *min;
- uint32_t mod = 1;
- uint32_t frac;
- uint32_t rst;
-
- min = get_unit (keys);
- if (NULL == min)
- return;
- frac = min->fraction;
- while (0 == frac % 10)
- {
- mod *= 10;
- frac /= 10;
- }
- rst = val->fraction % mod;
- if (rst < mod / 2)
- val->fraction -= rst;
- else
- val->fraction += mod - rst;
-}
diff --git a/src/lib/test_stefan.c b/src/lib/test_stefan.c
deleted file mode 100644
index 838cca769..000000000
--- a/src/lib/test_stefan.c
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2023 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software
- Foundation; either version 3, or (at your option) any later version.
-
- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- TALER; see the file COPYING. If not, see
- <http://www.gnu.org/licenses/>
-*/
-/**
- * @file lib/test_stefan.c
- * @brief test calculations on the STEFAN curve
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include "taler_json_lib.h"
-#include <gnunet/gnunet_curl_lib.h>
-#include "exchange_api_handle.h"
-
-
-/**
- * Check if @a a and @a b are numerically close.
- *
- * @param a an amount
- * @param b an amount
- * @return true if both values are quite close
- */
-static bool
-amount_close (const struct TALER_Amount *a,
- const struct TALER_Amount *b)
-{
- struct TALER_Amount delta;
-
- switch (TALER_amount_cmp (a,
- b))
- {
- case -1: /* a < b */
- GNUNET_assert (0 <
- TALER_amount_subtract (&delta,
- b,
- a));
- break;
- case 0:
- /* perfect */
- return true;
- case 1: /* a > b */
- GNUNET_assert (0 <
- TALER_amount_subtract (&delta,
- a,
- b));
- break;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Rounding error is %s\n",
- TALER_amount2s (&delta));
- if (delta.value > 0)
- {
- GNUNET_break (0);
- return false;
- }
- if (delta.fraction > 5000)
- {
- GNUNET_break (0);
- return false;
- }
- return true; /* let's consider this a rounding error */
-}
-
-
-int
-main (int argc,
- char **argv)
-{
- struct TALER_EXCHANGE_DenomPublicKey dk;
- struct TALER_EXCHANGE_Keys keys = {
- .denom_keys = &dk,
- .num_denom_keys = 1
- };
- struct TALER_Amount brut;
- struct TALER_Amount net;
-
- (void) argc;
- (void) argv;
- GNUNET_log_setup ("test-stefan",
- "INFO",
- NULL);
- GNUNET_assert (GNUNET_OK ==
- TALER_string_to_amount ("MAGIC:0.13",
- &dk.value));
- GNUNET_assert (GNUNET_OK ==
- TALER_string_to_amount ("MAGIC:1",
- &keys.stefan_abs));
- GNUNET_assert (GNUNET_OK ==
- TALER_string_to_amount ("MAGIC:0.13",
- &keys.stefan_log));
- keys.stefan_lin = 1.15;
- GNUNET_assert (GNUNET_OK ==
- TALER_string_to_amount ("MAGIC:4",
- &brut));
- GNUNET_log_skip (1,
- GNUNET_NO);
- GNUNET_assert (GNUNET_SYSERR ==
- TALER_EXCHANGE_keys_stefan_b2n (&keys,
- &brut,
- &net));
- GNUNET_assert (GNUNET_OK ==
- TALER_string_to_amount ("MAGIC:4",
- &net));
- GNUNET_log_skip (1,
- GNUNET_NO);
- GNUNET_assert (GNUNET_SYSERR ==
- TALER_EXCHANGE_keys_stefan_n2b (&keys,
- &net,
- &brut));
- keys.stefan_lin = 1.0;
- GNUNET_assert (GNUNET_OK ==
- TALER_string_to_amount ("MAGIC:4",
- &brut));
- GNUNET_log_skip (1,
- GNUNET_NO);
- GNUNET_assert (GNUNET_SYSERR ==
- TALER_EXCHANGE_keys_stefan_b2n (&keys,
- &brut,
- &net));
- GNUNET_assert (GNUNET_OK ==
- TALER_string_to_amount ("MAGIC:4",
- &net));
- GNUNET_log_skip (1,
- GNUNET_NO);
- GNUNET_assert (GNUNET_SYSERR ==
- TALER_EXCHANGE_keys_stefan_n2b (&keys,
- &net,
- &brut));
- GNUNET_assert (0 == GNUNET_get_log_skip ());
- keys.stefan_lin = 0.1;
-
- /* try various values for lin and log STEFAN values */
- for (unsigned int li = 1; li < 13; li += 1)
- {
- keys.stefan_lin = 1.0 * li / 100.0;
-
- for (unsigned int lx = 1; lx < 100; lx += 1)
- {
- keys.stefan_log.fraction = lx * TALER_AMOUNT_FRAC_BASE / 100;
-
- /* Check brutto-to-netto is stable */
- for (unsigned int i = 0; i<10; i++)
- {
- struct TALER_Amount rval;
-
- brut.value = i;
- brut.fraction = i * TALER_AMOUNT_FRAC_BASE / 10;
- GNUNET_assert (GNUNET_SYSERR !=
- TALER_EXCHANGE_keys_stefan_b2n (&keys,
- &brut,
- &net));
- GNUNET_assert (GNUNET_SYSERR !=
- TALER_EXCHANGE_keys_stefan_n2b (&keys,
- &net,
- &rval));
- if (TALER_amount_is_zero (&net))
- GNUNET_assert (TALER_amount_is_zero (&rval));
- else
- {
- GNUNET_assert (amount_close (&brut,
- &rval));
- TALER_EXCHANGE_keys_stefan_round (&keys,
- &rval);
- GNUNET_assert (amount_close (&brut,
- &rval));
- }
- }
-
- /* Check netto-to-brutto is stable */
- for (unsigned int i = 0; i<10; i++)
- {
- struct TALER_Amount rval;
-
- net.value = i;
- net.fraction = i * TALER_AMOUNT_FRAC_BASE / 10;
- GNUNET_assert (GNUNET_SYSERR !=
- TALER_EXCHANGE_keys_stefan_n2b (&keys,
- &net,
- &brut));
- GNUNET_assert (GNUNET_SYSERR !=
- TALER_EXCHANGE_keys_stefan_b2n (&keys,
- &brut,
- &rval));
- GNUNET_assert (amount_close (&net,
- &rval));
- TALER_EXCHANGE_keys_stefan_round (&keys,
- &rval);
- GNUNET_assert (amount_close (&net,
- &rval));
- }
- }
- }
- return 0;
-}