summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcello Stanisci <marcello.stanisci@inria.fr>2015-08-11 15:41:26 +0200
committerMarcello Stanisci <marcello.stanisci@inria.fr>2015-08-11 15:41:26 +0200
commita4845fb67d4c58a2fe17d6f82f005dbaa0c93b87 (patch)
tree6b0575abf4c030da05175249282afef429b30cdd
parentabe5971f7398bda68c0e2757ccb8cdbe23d081e5 (diff)
downloadmerchant-a4845fb67d4c58a2fe17d6f82f005dbaa0c93b87.tar.gz
merchant-a4845fb67d4c58a2fe17d6f82f005dbaa0c93b87.tar.bz2
merchant-a4845fb67d4c58a2fe17d6f82f005dbaa0c93b87.zip
first massive refinement
-rw-r--r--src/backend/Makefile.am13
-rw-r--r--src/backend/taler-merchant-dbinit.c79
-rw-r--r--src/backend/taler-merchant-httpd.c43
-rw-r--r--src/backend/taler-mint-httpd_admin.c163
-rw-r--r--src/backend/taler-mint-httpd_admin.h46
-rw-r--r--src/backend/taler-mint-httpd_db.c1444
-rw-r--r--src/backend/taler-mint-httpd_db.h190
-rw-r--r--src/backend/taler-mint-httpd_deposit.c270
-rw-r--r--src/backend/taler-mint-httpd_deposit.h54
-rw-r--r--src/backend/taler-mint-httpd_keystate.c867
-rw-r--r--src/backend/taler-mint-httpd_keystate.h142
-rw-r--r--src/backend/taler-mint-httpd_mhd.c152
-rw-r--r--src/backend/taler-mint-httpd_mhd.h111
-rw-r--r--src/backend/taler-mint-httpd_parsing.c880
-rw-r--r--src/backend/taler-mint-httpd_refresh.c907
-rw-r--r--src/backend/taler-mint-httpd_refresh.h94
-rw-r--r--src/backend/taler-mint-httpd_responses.c829
-rw-r--r--src/backend/taler-mint-httpd_withdraw.c180
-rw-r--r--src/backend/taler-mint-httpd_withdraw.h73
19 files changed, 4 insertions, 6533 deletions
diff --git a/src/backend/Makefile.am b/src/backend/Makefile.am
index 9744a2dd..7c100040 100644
--- a/src/backend/Makefile.am
+++ b/src/backend/Makefile.am
@@ -8,20 +8,13 @@ taler_merchant_httpd_SOURCES = \
taler-merchant-httpd.c \
merchant.c merchant.h \
merchant_db.c merchant_db.h \
- taler-mint-httpd_keystate.c taler-mint-httpd_keystate.h \
- taler-mint-httpd_db.c taler-mint-httpd_db.h \
taler-mint-httpd_parsing.c taler-mint-httpd_parsing.h \
- taler-mint-httpd_responses.c taler-mint-httpd_responses.h \
- taler-mint-httpd_mhd.c taler-mint-httpd_mhd.h \
- taler-mint-httpd_admin.c taler-mint-httpd_admin.h \
- taler-mint-httpd_deposit.c taler-mint-httpd_deposit.h \
- taler-mint-httpd_withdraw.c taler-mint-httpd_withdraw.h \
- taler-mint-httpd_refresh.c taler-mint-httpd_refresh.h
+ taler-mint-httpd_responses.c taler-mint-httpd_responses.h
taler_merchant_httpd_LDADD = \
$(LIBGCRYPT_LIBS) \
- /home/marcello/trans_mint/src/util/libtalerutil.la \
- /home/marcello/trans_mint/src/mintdb/libtalermintdb.la \
+ /home/marcello/Taler/trans_mint/src/util/libtalerutil.la \
+ /home/marcello/Taler/trans_mint/src/mintdb/libtalermintdb.la \
-lmicrohttpd \
-ljansson \
-lgnunetutil \
diff --git a/src/backend/taler-merchant-dbinit.c b/src/backend/taler-merchant-dbinit.c
deleted file mode 100644
index 07731b47..00000000
--- a/src/backend/taler-merchant-dbinit.c
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- This file is part of TALER
- (C) 2014 Christian Grothoff (and other contributing authors)
-
- 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, If not, see <http://www.gnu.org/licenses/>
-*/
-
-/**
- * @file merchant/taler_merchant_dbinit.c
- * @brief Program to initialise merchant database
- * @author Sree Harsha Totakura <sreeharsha@totakura.in>
- */
-
-#include "platform.h"
-#include <gnunet/gnunet_util_lib.h>
-#include "merchant_db.h"
-
-
-/**
- * Global execution result
- */
-static int result;
-
-
-/**
- * Main function that will be run by the scheduler.
- *
- * @param cls closure
- * @param args remaining command-line arguments
- * @param cfgfile name of the configuration file used (for saving, can be NULL!)
- * @param config configuration
- */
-static void
-run (void *cls, char *const *args, const char *cfgfile,
- const struct GNUNET_CONFIGURATION_Handle *config)
-{
- PGconn *conn;
-
- conn = MERCHANT_DB_connect (config);
- if (NULL == conn)
- return;
- if (GNUNET_OK == MERCHANT_DB_initialize (conn, GNUNET_NO))
- result = GNUNET_OK;
- MERCHANT_DB_disconnect (conn);
-}
-
-
-/**
- * The main function
- *
- * @param argc number of arguments from the command line
- * @param argv command line arguments
- * @return 0 ok, 1 on error
- */
-int
-main (int argc, char *const *argv)
-{
- static const struct GNUNET_GETOPT_CommandLineOption options[] = {
- GNUNET_GETOPT_OPTION_END
- };
-
- result = GNUNET_SYSERR;
- if (GNUNET_OK !=
- GNUNET_PROGRAM_run (argc, argv, "taler-merchant-dbinit",
- gettext_noop
- ("Initialise Taler Merchant's database"),
- options, &run, NULL))
- return 3;
- return (GNUNET_OK == result) ? 0 : 1;
-}
diff --git a/src/backend/taler-merchant-httpd.c b/src/backend/taler-merchant-httpd.c
index 9ac225b5..9c431c2b 100644
--- a/src/backend/taler-merchant-httpd.c
+++ b/src/backend/taler-merchant-httpd.c
@@ -27,12 +27,6 @@
#include <taler/taler_json_lib.h>
#include <taler/taler_mint_service.h>
#include "taler-mint-httpd_parsing.h"
-#include "taler-mint-httpd_mhd.h"
-#include "taler-mint-httpd_admin.h"
-#include "taler-mint-httpd_deposit.h"
-#include "taler-mint-httpd_withdraw.h"
-#include "taler-mint-httpd_refresh.h"
-#include "taler-mint-httpd_keystate.h"
#include "taler-mint-httpd_responses.h"
#include "merchant.h"
#include "merchant_db.h"
@@ -79,45 +73,10 @@ static struct MHD_Daemon *mhd;
PGconn *db_conn;
/**
- * Which currency is used by this mint?
- * (verbatim copy from mint's code, just to make this
- * merchant's source compile)
- */
-char *TMH_mint_currency_string;
-
-/* As above */
-struct TALER_MINTDB_Plugin *TMH_plugin;
-
-
-/**
- * As above, though the merchant does need some form of
- * configuration
+ * merchant's conf handle
*/
struct GNUNET_CONFIGURATION_Handle *cfg;
-
-/**
- * As above
- */
-int TMH_test_mode;
-
-
-/**
- * As above
- */
-char *TMH_mint_directory;
-
-
-/**
- * As above
- */
-struct GNUNET_CRYPTO_EddsaPublicKey TMH_master_public_key;
-
-/**
- * As above
- */
-char *TMH_expected_wire_format;
-
/**
* Shutdown task identifier
*/
diff --git a/src/backend/taler-mint-httpd_admin.c b/src/backend/taler-mint-httpd_admin.c
deleted file mode 100644
index 5fdfa58e..00000000
--- a/src/backend/taler-mint-httpd_admin.c
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2014 GNUnet e.V.
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU Affero General Public License as published by the Free Software
- 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 Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License along with
- TALER; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/>
-*/
-/**
- * @file taler-mint-httpd_admin.c
- * @brief Handle /admin/ requests
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include <gnunet/gnunet_util_lib.h>
-#include <jansson.h>
-#include "taler-mint-httpd_admin.h"
-#include "taler-mint-httpd_parsing.h"
-#include "taler-mint-httpd_responses.h"
-
-
-/**
- * Check permissions (we only allow access to /admin/ from loopback).
- *
- * @param connection connection to perform access check for
- * @return #GNUNET_OK if permitted,
- * #GNUNET_NO if denied and error was queued,
- * #GNUNET_SYSERR if denied and we failed to report
- */
-static int
-check_permissions (struct MHD_Connection *connection)
-{
- const union MHD_ConnectionInfo *ci;
- const struct sockaddr *addr;
- int res;
-
- ci = MHD_get_connection_info (connection,
- MHD_CONNECTION_INFO_CLIENT_ADDRESS);
- if (NULL == ci)
- {
- GNUNET_break (0);
- res = TMH_RESPONSE_reply_internal_error (connection,
- "Failed to verify client address");
- return (MHD_YES == res) ? GNUNET_NO : GNUNET_SYSERR;
- }
- addr = ci->client_addr;
- switch (addr->sa_family)
- {
- case AF_INET:
- {
- const struct sockaddr_in *sin = (const struct sockaddr_in *) addr;
-
- if (INADDR_LOOPBACK != ntohl (sin->sin_addr.s_addr))
- {
- res = TMH_RESPONSE_reply_permission_denied (connection,
- "/admin/ only allowed via loopback");
- return (MHD_YES == res) ? GNUNET_NO : GNUNET_SYSERR;
- }
- break;
- }
- case AF_INET6:
- {
- const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *) addr;
-
- if (! IN6_IS_ADDR_LOOPBACK (&sin6->sin6_addr))
- {
- res = TMH_RESPONSE_reply_permission_denied (connection,
- "/admin/ only allowed via loopback");
- return (MHD_YES == res) ? GNUNET_NO : GNUNET_SYSERR;
- }
- break;
- }
- default:
- GNUNET_break (0);
- res = TMH_RESPONSE_reply_internal_error (connection,
- "Unsupported AF");
- return (MHD_YES == res) ? GNUNET_NO : GNUNET_SYSERR;
- }
- return GNUNET_OK;
-}
-
-
-
-/**
- * Handle a "/admin/add/incoming" request. Parses the
- * given "reserve_pub", "amount", "transaction" and "h_wire"
- * details and adds the respective transaction to the database.
- *
- * @param rh context of the handler
- * @param connection the MHD connection to handle
- * @param[in,out] connection_cls the connection's closure (can be updated)
- * @param upload_data upload data
- * @param[in,out] upload_data_size number of bytes (left) in @a upload_data
- * @return MHD result code
- */
-int
-TMH_ADMIN_handler_admin_add_incoming (struct TMH_RequestHandler *rh,
- struct MHD_Connection *connection,
- void **connection_cls,
- const char *upload_data,
- size_t *upload_data_size)
-{
- struct TALER_ReservePublicKeyP reserve_pub;
- struct TALER_Amount amount;
- struct GNUNET_TIME_Absolute at;
- json_t *wire;
- json_t *root;
- struct TMH_PARSE_FieldSpecification spec[] = {
- TMH_PARSE_member_fixed ("reserve_pub", &reserve_pub),
- TMH_PARSE_member_amount ("amount", &amount),
- TMH_PARSE_member_time_abs ("execution_date", &at),
- TMH_PARSE_member_object ("wire", &wire),
- TMH_PARSE_MEMBER_END
- };
- int res;
-
- res = check_permissions (connection);
- if (GNUNET_OK != res)
- return (GNUNET_NO == res) ? MHD_YES : MHD_NO;
- res = TMH_PARSE_post_json (connection,
- connection_cls,
- upload_data,
- upload_data_size,
- &root);
- if (GNUNET_SYSERR == res)
- return MHD_NO;
- if ( (GNUNET_NO == res) || (NULL == root) )
- return MHD_YES;
- res = TMH_PARSE_json_data (connection,
- root,
- spec);
- if (GNUNET_OK != res)
- {
- json_decref (root);
- return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES;
- }
- if (GNUNET_YES !=
- TALER_json_validate_wireformat (TMH_expected_wire_format,
- wire))
- {
- TMH_PARSE_release_data (spec);
- json_decref (root);
- return TMH_RESPONSE_reply_arg_unknown (connection,
- "wire");
- }
- res = TMH_DB_execute_admin_add_incoming (connection,
- &reserve_pub,
- &amount,
- at,
- wire);
- TMH_PARSE_release_data (spec);
- json_decref (root);
- return res;
-}
-
-/* end of taler-mint-httpd_admin.c */
diff --git a/src/backend/taler-mint-httpd_admin.h b/src/backend/taler-mint-httpd_admin.h
deleted file mode 100644
index b8ca3ce5..00000000
--- a/src/backend/taler-mint-httpd_admin.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2014 GNUnet e.V.
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU Affero General Public License as published by the Free Software
- 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 Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License along with
- TALER; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/>
-*/
-/**
- * @file taler-mint-httpd_admin.h
- * @brief Handle /admin/ requests
- * @author Christian Grothoff
- */
-#ifndef TALER_MINT_HTTPD_ADMIN_H
-#define TALER_MINT_HTTPD_ADMIN_H
-
-#include <microhttpd.h>
-#include "taler-mint-httpd.h"
-
-/**
- * Handle a "/admin/add/incoming" request. Parses the
- * given "reserve_pub", "amount", "transaction" and "h_wire"
- * details and adds the respective transaction to the database.
- *
- * @param rh context of the handler
- * @param connection the MHD connection to handle
- * @param[in,out] connection_cls the connection's closure (can be updated)
- * @param upload_data upload data
- * @param[in,out] upload_data_size number of bytes (left) in @a upload_data
- * @return MHD result code
- */
-int
-TMH_ADMIN_handler_admin_add_incoming (struct TMH_RequestHandler *rh,
- struct MHD_Connection *connection,
- void **connection_cls,
- const char *upload_data,
- size_t *upload_data_size);
-
-#endif
diff --git a/src/backend/taler-mint-httpd_db.c b/src/backend/taler-mint-httpd_db.c
deleted file mode 100644
index 4e91e7e7..00000000
--- a/src/backend/taler-mint-httpd_db.c
+++ /dev/null
@@ -1,1444 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2014, 2015 Christian Grothoff (and other contributing authors)
-
- 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, If not, see <http://www.gnu.org/licenses/>
-*/
-/**
- * @file taler-mint-httpd_db.c
- * @brief High-level (transactional-layer) database operations for the mint.
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include <pthread.h>
-#include <jansson.h>
-#include "taler-mint-httpd_responses.h"
-#include "taler-mint-httpd_keystate.h"
-
-
-/**
- * Calculate the total value of all transactions performed.
- * Stores @a off plus the cost of all transactions in @a tl
- * in @a ret.
- *
- * @param tl transaction list to process
- * @param off offset to use as the starting value
- * @param ret where the resulting total is to be stored
- * @return #GNUNET_OK on success, #GNUNET_SYSERR on errors
- */
-static int
-calculate_transaction_list_totals (struct TALER_MINTDB_TransactionList *tl,
- const struct TALER_Amount *off,
- struct TALER_Amount *ret)
-{
- struct TALER_Amount spent = *off;
- struct TALER_MINTDB_TransactionList *pos;
-
- for (pos = tl; NULL != pos; pos = pos->next)
- {
- switch (pos->type)
- {
- case TALER_MINTDB_TT_DEPOSIT:
- if (GNUNET_OK !=
- TALER_amount_add (&spent,
- &spent,
- &pos->details.deposit->amount_with_fee))
- {
- GNUNET_break (0);
- return GNUNET_SYSERR;
- }
- break;
- case TALER_MINTDB_TT_REFRESH_MELT:
- if (GNUNET_OK !=
- TALER_amount_add (&spent,
- &spent,
- &pos->details.melt->amount_with_fee))
- {
- GNUNET_break (0);
- return GNUNET_SYSERR;
- }
- break;
- case TALER_MINTDB_TT_LOCK:
- /* should check if lock is still active,
- and if it is for THIS operation; if
- lock is inactive, delete it; if lock
- is for THIS operation, ignore it;
- if lock is for another operation,
- count it! */
- GNUNET_assert (0); // FIXME: not implemented! (#3625)
- return GNUNET_SYSERR;
- }
- }
- *ret = spent;
- return GNUNET_OK;
-}
-
-
-/**
- * Execute a deposit. The validity of the coin and signature
- * have already been checked. The database must now check that
- * the coin is not (double or over) spent, and execute the
- * transaction (record details, generate success or failure response).
- *
- * @param connection the MHD connection to handle
- * @param deposit information about the deposit
- * @return MHD result code
- */
-int
-TMH_DB_execute_deposit (struct MHD_Connection *connection,
- const struct TALER_MINTDB_Deposit *deposit)
-{
- struct TALER_MINTDB_Session *session;
- struct TALER_MINTDB_TransactionList *tl;
- struct TALER_Amount spent;
- struct TALER_Amount value;
- struct TALER_Amount amount_without_fee;
- struct TMH_KS_StateHandle *mks;
- struct TALER_MINTDB_DenominationKeyIssueInformation *dki;
- int ret;
-
- if (NULL == (session = TMH_plugin->get_session (TMH_plugin->cls,
- TMH_test_mode)))
- {
- GNUNET_break (0);
- return TMH_RESPONSE_reply_internal_db_error (connection);
- }
- if (GNUNET_YES ==
- TMH_plugin->have_deposit (TMH_plugin->cls,
- session,
- deposit))
- {
- GNUNET_assert (GNUNET_OK ==
- TALER_amount_subtract (&amount_without_fee,
- &deposit->amount_with_fee,
- &deposit->deposit_fee));
- return TMH_RESPONSE_reply_deposit_success (connection,
- &deposit->coin.coin_pub,
- &deposit->h_wire,
- &deposit->h_contract,
- deposit->transaction_id,
- deposit->timestamp,
- deposit->refund_deadline,
- &deposit->merchant_pub,
- &amount_without_fee);
- }
- mks = TMH_KS_acquire ();
- dki = TMH_KS_denomination_key_lookup (mks,
- &deposit->coin.denom_pub,
- TMH_KS_DKU_DEPOSIT);
- TALER_amount_ntoh (&value,
- &dki->issue.properties.value);
- TMH_KS_release (mks);
-
- if (GNUNET_OK !=
- TMH_plugin->start (TMH_plugin->cls,
- session))
- {
- GNUNET_break (0);
- return TMH_RESPONSE_reply_internal_db_error (connection);
- }
- /* fee for THIS transaction */
- spent = deposit->amount_with_fee;
- /* add cost of all previous transactions */
- tl = TMH_plugin->get_coin_transactions (TMH_plugin->cls,
- session,
- &deposit->coin.coin_pub);
- if (GNUNET_OK !=
- calculate_transaction_list_totals (tl,
- &spent,
- &spent))
- {
- TMH_plugin->free_coin_transaction_list (TMH_plugin->cls,
- tl);
- return TMH_RESPONSE_reply_internal_db_error (connection);
- }
- /* Check that cost of all transactions is smaller than
- the value of the coin. */
- if (0 < TALER_amount_cmp (&spent,
- &value))
- {
- TMH_plugin->rollback (TMH_plugin->cls,
- session);
- ret = TMH_RESPONSE_reply_deposit_insufficient_funds (connection,
- tl);
- TMH_plugin->free_coin_transaction_list (TMH_plugin->cls,
- tl);
- return ret;
- }
- TMH_plugin->free_coin_transaction_list (TMH_plugin->cls,
- tl);
-
- if (GNUNET_OK !=
- TMH_plugin->insert_deposit (TMH_plugin->cls,
- session,
- deposit))
- {
- TALER_LOG_WARNING ("Failed to store /deposit information in database\n");
- TMH_plugin->rollback (TMH_plugin->cls,
- session);
- return TMH_RESPONSE_reply_internal_db_error (connection);
- }
-
- if (GNUNET_OK !=
- TMH_plugin->commit (TMH_plugin->cls,
- session))
- {
- TALER_LOG_WARNING ("/deposit transaction commit failed\n");
- return TMH_RESPONSE_reply_commit_error (connection);
- }
- GNUNET_assert (GNUNET_OK ==
- TALER_amount_subtract (&amount_without_fee,
- &deposit->amount_with_fee,
- &deposit->deposit_fee));
- return TMH_RESPONSE_reply_deposit_success (connection,
- &deposit->coin.coin_pub,
- &deposit->h_wire,
- &deposit->h_contract,
- deposit->transaction_id,
- deposit->timestamp,
- deposit->refund_deadline,
- &deposit->merchant_pub,
- &amount_without_fee);
-}
-
-
-/**
- * Execute a /withdraw/status. Given the public key of a reserve,
- * return the associated transaction history.
- *
- * @param connection the MHD connection to handle
- * @param reserve_pub public key of the reserve to check
- * @return MHD result code
- */
-int
-TMH_DB_execute_withdraw_status (struct MHD_Connection *connection,
- const struct TALER_ReservePublicKeyP *reserve_pub)
-{
- struct TALER_MINTDB_Session *session;
- struct TALER_MINTDB_ReserveHistory *rh;
- int res;
-
- if (NULL == (session = TMH_plugin->get_session (TMH_plugin->cls,
- TMH_test_mode)))
- {
- GNUNET_break (0);
- return TMH_RESPONSE_reply_internal_db_error (connection);
- }
- rh = TMH_plugin->get_reserve_history (TMH_plugin->cls,
- session,
- reserve_pub);
- if (NULL == rh)
- return TMH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_NOT_FOUND,
- "{s:s, s:s}",
- "error", "Reserve not found",
- "parameter", "withdraw_pub");
- res = TMH_RESPONSE_reply_withdraw_status_success (connection,
- rh);
- TMH_plugin->free_reserve_history (TMH_plugin->cls,
- rh);
- return res;
-}
-
-
-/**
- * Execute a "/withdraw/sign". Given a reserve and a properly signed
- * request to withdraw a coin, check the balance of the reserve and
- * if it is sufficient, store the request and return the signed
- * blinded envelope.
- *
- * @param connection the MHD connection to handle
- * @param reserve public key of the reserve
- * @param denomination_pub public key of the denomination requested
- * @param blinded_msg blinded message to be signed
- * @param blinded_msg_len number of bytes in @a blinded_msg
- * @param signature signature over the withdraw request, to be stored in DB
- * @return MHD result code
- */
-int
-TMH_DB_execute_withdraw_sign (struct MHD_Connection *connection,
- const struct TALER_ReservePublicKeyP *reserve,
- const struct TALER_DenominationPublicKey *denomination_pub,
- const char *blinded_msg,
- size_t blinded_msg_len,
- const struct TALER_ReserveSignatureP *signature)
-{
- struct TALER_MINTDB_Session *session;
- struct TALER_MINTDB_ReserveHistory *rh;
- const struct TALER_MINTDB_ReserveHistory *pos;
- struct TMH_KS_StateHandle *key_state;
- struct TALER_MINTDB_CollectableBlindcoin collectable;
- struct TALER_MINTDB_DenominationKeyIssueInformation *dki;
- struct TALER_MINTDB_DenominationKeyIssueInformation *tdki;
- struct GNUNET_CRYPTO_rsa_Signature *sig;
- struct TALER_Amount amount_required;
- struct TALER_Amount deposit_total;
- struct TALER_Amount withdraw_total;
- struct TALER_Amount balance;
- struct TALER_Amount value;
- struct TALER_Amount fee_withdraw;
- struct GNUNET_HashCode h_blind;
- int res;
-
- GNUNET_CRYPTO_hash (blinded_msg,
- blinded_msg_len,
- &h_blind);
-
- if (NULL == (session = TMH_plugin->get_session (TMH_plugin->cls,
- TMH_test_mode)))
- {
- GNUNET_break (0);
- return TMH_RESPONSE_reply_internal_db_error (connection);
- }
- res = TMH_plugin->get_withdraw_info (TMH_plugin->cls,
- session,
- &h_blind,
- &collectable);
- if (GNUNET_SYSERR == res)
- {
- GNUNET_break (0);
- return TMH_RESPONSE_reply_internal_db_error (connection);
- }
-
- /* Don't sign again if we have already signed the coin */
- if (GNUNET_YES == res)
- {
- res = TMH_RESPONSE_reply_withdraw_sign_success (connection,
- &collectable);
- GNUNET_CRYPTO_rsa_signature_free (collectable.sig.rsa_signature);
- GNUNET_CRYPTO_rsa_public_key_free (collectable.denom_pub.rsa_public_key);
- return res;
- }
- GNUNET_assert (GNUNET_NO == res);
-
- /* Check if balance is sufficient */
- key_state = TMH_KS_acquire ();
- dki = TMH_KS_denomination_key_lookup (key_state,
- denomination_pub,
- TMH_KS_DKU_WITHDRAW);
- if (NULL == dki)
- {
- TMH_KS_release (key_state);
- return TMH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_NOT_FOUND,
- "{s:s}",
- "error",
- "Denomination not found");
- }
- if (GNUNET_OK !=
- TMH_plugin->start (TMH_plugin->cls,
- session))
- {
- GNUNET_break (0);
- TMH_KS_release (key_state);
- return TMH_RESPONSE_reply_internal_db_error (connection);
- }
-
- rh = TMH_plugin->get_reserve_history (TMH_plugin->cls,
- session,
- reserve);
- if (NULL == rh)
- {
- TMH_plugin->rollback (TMH_plugin->cls,
- session);
- TMH_KS_release (key_state);
- return TMH_RESPONSE_reply_arg_unknown (connection,
- "reserve_pub");
- }
-
- /* calculate amount required including fees */
- TALER_amount_ntoh (&value,
- &dki->issue.properties.value);
- TALER_amount_ntoh (&fee_withdraw,
- &dki->issue.properties.fee_withdraw);
-
- if (GNUNET_OK !=
- TALER_amount_add (&amount_required,
- &value,
- &fee_withdraw))
- {
- TMH_plugin->rollback (TMH_plugin->cls,
- session);
- TMH_KS_release (key_state);
- return TMH_RESPONSE_reply_internal_db_error (connection);
- }
-
- /* calculate balance of the reserve */
- res = 0;
- for (pos = rh; NULL != pos; pos = pos->next)
- {
- switch (pos->type)
- {
- case TALER_MINTDB_RO_BANK_TO_MINT:
- if (0 == (res & 1))
- deposit_total = pos->details.bank->amount;
- else
- if (GNUNET_OK !=
- TALER_amount_add (&deposit_total,
- &deposit_total,
- &pos->details.bank->amount))
- {
- TMH_plugin->rollback (TMH_plugin->cls,
- session);
- TMH_KS_release (key_state);
- return TMH_RESPONSE_reply_internal_db_error (connection);
- }
- res |= 1;
- break;
- case TALER_MINTDB_RO_WITHDRAW_COIN:
- tdki = TMH_KS_denomination_key_lookup (key_state,
- &pos->details.withdraw->denom_pub,
- TMH_KS_DKU_WITHDRAW);
- TALER_amount_ntoh (&value,
- &tdki->issue.properties.value);
- if (0 == (res & 2))
- withdraw_total = value;
- else
- if (GNUNET_OK !=
- TALER_amount_add (&withdraw_total,
- &withdraw_total,
- &value))
- {
- TMH_plugin->rollback (TMH_plugin->cls,
- session);
- TMH_KS_release (key_state);
- return TMH_RESPONSE_reply_internal_db_error (connection);
- }
- res |= 2;
- break;
- }
- }
- if (0 == (res & 1))
- {
- /* did not encounter any deposit operations, how can we have a reserve? */
- GNUNET_break (0);
- return TMH_RESPONSE_reply_internal_db_error (connection);
- }
- if (0 == (res & 2))
- {
- /* did not encounter any withdraw operations, set to zero */
- TALER_amount_get_zero (deposit_total.currency,
- &withdraw_total);
- }
- /* All reserve balances should be non-negative */
- GNUNET_assert (GNUNET_SYSERR !=
- TALER_amount_subtract (&balance,
- &deposit_total,
- &withdraw_total));
- if (0 < TALER_amount_cmp (&amount_required,
- &balance))
- {
- TMH_KS_release (key_state);
- TMH_plugin->rollback (TMH_plugin->cls,
- session);
- res = TMH_RESPONSE_reply_withdraw_sign_insufficient_funds (connection,
- rh);
- TMH_plugin->free_reserve_history (TMH_plugin->cls,
- rh);
- return res;
- }
- TMH_plugin->free_reserve_history (TMH_plugin->cls,
- rh);
-
- /* Balance is good, sign the coin! */
- sig = GNUNET_CRYPTO_rsa_sign (dki->denom_priv.rsa_private_key,
- blinded_msg,
- blinded_msg_len);
- TMH_KS_release (key_state);
- if (NULL == sig)
- {
- GNUNET_break (0);
- TMH_plugin->rollback (TMH_plugin->cls,
- session);
- return TMH_RESPONSE_reply_internal_error (connection,
- "Internal error");
- }
- collectable.sig.rsa_signature = sig;
- collectable.denom_pub = *denomination_pub;
- collectable.amount_with_fee = amount_required;
- collectable.withdraw_fee = fee_withdraw;
- collectable.reserve_pub = *reserve;
- collectable.h_coin_envelope = h_blind;
- collectable.reserve_sig = *signature;
- if (GNUNET_OK !=
- TMH_plugin->insert_withdraw_info (TMH_plugin->cls,
- session,
- &collectable))
- {
- GNUNET_break (0);
- GNUNET_CRYPTO_rsa_signature_free (sig);
- TMH_plugin->rollback (TMH_plugin->cls,
- session);
- return TMH_RESPONSE_reply_internal_db_error (connection);
- }
- if (GNUNET_OK !=
- TMH_plugin->commit (TMH_plugin->cls,
- session))
- {
- TALER_LOG_WARNING ("/withdraw/sign transaction commit failed\n");
- return TMH_RESPONSE_reply_commit_error (connection);
- }
- res = TMH_RESPONSE_reply_withdraw_sign_success (connection,
- &collectable);
- GNUNET_CRYPTO_rsa_signature_free (sig);
- return res;
-}
-
-
-/**
- * Parse coin melt requests from a JSON object and write them to
- * the database.
- *
- * @param connection the connection to send errors to
- * @param session the database connection
- * @param key_state the mint's key state
- * @param session_hash hash identifying the refresh session
- * @param coin_details details about the coin being melted
- * @param oldcoin_index what is the number assigned to this coin
- * @return #GNUNET_OK on success,
- * #GNUNET_NO if an error message was generated,
- * #GNUNET_SYSERR on internal errors (no response generated)
- */
-static int
-refresh_accept_melts (struct MHD_Connection *connection,
- struct TALER_MINTDB_Session *session,
- const struct TMH_KS_StateHandle *key_state,
- const struct GNUNET_HashCode *session_hash,
- const struct TMH_DB_MeltDetails *coin_details,
- uint16_t oldcoin_index)
-{
- struct TALER_MINTDB_DenominationKeyInformationP *dki;
- struct TALER_MINTDB_TransactionList *tl;
- struct TALER_Amount coin_value;
- struct TALER_Amount coin_residual;
- struct TALER_Amount spent;
- struct TALER_MINTDB_RefreshMelt melt;
- int res;
-
- dki = &TMH_KS_denomination_key_lookup (key_state,
- &coin_details->coin_info.denom_pub,
- TMH_KS_DKU_DEPOSIT)->issue;
-
- if (NULL == dki)
- return (MHD_YES ==
- TMH_RESPONSE_reply_arg_unknown (connection,
- "denom_pub"))
- ? GNUNET_NO : GNUNET_SYSERR;
-
- TALER_amount_ntoh (&coin_value,
- &dki->properties.value);
- /* fee for THIS transaction; the melt amount includes the fee! */
- spent = coin_details->melt_amount_with_fee;
- /* add historic transaction costs of this coin */
- tl = TMH_plugin->get_coin_transactions (TMH_plugin->cls,
- session,
- &coin_details->coin_info.coin_pub);
- if (GNUNET_OK !=
- calculate_transaction_list_totals (tl,
- &spent,
- &spent))
- {
- GNUNET_break (0);
- TMH_plugin->free_coin_transaction_list (TMH_plugin->cls,
- tl);
- return TMH_RESPONSE_reply_internal_db_error (connection);
- }
- /* Refuse to refresh when the coin's value is insufficient
- for the cost of all transactions. */
- if (TALER_amount_cmp (&coin_value,
- &spent) < 0)
- {
- GNUNET_assert (GNUNET_OK ==
- TALER_amount_subtract (&coin_residual,
- &spent,
- &coin_details->melt_amount_with_fee));
- res = (MHD_YES ==
- TMH_RESPONSE_reply_refresh_melt_insufficient_funds (connection,
- &coin_details->coin_info.coin_pub,
- coin_value,
- tl,
- coin_details->melt_amount_with_fee,
- coin_residual))
- ? GNUNET_NO : GNUNET_SYSERR;
- TMH_plugin->free_coin_transaction_list (TMH_plugin->cls,
- tl);
- return res;
- }
- TMH_plugin->free_coin_transaction_list (TMH_plugin->cls,
- tl);
-
- melt.coin = coin_details->coin_info;
- melt.coin_sig = coin_details->melt_sig;
- melt.session_hash = *session_hash;
- melt.amount_with_fee = coin_details->melt_amount_with_fee;
- if (GNUNET_OK !=
- TMH_plugin->insert_refresh_melt (TMH_plugin->cls,
- session,
- oldcoin_index,
- &melt))
- {
- GNUNET_break (0);
- return GNUNET_SYSERR;
- }
- return GNUNET_OK;
-}
-
-
-/**
- * Execute a "/refresh/melt". We have been given a list of valid
- * coins and a request to melt them into the given
- * @a refresh_session_pub. Check that the coins all have the
- * required value left and if so, store that they have been
- * melted and confirm the melting operation to the client.
- *
- * @param connection the MHD connection to handle
- * @param session_hash hash code of the session the coins are melted into
- * @param num_new_denoms number of entries in @a denom_pubs, size of y-dimension of @a commit_coin array
- * @param denom_pubs public keys of the coins we want to withdraw in the end
- * @param coin_count number of entries in @a coin_melt_details, size of y-dimension of @a commit_link array
- * @param coin_melt_details signatures and (residual) value of the respective coin should be melted
- * @param commit_coin 2d array of coin commitments (what the mint is to sign
- * once the "/refres/reveal" of cut and choose is done),
- * x-dimension must be #TALER_CNC_KAPPA
- * @param commit_link 2d array of coin link commitments (what the mint is
- * to return via "/refresh/link" to enable linkage in the
- * future)
- * x-dimension must be #TALER_CNC_KAPPA
- * @return MHD result code
- */
-int
-TMH_DB_execute_refresh_melt (struct MHD_Connection *connection,
- const struct GNUNET_HashCode *session_hash,
- unsigned int num_new_denoms,
- const struct TALER_DenominationPublicKey *denom_pubs,
- unsigned int coin_count,
- const struct TMH_DB_MeltDetails *coin_melt_details,
- struct TALER_MINTDB_RefreshCommitCoin *const* commit_coin,
- struct TALER_MINTDB_RefreshCommitLinkP *const* commit_link)
-{
- struct TMH_KS_StateHandle *key_state;
- struct TALER_MINTDB_RefreshSession refresh_session;
- struct TALER_MINTDB_Session *session;
- int res;
- unsigned int i;
-
- if (NULL == (session = TMH_plugin->get_session (TMH_plugin->cls,
- TMH_test_mode)))
- {
- GNUNET_break (0);
- return TMH_RESPONSE_reply_internal_db_error (connection);
- }
- if (GNUNET_OK !=
- TMH_plugin->start (TMH_plugin->cls,
- session))
- {
- GNUNET_break (0);
- return TMH_RESPONSE_reply_internal_db_error (connection);
- }
- res = TMH_plugin->get_refresh_session (TMH_plugin->cls,
- session,
- session_hash,
- &refresh_session);
- if (GNUNET_YES == res)
- {
- TMH_plugin->rollback (TMH_plugin->cls,
- session);
- res = TMH_RESPONSE_reply_refresh_melt_success (connection,
- session_hash,
- refresh_session.noreveal_index);
- return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES;
- }
- if (GNUNET_SYSERR == res)
- {
- TMH_plugin->rollback (TMH_plugin->cls,
- session);
- return TMH_RESPONSE_reply_internal_db_error (connection);
- }
-
- /* store 'global' session data */
- refresh_session.num_oldcoins = coin_count;
- refresh_session.num_newcoins = num_new_denoms;
- refresh_session.noreveal_index
- = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_STRONG,
- TALER_CNC_KAPPA);
- if (GNUNET_OK !=
- (res = TMH_plugin->create_refresh_session (TMH_plugin->cls,
- session,
- session_hash,
- &refresh_session)))
- {
- TMH_plugin->rollback (TMH_plugin->cls,
- session);
- return TMH_RESPONSE_reply_internal_db_error (connection);
- }
-
- /* Melt old coins and check that they had enough residual value */
- key_state = TMH_KS_acquire ();
- for (i=0;i<coin_count;i++)
- {
- if (GNUNET_OK !=
- (res = refresh_accept_melts (connection,
- session,
- key_state,
- session_hash,
- &coin_melt_details[i],
- i)))
- {
- TMH_KS_release (key_state);
- TMH_plugin->rollback (TMH_plugin->cls,
- session);
- return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES;
- }
- }
- TMH_KS_release (key_state);
-
- /* store requested new denominations */
- if (GNUNET_OK !=
- TMH_plugin->insert_refresh_order (TMH_plugin->cls,
- session,
- session_hash,
- num_new_denoms,
- denom_pubs))
- {
- TMH_plugin->rollback (TMH_plugin->cls,
- session);
- return TMH_RESPONSE_reply_internal_db_error (connection);
- }
-
- for (i = 0; i < TALER_CNC_KAPPA; i++)
- {
- if (GNUNET_OK !=
- TMH_plugin->insert_refresh_commit_coins (TMH_plugin->cls,
- session,
- session_hash,
- i,
- num_new_denoms,
- commit_coin[i]))
- {
- TMH_plugin->rollback (TMH_plugin->cls,
- session);
- return TMH_RESPONSE_reply_internal_db_error (connection);
- }
- }
- for (i = 0; i < TALER_CNC_KAPPA; i++)
- {
- if (GNUNET_OK !=
- TMH_plugin->insert_refresh_commit_links (TMH_plugin->cls,
- session,
- session_hash,
- i,
- coin_count,
- commit_link[i]))
- {
- TMH_plugin->rollback (TMH_plugin->cls,
- session);
- return TMH_RESPONSE_reply_internal_db_error (connection);
- }
- }
-
- if (GNUNET_OK !=
- TMH_plugin->commit (TMH_plugin->cls,
- session))
- {
- TALER_LOG_WARNING ("/refresh/melt transaction commit failed\n");
- return TMH_RESPONSE_reply_commit_error (connection);
- }
- return TMH_RESPONSE_reply_refresh_melt_success (connection,
- session_hash,
- refresh_session.noreveal_index);
-}
-
-
-/**
- * Send an error response with the details of the original melt
- * commitment and the location of the mismatch.
- *
- * @param connection the MHD connection to handle
- * @param session database connection to use
- * @param session_hash hash of session to query
- * @param off commitment offset to check
- * @param index index of the mismatch
- * @param object_name name of the object with the problem
- * @return #GNUNET_NO if we generated the error message
- * #GNUNET_SYSERR if we could not even generate an error message
- */
-static int
-send_melt_commitment_error (struct MHD_Connection *connection,
- struct TALER_MINTDB_Session *session,
- const struct GNUNET_HashCode *session_hash,
- unsigned int off,
- unsigned int index,
- const char *object_name)
-{
- struct TALER_MINTDB_MeltCommitment *mc;
- int ret;
-
- mc = TMH_plugin->get_melt_commitment (TMH_plugin->cls,
- session,
- session_hash);
- if (NULL == mc)
- {
- GNUNET_break (0);
- return (MHD_YES ==
- TMH_RESPONSE_reply_internal_error (connection,
- "Melt commitment assembly"))
- ? GNUNET_NO : GNUNET_SYSERR;
- }
- ret = (MHD_YES ==
- TMH_RESPONSE_reply_refresh_reveal_missmatch (connection,
- mc,
- off,
- index,
- object_name))
- ? GNUNET_NO : GNUNET_SYSERR;
- TMH_plugin->free_melt_commitment (TMH_plugin->cls,
- mc);
- return ret;
-}
-
-
-/**
- * Check if the given @a transfer_privs correspond to an honest
- * commitment for the given session.
- * Checks that the transfer private keys match their commitments.
- * Then derives the shared secret for each #TALER_CNC_KAPPA, and check that they match.
- *
- * @param connection the MHD connection to handle
- * @param session database connection to use
- * @param session_hash hash of session to query
- * @param off commitment offset to check
- * @param num_oldcoins size of the @a transfer_privs and @a melts arrays
- * @param transfer_privs private transfer keys
- * @param melts array of melted coins
- * @param num_newcoins number of newcoins being generated
- * @param denom_pubs array of @a num_newcoins keys for the new coins
- * @return #GNUNET_OK if the committment was honest,
- * #GNUNET_NO if there was a problem and we generated an error message
- * #GNUNET_SYSERR if we could not even generate an error message
- */
-static int
-check_commitment (struct MHD_Connection *connection,
- struct TALER_MINTDB_Session *session,
- const struct GNUNET_HashCode *session_hash,
- unsigned int off,
- unsigned int num_oldcoins,
- const struct TALER_TransferPrivateKeyP *transfer_privs,
- const struct TALER_MINTDB_RefreshMelt *melts,
- unsigned int num_newcoins,
- const struct TALER_DenominationPublicKey *denom_pubs)
-{
- unsigned int j;
- struct TALER_LinkSecretP last_shared_secret;
- int secret_initialized = GNUNET_NO;
- struct TALER_MINTDB_RefreshCommitLinkP *commit_links;
- struct TALER_MINTDB_RefreshCommitCoin *commit_coins;
-
- commit_links = GNUNET_malloc (num_oldcoins *
- sizeof (struct TALER_MINTDB_RefreshCommitLinkP));
- if (GNUNET_OK !=
- TMH_plugin->get_refresh_commit_links (TMH_plugin->cls,
- session,
- session_hash,
- off,
- num_oldcoins,
- commit_links))
- {
- GNUNET_break (0);
- GNUNET_free (commit_links);
- return (MHD_YES == TMH_RESPONSE_reply_internal_db_error (connection))
- ? GNUNET_NO : GNUNET_SYSERR;
- }
-
- for (j = 0; j < num_oldcoins; j++)
- {
- struct TALER_LinkSecretP shared_secret;
- struct TALER_TransferPublicKeyP transfer_pub_check;
-
- GNUNET_CRYPTO_ecdhe_key_get_public (&transfer_privs[j].ecdhe_priv,
- &transfer_pub_check.ecdhe_pub);
- if (0 !=
- memcmp (&transfer_pub_check,
- &commit_links[j].transfer_pub,
- sizeof (struct TALER_TransferPublicKeyP)))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "transfer keys do not match\n");
- GNUNET_free (commit_links);
- return send_melt_commitment_error (connection,
- session,
- session_hash,
- off,
- j,
- "transfer key");
- }
-
- if (GNUNET_OK !=
- TALER_link_decrypt_secret (&commit_links[j].shared_secret_enc,
- &transfer_privs[j],
- &melts[j].coin.coin_pub,
- &shared_secret))
- {
- GNUNET_free (commit_links);
- return (MHD_YES ==
- TMH_RESPONSE_reply_internal_error (connection,
- "Transfer secret decryption error"))
- ? GNUNET_NO : GNUNET_SYSERR;
- }
- if (GNUNET_NO == secret_initialized)
- {
- secret_initialized = GNUNET_YES;
- last_shared_secret = shared_secret;
- }
- else if (0 != memcmp (&shared_secret,
- &last_shared_secret,
- sizeof (struct GNUNET_HashCode)))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "shared secrets do not match\n");
- GNUNET_free (commit_links);
- return send_melt_commitment_error (connection,
- session,
- session_hash,
- off,
- j,
- "transfer secret");
- }
- }
- GNUNET_break (GNUNET_YES == secret_initialized);
- GNUNET_free (commit_links);
-
- /* Check that the commitments for all new coins were correct */
- commit_coins = GNUNET_malloc (num_newcoins *
- sizeof (struct TALER_MINTDB_RefreshCommitCoin));
-
- if (GNUNET_OK !=
- TMH_plugin->get_refresh_commit_coins (TMH_plugin->cls,
- session,
- session_hash,
- off,
- num_newcoins,
- commit_coins))
- {
- GNUNET_break (0);
- GNUNET_free (commit_coins);
- return (MHD_YES == TMH_RESPONSE_reply_internal_db_error (connection))
- ? GNUNET_NO : GNUNET_SYSERR;
- }
-
- for (j = 0; j < num_newcoins; j++)
- {
- struct TALER_RefreshLinkDecrypted *link_data;
- struct TALER_CoinSpendPublicKeyP coin_pub;
- struct GNUNET_HashCode h_msg;
- char *buf;
- size_t buf_len;
-
- link_data = TALER_refresh_decrypt (commit_coins[j].refresh_link,
- &last_shared_secret);
- if (NULL == link_data)
- {
- GNUNET_break (0);
- GNUNET_free (commit_coins);
- return (MHD_YES == TMH_RESPONSE_reply_internal_error (connection,
- "Decryption error"))
- ? GNUNET_NO : GNUNET_SYSERR;
- }
-
- GNUNET_CRYPTO_eddsa_key_get_public (&link_data->coin_priv.eddsa_priv,
- &coin_pub.eddsa_pub);
- GNUNET_CRYPTO_hash (&coin_pub,
- sizeof (struct TALER_CoinSpendPublicKeyP),
- &h_msg);
- if (0 == (buf_len =
- GNUNET_CRYPTO_rsa_blind (&h_msg,
- link_data->blinding_key.rsa_blinding_key,
- denom_pubs[j].rsa_public_key,
- &buf)))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "blind failed\n");
- GNUNET_free (commit_coins);
- return (MHD_YES == TMH_RESPONSE_reply_internal_error (connection,
- "Blinding error"))
- ? GNUNET_NO : GNUNET_SYSERR;
- }
-
- if ( (buf_len != commit_coins[j].coin_ev_size) ||
- (0 != memcmp (buf,
- commit_coins[j].coin_ev,
- buf_len)) )
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "blind envelope does not match for k=%u, old=%d\n",
- off,
- (int) j);
- GNUNET_free (commit_coins);
- return send_melt_commitment_error (connection,
- session,
- session_hash,
- off,
- j,
- "envelope");
- }
- GNUNET_free (buf);
- }
- GNUNET_free (commit_coins);
-
- return GNUNET_OK;
-}
-
-
-/**
- * Mint a coin as part of a refresh operation. Obtains the
- * envelope from the database and performs the signing operation.
- *
- * @param connection the MHD connection to handle
- * @param session database connection to use
- * @param session_hash hash of session to query
- * @param key_state key state to lookup denomination pubs
- * @param denom_pub denomination key for the coin to create
- * @param commit_coin the coin that was committed
- * @param coin_off number of the coin
- * @return NULL on error, otherwise signature over the coin
- */
-static struct TALER_DenominationSignature
-refresh_mint_coin (struct MHD_Connection *connection,
- struct TALER_MINTDB_Session *session,
- const struct GNUNET_HashCode *session_hash,
- struct TMH_KS_StateHandle *key_state,
- const struct TALER_DenominationPublicKey *denom_pub,
- const struct TALER_MINTDB_RefreshCommitCoin *commit_coin,
- unsigned int coin_off)
-{
- struct TALER_MINTDB_DenominationKeyIssueInformation *dki;
- struct TALER_DenominationSignature ev_sig;
-
- dki = TMH_KS_denomination_key_lookup (key_state,
- denom_pub,
- TMH_KS_DKU_WITHDRAW);
- if (NULL == dki)
- {
- GNUNET_break (0);
- ev_sig.rsa_signature = NULL;
- return ev_sig;
- }
- ev_sig.rsa_signature
- = GNUNET_CRYPTO_rsa_sign (dki->denom_priv.rsa_private_key,
- commit_coin->coin_ev,
- commit_coin->coin_ev_size);
- if (NULL == ev_sig.rsa_signature)
- {
- GNUNET_break (0);
- return ev_sig;
- }
- if (GNUNET_OK !=
- TMH_plugin->insert_refresh_out (TMH_plugin->cls,
- session,
- session_hash,
- coin_off,
- &ev_sig))
- {
- GNUNET_break (0);
- GNUNET_CRYPTO_rsa_signature_free (ev_sig.rsa_signature);
- ev_sig.rsa_signature = NULL;
- }
- return ev_sig;
-}
-
-
-/**
- * Execute a "/refresh/reveal". The client is revealing to us the
- * transfer keys for @a #TALER_CNC_KAPPA-1 sets of coins. Verify that the
- * revealed transfer keys would allow linkage to the blinded coins,
- * and if so, return the signed coins for corresponding to the set of
- * coins that was not chosen.
- *
- * @param connection the MHD connection to handle
- * @param session_hash hash identifying the refresh session
- * @param num_oldcoins size of y-dimension of @a transfer_privs array
- * @param transfer_privs array with the revealed transfer keys,
- * x-dimension must be #TALER_CNC_KAPPA - 1
- * @return MHD result code
- */
-int
-TMH_DB_execute_refresh_reveal (struct MHD_Connection *connection,
- const struct GNUNET_HashCode *session_hash,
- unsigned int num_oldcoins,
- struct TALER_TransferPrivateKeyP **transfer_privs)
-{
- int res;
- struct TALER_MINTDB_Session *session;
- struct TALER_MINTDB_RefreshSession refresh_session;
- struct TMH_KS_StateHandle *key_state;
- struct TALER_MINTDB_RefreshMelt *melts;
- struct TALER_DenominationPublicKey *denom_pubs;
- struct TALER_DenominationSignature *ev_sigs;
- struct TALER_MINTDB_RefreshCommitCoin *commit_coins;
- unsigned int i;
- unsigned int j;
- unsigned int off;
-
- if (NULL == (session = TMH_plugin->get_session (TMH_plugin->cls,
- TMH_test_mode)))
- {
- GNUNET_break (0);
- return TMH_RESPONSE_reply_internal_db_error (connection);
- }
-
- res = TMH_plugin->get_refresh_session (TMH_plugin->cls,
- session,
- session_hash,
- &refresh_session);
- if (GNUNET_NO == res)
- return TMH_RESPONSE_reply_arg_invalid (connection,
- "session_hash");
- if (GNUNET_SYSERR == res)
- return TMH_RESPONSE_reply_internal_db_error (connection);
- if (0 == refresh_session.num_oldcoins)
- {
- GNUNET_break (0);
- return TMH_RESPONSE_reply_internal_db_error (connection);
- }
-
- melts = GNUNET_malloc (refresh_session.num_oldcoins *
- sizeof (struct TALER_MINTDB_RefreshMelt));
- for (j=0;j<refresh_session.num_oldcoins;j++)
- {
- if (GNUNET_OK !=
- TMH_plugin->get_refresh_melt (TMH_plugin->cls,
- session,
- session_hash,
- j,
- &melts[j]))
- {
- GNUNET_break (0);
- GNUNET_free (melts);
- return TMH_RESPONSE_reply_internal_db_error (connection);
- }
- }
- denom_pubs = GNUNET_malloc (refresh_session.num_newcoins *
- sizeof (struct TALER_DenominationPublicKey));
- if (GNUNET_OK !=
- TMH_plugin->get_refresh_order (TMH_plugin->cls,
- session,
- session_hash,
- refresh_session.num_newcoins,
- denom_pubs))
- {
- GNUNET_break (0);
- GNUNET_free (denom_pubs);
- GNUNET_free (melts);
- return (MHD_YES == TMH_RESPONSE_reply_internal_db_error (connection))
- ? GNUNET_NO : GNUNET_SYSERR;
- }
-
-
- off = 0;
- for (i=0;i<TALER_CNC_KAPPA - 1;i++)
- {
- if (i == refresh_session.noreveal_index)
- off = 1;
- if (GNUNET_OK !=
- (res = check_commitment (connection,
- session,
- session_hash,
- i + off,
- refresh_session.num_oldcoins,
- transfer_privs[i + off],
- melts,
- refresh_session.num_newcoins,
- denom_pubs)))
- {
- for (j=0;j<refresh_session.num_newcoins;j++)
- GNUNET_CRYPTO_rsa_public_key_free (denom_pubs[j].rsa_public_key);
- GNUNET_free (denom_pubs);
- GNUNET_free (melts);
- return (GNUNET_NO == res) ? MHD_YES : MHD_NO;
- }
- }
- GNUNET_free (melts);
-
- /* Client request OK, start transaction */
- if (GNUNET_OK !=
- TMH_plugin->start (TMH_plugin->cls,
- session))
- {
- GNUNET_break (0);
- for (j=0;j<refresh_session.num_newcoins;j++)
- GNUNET_CRYPTO_rsa_public_key_free (denom_pubs[j].rsa_public_key);
- GNUNET_free (denom_pubs);
- return TMH_RESPONSE_reply_internal_db_error (connection);
- }
-
- commit_coins = GNUNET_malloc (refresh_session.num_newcoins *
- sizeof (struct TALER_MINTDB_RefreshCommitCoin));
- if (GNUNET_OK !=
- TMH_plugin->get_refresh_commit_coins (TMH_plugin->cls,
- session,
- session_hash,
- refresh_session.noreveal_index,
- refresh_session.num_newcoins,
- commit_coins))
- {
- GNUNET_break (0);
- GNUNET_free (commit_coins);
- for (j=0;j<refresh_session.num_newcoins;j++)
- GNUNET_CRYPTO_rsa_public_key_free (denom_pubs[j].rsa_public_key);
- GNUNET_free (denom_pubs);
- return TMH_RESPONSE_reply_internal_db_error (connection);
- }
- ev_sigs = GNUNET_malloc (refresh_session.num_newcoins *
- sizeof (struct TALER_DenominationSignature));
- key_state = TMH_KS_acquire ();
- for (j=0;j<refresh_session.num_newcoins;j++)
- {
- ev_sigs[j] = refresh_mint_coin (connection,
- session,
- session_hash,
- key_state,
- &denom_pubs[j],
- &commit_coins[j],
- j);
- if (NULL == ev_sigs[j].rsa_signature)
- {
- TMH_KS_release (key_state);
- for (i=0;i<j;i++)
- GNUNET_CRYPTO_rsa_signature_free (ev_sigs[i].rsa_signature);
- GNUNET_free (ev_sigs);
- for (j=0;j<refresh_session.num_newcoins;j++)
- GNUNET_CRYPTO_rsa_public_key_free (denom_pubs[j].rsa_public_key);
- GNUNET_free (denom_pubs);
- GNUNET_free (commit_coins);
- return TMH_RESPONSE_reply_internal_db_error (connection);
- }
- }
- TMH_KS_release (key_state);
- for (j=0;j<refresh_session.num_newcoins;j++)
- GNUNET_CRYPTO_rsa_public_key_free (denom_pubs[j].rsa_public_key);
- GNUNET_free (denom_pubs);
- GNUNET_free (commit_coins);
-
- if (GNUNET_OK !=
- TMH_plugin->commit (TMH_plugin->cls,
- session))
- {
- TALER_LOG_WARNING ("/refresh/reveal transaction commit failed\n");
- for (i=0;i<refresh_session.num_newcoins;i++)
- GNUNET_CRYPTO_rsa_signature_free (ev_sigs[i].rsa_signature);
- GNUNET_free (ev_sigs);
- return TMH_RESPONSE_reply_commit_error (connection);
- }
-
- res = TMH_RESPONSE_reply_refresh_reveal_success (connection,
- refresh_session.num_newcoins,
- ev_sigs);
- for (i=0;i<refresh_session.num_newcoins;i++)
- GNUNET_CRYPTO_rsa_signature_free (ev_sigs[i].rsa_signature);
- GNUNET_free (ev_sigs);
- return res;
-}
-
-
-/**
- * Closure for #handle_transfer_data().
- */
-struct HTD_Context
-{
-
- /**
- * Session link data we collect.
- */
- struct TMH_RESPONSE_LinkSessionInfo *sessions;
-
- /**
- * Database session. Nothing to do with @a sessions.
- */
- struct TALER_MINTDB_Session *session;
-
- /**
- * MHD connection, for queueing replies.
- */
- struct MHD_Connection *connection;
-
- /**
- * Number of sessions the coin was melted into.
- */
- unsigned int num_sessions;
-
- /**
- * How are we expected to proceed. #GNUNET_SYSERR if we
- * failed to return an error (should return #MHD_NO).
- * #GNUNET_NO if we succeeded in queueing an MHD error
- * (should return #MHD_YES from #TMH_execute_refresh_link),
- * #GNUNET_OK if we should call #TMH_RESPONSE_reply_refresh_link_success().
- */
- int status;
-};
-
-
-/**
- * Function called with the session hashes and transfer secret
- * information for a given coin. Gets the linkage data and
- * builds the reply for the client.
- *
- *
- * @param cls closure, a `struct HTD_Context`
- * @param session_hash a session the coin was melted in
- * @param transfer_pub public transfer key for the session
- * @param shared_secret_enc set to shared secret for the session
- */
-static void
-handle_transfer_data (void *cls,
- const struct GNUNET_HashCode *session_hash,
- const struct TALER_TransferPublicKeyP *transfer_pub,
- const struct TALER_EncryptedLinkSecretP *shared_secret_enc)
-{
- struct HTD_Context *ctx = cls;
- struct TALER_MINTDB_LinkDataList *ldl;
- struct TMH_RESPONSE_LinkSessionInfo *lsi;
-
- if (GNUNET_OK != ctx->status)
- return;
- ldl = TMH_plugin->get_link_data_list (TMH_plugin->cls,
- ctx->session,
- session_hash);
- if (NULL == ldl)
- {
- GNUNET_break (0);
- ctx->status = GNUNET_NO;
- if (MHD_NO ==
- TMH_RESPONSE_reply_json_pack (ctx->connection,
- MHD_HTTP_NOT_FOUND,
- "{s:s}",
- "error",
- "link data not found (link)"))
- ctx->status = GNUNET_SYSERR;
- return;
- }
- GNUNET_array_grow (ctx->sessions,
- ctx->num_sessions,
- ctx->num_sessions + 1);
- lsi = &ctx->sessions[ctx->num_sessions - 1];
- lsi->transfer_pub = *transfer_pub;
- lsi->shared_secret_enc = *shared_secret_enc;
- lsi->ldl = ldl;
-}
-
-
-/**
- * Execute a "/refresh/link". Returns the linkage information that
- * will allow the owner of a coin to follow the refresh trail to
- * the refreshed coin.
- *
- * @param connection the MHD connection to handle
- * @param coin_pub public key of the coin to link
- * @return MHD result code
- */
-int
-TMH_DB_execute_refresh_link (struct MHD_Connection *connection,
- const struct TALER_CoinSpendPublicKeyP *coin_pub)
-{
- struct HTD_Context ctx;
- int res;
- unsigned int i;
-
- if (NULL == (ctx.session = TMH_plugin->get_session (TMH_plugin->cls,
- TMH_test_mode)))
- {
- GNUNET_break (0);
- return TMH_RESPONSE_reply_internal_db_error (connection);
- }
- ctx.connection = connection;
- ctx.num_sessions = 0;
- ctx.sessions = NULL;
- ctx.status = GNUNET_OK;
- res = TMH_plugin->get_transfer (TMH_plugin->cls,
- ctx.session,
- coin_pub,
- &handle_transfer_data,
- &ctx);
- if (GNUNET_SYSERR == ctx.status)
- {
- res = MHD_NO;
- goto cleanup;
- }
- if (GNUNET_NO == ctx.status)
- {
- res = MHD_YES;
- goto cleanup;
- }
- GNUNET_assert (GNUNET_OK == ctx.status);
- if (0 == ctx.num_sessions)
- return TMH_RESPONSE_reply_arg_unknown (connection,
- "coin_pub");
- res = TMH_RESPONSE_reply_refresh_link_success (connection,
- ctx.num_sessions,
- ctx.sessions);
- cleanup:
- for (i=0;i<ctx.num_sessions;i++)
- TMH_plugin->free_link_data_list (TMH_plugin->cls,
- ctx.sessions[i].ldl);
- GNUNET_free (ctx.sessions);
- return res;
-}
-
-
-/**
- * Add an incoming transaction to the database. Checks if the
- * transaction is fresh (not a duplicate) and if so adds it to
- * the database.
- *
- * @param connection the MHD connection to handle
- * @param reserve_pub public key of the reserve
- * @param amount amount to add to the reserve
- * @param execution_time when did we receive the wire transfer
- * @param wire details about the wire transfer
- * @return MHD result code
- */
-int
-TMH_DB_execute_admin_add_incoming (struct MHD_Connection *connection,
- const struct TALER_ReservePublicKeyP *reserve_pub,
- const struct TALER_Amount *amount,
- struct GNUNET_TIME_Absolute execution_time,
- json_t *wire)
-{
- struct TALER_MINTDB_Session *session;
- int ret;
-
- if (NULL == (session = TMH_plugin->get_session (TMH_plugin->cls,
- TMH_test_mode)))
- {
- GNUNET_break (0);
- return TMH_RESPONSE_reply_internal_db_error (connection);
- }
- ret = TMH_plugin->reserves_in_insert (TMH_plugin->cls,
- session,
- reserve_pub,
- amount,
- execution_time,
- wire);
- if (GNUNET_SYSERR == ret)
- {
- GNUNET_break (0);
- return TMH_RESPONSE_reply_internal_db_error (connection);
- }
- return TMH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_OK,
- "{s:s}",
- "status",
- (GNUNET_OK == ret)
- ? "NEW"
- : "DUP");
-}
-
-
-/* end of taler-mint-httpd_db.c */
diff --git a/src/backend/taler-mint-httpd_db.h b/src/backend/taler-mint-httpd_db.h
deleted file mode 100644
index 8a171153..00000000
--- a/src/backend/taler-mint-httpd_db.h
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2014, 2015 Christian Grothoff (and other contributing authors)
-
- 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, If not, see <http://www.gnu.org/licenses/>
-*/
-/**
- * @file mint/taler-mint-httpd_db.h
- * @brief High-level (transactional-layer) database operations for the mint
- * @author Chrisitan Grothoff
- */
-#ifndef TALER_MINT_HTTPD_DB_H
-#define TALER_MINT_HTTPD_DB_H
-
-#include <microhttpd.h>
-#include "taler_mintdb_plugin.h"
-
-
-/**
- * Execute a "/deposit". The validity of the coin and signature
- * have already been checked. The database must now check that
- * the coin is not (double or over) spent, and execute the
- * transaction (record details, generate success or failure response).
- *
- * @param connection the MHD connection to handle
- * @param deposit information about the deposit
- * @return MHD result code
- */
-int
-TMH_DB_execute_deposit (struct MHD_Connection *connection,
- const struct TALER_MINTDB_Deposit *deposit);
-
-
-/**
- * Execute a "/withdraw/status". Given the public key of a reserve,
- * return the associated transaction history.
- *
- * @param connection the MHD connection to handle
- * @param reserve_pub public key of the reserve to check
- * @return MHD result code
- */
-int
-TMH_DB_execute_withdraw_status (struct MHD_Connection *connection,
- const struct TALER_ReservePublicKeyP *reserve_pub);
-
-
-/**
- * Execute a "/withdraw/sign". Given a reserve and a properly signed
- * request to withdraw a coin, check the balance of the reserve and
- * if it is sufficient, store the request and return the signed
- * blinded envelope.
- *
- * @param connection the MHD connection to handle
- * @param reserve public key of the reserve
- * @param denomination_pub public key of the denomination requested
- * @param blinded_msg blinded message to be signed
- * @param blinded_msg_len number of bytes in @a blinded_msg
- * @param signature signature over the withdraw request, to be stored in DB
- * @return MHD result code
- */
-int
-TMH_DB_execute_withdraw_sign (struct MHD_Connection *connection,
- const struct TALER_ReservePublicKeyP *reserve,
- const struct TALER_DenominationPublicKey *denomination_pub,
- const char *blinded_msg,
- size_t blinded_msg_len,
- const struct TALER_ReserveSignatureP *signature);
-
-
-/**
- * @brief Details about a melt operation of an individual coin.
- */
-struct TMH_DB_MeltDetails
-{
-
- /**
- * Information about the coin being melted.
- */
- struct TALER_CoinPublicInfo coin_info;
-
- /**
- * Signature allowing the melt (using
- * a `struct TALER_MINTDB_RefreshMeltConfirmSignRequestBody`) to sign over.
- */
- struct TALER_CoinSpendSignatureP melt_sig;
-
- /**
- * How much of the coin's value did the client allow to be melted?
- * This amount includes the fees, so the final amount contributed
- * to the melt is this value minus the fee for melting the coin.
- */
- struct TALER_Amount melt_amount_with_fee;
-};
-
-
-/**
- * Execute a "/refresh/melt". We have been given a list of valid
- * coins and a request to melt them into the given
- * @a refresh_session_pub. Check that the coins all have the
- * required value left and if so, store that they have been
- * melted and confirm the melting operation to the client.
- *
- * @param connection the MHD connection to handle
- * @param session_hash hash code of the session the coins are melted into
- * @param num_new_denoms number of entries in @a denom_pubs, size of y-dimension of @a commit_coin array
- * @param denom_pubs array of public denomination keys for the refresh (?)
- * @param coin_count number of entries in @ a coin_melt_details, size of y-dimension of @a commit_link array
- * @param coin_melt_details signatures and (residual) value of and information about the respective coin to be melted
- * @param commit_coin 2d array of coin commitments (what the mint is to sign
- * once the "/refres/reveal" of cut and choose is done)
- * @param commit_link 2d array of coin link commitments (what the mint is
- * to return via "/refresh/link" to enable linkage in the
- * future)
- * @return MHD result code
- */
-int
-TMH_DB_execute_refresh_melt (struct MHD_Connection *connection,
- const struct GNUNET_HashCode *session_hash,
- unsigned int num_new_denoms,
- const struct TALER_DenominationPublicKey *denom_pubs,
- unsigned int coin_count,
- const struct TMH_DB_MeltDetails *coin_melt_details,
- struct TALER_MINTDB_RefreshCommitCoin *const* commit_coin,
- struct TALER_MINTDB_RefreshCommitLinkP *const* commit_link);
-
-
-/**
- * Execute a "/refresh/reveal". The client is revealing to us the
- * transfer keys for #TALER_CNC_KAPPA-1 sets of coins. Verify that the
- * revealed transfer keys would allow linkage to the blinded coins,
- * and if so, return the signed coins for corresponding to the set of
- * coins that was not chosen.
- *
- * @param connection the MHD connection to handle
- * @param session_hash hash over the refresh session
- * @param num_oldcoins size of y-dimension of @a transfer_privs array
- * @param transfer_privs array with the revealed transfer keys, #TALER_CNC_KAPPA is 1st-dimension
- * @return MHD result code
- */
-int
-TMH_DB_execute_refresh_reveal (struct MHD_Connection *connection,
- const struct GNUNET_HashCode *session_hash,
- unsigned int num_oldcoins,
- struct TALER_TransferPrivateKeyP **transfer_privs);
-
-
-/**
- * Execute a "/refresh/link". Returns the linkage information that
- * will allow the owner of a coin to follow the refresh trail to the
- * refreshed coin.
- *
- * @param connection the MHD connection to handle
- * @param coin_pub public key of the coin to link
- * @return MHD result code
- */
-int
-TMH_DB_execute_refresh_link (struct MHD_Connection *connection,
- const struct TALER_CoinSpendPublicKeyP *coin_pub);
-
-
-
-/**
- * Add an incoming transaction to the database.
- *
- * @param connection the MHD connection to handle
- * @param reserve_pub public key of the reserve
- * @param amount amount to add to the reserve
- * @param execution_time when did we receive the wire transfer
- * @param wire details about the wire transfer
- * @return MHD result code
- */
-int
-TMH_DB_execute_admin_add_incoming (struct MHD_Connection *connection,
- const struct TALER_ReservePublicKeyP *reserve_pub,
- const struct TALER_Amount *amount,
- struct GNUNET_TIME_Absolute execution_time,
- json_t *wire);
-
-
-#endif
-/* TALER_MINT_HTTPD_DB_H */
diff --git a/src/backend/taler-mint-httpd_deposit.c b/src/backend/taler-mint-httpd_deposit.c
deleted file mode 100644
index 5725cd1c..00000000
--- a/src/backend/taler-mint-httpd_deposit.c
+++ /dev/null
@@ -1,270 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2014, 2015 GNUnet e.V.
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU Affero General Public License as published by the Free Software
- 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 Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License along with
- TALER; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/>
-*/
-/**
- * @file taler-mint-httpd_deposit.c
- * @brief Handle /deposit requests; parses the POST and JSON and
- * verifies the coin signature before handing things off
- * to the database.
- * @author Florian Dold
- * @author Benedikt Mueller
- * @author Christian Grothoff
- *
- * TODO:
- * - ugly if-construction for deposit type
- */
-#include "platform.h"
-#include <gnunet/gnunet_util_lib.h>
-#include <jansson.h>
-#include <microhttpd.h>
-#include <pthread.h>
-#include "taler-mint-httpd_parsing.h"
-#include "taler-mint-httpd_deposit.h"
-#include "taler-mint-httpd_responses.h"
-#include "taler-mint-httpd_keystate.h"
-
-
-/**
- * We have parsed the JSON information about the deposit, do some
- * basic sanity checks (especially that the signature on the coin is
- * valid, and that this type of coin exists) and then execute the
- * deposit.
- *
- * @param connection the MHD connection to handle
- * @param deposit information about the deposit
- * @return MHD result code
- */
-static int
-verify_and_execute_deposit (struct MHD_Connection *connection,
- const struct TALER_MINTDB_Deposit *deposit)
-{
- struct TMH_KS_StateHandle *key_state;
- struct TALER_DepositRequestPS dr;
- struct TALER_MINTDB_DenominationKeyIssueInformation *dki;
- struct TALER_Amount fee_deposit;
-
- dr.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_DEPOSIT);
- dr.purpose.size = htonl (sizeof (struct TALER_DepositRequestPS));
- dr.h_contract = deposit->h_contract;
- dr.h_wire = deposit->h_wire;
- dr.timestamp = GNUNET_TIME_absolute_hton (deposit->timestamp);
- dr.refund_deadline = GNUNET_TIME_absolute_hton (deposit->refund_deadline);
- dr.transaction_id = GNUNET_htonll (deposit->transaction_id);
- TALER_amount_hton (&dr.amount_with_fee,
- &deposit->amount_with_fee);
- TALER_amount_hton (&dr.deposit_fee,
- &deposit->deposit_fee);
- dr.merchant = deposit->merchant_pub;
- dr.coin_pub = deposit->coin.coin_pub;
- if (GNUNET_OK !=
- GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_DEPOSIT,
- &dr.purpose,
- &deposit->csig.eddsa_signature,
- &deposit->coin.coin_pub.eddsa_pub))
- {
- TALER_LOG_WARNING ("Invalid signature on /deposit request\n");
- return TMH_RESPONSE_reply_signature_invalid (connection,
- "coin_sig");
- }
- /* check denomination exists and is valid */
- key_state = TMH_KS_acquire ();
- dki = TMH_KS_denomination_key_lookup (key_state,
- &deposit->coin.denom_pub,
- TMH_KS_DKU_DEPOSIT);
- if (NULL == dki)
- {
- TMH_KS_release (key_state);
- TALER_LOG_WARNING ("Unknown denomination key in /deposit request\n");
- return TMH_RESPONSE_reply_arg_unknown (connection,
- "denom_pub");
- }
- /* check coin signature */
- if (GNUNET_YES !=
- TALER_test_coin_valid (&deposit->coin))
- {
- TALER_LOG_WARNING ("Invalid coin passed for /deposit\n");
- TMH_KS_release (key_state);
- return TMH_RESPONSE_reply_signature_invalid (connection,
- "ub_sig");
- }
- TALER_amount_ntoh (&fee_deposit,
- &dki->issue.properties.fee_deposit);
- if (0 < TALER_amount_cmp (&fee_deposit,
- &deposit->amount_with_fee))
- {
- TMH_KS_release (key_state);
- return TMH_RESPONSE_reply_external_error (connection,
- "deposited amount smaller than depositing fee");
- }
- TMH_KS_release (key_state);
-
- return TMH_DB_execute_deposit (connection,
- deposit);
-}
-
-
-/**
- * Handle a "/deposit" request. This function parses the
- * JSON information and then calls #verify_and_execute_deposit()
- * to verify the signatures and execute the deposit.
- *
- * @param connection the MHD connection to handle
- * @param root root of the posted JSON
- * @param amount how much should be deposited
- * @param wire json describing the wire details (?)
- * @return MHD result code
- */
-static int
-parse_and_handle_deposit_request (struct MHD_Connection *connection,
- const json_t *root,
- const struct TALER_Amount *amount,
- json_t *wire)
-{
- int res;
- struct TALER_MINTDB_Deposit deposit;
- struct TALER_MINTDB_DenominationKeyIssueInformation *dki;
- struct TMH_KS_StateHandle *ks;
- struct TMH_PARSE_FieldSpecification spec[] = {
- TMH_PARSE_member_denomination_public_key ("denom_pub", &deposit.coin.denom_pub),
- TMH_PARSE_member_denomination_signature ("ub_sig", &deposit.coin.denom_sig),
- TMH_PARSE_member_fixed ("coin_pub", &deposit.coin.coin_pub),
- TMH_PARSE_member_fixed ("merchant_pub", &deposit.merchant_pub),
- TMH_PARSE_member_fixed ("H_contract", &deposit.h_contract),
- TMH_PARSE_member_fixed ("H_wire", &deposit.h_wire),
- TMH_PARSE_member_fixed ("coin_sig", &deposit.csig),
- TMH_PARSE_member_uint64 ("transaction_id", &deposit.transaction_id),
- TMH_PARSE_member_time_abs ("timestamp", &deposit.timestamp),
- TMH_PARSE_member_time_abs ("refund_deadline", &deposit.refund_deadline),
- TMH_PARSE_MEMBER_END
- };
-
- memset (&deposit, 0, sizeof (deposit));
- res = TMH_PARSE_json_data (connection,
- root,
- spec);
- if (GNUNET_SYSERR == res)
- return MHD_NO; /* hard failure */
- if (GNUNET_NO == res)
- return MHD_YES; /* failure */
-
- if (GNUNET_YES !=
- TALER_json_validate_wireformat (TMH_expected_wire_format,
- wire))
- {
- TMH_PARSE_release_data (spec);
- return TMH_RESPONSE_reply_arg_unknown (connection,
- "wire");
- }
- if (GNUNET_OK !=
- TALER_hash_json (wire,
- &deposit.h_wire))
- {
- TALER_LOG_WARNING ("Failed to parse JSON wire format specification for /deposit request\n");
- TMH_PARSE_release_data (spec);
- return TMH_RESPONSE_reply_arg_invalid (connection,
- "wire");
- }
- ks = TMH_KS_acquire ();
- dki = TMH_KS_denomination_key_lookup (ks,
- &deposit.coin.denom_pub,
- TMH_KS_DKU_DEPOSIT);
- if (NULL == dki)
- {
- TMH_KS_release (ks);
- TMH_PARSE_release_data (spec);
- return TMH_RESPONSE_reply_arg_unknown (connection,
- "denom_pub");
- }
- TALER_amount_ntoh (&deposit.deposit_fee,
- &dki->issue.properties.fee_deposit);
- TMH_KS_release (ks);
- deposit.wire = wire;
- deposit.amount_with_fee = *amount;
- if (-1 == TALER_amount_cmp (&deposit.amount_with_fee,
- &deposit.deposit_fee))
- {
- /* Total amount smaller than fee, invalid */
- TMH_PARSE_release_data (spec);
- return TMH_RESPONSE_reply_arg_invalid (connection,
- "f");
- }
- res = verify_and_execute_deposit (connection,
- &deposit);
- TMH_PARSE_release_data (spec);
- return res;
-}
-
-
-/**
- * Handle a "/deposit" request. Parses the JSON in the post to find
- * the "type" (either DIRECT_DEPOSIT or INCREMENTAL_DEPOSIT), and, if
- * successful, passes the JSON data to
- * #parse_and_handle_deposit_request() to further check the details
- * of the operation specified in the "wire" field of the JSON data.
- * If everything checks out, this will ultimately lead to the
- * "/deposit" being executed, or rejected.
- *
- * @param rh context of the handler
- * @param connection the MHD connection to handle
- * @param[in,out] connection_cls the connection's closure (can be updated)
- * @param upload_data upload data
- * @param[in,out] upload_data_size number of bytes (left) in @a upload_data
- * @return MHD result code
- */
-int
-TMH_DEPOSIT_handler_deposit (struct TMH_RequestHandler *rh,
- struct MHD_Connection *connection,
- void **connection_cls,
- const char *upload_data,
- size_t *upload_data_size)
-{
- json_t *json;
- json_t *wire;
- int res;
- struct TALER_Amount amount;
- struct TMH_PARSE_FieldSpecification spec[] = {
- TMH_PARSE_member_object ("wire", &wire),
- TMH_PARSE_member_amount ("f", &amount),
- TMH_PARSE_MEMBER_END
- };
-
- res = TMH_PARSE_post_json (connection,
- connection_cls,
- upload_data,
- upload_data_size,
- &json);
- if (GNUNET_SYSERR == res)
- return MHD_NO;
- if ( (GNUNET_NO == res) || (NULL == json) )
- return MHD_YES;
- res = TMH_PARSE_json_data (connection,
- json,
- spec);
- if (GNUNET_OK != res)
- {
- json_decref (json);
- return (GNUNET_NO == res) ? MHD_YES : MHD_NO;
- }
- res = parse_and_handle_deposit_request (connection,
- json,
- &amount,
- wire);
- TMH_PARSE_release_data (spec);
- json_decref (json);
- return res;
-}
-
-
-/* end of taler-mint-httpd_deposit.c */
diff --git a/src/backend/taler-mint-httpd_deposit.h b/src/backend/taler-mint-httpd_deposit.h
deleted file mode 100644
index c2d3fe13..00000000
--- a/src/backend/taler-mint-httpd_deposit.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2014 GNUnet e.V.
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU Affero General Public License as published by the Free Software
- 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 Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License along with
- TALER; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/>
-*/
-/**
- * @file taler-mint-httpd_deposit.h
- * @brief Handle /deposit requests
- * @author Florian Dold
- * @author Benedikt Mueller
- * @author Christian Grothoff
- */
-#ifndef TALER_MINT_HTTPD_DEPOSIT_H
-#define TALER_MINT_HTTPD_DEPOSIT_H
-
-#include <gnunet/gnunet_util_lib.h>
-#include <microhttpd.h>
-#include "taler-mint-httpd.h"
-
-
-/**
- * Handle a "/deposit" request. Parses the JSON in the post to find
- * the "type" (either DIRECT_DEPOSIT or INCREMENTAL_DEPOSIT), and, if
- * successful, passes the JSON data to
- * #parse_and_handle_deposit_request() to further check the details
- * of the operation specified in the "wire" field of the JSON data.
- * If everything checks out, this will ultimately lead to the
- * "/deposit" being executed, or rejected.
- *
- * @param rh context of the handler
- * @param connection the MHD connection to handle
- * @param[in,out] connection_cls the connection's closure (can be updated)
- * @param upload_data upload data
- * @param[in,out] upload_data_size number of bytes (left) in @a upload_data
- * @return MHD result code
- */
-int
-TMH_DEPOSIT_handler_deposit (struct TMH_RequestHandler *rh,
- struct MHD_Connection *connection,
- void **connection_cls,
- const char *upload_data,
- size_t *upload_data_size);
-
-#endif
diff --git a/src/backend/taler-mint-httpd_keystate.c b/src/backend/taler-mint-httpd_keystate.c
deleted file mode 100644
index ec09ab44..00000000
--- a/src/backend/taler-mint-httpd_keystate.c
+++ /dev/null
@@ -1,867 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2014, 2015 GNUnet e.V.
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU Affero General Public License as published by the Free Software
- 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 Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License along with
- TALER; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/>
-*/
-/**
- * @file taler-mint-httpd_keystate.c
- * @brief management of our coin signing keys
- * @author Florian Dold
- * @author Benedikt Mueller
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include <pthread.h>
-#include "taler-mint-httpd_keystate.h"
-#include "taler_mintdb_plugin.h"
-
-
-/**
- * Snapshot of the (coin and signing) keys (including private keys) of
- * the mint. There can be multiple instances of this struct, as it is
- * reference counted and only destroyed once the last user is done
- * with it. The current instance is acquired using
- * #TMH_KS_acquire(). Using this function increases the
- * reference count. The contents of this structure (except for the
- * reference counter) should be considered READ-ONLY until it is
- * ultimately destroyed (as there can be many concurrent users).
- */
-struct TMH_KS_StateHandle
-{
- /**
- * JSON array with denomination keys. (Currently not really used
- * after initialization.)
- */
- json_t *denom_keys_array;
-
- /**
- * JSON array with signing keys. (Currently not really used
- * after initialization.)
- */
- json_t *sign_keys_array;
-
- /**
- * Cached JSON text that the mint will send for a "/keys" request.
- * Includes our @e TMH_master_public_key public key, the signing and
- * denomination keys as well as the @e reload_time.
- */
- char *keys_json;
-
- /**
- * Mapping from denomination keys to denomination key issue struct.
- * Used to lookup the key by hash.
- */
- struct GNUNET_CONTAINER_MultiHashMap *denomkey_map;
-
- /**
- * Hash context we used to combine the hashes of all denomination
- * keys into one big hash.
- */
- struct GNUNET_HashContext *hash_context;
-
- /**
- * When did we initiate the key reloading?
- */
- struct GNUNET_TIME_Absolute reload_time;
-
- /**
- * When is the next key invalid and we have to reload? (We also
- * reload on SIGUSR1.)
- */
- struct GNUNET_TIME_Absolute next_reload;
-
- /**
- * Mint signing key that should be used currently.
- */
- struct TALER_MINTDB_PrivateSigningKeyInformationP current_sign_key_issue;
-
- /**
- * Reference count. The struct is released when the RC hits zero.
- */
- unsigned int refcnt;
-};
-
-
-/**
- * Mint key state. Never use directly, instead access via
- * #TMH_KS_acquire() and #TMH_KS_release().
- */
-static struct TMH_KS_StateHandle *internal_key_state;
-
-/**
- * Mutex protecting access to #internal_key_state.
- */
-static pthread_mutex_t internal_key_state_mutex = PTHREAD_MUTEX_INITIALIZER;
-
-/**
- * Pipe used for signaling reloading of our key state.
- */
-static int reload_pipe[2];
-
-
-/**
- * Convert the public part of a denomination key issue to a JSON
- * object.
- *
- * @param pk public key of the denomination key
- * @param dki the denomination key issue
- * @return a JSON object describing the denomination key isue (public part)
- */
-static json_t *
-denom_key_issue_to_json (const struct TALER_DenominationPublicKey *pk,
- const struct TALER_MINTDB_DenominationKeyInformationP *dki)
-{
- struct TALER_Amount value;
- struct TALER_Amount fee_withdraw;
- struct TALER_Amount fee_deposit;
- struct TALER_Amount fee_refresh;
-
- TALER_amount_ntoh (&value,
- &dki->properties.value);
- TALER_amount_ntoh (&fee_withdraw,
- &dki->properties.fee_withdraw);
- TALER_amount_ntoh (&fee_deposit,
- &dki->properties.fee_deposit);
- TALER_amount_ntoh (&fee_refresh,
- &dki->properties.fee_refresh);
- return
- json_pack ("{s:o, s:o, s:o, s:o, s:o, s:o, s:o, s:o, s:o, s:o}",
- "master_sig",
- TALER_json_from_data (&dki->signature,
- sizeof (struct GNUNET_CRYPTO_EddsaSignature)),
- "stamp_start",
- TALER_json_from_abs (GNUNET_TIME_absolute_ntoh (dki->properties.start)),
- "stamp_expire_withdraw",
- TALER_json_from_abs (GNUNET_TIME_absolute_ntoh (dki->properties.expire_withdraw)),
- "stamp_expire_deposit",
- TALER_json_from_abs (GNUNET_TIME_absolute_ntoh (dki->properties.expire_spend)),
- "stamp_expire_legal",
- TALER_json_from_abs (GNUNET_TIME_absolute_ntoh (dki->properties.expire_legal)),
- "denom_pub",
- TALER_json_from_rsa_public_key (pk->rsa_public_key),
- "value",
- TALER_json_from_amount (&value),
- "fee_withdraw",
- TALER_json_from_amount (&fee_withdraw),
- "fee_deposit",
- TALER_json_from_amount (&fee_deposit),
- "fee_refresh",
- TALER_json_from_amount (&fee_refresh));
-}
-
-
-/**
- * Get the relative time value that describes how
- * far in the future do we want to provide coin keys.
- *
- * @return the provide duration
- */
-static struct GNUNET_TIME_Relative
-TALER_MINT_conf_duration_provide ()
-{
- struct GNUNET_TIME_Relative rel;
-
- if (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_time (cfg,
- "mint_keys",
- "lookahead_provide",
- &rel))
- {
- GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
- "mint_keys",
- "lookahead_provide",
- "time value required");
- GNUNET_assert (0);
- }
- return rel;
-}
-
-
-/**
- * Iterator for (re)loading/initializing denomination keys.
- *
- * @param cls closure
- * @param dki the denomination key issue
- * @param alias coin alias
- * @return #GNUNET_OK to continue to iterate,
- * #GNUNET_NO to stop iteration with no error,
- * #GNUNET_SYSERR to abort iteration with error!
- */
-static int
-reload_keys_denom_iter (void *cls,
- const char *alias,
- const struct TALER_MINTDB_DenominationKeyIssueInformation *dki)
-{
- struct TMH_KS_StateHandle *ctx = cls;
- struct GNUNET_TIME_Absolute now;
- struct GNUNET_TIME_Absolute horizon;
- struct GNUNET_HashCode denom_key_hash;
- struct TALER_MINTDB_DenominationKeyIssueInformation *d2;
- struct TALER_MINTDB_Session *session;
- int res;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Loading denomination key `%s'\n",
- alias);
- horizon = GNUNET_TIME_relative_to_absolute (TALER_MINT_conf_duration_provide ());
- if (GNUNET_TIME_absolute_ntoh (dki->issue.properties.start).abs_value_us >
- horizon.abs_value_us)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Skipping future denomination key `%s'\n",
- alias);
- return GNUNET_OK;
- }
- now = GNUNET_TIME_absolute_get ();
- if (GNUNET_TIME_absolute_ntoh (dki->issue.properties.expire_spend).abs_value_us <
- now.abs_value_us)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Skipping expired denomination key `%s'\n",
- alias);
- return GNUNET_OK;
- }
-
- GNUNET_CRYPTO_rsa_public_key_hash (dki->denom_pub.rsa_public_key,
- &denom_key_hash);
- GNUNET_CRYPTO_hash_context_read (ctx->hash_context,
- &denom_key_hash,
- sizeof (struct GNUNET_HashCode));
- session = TMH_plugin->get_session (TMH_plugin->cls,
- TMH_test_mode);
- if (NULL == session)
- return GNUNET_SYSERR;
- /* Try to insert DKI into DB until we succeed; note that if the DB
- failure is persistent, this code may loop forever (as there is no
- sane alternative, we cannot continue without the DKI being in the
- DB). */
- res = GNUNET_SYSERR;
- while (GNUNET_OK != res)
- {
- res = TMH_plugin->start (TMH_plugin->cls,
- session);
- if (GNUNET_OK != res)
- {
- /* Transaction start failed!? Very bad error, log and retry */
- GNUNET_break (0);
- continue;
- }
- res = TMH_plugin->get_denomination_info (TMH_plugin->cls,
- session,
- &dki->denom_pub,
- NULL);
- if (GNUNET_SYSERR == res)
- {
- /* Fetch failed!? Very bad error, log and retry */
- GNUNET_break (0);
- TMH_plugin->rollback (TMH_plugin->cls,
- session);
- continue;
- }
- if (GNUNET_OK == res)
- {
- /* Record exists, we're good, just exit */
- TMH_plugin->rollback (TMH_plugin->cls,
- session);
- break;
- }
- res = TMH_plugin->insert_denomination_info (TMH_plugin->cls,
- session,
- &dki->denom_pub,
- &dki->issue);
- if (GNUNET_OK != res)
- {
- /* Insert failed!? Very bad error, log and retry */
- GNUNET_break (0);
- TMH_plugin->rollback (TMH_plugin->cls,
- session);
- continue;
- }
- res = TMH_plugin->commit (TMH_plugin->cls,
- session);
- /* If commit succeeded, we're done, otherwise we retry; this
- time without logging, as theroetically commits can fail
- in a transactional DB due to concurrent activities that
- cannot be reconciled. This should be rare for DKIs, but
- as it is possible we just retry until we succeed. */
- }
-
- d2 = GNUNET_new (struct TALER_MINTDB_DenominationKeyIssueInformation);
- d2->issue = dki->issue;
- d2->denom_priv.rsa_private_key
- = GNUNET_CRYPTO_rsa_private_key_dup (dki->denom_priv.rsa_private_key);
- d2->denom_pub.rsa_public_key
- = GNUNET_CRYPTO_rsa_public_key_dup (dki->denom_pub.rsa_public_key);
- res = GNUNET_CONTAINER_multihashmap_put (ctx->denomkey_map,
- &denom_key_hash,
- d2,
- GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
- if (GNUNET_OK != res)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "Duplicate denomination key `%s'\n",
- alias);
- GNUNET_CRYPTO_rsa_private_key_free (d2->denom_priv.rsa_private_key);
- GNUNET_CRYPTO_rsa_public_key_free (d2->denom_pub.rsa_public_key);
- GNUNET_free (d2);
- return GNUNET_OK;
- }
- json_array_append_new (ctx->denom_keys_array,
- denom_key_issue_to_json (&dki->denom_pub,
- &dki->issue));
- return GNUNET_OK;
-}
-
-
-/**
- * Convert the public part of a sign key issue to a JSON object.
- *
- * @param ski the sign key issue
- * @return a JSON object describing the sign key isue (public part)
- */
-static json_t *
-sign_key_issue_to_json (const struct TALER_MintSigningKeyValidityPS *ski)
-{
- return
- json_pack ("{s:o, s:o, s:o, s:o, s:o, s:o}",
- "stamp_start",
- TALER_json_from_abs (GNUNET_TIME_absolute_ntoh (ski->start)),
- "stamp_expire",
- TALER_json_from_abs (GNUNET_TIME_absolute_ntoh (ski->expire)),
- "stamp_end",
- TALER_json_from_abs (GNUNET_TIME_absolute_ntoh (ski->end)),
- "master_pub",
- TALER_json_from_data (&ski->master_public_key,
- sizeof (struct TALER_MasterPublicKeyP)),
- "master_sig",
- TALER_json_from_data (&ski->signature,
- sizeof (struct TALER_MasterSignatureP)),
- "key",
- TALER_json_from_data (&ski->signkey_pub,
- sizeof (struct TALER_MintPublicKeyP)));
-}
-
-
-/**
- * Iterator for sign keys.
- *
- * @param cls closure
- * @param filename name of the file the key came from
- * @param ski the sign key issue
- * @return #GNUNET_OK to continue to iterate,
- * #GNUNET_NO to stop iteration with no error,
- * #GNUNET_SYSERR to abort iteration with error!
- */
-static int
-reload_keys_sign_iter (void *cls,
- const char *filename,
- const struct TALER_MINTDB_PrivateSigningKeyInformationP *ski)
-{
- struct TMH_KS_StateHandle *ctx = cls;
- struct GNUNET_TIME_Absolute now;
- struct GNUNET_TIME_Absolute horizon;
-
- horizon = GNUNET_TIME_relative_to_absolute (TALER_MINT_conf_duration_provide ());
- if (GNUNET_TIME_absolute_ntoh (ski->issue.start).abs_value_us >
- horizon.abs_value_us)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Skipping future signing key `%s'\n",
- filename);
- return GNUNET_OK;
- }
- now = GNUNET_TIME_absolute_get ();
- if (GNUNET_TIME_absolute_ntoh (ski->issue.expire).abs_value_us <
- now.abs_value_us)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Skipping expired signing key `%s'\n",
- filename);
- return GNUNET_OK;
- }
-
- /* The signkey is valid at this time, check if it's more recent than
- what we have so far! */
- if ( (GNUNET_TIME_absolute_ntoh (ctx->current_sign_key_issue.issue.start).abs_value_us <
- GNUNET_TIME_absolute_ntoh (ski->issue.start).abs_value_us) &&
- (GNUNET_TIME_absolute_ntoh (ski->issue.start).abs_value_us <
- now.abs_value_us) )
- {
- /* We use the most recent one, if it is valid now (not just in the near future) */
- ctx->current_sign_key_issue = *ski;
- }
- json_array_append_new (ctx->sign_keys_array,
- sign_key_issue_to_json (&ski->issue));
-
- return GNUNET_OK;
-}
-
-
-/**
- * Iterator for freeing denomination keys.
- *
- * @param cls closure with the `struct TMH_KS_StateHandle`
- * @param key key for the denomination key
- * @param value coin details
- * @return #GNUNET_OK to continue to iterate,
- * #GNUNET_NO to stop iteration with no error,
- * #GNUNET_SYSERR to abort iteration with error!
- */
-static int
-free_denom_key (void *cls,
- const struct GNUNET_HashCode *key,
- void *value)
-{
- struct TALER_MINTDB_DenominationKeyIssueInformation *dki = value;
-
- GNUNET_CRYPTO_rsa_private_key_free (dki->denom_priv.rsa_private_key);
- GNUNET_CRYPTO_rsa_public_key_free (dki->denom_pub.rsa_public_key);
- GNUNET_free (dki);
- return GNUNET_OK;
-}
-
-
-/**
- * Release key state, free if necessary (if reference count gets to zero).
- * Internal method used when the mutex is already held.
- *
- * @param key_state the key state to release
- */
-static void
-TMH_KS_release_ (struct TMH_KS_StateHandle *key_state)
-{
- GNUNET_assert (0 < key_state->refcnt);
- key_state->refcnt--;
- if (0 == key_state->refcnt)
- {
- if (NULL != key_state->denom_keys_array)
- {
- json_decref (key_state->denom_keys_array);
- key_state->denom_keys_array = NULL;
- }
- if (NULL != key_state->sign_keys_array)
- {
- json_decref (key_state->sign_keys_array);
- key_state->sign_keys_array = NULL;
- }
- if (NULL != key_state->denomkey_map)
- {
- GNUNET_CONTAINER_multihashmap_iterate (key_state->denomkey_map,
- &free_denom_key,
- key_state);
- GNUNET_CONTAINER_multihashmap_destroy (key_state->denomkey_map);
- key_state->denomkey_map = NULL;
- }
- GNUNET_free_non_null (key_state->keys_json);
- GNUNET_free (key_state);
- }
-}
-
-
-/**
- * Release key state, free if necessary (if reference count gets to zero).
- *
- * @param key_state the key state to release
- */
-void
-TMH_KS_release (struct TMH_KS_StateHandle *key_state)
-{
- GNUNET_assert (0 == pthread_mutex_lock (&internal_key_state_mutex));
- TMH_KS_release_ (key_state);
- GNUNET_assert (0 == pthread_mutex_unlock (&internal_key_state_mutex));
-}
-
-
-/**
- * Acquire the key state of the mint. Updates keys if necessary.
- * For every call to #TMH_KS_acquire(), a matching call
- * to #TMH_KS_release() must be made.
- *
- * @return the key state
- */
-struct TMH_KS_StateHandle *
-TMH_KS_acquire (void)
-{
- struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ();
- struct TMH_KS_StateHandle *key_state;
- json_t *keys;
- struct TALER_MintKeySetPS ks;
- struct TALER_MintSignatureP sig;
-
- GNUNET_assert (0 == pthread_mutex_lock (&internal_key_state_mutex));
- if ( (NULL != internal_key_state) &&
- (internal_key_state->next_reload.abs_value_us <= now.abs_value_us) )
- {
- TMH_KS_release_ (internal_key_state);
- internal_key_state = NULL;
- }
- if (NULL == internal_key_state)
- {
- key_state = GNUNET_new (struct TMH_KS_StateHandle);
- key_state->hash_context = GNUNET_CRYPTO_hash_context_start ();
- key_state->denom_keys_array = json_array ();
- GNUNET_assert (NULL != key_state->denom_keys_array);
- key_state->sign_keys_array = json_array ();
- GNUNET_assert (NULL != key_state->sign_keys_array);
- key_state->denomkey_map = GNUNET_CONTAINER_multihashmap_create (32,
- GNUNET_NO);
- key_state->reload_time = GNUNET_TIME_absolute_get ();
- TALER_round_abs_time (&key_state->reload_time);
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Loading keys from `%s'\n",
- TMH_mint_directory);
- TALER_MINTDB_denomination_keys_iterate (TMH_mint_directory,
- &reload_keys_denom_iter,
- key_state);
- TALER_MINTDB_signing_keys_iterate (TMH_mint_directory,
- &reload_keys_sign_iter,
- key_state);
- ks.purpose.size = htonl (sizeof (ks));
- ks.purpose.purpose = htonl (TALER_SIGNATURE_MINT_KEY_SET);
- ks.list_issue_date = GNUNET_TIME_absolute_hton (key_state->reload_time);
- GNUNET_CRYPTO_hash_context_finish (key_state->hash_context,
- &ks.hc);
- key_state->hash_context = NULL;
- GNUNET_assert (GNUNET_OK ==
- GNUNET_CRYPTO_eddsa_sign (&key_state->current_sign_key_issue.signkey_priv.eddsa_priv,
- &ks.purpose,
- &sig.eddsa_signature));
- key_state->next_reload = GNUNET_TIME_absolute_ntoh (key_state->current_sign_key_issue.issue.expire);
- if (0 == key_state->next_reload.abs_value_us)
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "No valid signing key found!\n");
-
- keys = json_pack ("{s:o, s:o, s:o, s:o, s:o, s:o}",
- "master_public_key",
- TALER_json_from_data (&TMH_master_public_key,
- sizeof (struct GNUNET_CRYPTO_EddsaPublicKey)),
- "signkeys", key_state->sign_keys_array,
- "denoms", key_state->denom_keys_array,
- "list_issue_date", TALER_json_from_abs (key_state->reload_time),
- "eddsa_pub", TALER_json_from_data (&key_state->current_sign_key_issue.issue.signkey_pub,
- sizeof (struct TALER_MintPublicKeyP)),
- "eddsa_sig", TALER_json_from_data (&sig,
- sizeof (struct TALER_MintSignatureP)));
- key_state->sign_keys_array = NULL;
- key_state->denom_keys_array = NULL;
- key_state->keys_json = json_dumps (keys,
- JSON_INDENT (2));
- json_decref (keys);
- internal_key_state = key_state;
- }
- key_state = internal_key_state;
- key_state->refcnt++;
- GNUNET_assert (0 == pthread_mutex_unlock (&internal_key_state_mutex));
-
- return key_state;
-}
-
-
-/**
- * Look up the issue for a denom public key.
- *
- * @param key_state state to look in
- * @param denom_pub denomination public key
- * @param use purpose for which the key is being located
- * @return the denomination key issue,
- * or NULL if denom_pub could not be found
- */
-struct TALER_MINTDB_DenominationKeyIssueInformation *
-TMH_KS_denomination_key_lookup (const struct TMH_KS_StateHandle *key_state,
- const struct TALER_DenominationPublicKey *denom_pub,
- enum TMH_KS_DenominationKeyUse use)
-{
- struct GNUNET_HashCode hc;
- struct TALER_MINTDB_DenominationKeyIssueInformation *dki;
- struct GNUNET_TIME_Absolute now;
-
- GNUNET_CRYPTO_rsa_public_key_hash (denom_pub->rsa_public_key,
- &hc);
- dki = GNUNET_CONTAINER_multihashmap_get (key_state->denomkey_map,
- &hc);
- if (NULL == dki)
- return NULL;
- now = GNUNET_TIME_absolute_get ();
- if (now.abs_value_us <
- GNUNET_TIME_absolute_ntoh (dki->issue.properties.start).abs_value_us)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Not returning DKI for %s, as start time is in the future\n",
- GNUNET_h2s (&hc));
- return NULL;
- }
- now = GNUNET_TIME_absolute_get ();
- switch (use)
- {
- case TMH_KS_DKU_WITHDRAW:
- if (now.abs_value_us >
- GNUNET_TIME_absolute_ntoh (dki->issue.properties.expire_withdraw).abs_value_us)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Not returning DKI for %s, as time to create coins has passed\n",
- GNUNET_h2s (&hc));
- return NULL;
- }
- break;
- case TMH_KS_DKU_DEPOSIT:
- if (now.abs_value_us >
- GNUNET_TIME_absolute_ntoh (dki->issue.properties.expire_spend).abs_value_us)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Not returning DKI for %s, as time to spend coin has passed\n",
- GNUNET_h2s (&hc));
- return NULL;
- }
- break;
- }
- return dki;
-}
-
-
-/**
- * Handle a signal, writing relevant signal numbers to the pipe.
- *
- * @param signal_number the signal number
- */
-static void
-handle_signal (int signal_number)
-{
- ssize_t res;
- char c = signal_number;
-
- res = write (reload_pipe[1],
- &c,
- 1);
- if ( (res < 0) &&
- (EINTR != errno) )
- {
- GNUNET_break (0);
- return;
- }
- if (0 == res)
- {
- GNUNET_break (0);
- return;
- }
-}
-
-
-/**
- * Call #handle_signal() to pass the received signal via
- * the control pipe.
- */
-static void
-handle_sigusr1 ()
-{
- handle_signal (SIGUSR1);
-}
-
-
-/**
- * Call #handle_signal() to pass the received signal via
- * the control pipe.
- */
-static void
-handle_sigint ()
-{
- handle_signal (SIGINT);
-}
-
-
-/**
- * Call #handle_signal() to pass the received signal via
- * the control pipe.
- */
-static void
-handle_sigterm ()
-{
- handle_signal (SIGTERM);
-}
-
-
-/**
- * Call #handle_signal() to pass the received signal via
- * the control pipe.
- */
-static void
-handle_sighup ()
-{
- handle_signal (SIGHUP);
-}
-
-
-/**
- * Read signals from a pipe in a loop, and reload keys from disk if
- * SIGUSR1 is received, terminate if SIGTERM/SIGINT is received, and
- * restart if SIGHUP is received.
- *
- * @return #GNUNET_SYSERR on errors,
- * #GNUNET_OK to terminate normally
- * #GNUNET_NO to restart an update version of the binary
- */
-int
-TMH_KS_loop (void)
-{
- struct GNUNET_SIGNAL_Context *sigusr1;
- struct GNUNET_SIGNAL_Context *sigterm;
- struct GNUNET_SIGNAL_Context *sigint;
- struct GNUNET_SIGNAL_Context *sighup;
- int ret;
-
- if (0 != pipe (reload_pipe))
- {
- fprintf (stderr,
- "Failed to create pipe.\n");
- return GNUNET_SYSERR;
- }
- sigusr1 = GNUNET_SIGNAL_handler_install (SIGUSR1,
- &handle_sigusr1);
- sigterm = GNUNET_SIGNAL_handler_install (SIGTERM,
- &handle_sigterm);
- sigint = GNUNET_SIGNAL_handler_install (SIGINT,
- &handle_sigint);
- sighup = GNUNET_SIGNAL_handler_install (SIGHUP,
- &handle_sighup);
-
- ret = 0;
- while (0 == ret)
- {
- char c;
- ssize_t res;
-
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "(re-)loading keys\n");
- if (NULL != internal_key_state)
- {
- TMH_KS_release (internal_key_state);
- internal_key_state = NULL;
- }
- /* This will re-initialize 'internal_key_state' with
- an initial refcnt of 1 */
- (void) TMH_KS_acquire ();
-
-read_again:
- errno = 0;
- res = read (reload_pipe[0],
- &c,
- 1);
- if ((res < 0) && (EINTR != errno))
- {
- GNUNET_break (0);
- ret = GNUNET_SYSERR;
- break;
- }
- if (EINTR == errno)
- goto read_again;
- switch (c)
- {
- case SIGUSR1:
- /* reload internal key state, we do this in the loop */
- break;
- case SIGTERM:
- case SIGINT:
- /* terminate */
- ret = GNUNET_OK;
- break;
- case SIGHUP:
- /* restart updated binary */
- ret = GNUNET_NO;
- break;
- default:
- /* unexpected character */
- GNUNET_break (0);
- break;
- }
- }
- if (NULL != internal_key_state)
- {
- TMH_KS_release (internal_key_state);
- internal_key_state = NULL;
- }
- GNUNET_SIGNAL_handler_uninstall (sigusr1);
- GNUNET_SIGNAL_handler_uninstall (sigterm);
- GNUNET_SIGNAL_handler_uninstall (sigint);
- GNUNET_SIGNAL_handler_uninstall (sighup);
- return ret;
-}
-
-
-/**
- * Sign the message in @a purpose with the mint's signing key.
- *
- * @param purpose the message to sign
- * @param[out] pub set to the current public signing key of the mint
- * @param[out] sig signature over purpose using current signing key
- */
-void
-TMH_KS_sign (const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose,
- struct TALER_MintPublicKeyP *pub,
- struct TALER_MintSignatureP *sig)
-
-{
- struct TMH_KS_StateHandle *key_state;
-
- key_state = TMH_KS_acquire ();
- *pub = key_state->current_sign_key_issue.issue.signkey_pub;
- GNUNET_assert (GNUNET_OK ==
- GNUNET_CRYPTO_eddsa_sign (&key_state->current_sign_key_issue.signkey_priv.eddsa_priv,
- purpose,
- &sig->eddsa_signature));
- TMH_KS_release (key_state);
-}
-
-
-/**
- * Function to call to handle the request by sending
- * back static data from the @a rh.
- *
- * @param rh context of the handler
- * @param connection the MHD connection to handle
- * @param[in,out] connection_cls the connection's closure (can be updated)
- * @param upload_data upload data
- * @param[in,out] upload_data_size number of bytes (left) in @a upload_data
- * @return MHD result code
- */
-int
-TMH_KS_handler_keys (struct TMH_RequestHandler *rh,
- struct MHD_Connection *connection,
- void **connection_cls,
- const char *upload_data,
- size_t *upload_data_size)
-{
- struct TMH_KS_StateHandle *key_state;
- struct MHD_Response *response;
- int ret;
-
- key_state = TMH_KS_acquire ();
- response = MHD_create_response_from_buffer (strlen (key_state->keys_json),
- key_state->keys_json,
- MHD_RESPMEM_MUST_COPY);
- TMH_KS_release (key_state);
- if (NULL == response)
- {
- GNUNET_break (0);
- return MHD_NO;
- }
- (void) MHD_add_response_header (response,
- "Content-Type",
- rh->mime_type);
- ret = MHD_queue_response (connection,
- rh->response_code,
- response);
- MHD_destroy_response (response);
- return ret;
-}
-
-
-/* end of taler-mint-httpd_keystate.c */
diff --git a/src/backend/taler-mint-httpd_keystate.h b/src/backend/taler-mint-httpd_keystate.h
deleted file mode 100644
index 62b041e9..00000000
--- a/src/backend/taler-mint-httpd_keystate.h
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2014, 2015 GNUnet e.V.
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU Affero General Public License as published by the Free Software
- 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 Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License along with
- TALER; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/>
-*/
-/**
- * @file mint/taler-mint-httpd_keystate.h
- * @brief management of our private signing keys (denomination keys)
- * @author Florian Dold
- * @author Benedikt Mueller
- * @author Christian Grothoff
- */
-#ifndef TALER_MINT_HTTPD_KEYSTATE_H
-#define TALER_MINT_HTTPD_KEYSTATE_H
-
-#include <gnunet/gnunet_util_lib.h>
-#include <microhttpd.h>
-#include "taler-mint-httpd.h"
-#include "taler_mintdb_lib.h"
-
-
-/**
- * Snapshot of the (coin and signing)
- * keys (including private keys) of the mint.
- */
-struct TMH_KS_StateHandle;
-
-
-/**
- * Acquire the key state of the mint. Updates keys if necessary.
- * For every call to #TMH_KS_acquire(), a matching call
- * to #TMH_KS_release() must be made.
- *
- * @return the key state
- */
-struct TMH_KS_StateHandle *
-TMH_KS_acquire (void);
-
-
-/**
- * Release key state, free if necessary (if reference count gets to zero).
- *
- * @param key_state the key state to release
- */
-void
-TMH_KS_release (struct TMH_KS_StateHandle *key_state);
-
-
-/**
- * Denomination key lookups can be for signing of fresh coins
- * or to validate signatures on existing coins. As the validity
- * periods for a key differ, the caller must specify which
- * use is relevant for the current operation.
- */
-enum TMH_KS_DenominationKeyUse {
-
- /**
- * The key is to be used for a /withdraw/sign or /refresh (mint)
- * operation.
- */
- TMH_KS_DKU_WITHDRAW,
-
- /**
- * The key is to be usd for a /deposit or /refresh (melt) operation.
- */
- TMH_KS_DKU_DEPOSIT
-
-};
-
-
-/**
- * Look up the issue for a denom public key. Note that the result
- * is only valid while the @a key_state is not released!
- *
- * @param key_state state to look in
- * @param denom_pub denomination public key
- * @param use purpose for which the key is being located
- * @return the denomination key issue,
- * or NULL if denom_pub could not be found (or is not valid at this time for the given @a use)
- */
-struct TALER_MINTDB_DenominationKeyIssueInformation *
-TMH_KS_denomination_key_lookup (const struct TMH_KS_StateHandle *key_state,
- const struct TALER_DenominationPublicKey *denom_pub,
- enum TMH_KS_DenominationKeyUse use);
-
-
-/**
- * Read signals from a pipe in a loop, and reload keys from disk if
- * SIGUSR1 is received, terminate if SIGTERM/SIGINT is received, and
- * restart if SIGHUP is received.
- *
- * @return #GNUNET_SYSERR on errors,
- * #GNUNET_OK to terminate normally
- * #GNUNET_NO to restart an update version of the binary
- */
-int
-TMH_KS_loop (void);
-
-
-/**
- * Sign the message in @a purpose with the mint's signing
- * key.
- *
- * @param purpose the message to sign
- * @param[out] pub set to the current public signing key of the mint
- * @param[out] sig signature over purpose using current signing key
- */
-void
-TMH_KS_sign (const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose,
- struct TALER_MintPublicKeyP *pub,
- struct TALER_MintSignatureP *sig);
-
-
-/**
- * Handle a "/keys" request
- *
- * @param rh context of the handler
- * @param connection the MHD connection to handle
- * @param[in,out] connection_cls the connection's closure (can be updated)
- * @param upload_data upload data
- * @param[in,out] upload_data_size number of bytes (left) in @a upload_data
- * @return MHD result code
- */
-int
-TMH_KS_handler_keys (struct TMH_RequestHandler *rh,
- struct MHD_Connection *connection,
- void **connection_cls,
- const char *upload_data,
- size_t *upload_data_size);
-
-
-#endif
diff --git a/src/backend/taler-mint-httpd_mhd.c b/src/backend/taler-mint-httpd_mhd.c
deleted file mode 100644
index b4e3c1f6..00000000
--- a/src/backend/taler-mint-httpd_mhd.c
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2014 GNUnet e.V.
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU Affero General Public License as published by the Free Software
- 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 Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License along with
- TALER; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/>
-*/
-
-/**
- * @file taler-mint-httpd_mhd.c
- * @brief helpers for MHD interaction; these are TALER_MINT_handler_ functions
- * that generate simple MHD replies that do not require any real operations
- * to be performed (error handling, static pages, etc.)
- * @author Florian Dold
- * @author Benedikt Mueller
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include <gnunet/gnunet_util_lib.h>
-#include <jansson.h>
-#include <microhttpd.h>
-#include <pthread.h>
-#include "taler-mint-httpd_responses.h"
-#include "taler-mint-httpd.h"
-#include "taler-mint-httpd_mhd.h"
-#include "taler-mint-httpd_responses.h"
-
-
-/**
- * Function to call to handle the request by sending
- * back static data from the @a rh.
- *
- * @param rh context of the handler
- * @param connection the MHD connection to handle
- * @param[in,out] connection_cls the connection's closure (can be updated)
- * @param upload_data upload data
- * @param[in,out] upload_data_size number of bytes (left) in @a upload_data
- * @return MHD result code
- */
-int
-TMH_MHD_handler_static_response (struct TMH_RequestHandler *rh,
- struct MHD_Connection *connection,
- void **connection_cls,
- const char *upload_data,
- size_t *upload_data_size)
-{
- struct MHD_Response *response;
- int ret;
-
- if (0 == rh->data_size)
- rh->data_size = strlen ((const char *) rh->data);
- response = MHD_create_response_from_buffer (rh->data_size,
- (void *) rh->data,
- MHD_RESPMEM_PERSISTENT);
- if (NULL == response)
- {
- GNUNET_break (0);
- return MHD_NO;
- }
- if (NULL != rh->mime_type)
- (void) MHD_add_response_header (response,
- MHD_HTTP_HEADER_CONTENT_TYPE,
- rh->mime_type);
- ret = MHD_queue_response (connection,
- rh->response_code,
- response);
- MHD_destroy_response (response);
- return ret;
-}
-
-
-/**
- * Function to call to handle the request by sending
- * back a redirect to the AGPL source code.
- *
- * @param rh context of the handler
- * @param connection the MHD connection to handle
- * @param[in,out] connection_cls the connection's closure (can be updated)
- * @param upload_data upload data
- * @param[in,out] upload_data_size number of bytes (left) in @a upload_data
- * @return MHD result code
- */
-int
-TMH_MHD_handler_agpl_redirect (struct TMH_RequestHandler *rh,
- struct MHD_Connection *connection,
- void **connection_cls,
- const char *upload_data,
- size_t *upload_data_size)
-{
- const char *agpl =
- "This server is licensed under the Affero GPL. You will now be redirected to the source code.";
- struct MHD_Response *response;
- int ret;
-
- response = MHD_create_response_from_buffer (strlen (agpl),
- (void *) agpl,
- MHD_RESPMEM_PERSISTENT);
- if (NULL == response)
- {
- GNUNET_break (0);
- return MHD_NO;
- }
- if (NULL != rh->mime_type)
- (void) MHD_add_response_header (response,
- MHD_HTTP_HEADER_CONTENT_TYPE,
- rh->mime_type);
- MHD_add_response_header (response,
- MHD_HTTP_HEADER_LOCATION,
- "http://www.git.taler.net/?p=mint.git");
- ret = MHD_queue_response (connection,
- rh->response_code,
- response);
- MHD_destroy_response (response);
- return ret;
-}
-
-
-/**
- * Function to call to handle the request by building a JSON
- * reply with an error message from @a rh.
- *
- * @param rh context of the handler
- * @param connection the MHD connection to handle
- * @param[in,out] connection_cls the connection's closure (can be updated)
- * @param upload_data upload data
- * @param[in,out] upload_data_size number of bytes (left) in @a upload_data
- * @return MHD result code
- */
-int
-TMH_MHD_handler_send_json_pack_error (struct TMH_RequestHandler *rh,
- struct MHD_Connection *connection,
- void **connection_cls,
- const char *upload_data,
- size_t *upload_data_size)
-{
- return TMH_RESPONSE_reply_json_pack (connection,
- rh->response_code,
- "{s:s}",
- "error",
- rh->data);
-}
-
-
-/* end of taler-mint-httpd_mhd.c */
diff --git a/src/backend/taler-mint-httpd_mhd.h b/src/backend/taler-mint-httpd_mhd.h
deleted file mode 100644
index a9f575df..00000000
--- a/src/backend/taler-mint-httpd_mhd.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2014 GNUnet e.V.
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU Affero General Public License as published by the Free Software
- 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 Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License along with
- TALER; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/>
-*/
-
-/**
- * @file taler-mint-httpd_mhd.h
- * @brief helpers for MHD interaction, used to generate simple responses
- * @author Florian Dold
- * @author Benedikt Mueller
- * @author Christian Grothoff
- */
-#ifndef TALER_MINT_HTTPD_MHD_H
-#define TALER_MINT_HTTPD_MHD_H
-#include <gnunet/gnunet_util_lib.h>
-#include <microhttpd.h>
-#include "taler-mint-httpd.h"
-
-
-/**
- * Function to call to handle the request by sending
- * back static data from the @a rh.
- *
- * @param rh context of the handler
- * @param connection the MHD connection to handle
- * @param[in,out] connection_cls the connection's closure (can be updated)
- * @param upload_data upload data
- * @param[in,out] upload_data_size number of bytes (left) in @a upload_data
- * @return MHD result code
- */
-int
-TMH_MHD_handler_static_response (struct TMH_RequestHandler *rh,
- struct MHD_Connection *connection,
- void **connection_cls,
- const char *upload_data,
- size_t *upload_data_size);
-
-
-/**
- * Function to call to handle the request by sending
- * back a redirect to the AGPL source code.
- *
- * @param rh context of the handler
- * @param connection the MHD connection to handle
- * @param[in,out] connection_cls the connection's closure (can be updated)
- * @param upload_data upload data
- * @param[in,out] upload_data_size number of bytes (left) in @a upload_data
- * @return MHD result code
- */
-int
-TMH_MHD_handler_agpl_redirect (struct TMH_RequestHandler *rh,
- struct MHD_Connection *connection,
- void **connection_cls,
- const char *upload_data,
- size_t *upload_data_size);
-
-
-/**
- * Function to call to handle the request by building a JSON
- * reply from varargs.
- *
- * @param rh context of the handler
- * @param connection the MHD connection to handle
- * @param[in,out] connection_cls the connection's closure (can be updated)
- * @param response_code HTTP response code to use
- * @param do_cache can the response be cached? (0: no, 1: yes)
- * @param fmt format string for pack
- * @param ... varargs
- * @return MHD result code
- */
-int
-TMH_MHD_helper_send_json_pack (struct TMH_RequestHandler *rh,
- struct MHD_Connection *connection,
- void *connection_cls,
- int response_code,
- int do_cache,
- const char *fmt,
- ...);
-
-
-/**
- * Function to call to handle the request by building a JSON
- * reply with an error message from @a rh.
- *
- * @param rh context of the handler
- * @param connection the MHD connection to handle
- * @param[in,out] connection_cls the connection's closure (can be updated)
- * @param upload_data upload data
- * @param[in,out] upload_data_size number of bytes (left) in @a upload_data
- * @return MHD result code
- */
-int
-TMH_MHD_handler_send_json_pack_error (struct TMH_RequestHandler *rh,
- struct MHD_Connection *connection,
- void **connection_cls,
- const char *upload_data,
- size_t *upload_data_size);
-
-
-#endif
diff --git a/src/backend/taler-mint-httpd_parsing.c b/src/backend/taler-mint-httpd_parsing.c
index 1844fa88..f84e7314 100644
--- a/src/backend/taler-mint-httpd_parsing.c
+++ b/src/backend/taler-mint-httpd_parsing.c
@@ -139,90 +139,6 @@ buffer_append (struct Buffer *buf,
return GNUNET_OK;
}
-
-/**
- * Release all memory allocated for the variable-size fields in
- * the parser specification.
- *
- * @param spec specification to free
- * @param spec_len number of items in @a spec to look at
- */
-static void
-release_data (struct TMH_PARSE_FieldSpecification *spec,
- unsigned int spec_len)
-{
- unsigned int i;
-
- for (i=0; i < spec_len; i++)
- {
- switch (spec[i].command)
- {
- case TMH_PARSE_JNC_FIELD:
- GNUNET_break (0);
- return;
- case TMH_PARSE_JNC_INDEX:
- GNUNET_break (0);
- return;
- case TMH_PARSE_JNC_RET_DATA:
- break;
- case TMH_PARSE_JNC_RET_DATA_VAR:
- if (NULL != spec[i].destination)
- {
- GNUNET_free (* (void**) spec[i].destination);
- *(void**) spec[i].destination = NULL;
- *spec[i].destination_size_out = 0;
- }
- break;
- case TMH_PARSE_JNC_RET_TYPED_JSON:
- {
- json_t *json;
-
- json = *(json_t **) spec[i].destination;
- if (NULL != json)
- {
- json_decref (json);
- *(json_t**) spec[i].destination = NULL;
- }
- }
- break;
- case TMH_PARSE_JNC_RET_RSA_PUBLIC_KEY:
- {
- struct TALER_DenominationPublicKey *pk;
-
- pk = spec[i].destination;
- if (NULL != pk->rsa_public_key)
- {
- GNUNET_CRYPTO_rsa_public_key_free (pk->rsa_public_key);
- pk->rsa_public_key = NULL;
- }
- }
- break;
- case TMH_PARSE_JNC_RET_RSA_SIGNATURE:
- {
- struct TALER_DenominationSignature *sig;
-
- sig = spec[i].destination;
- if (NULL != sig->rsa_signature)
- {
- GNUNET_CRYPTO_rsa_signature_free (sig->rsa_signature);
- sig->rsa_signature = NULL;
- }
- }
- break;
- case TMH_PARSE_JNC_RET_AMOUNT:
- memset (spec[i].destination,
- 0,
- sizeof (struct TALER_Amount));
- break;
- case TMH_PARSE_JNC_RET_TIME_ABSOLUTE:
- break;
- case TMH_PARSE_JNC_RET_UINT64:
- break;
- }
- }
-}
-
-
/**
* Process a POST request containing a JSON object. This function
* realizes an MHD POST processor that will (incrementally) process
@@ -324,800 +240,4 @@ TMH_PARSE_post_json (struct MHD_Connection *connection,
return GNUNET_YES;
}
-
-/**
- * Function called whenever we are done with a request
- * to clean up our state.
- *
- * @param con_cls value as it was left by
- * #TMH_PARSE_post_json(), to be cleaned up
- */
-void
-TMH_PARSE_post_cleanup_callback (void *con_cls)
-{
- struct Buffer *r = con_cls;
-
- if (NULL != r)
- {
- buffer_deinit (r);
- GNUNET_free (r);
- }
-}
-
-
-/**
- * Extract base32crockford encoded data from request.
- *
- * Queues an error response to the connection if the parameter is missing or
- * invalid.
- *
- * @param connection the MHD connection
- * @param param_name the name of the parameter with the key
- * @param[out] out_data pointer to store the result
- * @param out_size expected size of data
- * @return
- * #GNUNET_YES if the the argument is present
- * #GNUNET_NO if the argument is absent or malformed
- * #GNUNET_SYSERR on internal error (error response could not be sent)
- */
-int
-TMH_PARSE_mhd_request_arg_data (struct MHD_Connection *connection,
- const char *param_name,
- void *out_data,
- size_t out_size)
-{
- const char *str;
-
- str = MHD_lookup_connection_value (connection,
- MHD_GET_ARGUMENT_KIND,
- param_name);
- if (NULL == str)
- {
- return (MHD_NO ==
- TMH_RESPONSE_reply_arg_missing (connection, param_name))
- ? GNUNET_SYSERR : GNUNET_NO;
- }
- if (GNUNET_OK !=
- GNUNET_STRINGS_string_to_data (str,
- strlen (str),
- out_data,
- out_size))
- return (MHD_NO ==
- TMH_RESPONSE_reply_arg_invalid (connection, param_name))
- ? GNUNET_SYSERR : GNUNET_NO;
- return GNUNET_OK;
-}
-
-
-/**
- * Extraxt variable-size base32crockford encoded data from request.
- *
- * Queues an error response to the connection if the parameter is missing
- * or the encoding is invalid.
- *
- * @param connection the MHD connection
- * @param param_name the name of the parameter with the key
- * @param[out] out_data pointer to allocate buffer and store the result
- * @param[out] out_size set to the size of the buffer allocated in @a out_data
- * @return
- * #GNUNET_YES if the the argument is present
- * #GNUNET_NO if the argument is absent or malformed
- * #GNUNET_SYSERR on internal error (error response could not be sent)
- */
-int
-TMH_PARSE_mhd_request_var_arg_data (struct MHD_Connection *connection,
- const char *param_name,
- void **out_data,
- size_t *out_size)
-{
- const char *str;
- size_t slen;
- size_t olen;
- void *out;
-
- str = MHD_lookup_connection_value (connection,
- MHD_GET_ARGUMENT_KIND,
- param_name);
- if (NULL == str)
- {
- return (MHD_NO ==
- TMH_RESPONSE_reply_arg_missing (connection, param_name))
- ? GNUNET_SYSERR : GNUNET_NO;
- }
- slen = strlen (str);
- olen = (slen * 5) / 8;
- out = GNUNET_malloc (olen);
- if (GNUNET_OK !=
- GNUNET_STRINGS_string_to_data (str,
- strlen (str),
- out,
- olen))
- {
- GNUNET_free (out);
- *out_size = 0;
- return (MHD_NO ==
- TMH_RESPONSE_reply_arg_invalid (connection, param_name))
- ? GNUNET_SYSERR : GNUNET_NO;
- }
- *out_data = out;
- *out_size = olen;
- return GNUNET_OK;
-}
-
-
-/**
- * Navigate through a JSON tree.
- *
- * Sends an error response if navigation is impossible (i.e.
- * the JSON object is invalid)
- *
- * @param connection the connection to send an error response to
- * @param root the JSON node to start the navigation at.
- * @param ... navigation specification (see `enum TMH_PARSE_JsonNavigationCommand`)
- * @return
- * #GNUNET_YES if navigation was successful
- * #GNUNET_NO if json is malformed, error response was generated
- * #GNUNET_SYSERR on internal error (no response was generated,
- * connection must be closed)
- */
-int
-TMH_PARSE_navigate_json (struct MHD_Connection *connection,
- const json_t *root,
- ...)
-{
- va_list argp;
- int ret;
- json_t *path; /* what's our current path from 'root'? */
-
- path = json_array ();
- va_start (argp, root);
- ret = 2; /* just not any of the valid return values */
- while (2 == ret)
- {
- enum TMH_PARSE_JsonNavigationCommand command
- = va_arg (argp,
- enum TMH_PARSE_JsonNavigationCommand);
-
- switch (command)
- {
- case TMH_PARSE_JNC_FIELD:
- {
- const char *fname = va_arg(argp, const char *);
-
- json_array_append_new (path,
- json_string (fname));
- root = json_object_get (root,
- fname);
- if (NULL == root)
- {
- ret = (MHD_YES ==
- TMH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_BAD_REQUEST,
- "{s:s, s:s, s:O}",
- "error", "missing field in JSON",
- "field", fname,
- "path", path))
- ? GNUNET_NO : GNUNET_SYSERR;
- break;
- }
- }
- break;
-
- case TMH_PARSE_JNC_INDEX:
- {
- int fnum = va_arg(argp, int);
-
- json_array_append_new (path,
- json_integer (fnum));
- root = json_array_get (root,
- fnum);
- if (NULL == root)
- {
- ret = (MHD_YES ==
- TMH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_BAD_REQUEST,
- "{s:s, s:O}",
- "error", "missing index in JSON",
- "path", path))
- ? GNUNET_NO : GNUNET_SYSERR;
- break;
- }
- }
- break;
-
- case TMH_PARSE_JNC_RET_DATA:
- {
- void *where = va_arg (argp, void *);
- size_t len = va_arg (argp, size_t);
- const char *str;
- int res;
-
- str = json_string_value (root);
- if (NULL == str)
- {
- ret = (MHD_YES ==
- TMH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_BAD_REQUEST,
- "{s:s, s:O}",
- "error", "string expected",
- "path", path))
- ? GNUNET_NO : GNUNET_SYSERR;
- break;
- }
- res = GNUNET_STRINGS_string_to_data (str, strlen (str),
- where, len);
- if (GNUNET_OK != res)
- {
- ret = (MHD_YES ==
- TMH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_BAD_REQUEST,
- "{s:s, s:O}",
- "error", "malformed binary data in JSON",
- "path", path))
- ? GNUNET_NO : GNUNET_SYSERR;
- break;
- }
- ret = GNUNET_OK;
- }
- break;
-
- case TMH_PARSE_JNC_RET_DATA_VAR:
- {
- void **where = va_arg (argp, void **);
- size_t *len = va_arg (argp, size_t *);
- const char *str;
- int res;
-
- str = json_string_value (root);
- if (NULL == str)
- {
- ret = (MHD_YES ==
- TMH_RESPONSE_reply_internal_error (connection,
- "json_string_value() failed"))
- ? GNUNET_NO : GNUNET_SYSERR;
- break;
- }
- *len = (strlen (str) * 5) / 8;
- if (NULL != where)
- {
- *where = GNUNET_malloc (*len);
- res = GNUNET_STRINGS_string_to_data (str,
- strlen (str),
- *where,
- *len);
- if (GNUNET_OK != res)
- {
- GNUNET_free (*where);
- *where = NULL;
- *len = 0;
- ret = (MHD_YES ==
- TMH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_BAD_REQUEST,
- "{s:s, s:O}",
- "error", "malformed binary data in JSON",
- "path", path))
- ? GNUNET_NO : GNUNET_SYSERR;
- break;
- }
- }
- ret = GNUNET_OK;
- }
- break;
-
- case TMH_PARSE_JNC_RET_TYPED_JSON:
- {
- int typ = va_arg (argp, int);
- const json_t **r_json = va_arg (argp, const json_t **);
-
- if ( (NULL == root) ||
- ( (-1 != typ) &&
- (json_typeof (root) != typ)) )
- {
- *r_json = NULL;
- ret = (MHD_YES ==
- TMH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_BAD_REQUEST,
- "{s:s, s:i, s:i, s:O}",
- "error", "wrong JSON field type",
- "type_expected", typ,
- "type_actual", json_typeof (root),
- "path", path))
- ? GNUNET_NO : GNUNET_SYSERR;
- break;
- }
- *r_json = root;
- json_incref ((json_t *) root);
- ret = GNUNET_OK;
- }
- break;
-
- case TMH_PARSE_JNC_RET_UINT64:
- {
- uint64_t *r_u64 = va_arg (argp, uint64_t *);
-
- if (json_typeof (root) != JSON_INTEGER)
- {
- ret = (MHD_YES ==
- TMH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_BAD_REQUEST,
- "{s:s, s:s, s:i, s:O}",
- "error", "wrong JSON field type",
- "type_expected", "integer",
- "type_actual", json_typeof (root),
- "path", path))
- ? GNUNET_NO : GNUNET_SYSERR;
- break;
- }
- *r_u64 = (uint64_t) json_integer_value (root);
- ret = GNUNET_OK;
- }
- break;
-
- case TMH_PARSE_JNC_RET_RSA_PUBLIC_KEY:
- {
- struct TALER_DenominationPublicKey *where;
- size_t len;
- const char *str;
- int res;
- void *buf;
-
- where = va_arg (argp,
- struct TALER_DenominationPublicKey *);
- str = json_string_value (root);
- if (NULL == str)
- {
- ret = (MHD_YES ==
- TMH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_BAD_REQUEST,
- "{s:s, s:O}",
- "error", "string expected",
- "path", path))
- ? GNUNET_NO : GNUNET_SYSERR;
- break;
- }
- len = (strlen (str) * 5) / 8;
- buf = GNUNET_malloc (len);
- res = GNUNET_STRINGS_string_to_data (str,
- strlen (str),
- buf,
- len);
- if (GNUNET_OK != res)
- {
- GNUNET_free (buf);
- ret = (MHD_YES ==
- TMH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_BAD_REQUEST,
- "{s:s, s:O}",
- "error", "malformed binary data in JSON",
- "path", path))
- ? GNUNET_NO : GNUNET_SYSERR;
- break;
- }
- where->rsa_public_key = GNUNET_CRYPTO_rsa_public_key_decode (buf,
- len);
- GNUNET_free (buf);
- if (NULL == where->rsa_public_key)
- {
- ret = (MHD_YES ==
- TMH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_BAD_REQUEST,
- "{s:s, s:O}",
- "error", "malformed RSA public key in JSON",
- "path", path))
- ? GNUNET_NO : GNUNET_SYSERR;
- break;
- }
- ret = GNUNET_OK;
- break;
- }
-
- case TMH_PARSE_JNC_RET_RSA_SIGNATURE:
- {
- struct TALER_DenominationSignature *where;
- size_t len;
- const char *str;
- int res;
- void *buf;
-
- where = va_arg (argp,
- struct TALER_DenominationSignature *);
- str = json_string_value (root);
- if (NULL == str)
- {
- ret = (MHD_YES ==
- TMH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_BAD_REQUEST,
- "{s:s, s:O}",
- "error", "string expected",
- "path", path))
- ? GNUNET_NO : GNUNET_SYSERR;
- break;
- }
- len = (strlen (str) * 5) / 8;
- buf = GNUNET_malloc (len);
- res = GNUNET_STRINGS_string_to_data (str,
- strlen (str),
- buf,
- len);
- if (GNUNET_OK != res)
- {
- GNUNET_free (buf);
- ret = (MHD_YES ==
- TMH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_BAD_REQUEST,
- "{s:s, s:O}",
- "error", "malformed binary data in JSON",
- "path", path))
- ? GNUNET_NO : GNUNET_SYSERR;
- break;
- }
- where->rsa_signature = GNUNET_CRYPTO_rsa_signature_decode (buf,
- len);
- GNUNET_free (buf);
- if (NULL == where->rsa_signature)
- {
- ret = (MHD_YES ==
- TMH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_BAD_REQUEST,
- "{s:s, s:O}",
- "error", "malformed RSA signature in JSON",
- "path", path))
- ? GNUNET_NO : GNUNET_SYSERR;
- break;
- }
- ret = GNUNET_OK;
- break;
- }
-
- case TMH_PARSE_JNC_RET_AMOUNT:
- {
- struct TALER_Amount *where = va_arg (argp, void *);
-
- if (GNUNET_OK !=
- TALER_json_to_amount ((json_t *) root,
- where))
- {
- if (MHD_YES !=
- TMH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_BAD_REQUEST,
- "{s:s, s:O}",
- "error", "Bad format",
- "path", path))
- return GNUNET_SYSERR;
- return GNUNET_NO;
- }
- if (0 != strcmp (where->currency,
- TMH_mint_currency_string))
- {
- if (MHD_YES !=
- TMH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_BAD_REQUEST,
- "{s:s, s:O, s:s}",
- "error", "Currency not supported",
- "path", path,
- "currency", where->currency))
- {
- memset (where, 0, sizeof (struct TALER_Amount));
- return GNUNET_SYSERR;
- }
- memset (where, 0, sizeof (struct TALER_Amount));
- return GNUNET_NO;
- }
- ret = GNUNET_OK;
- break;
- }
-
- case TMH_PARSE_JNC_RET_TIME_ABSOLUTE:
- {
- struct GNUNET_TIME_Absolute *where = va_arg (argp, void *);
-
- if (GNUNET_OK !=
- TALER_json_to_abs ((json_t *) root,
- where))
- {
- if (MHD_YES !=
- TMH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_BAD_REQUEST,
- "{s:s, s:s, s:O}",
- "error", "Bad format",
- "hint", "expected absolute time",
- "path", path))
- return GNUNET_SYSERR;
- return GNUNET_NO;
- }
- ret = GNUNET_OK;
- break;
- }
-
- default:
- GNUNET_break (0);
- ret = (MHD_YES ==
- TMH_RESPONSE_reply_internal_error (connection,
- "unhandled value in switch"))
- ? GNUNET_NO : GNUNET_SYSERR;
- break;
- }
- }
- va_end (argp);
- json_decref (path);
- return ret;
-}
-
-
-/**
- * Parse JSON object into components based on the given field
- * specification.
- *
- * @param connection the connection to send an error response to
- * @param root the JSON node to start the navigation at.
- * @param spec field specification for the parser
- * @return
- * #GNUNET_YES if navigation was successful (caller is responsible
- * for freeing allocated variable-size data using
- * #TMH_PARSE_release_data() when done)
- * #GNUNET_NO if json is malformed, error response was generated
- * #GNUNET_SYSERR on internal error
- */
-int
-TMH_PARSE_json_data (struct MHD_Connection *connection,
- const json_t *root,
- struct TMH_PARSE_FieldSpecification *spec)
-{
- unsigned int i;
- int ret;
-
- ret = GNUNET_YES;
- for (i=0; NULL != spec[i].field_name; i++)
- {
- if (GNUNET_YES != ret)
- break;
- switch (spec[i].command)
- {
- case TMH_PARSE_JNC_FIELD:
- GNUNET_break (0);
- return GNUNET_SYSERR;
- case TMH_PARSE_JNC_INDEX:
- GNUNET_break (0);
- return GNUNET_SYSERR;
- case TMH_PARSE_JNC_RET_DATA:
- ret = TMH_PARSE_navigate_json (connection,
- root,
- TMH_PARSE_JNC_FIELD,
- spec[i].field_name,
- TMH_PARSE_JNC_RET_DATA,
- spec[i].destination,
- spec[i].destination_size_in);
- break;
- case TMH_PARSE_JNC_RET_DATA_VAR:
- ret = TMH_PARSE_navigate_json (connection,
- root,
- TMH_PARSE_JNC_FIELD,
- spec[i].field_name,
- TMH_PARSE_JNC_RET_DATA_VAR,
- (void **) spec[i].destination,
- spec[i].destination_size_out);
- break;
- case TMH_PARSE_JNC_RET_TYPED_JSON:
- ret = TMH_PARSE_navigate_json (connection,
- root,
- TMH_PARSE_JNC_FIELD,
- spec[i].field_name,
- TMH_PARSE_JNC_RET_TYPED_JSON,
- spec[i].type,
- spec[i].destination);
- break;
- case TMH_PARSE_JNC_RET_RSA_PUBLIC_KEY:
- ret = TMH_PARSE_navigate_json (connection,
- root,
- TMH_PARSE_JNC_FIELD,
- spec[i].field_name,
- TMH_PARSE_JNC_RET_RSA_PUBLIC_KEY,
- spec[i].destination);
- break;
- case TMH_PARSE_JNC_RET_RSA_SIGNATURE:
- ret = TMH_PARSE_navigate_json (connection,
- root,
- TMH_PARSE_JNC_FIELD,
- spec[i].field_name,
- TMH_PARSE_JNC_RET_RSA_SIGNATURE,
- spec[i].destination);
- break;
- case TMH_PARSE_JNC_RET_AMOUNT:
- GNUNET_assert (sizeof (struct TALER_Amount) ==
- spec[i].destination_size_in);
- ret = TMH_PARSE_navigate_json (connection,
- root,
- TMH_PARSE_JNC_FIELD,
- spec[i].field_name,
- TMH_PARSE_JNC_RET_AMOUNT,
- spec[i].destination);
- break;
- case TMH_PARSE_JNC_RET_TIME_ABSOLUTE:
- GNUNET_assert (sizeof (struct GNUNET_TIME_Absolute) ==
- spec[i].destination_size_in);
- ret = TMH_PARSE_navigate_json (connection,
- root,
- TMH_PARSE_JNC_FIELD,
- spec[i].field_name,
- TMH_PARSE_JNC_RET_TIME_ABSOLUTE,
- spec[i].destination);
- break;
- case TMH_PARSE_JNC_RET_UINT64:
- GNUNET_assert (sizeof (uint64_t) ==
- spec[i].destination_size_in);
- ret = TMH_PARSE_navigate_json (connection,
- root,
- TMH_PARSE_JNC_FIELD,
- spec[i].field_name,
- TMH_PARSE_JNC_RET_UINT64,
- spec[i].destination);
- break;
- }
- }
- if (GNUNET_YES != ret)
- release_data (spec,
- i - 1);
- return ret;
-}
-
-
-/**
- * Release all memory allocated for the variable-size fields in
- * the parser specification.
- *
- * @param spec specification to free
- */
-void
-TMH_PARSE_release_data (struct TMH_PARSE_FieldSpecification *spec)
-{
- unsigned int i;
-
- for (i=0; NULL != spec[i].field_name; i++) ;
- release_data (spec, i);
-}
-
-
-/**
- * Generate line in parser specification for 64-bit integer
- * given as an integer in JSON.
- *
- * @param field name of the field
- * @param[out] u64 integer to initialize
- * @return corresponding field spec
- */
-struct TMH_PARSE_FieldSpecification
-TMH_PARSE_member_uint64 (const char *field,
- uint64_t *u64)
-{
- struct TMH_PARSE_FieldSpecification ret =
- { field, (void *) u64, sizeof (uint64_t), NULL, TMH_PARSE_JNC_RET_UINT64, 0 };
- return ret;
-}
-
-
-/**
- * Generate line in parser specification for JSON object value.
- *
- * @param field name of the field
- * @param[out] jsonp address of pointer to JSON to initialize
- * @return corresponding field spec
- */
-struct TMH_PARSE_FieldSpecification
-TMH_PARSE_member_object (const char *field,
- json_t **jsonp)
-{
- struct TMH_PARSE_FieldSpecification ret =
- { field, jsonp, 0, NULL, TMH_PARSE_JNC_RET_TYPED_JSON, JSON_OBJECT };
- *jsonp = NULL;
- return ret;
-}
-
-
-/**
- * Generate line in parser specification for JSON array value.
- *
- * @param field name of the field
- * @param[out] jsonp address of JSON pointer to initialize
- * @return corresponding field spec
- */
-struct TMH_PARSE_FieldSpecification
-TMH_PARSE_member_array (const char *field,
- json_t **jsonp)
-{
- struct TMH_PARSE_FieldSpecification ret =
- { field, jsonp, 0, NULL, TMH_PARSE_JNC_RET_TYPED_JSON, JSON_ARRAY };
- *jsonp = NULL;
- return ret;
-}
-
-
-/**
- * Generate line in parser specification for an absolute time.
- *
- * @param field name of the field
- * @param[out] atime time to initialize
- */
-struct TMH_PARSE_FieldSpecification
-TMH_PARSE_member_time_abs (const char *field,
- struct GNUNET_TIME_Absolute *atime)
-{
- struct TMH_PARSE_FieldSpecification ret =
- { field, atime, sizeof(struct GNUNET_TIME_Absolute), NULL, TMH_PARSE_JNC_RET_TIME_ABSOLUTE, 0 };
- return ret;
-}
-
-
-/**
- * Generate line in parser specification for RSA public key.
- *
- * @param field name of the field
- * @param[out] pk key to initialize
- * @return corresponding field spec
- */
-struct TMH_PARSE_FieldSpecification
-TMH_PARSE_member_denomination_public_key (const char *field,
- struct TALER_DenominationPublicKey *pk)
-{
- struct TMH_PARSE_FieldSpecification ret =
- { field, pk, 0, NULL, TMH_PARSE_JNC_RET_RSA_PUBLIC_KEY, 0 };
- pk->rsa_public_key = NULL;
- return ret;
-}
-
-
-/**
- * Generate line in parser specification for RSA public key.
- *
- * @param field name of the field
- * @param sig the signature to initialize
- * @return corresponding field spec
- */
-struct TMH_PARSE_FieldSpecification
-TMH_PARSE_member_denomination_signature (const char *field,
- struct TALER_DenominationSignature *sig)
-{
- struct TMH_PARSE_FieldSpecification ret =
- { field, sig, 0, NULL, TMH_PARSE_JNC_RET_RSA_SIGNATURE, 0 };
- sig->rsa_signature = NULL;
- return ret;
-}
-
-
-/**
- * Generate line in parser specification for an amount.
- *
- * @param field name of the field
- * @param amount a `struct TALER_Amount *` to initialize
- * @return corresponding field spec
- */
-struct TMH_PARSE_FieldSpecification
-TMH_PARSE_member_amount (const char *field,
- struct TALER_Amount *amount)
-{
- struct TMH_PARSE_FieldSpecification ret =
- { field, amount, sizeof(struct TALER_Amount), NULL, TMH_PARSE_JNC_RET_AMOUNT, 0 };
- memset (amount, 0, sizeof (struct TALER_Amount));
- return ret;
-}
-
-
-/**
- * Generate line in parser specification for variable-size value.
- *
- * @param field name of the field
- * @param[out] ptr pointer to initialize
- * @param[out] ptr_size size to initialize
- * @return corresponding field spec
- */
-struct TMH_PARSE_FieldSpecification
-TMH_PARSE_member_variable (const char *field,
- void **ptr,
- size_t *ptr_size)
-{
- struct TMH_PARSE_FieldSpecification ret =
- { field, ptr, 0, ptr_size, TMH_PARSE_JNC_RET_DATA_VAR, 0 };
- *ptr = NULL;
- return ret;
-}
-
/* end of taler-mint-httpd_parsing.c */
diff --git a/src/backend/taler-mint-httpd_refresh.c b/src/backend/taler-mint-httpd_refresh.c
deleted file mode 100644
index 687fb998..00000000
--- a/src/backend/taler-mint-httpd_refresh.c
+++ /dev/null
@@ -1,907 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2014, 2015 GNUnet e.V.
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU Affero General Public License as published by the Free Software
- 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 Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License along with
- TALER; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/>
-*/
-/**
- * @file taler-mint-httpd_refresh.c
- * @brief Handle /refresh/ requests
- * @author Florian Dold
- * @author Benedikt Mueller
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include <gnunet/gnunet_util_lib.h>
-#include <jansson.h>
-#include <microhttpd.h>
-#include "taler-mint-httpd_parsing.h"
-#include "taler-mint-httpd_mhd.h"
-#include "taler-mint-httpd_refresh.h"
-#include "taler-mint-httpd_responses.h"
-#include "taler-mint-httpd_keystate.h"
-
-
-/**
- * Handle a "/refresh/melt" request after the main JSON parsing has happened.
- * We now need to validate the coins being melted and the session signature
- * and then hand things of to execute the melt operation.
- *
- * @param connection the MHD connection to handle
- * @param num_new_denoms number of coins to be created, size of y-dimension of @a commit_link array
- * @param denom_pubs array of @a num_new_denoms keys
- * @param coin_count number of coins to be melted, size of y-dimension of @a commit_coin array
- * @param coin_melt_details array with @a coin_count entries with melting details
- * @param session_hash hash over the data that the client commits to
- * @param commit_coin 2d array of coin commitments (what the mint is to sign
- * once the "/refres/reveal" of cut and choose is done)
- * @param commit_link 2d array of coin link commitments (what the mint is
- * to return via "/refresh/link" to enable linkage in the
- * future)
- * @return MHD result code
- */
-static int
-handle_refresh_melt_binary (struct MHD_Connection *connection,
- unsigned int num_new_denoms,
- const struct TALER_DenominationPublicKey *denom_pubs,
- unsigned int coin_count,
- const struct TMH_DB_MeltDetails *coin_melt_details,
- const struct GNUNET_HashCode *session_hash,
- struct TALER_MINTDB_RefreshCommitCoin *const* commit_coin,
- struct TALER_MINTDB_RefreshCommitLinkP *const* commit_link)
-{
- unsigned int i;
- struct TMH_KS_StateHandle *key_state;
- struct TALER_MINTDB_DenominationKeyInformationP *dki;
- struct TALER_Amount cost;
- struct TALER_Amount total_cost;
- struct TALER_Amount melt;
- struct TALER_Amount value;
- struct TALER_Amount fee_withdraw;
- struct TALER_Amount fee_melt;
- struct TALER_Amount total_melt;
-
- GNUNET_assert (GNUNET_OK ==
- TALER_amount_get_zero (TMH_mint_currency_string,
- &total_cost));
- key_state = TMH_KS_acquire ();
- for (i=0;i<num_new_denoms;i++)
- {
- dki = &TMH_KS_denomination_key_lookup (key_state,
- &denom_pubs[i],
- TMH_KS_DKU_WITHDRAW)->issue;
- TALER_amount_ntoh (&value,
- &dki->properties.value);
- TALER_amount_ntoh (&fee_withdraw,
- &dki->properties.fee_withdraw);
- if ( (GNUNET_OK !=
- TALER_amount_add (&cost,
- &value,
- &fee_withdraw)) ||
- (GNUNET_OK !=
- TALER_amount_add (&total_cost,
- &cost,
- &total_cost)) )
- {
- TMH_KS_release (key_state);
- return TMH_RESPONSE_reply_internal_error (connection,
- "cost calculation failure");
- }
- }
-
- GNUNET_assert (GNUNET_OK ==
- TALER_amount_get_zero (TMH_mint_currency_string,
- &total_melt));
- for (i=0;i<coin_count;i++)
- {
- /* calculate contribution of the i-th melt by subtracting
- the fee; add the rest to the total_melt value */
- dki = &TMH_KS_denomination_key_lookup (key_state,
- &coin_melt_details[i].coin_info.denom_pub,
- TMH_KS_DKU_DEPOSIT)->issue;
- TALER_amount_ntoh (&fee_melt,
- &dki->properties.fee_refresh);
- if (GNUNET_OK !=
- TALER_amount_subtract (&melt,
- &coin_melt_details->melt_amount_with_fee,
- &fee_melt))
- {
- TMH_KS_release (key_state);
- return TMH_RESPONSE_reply_external_error (connection,
- "Melt contribution below melting fee");
- }
- if (GNUNET_OK !=
- TALER_amount_add (&total_melt,
- &melt,
- &total_melt))
- {
- TMH_KS_release (key_state);
- return TMH_RESPONSE_reply_internal_error (connection,
- "balance calculation failure");
- }
- }
- TMH_KS_release (key_state);
- if (0 !=
- TALER_amount_cmp (&total_cost,
- &total_melt))
- {
- /* We require total value of coins being melted and
- total value of coins being generated to match! */
- return TMH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_BAD_REQUEST,
- "{s:s}",
- "error", "value mismatch");
- }
- return TMH_DB_execute_refresh_melt (connection,
- session_hash,
- num_new_denoms,
- denom_pubs,
- coin_count,
- coin_melt_details,
- commit_coin,
- commit_link);
-}
-
-
-/**
- * Extract public coin information from a JSON object.
- *
- * @param connection the connection to send error responses to
- * @param coin_info the JSON object to extract the coin info from
- * @param[out] r_melt_detail set to details about the coin's melting permission (if valid)
- * @return #GNUNET_YES if coin public info in JSON was valid
- * #GNUNET_NO JSON was invalid, response was generated
- * #GNUNET_SYSERR on internal error
- */
-static int
-get_coin_public_info (struct MHD_Connection *connection,
- json_t *coin_info,
- struct TMH_DB_MeltDetails *r_melt_detail)
-{
- int ret;
- struct TALER_CoinSpendSignatureP melt_sig;
- struct TALER_DenominationSignature sig;
- struct TALER_DenominationPublicKey pk;
- struct TALER_Amount amount;
- struct TMH_PARSE_FieldSpecification spec[] = {
- TMH_PARSE_member_fixed ("coin_pub", &r_melt_detail->coin_info.coin_pub),
- TMH_PARSE_member_denomination_signature ("denom_sig", &sig),
- TMH_PARSE_member_denomination_public_key ("denom_pub", &pk),
- TMH_PARSE_member_fixed ("confirm_sig", &melt_sig),
- TMH_PARSE_member_amount ("value_with_fee", &amount),
- TMH_PARSE_MEMBER_END
- };
-
- ret = TMH_PARSE_json_data (connection,
- coin_info,
- spec);
- if (GNUNET_OK != ret)
- return ret;
- /* check mint signature on the coin */
- r_melt_detail->coin_info.denom_sig = sig;
- r_melt_detail->coin_info.denom_pub = pk;
- if (GNUNET_OK !=
- TALER_test_coin_valid (&r_melt_detail->coin_info))
- {
- TMH_PARSE_release_data (spec);
- r_melt_detail->coin_info.denom_sig.rsa_signature = NULL;
- r_melt_detail->coin_info.denom_pub.rsa_public_key = NULL;
- return (MHD_YES ==
- TMH_RESPONSE_reply_signature_invalid (connection,
- "denom_sig"))
- ? GNUNET_NO : GNUNET_SYSERR;
- }
- r_melt_detail->melt_sig = melt_sig;
- r_melt_detail->melt_amount_with_fee = amount;
- TMH_PARSE_release_data (spec);
- return GNUNET_OK;
-}
-
-
-/**
- * Verify that the signature shows that this coin is to be melted into
- * the given @a session_pub melting session, and that this is a valid
- * coin (we know the denomination key and the signature on it is
- * valid). Essentially, this does all of the per-coin checks that can
- * be done before the transaction starts.
- *
- * @param connection the connection to send error responses to
- * @param session_hash hash over refresh session the coin is melted into
- * @param melt_detail details about the coin's melting permission (if valid)
- * @return #GNUNET_YES if coin public info in JSON was valid
- * #GNUNET_NO JSON was invalid, response was generated
- * #GNUNET_SYSERR on internal error
- */
-static int
-verify_coin_public_info (struct MHD_Connection *connection,
- const struct GNUNET_HashCode *session_hash,
- const struct TMH_DB_MeltDetails *melt_detail)
-{
- struct TALER_RefreshMeltCoinAffirmationPS body;
- struct TMH_KS_StateHandle *key_state;
- struct TALER_MINTDB_DenominationKeyIssueInformation *dki;
- struct TALER_Amount fee_refresh;
-
- key_state = TMH_KS_acquire ();
- dki = TMH_KS_denomination_key_lookup (key_state,
- &melt_detail->coin_info.denom_pub,
- TMH_KS_DKU_DEPOSIT);
- if (NULL == dki)
- {
- TMH_KS_release (key_state);
- TALER_LOG_WARNING ("Unknown denomination key in /refresh/melt request\n");
- return TMH_RESPONSE_reply_arg_unknown (connection,
- "denom_pub");
- }
- /* FIXME: need to check if denomination key is still
- valid for issuing! (#3634) */
- TALER_amount_ntoh (&fee_refresh,
- &dki->issue.properties.fee_refresh);
- body.purpose.size = htonl (sizeof (struct TALER_RefreshMeltCoinAffirmationPS));
- body.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_MELT);
- body.session_hash = *session_hash;
- TALER_amount_hton (&body.amount_with_fee,
- &melt_detail->melt_amount_with_fee);
- TALER_amount_hton (&body.melt_fee,
- &fee_refresh);
- body.coin_pub = melt_detail->coin_info.coin_pub;
- if (TALER_amount_cmp (&fee_refresh,
- &melt_detail->melt_amount_with_fee) < 0)
- {
- TMH_KS_release (key_state);
- return (MHD_YES ==
- TMH_RESPONSE_reply_external_error (connection,
- "melt amount smaller than melting fee"))
- ? GNUNET_NO : GNUNET_SYSERR;
- }
-
- TMH_KS_release (key_state);
- if (GNUNET_OK !=
- GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_MELT,
- &body.purpose,
- &melt_detail->melt_sig.eddsa_signature,
- &melt_detail->coin_info.coin_pub.eddsa_pub))
- {
- if (MHD_YES !=
- TMH_RESPONSE_reply_signature_invalid (connection,
- "confirm_sig"))
- return GNUNET_SYSERR;
- return GNUNET_NO;
- }
- return GNUNET_OK;
-}
-
-
-/**
- * Release memory from the @a commit_coin array.
- *
- * @param commit_coin array to release
- * @param kappa size of 1st dimension
- * @param num_new_coins size of 2nd dimension
- */
-static void
-free_commit_coins (struct TALER_MINTDB_RefreshCommitCoin **commit_coin,
- unsigned int kappa,
- unsigned int num_new_coins)
-{
- unsigned int i;
- unsigned int j;
-
- for (i=0;i<kappa;i++)
- {
- if (NULL == commit_coin[i])
- break;
- for (j=0;j<num_new_coins;j++)
- {
- GNUNET_free_non_null (commit_coin[i][j].coin_ev);
- GNUNET_free_non_null (commit_coin[i][j].refresh_link);
- }
- GNUNET_free (commit_coin[i]);
- }
-}
-
-
-/**
- * Release memory from the @a commit_link array.
- *
- * @param commit_link array to release
- * @param kappa size of 1st dimension
- * @param num_old_coins size of 2nd dimension
- */
-static void
-free_commit_links (struct TALER_MINTDB_RefreshCommitLinkP **commit_link,
- unsigned int kappa,
- unsigned int num_old_coins)
-{
- unsigned int i;
-
- for (i=0;i<kappa;i++)
- {
- if (NULL == commit_link[i])
- break;
- GNUNET_free (commit_link[i]);
- }
-}
-
-
-/**
- * Handle a "/refresh/melt" request after the first parsing has happened.
- * We now need to validate the coins being melted and the session signature
- * and then hand things of to execute the melt operation. This function
- * parses the JSON arrays and then passes processing on to
- * #handle_refresh_melt_binary().
- *
- * @param connection the MHD connection to handle
- * @param new_denoms array of denomination keys
- * @param melt_coins array of coins to melt
- * @param num_oldcoins number of coins that are being melted
- * @param transfer_pubs #TALER_CNC_KAPPA-dimensional array of @a num_oldcoins transfer keys
- * @param secret_encs #TALER_CNC_KAPPA-dimensional array of @a num_oldcoins secrets
- * @param num_newcoins number of coins that the refresh will generate
- * @param coin_evs #TALER_CNC_KAPPA-dimensional array of @a num_newcoins envelopes to sign
- * @param link_encs #TALER_CNC_KAPPA-dimensional array of @a num_newcoins encrypted links
- * @return MHD result code
- */
-static int
-handle_refresh_melt_json (struct MHD_Connection *connection,
- const json_t *new_denoms,
- const json_t *melt_coins,
- unsigned int num_oldcoins,
- const json_t *transfer_pubs,
- const json_t *secret_encs,
- unsigned int num_newcoins,
- const json_t *coin_evs,
- const json_t *link_encs)
-
-{
- int res;
- unsigned int i;
- unsigned int j;
- struct TALER_DenominationPublicKey *denom_pubs;
- unsigned int num_new_denoms;
- struct TMH_DB_MeltDetails *coin_melt_details;
- unsigned int coin_count;
- struct GNUNET_HashCode session_hash;
- struct GNUNET_HashContext *hash_context;
- struct TALER_MINTDB_RefreshCommitCoin *commit_coin[TALER_CNC_KAPPA];
- struct TALER_MINTDB_RefreshCommitLinkP *commit_link[TALER_CNC_KAPPA];
-
- /* For the signature check, we hash most of the inputs together
- (except for the signatures on the coins). */
- hash_context = GNUNET_CRYPTO_hash_context_start ();
- num_new_denoms = json_array_size (new_denoms);
- denom_pubs = GNUNET_malloc (num_new_denoms *
- sizeof (struct TALER_DenominationPublicKey));
- for (i=0;i<num_new_denoms;i++)
- {
- char *buf;
- size_t buf_size;
-
- res = TMH_PARSE_navigate_json (connection,
- new_denoms,
- TMH_PARSE_JNC_INDEX, (int) i,
- TMH_PARSE_JNC_RET_RSA_PUBLIC_KEY,
- &denom_pubs[i].rsa_public_key);
- if (GNUNET_OK != res)
- {
- for (j=0;j<i;j++)
- GNUNET_CRYPTO_rsa_public_key_free (denom_pubs[j].rsa_public_key);
- GNUNET_free (denom_pubs);
- return res;
- }
- buf_size = GNUNET_CRYPTO_rsa_public_key_encode (denom_pubs[i].rsa_public_key,
- &buf);
- GNUNET_CRYPTO_hash_context_read (hash_context,
- buf,
- buf_size);
- GNUNET_free (buf);
- }
-
- coin_count = json_array_size (melt_coins);
- coin_melt_details = GNUNET_malloc (coin_count *
- sizeof (struct TMH_DB_MeltDetails));
- for (i=0;i<coin_count;i++)
- {
- /* decode JSON data on coin to melt */
- struct TALER_AmountNBO melt_amount;
-
- res = get_coin_public_info (connection,
- json_array_get (melt_coins, i),
- &coin_melt_details[i]);
- if (GNUNET_OK != res)
- {
- for (j=0;j<i;j++)
- {
- GNUNET_CRYPTO_rsa_public_key_free (coin_melt_details[j].coin_info.denom_pub.rsa_public_key);
- GNUNET_CRYPTO_rsa_signature_free (coin_melt_details[j].coin_info.denom_sig.rsa_signature);
- }
- for (j=0;j<num_new_denoms;j++)
- GNUNET_CRYPTO_rsa_public_key_free (denom_pubs[j].rsa_public_key);
- GNUNET_free (coin_melt_details);
- GNUNET_free (denom_pubs);
- return (GNUNET_NO == res) ? MHD_YES : MHD_NO;
- }
- /* Check that the client does not try to melt the same coin twice
- into the same session! */
- for (j=0;j<i;j++)
- {
- if (0 == memcmp (&coin_melt_details[i].coin_info.coin_pub,
- &coin_melt_details[j].coin_info.coin_pub,
- sizeof (struct TALER_CoinSpendPublicKeyP)))
- {
- for (j=0;j<i;j++)
- {
- GNUNET_CRYPTO_rsa_public_key_free (coin_melt_details[j].coin_info.denom_pub.rsa_public_key);
- GNUNET_CRYPTO_rsa_signature_free (coin_melt_details[j].coin_info.denom_sig.rsa_signature);
- }
- for (j=0;j<num_new_denoms;j++)
- GNUNET_CRYPTO_rsa_public_key_free (denom_pubs[j].rsa_public_key);
- GNUNET_free (coin_melt_details);
- GNUNET_free (denom_pubs);
- return TMH_RESPONSE_reply_external_error (connection,
- "melting same coin twice in same session is not allowed");
- }
- }
- TALER_amount_hton (&melt_amount,
- &coin_melt_details[i].melt_amount_with_fee);
- GNUNET_CRYPTO_hash_context_read (hash_context,
- &coin_melt_details[i].coin_info.coin_pub,
- sizeof (struct TALER_CoinSpendPublicKeyP));
- GNUNET_CRYPTO_hash_context_read (hash_context,
- &melt_amount,
- sizeof (struct TALER_AmountNBO));
-
- }
-
- /* parse JSON arrays into 2d binary arrays and hash everything
- together for the signature check */
- memset (commit_coin, 0, sizeof (commit_coin));
- memset (commit_link, 0, sizeof (commit_link));
- for (i = 0; i < TALER_CNC_KAPPA; i++)
- {
- commit_coin[i] = GNUNET_malloc (num_newcoins *
- sizeof (struct TALER_MINTDB_RefreshCommitCoin));
- for (j = 0; j < num_newcoins; j++)
- {
- char *link_enc;
- size_t link_enc_size;
- struct TALER_MINTDB_RefreshCommitCoin *rcc = &commit_coin[i][j];
-
- res = TMH_PARSE_navigate_json (connection,
- coin_evs,
- TMH_PARSE_JNC_INDEX, (int) i,
- TMH_PARSE_JNC_INDEX, (int) j,
- TMH_PARSE_JNC_RET_DATA_VAR,
- &rcc->coin_ev,
- &rcc->coin_ev_size);
-
- if (GNUNET_OK != res)
- {
- GNUNET_CRYPTO_hash_context_abort (hash_context);
- free_commit_coins (commit_coin,
- TALER_CNC_KAPPA,
- num_newcoins);
- return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES;
- }
- GNUNET_CRYPTO_hash_context_read (hash_context,
- rcc->coin_ev,
- rcc->coin_ev_size);
- res = TMH_PARSE_navigate_json (connection,
- link_encs,
- TMH_PARSE_JNC_INDEX, (int) i,
- TMH_PARSE_JNC_INDEX, (int) j,
- TMH_PARSE_JNC_RET_DATA_VAR,
- &link_enc,
- &link_enc_size);
- if (GNUNET_OK != res)
- {
- GNUNET_CRYPTO_hash_context_abort (hash_context);
- free_commit_coins (commit_coin,
- TALER_CNC_KAPPA,
- num_newcoins);
- GNUNET_free (link_enc);
- return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES;
- }
- rcc->refresh_link
- = TALER_refresh_link_encrypted_decode (link_enc,
- link_enc_size);
- GNUNET_CRYPTO_hash_context_read (hash_context,
- link_enc,
- link_enc_size);
- GNUNET_free (link_enc);
- }
- }
-
- for (i = 0; i < TALER_CNC_KAPPA; i++)
- {
- commit_link[i] = GNUNET_malloc (num_oldcoins *
- sizeof (struct TALER_MINTDB_RefreshCommitLinkP));
- for (j = 0; j < num_oldcoins; j++)
- {
- struct TALER_MINTDB_RefreshCommitLinkP *rcl = &commit_link[i][j];
-
- res = TMH_PARSE_navigate_json (connection,
- transfer_pubs,
- TMH_PARSE_JNC_INDEX, (int) i,
- TMH_PARSE_JNC_INDEX, (int) j,
- TMH_PARSE_JNC_RET_DATA,
- &rcl->transfer_pub,
- sizeof (struct TALER_TransferPublicKeyP));
-
- if (GNUNET_OK != res)
- {
- GNUNET_break (GNUNET_SYSERR != res);
- GNUNET_CRYPTO_hash_context_abort (hash_context);
- free_commit_coins (commit_coin,
- TALER_CNC_KAPPA,
- num_newcoins);
- free_commit_links (commit_link,
- TALER_CNC_KAPPA,
- num_oldcoins);
- return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES;
- }
- res = TMH_PARSE_navigate_json (connection,
- secret_encs,
- TMH_PARSE_JNC_INDEX, (int) i,
- TMH_PARSE_JNC_INDEX, (int) j,
- TMH_PARSE_JNC_RET_DATA,
- &rcl->shared_secret_enc,
- sizeof (struct TALER_EncryptedLinkSecretP));
-
- if (GNUNET_OK != res)
- {
- GNUNET_break (GNUNET_SYSERR != res);
- GNUNET_CRYPTO_hash_context_abort (hash_context);
- free_commit_coins (commit_coin,
- TALER_CNC_KAPPA,
- num_newcoins);
- free_commit_links (commit_link,
- TALER_CNC_KAPPA,
- num_oldcoins);
- return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES;
- }
-
- GNUNET_CRYPTO_hash_context_read (hash_context,
- rcl,
- sizeof (struct TALER_MINTDB_RefreshCommitLinkP));
- }
-
- }
- GNUNET_CRYPTO_hash_context_finish (hash_context,
- &session_hash);
-
- for (i=0;i<coin_count;i++)
- {
- /* verify signatures on coins to melt */
- res = verify_coin_public_info (connection,
- &session_hash,
- &coin_melt_details[i]);
- if (GNUNET_OK != res)
- {
- res = (GNUNET_NO == res) ? MHD_YES : MHD_NO;
- goto cleanup;
- }
- }
-
- /* execute commit */
- res = handle_refresh_melt_binary (connection,
- num_new_denoms,
- denom_pubs,
- coin_count,
- coin_melt_details,
- &session_hash,
- commit_coin,
- commit_link);
- cleanup:
- free_commit_coins (commit_coin,
- TALER_CNC_KAPPA,
- num_newcoins);
- free_commit_links (commit_link,
- TALER_CNC_KAPPA,
- num_oldcoins);
- for (j=0;j<coin_count;j++)
- {
- GNUNET_CRYPTO_rsa_public_key_free (coin_melt_details[j].coin_info.denom_pub.rsa_public_key);
- GNUNET_CRYPTO_rsa_signature_free (coin_melt_details[j].coin_info.denom_sig.rsa_signature);
- }
- for (j=0;j<num_new_denoms;j++)
- GNUNET_CRYPTO_rsa_public_key_free (denom_pubs[j].rsa_public_key);
- GNUNET_free (coin_melt_details);
- GNUNET_free (denom_pubs);
- return res;
-}
-
-
-/**
- * Handle a "/refresh/melt" request. Parses the request into the JSON
- * components and then hands things of to #handle_refresh_melt_json()
- * to validate the melted coins, the signature and execute the melt
- * using TMH_DB_execute_refresh_melt().
- *
- * @param rh context of the handler
- * @param connection the MHD connection to handle
- * @param[in,out] connection_cls the connection's closure (can be updated)
- * @param upload_data upload data
- * @param[in,out] upload_data_size number of bytes (left) in @a upload_data
- * @return MHD result code
- */
-int
-TMH_REFRESH_handler_refresh_melt (struct TMH_RequestHandler *rh,
- struct MHD_Connection *connection,
- void **connection_cls,
- const char *upload_data,
- size_t *upload_data_size)
-{
- json_t *root;
- json_t *new_denoms;
- json_t *melt_coins;
- json_t *coin_evs;
- json_t *link_encs;
- json_t *transfer_pubs;
- json_t *secret_encs;
- unsigned int num_oldcoins;
- unsigned int num_newcoins;
- json_t *coin_detail;
- int res;
- struct TMH_PARSE_FieldSpecification spec[] = {
- TMH_PARSE_member_array ("new_denoms", &new_denoms),
- TMH_PARSE_member_array ("melt_coins", &melt_coins),
- TMH_PARSE_member_array ("coin_evs", &coin_evs),
- TMH_PARSE_member_array ("link_encs", &link_encs),
- TMH_PARSE_member_array ("transfer_pubs", &transfer_pubs),
- TMH_PARSE_member_array ("secret_encs", &secret_encs),
- TMH_PARSE_MEMBER_END
- };
-
- res = TMH_PARSE_post_json (connection,
- connection_cls,
- upload_data,
- upload_data_size,
- &root);
- if (GNUNET_SYSERR == res)
- return MHD_NO;
- if ( (GNUNET_NO == res) || (NULL == root) )
- return MHD_YES;
-
- res = TMH_PARSE_json_data (connection,
- root,
- spec);
- json_decref (root);
- if (GNUNET_OK != res)
- return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES;
-
- /* Determine dimensionality of the request (kappa, #old and #new coins) */
- if (TALER_CNC_KAPPA != json_array_size (coin_evs))
- {
- GNUNET_break_op (0);
- TMH_PARSE_release_data (spec);
- return TMH_RESPONSE_reply_arg_invalid (connection,
- "coin_evs");
- }
- if (TALER_CNC_KAPPA != json_array_size (transfer_pubs))
- {
- GNUNET_break_op (0);
- TMH_PARSE_release_data (spec);
- return TMH_RESPONSE_reply_arg_invalid (connection,
- "transfer_pubs");
- }
- res = TMH_PARSE_navigate_json (connection, coin_evs,
- TMH_PARSE_JNC_INDEX, (int) 0,
- TMH_PARSE_JNC_RET_DATA,
- JSON_ARRAY, &coin_detail);
- if (GNUNET_OK != res)
- {
- TMH_PARSE_release_data (spec);
- return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES;
- }
- num_newcoins = json_array_size (coin_detail);
- res = TMH_PARSE_navigate_json (connection,
- transfer_pubs,
- TMH_PARSE_JNC_INDEX, (int) 0,
- TMH_PARSE_JNC_RET_DATA,
- JSON_ARRAY, &coin_detail);
- if (GNUNET_OK != res)
- {
- TMH_PARSE_release_data (spec);
- return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES;
- }
- num_oldcoins = json_array_size (coin_detail);
-
- res = handle_refresh_melt_json (connection,
- new_denoms,
- melt_coins,
- num_oldcoins,
- transfer_pubs,
- secret_encs,
- num_newcoins,
- coin_evs,
- link_encs);
-
- TMH_PARSE_release_data (spec);
- return res;
-}
-
-
-/**
- * Handle a "/refresh/reveal" request. Parses the given JSON
- * transfer private keys and if successful, passes everything to
- * #TMH_DB_execute_refresh_reveal() which will verify that the
- * revealed information is valid then returns the signed refreshed
- * coins.
- *
- * @param connection the MHD connection to handle
- * @param session_hash hash identifying the melting session
- * @param num_oldcoins length of the 2nd dimension of @a transfer_privs array
- * @param tp_json private transfer keys in JSON format
- * @return MHD result code
- */
-static int
-handle_refresh_reveal_json (struct MHD_Connection *connection,
- const struct GNUNET_HashCode *session_hash,
- unsigned int num_oldcoins,
- const json_t *tp_json)
-{
- struct TALER_TransferPrivateKeyP *transfer_privs[TALER_CNC_KAPPA - 1];
- unsigned int i;
- unsigned int j;
- int res;
-
- for (i = 0; i < TALER_CNC_KAPPA - 1; i++)
- transfer_privs[i] = GNUNET_malloc (num_oldcoins *
- sizeof (struct TALER_TransferPrivateKeyP));
- res = GNUNET_OK;
- for (i = 0; i < TALER_CNC_KAPPA - 1; i++)
- {
- if (GNUNET_OK != res)
- break;
- for (j = 0; j < num_oldcoins; j++)
- {
- if (GNUNET_OK != res)
- break;
- res = TMH_PARSE_navigate_json (connection,
- tp_json,
- TMH_PARSE_JNC_INDEX, (int) i,
- TMH_PARSE_JNC_INDEX, (int) j,
- TMH_PARSE_JNC_RET_DATA,
- &transfer_privs[i][j],
- sizeof (struct TALER_TransferPrivateKeyP));
- }
- }
- if (GNUNET_OK != res)
- res = (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES;
- else
- res = TMH_DB_execute_refresh_reveal (connection,
- session_hash,
- num_oldcoins,
- transfer_privs);
- for (i = 0; i < TALER_CNC_KAPPA - 1; i++)
- GNUNET_free (transfer_privs[i]);
- return res;
-}
-
-
-/**
- * Handle a "/refresh/reveal" request. This time, the client reveals
- * the private transfer keys except for the cut-and-choose value
- * returned from "/refresh/melt". This function parses the revealed
- * keys and secrets and ultimately passes everything to
- * #TMH_DB_execute_refresh_reveal() which will verify that the
- * revealed information is valid then returns the signed refreshed
- * coins.
- *
- * @param rh context of the handler
- * @param connection the MHD connection to handle
- * @param[in,out] connection_cls the connection's closure (can be updated)
- * @param upload_data upload data
- * @param[in,out] upload_data_size number of bytes (left) in @a upload_data
- * @return MHD result code
- */
-int
-TMH_REFRESH_handler_refresh_reveal (struct TMH_RequestHandler *rh,
- struct MHD_Connection *connection,
- void **connection_cls,
- const char *upload_data,
- size_t *upload_data_size)
-{
- struct GNUNET_HashCode session_hash;
- int res;
- unsigned int num_oldcoins;
- json_t *reveal_detail;
- json_t *root;
- json_t *transfer_privs;
- struct TMH_PARSE_FieldSpecification spec[] = {
- TMH_PARSE_member_fixed ("session_hash", &session_hash),
- TMH_PARSE_member_array ("transfer_privs", &transfer_privs),
- TMH_PARSE_MEMBER_END
- };
-
- res = TMH_PARSE_post_json (connection,
- connection_cls,
- upload_data,
- upload_data_size,
- &root);
- if (GNUNET_SYSERR == res)
- return MHD_NO;
- if ( (GNUNET_NO == res) || (NULL == root) )
- return MHD_YES;
-
- res = TMH_PARSE_json_data (connection,
- root,
- spec);
- json_decref (root);
- if (GNUNET_OK != res)
- return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES;
-
- /* Determine dimensionality of the request (kappa and #old coins) */
- /* Note we do +1 as 1 row (cut-and-choose!) is missing! */
- if (TALER_CNC_KAPPA != json_array_size (transfer_privs) + 1)
- {
- TMH_PARSE_release_data (spec);
- return TMH_RESPONSE_reply_arg_invalid (connection,
- "transfer_privs");
- }
- res = TMH_PARSE_navigate_json (connection,
- transfer_privs,
- TMH_PARSE_JNC_INDEX, 0,
- TMH_PARSE_JNC_RET_TYPED_JSON,
- JSON_ARRAY,
- &reveal_detail);
- if (GNUNET_OK != res)
- {
- TMH_PARSE_release_data (spec);
- return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES;
- }
- num_oldcoins = json_array_size (reveal_detail);
- res = handle_refresh_reveal_json (connection,
- &session_hash,
- num_oldcoins,
- transfer_privs);
- TMH_PARSE_release_data (spec);
- return res;
-}
-
-
-/**
- * Handle a "/refresh/link" request. Note that for "/refresh/link"
- * we do use a simple HTTP GET, and a HTTP POST!
- *
- * @param rh context of the handler
- * @param connection the MHD connection to handle
- * @param[in,out] connection_cls the connection's closure (can be updated)
- * @param upload_data upload data
- * @param[in,out] upload_data_size number of bytes (left) in @a upload_data
- * @return MHD result code
- */
-int
-TMH_REFRESH_handler_refresh_link (struct TMH_RequestHandler *rh,
- struct MHD_Connection *connection,
- void **connection_cls,
- const char *upload_data,
- size_t *upload_data_size)
-{
- struct TALER_CoinSpendPublicKeyP coin_pub;
- int res;
-
- res = TMH_PARSE_mhd_request_arg_data (connection,
- "coin_pub",
- &coin_pub,
- sizeof (struct TALER_CoinSpendPublicKeyP));
- if (GNUNET_SYSERR == res)
- return MHD_NO;
- if (GNUNET_OK != res)
- return MHD_YES;
- return TMH_DB_execute_refresh_link (connection,
- &coin_pub);
-}
-
-
-/* end of taler-mint-httpd_refresh.c */
diff --git a/src/backend/taler-mint-httpd_refresh.h b/src/backend/taler-mint-httpd_refresh.h
deleted file mode 100644
index 8fe12a27..00000000
--- a/src/backend/taler-mint-httpd_refresh.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2014, 2015 GNUnet e.V.
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU Affero General Public License as published by the Free Software
- 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 Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License along with
- TALER; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/>
-*/
-/**
- * @file taler-mint-httpd_refresh.h
- * @brief Handle /refresh/ requests
- * @author Florian Dold
- * @author Benedikt Mueller
- * @author Christian Grothoff
- */
-#ifndef TALER_MINT_HTTPD_REFRESH_H
-#define TALER_MINT_HTTPD_REFRESH_H
-
-#include <gnunet/gnunet_util_lib.h>
-#include <microhttpd.h>
-#include "taler-mint-httpd.h"
-
-
-/**
- * Handle a "/refresh/melt" request. Parses the request into the JSON
- * components and then hands things of to #handle_refresh_melt_json()
- * to validate the melted coins, the signature and execute the melt
- * using TMH_DB_execute_refresh_melt().
- *
- * @param rh context of the handler
- * @param connection the MHD connection to handle
- * @param[in,out] connection_cls the connection's closure (can be updated)
- * @param upload_data upload data
- * @param[in,out] upload_data_size number of bytes (left) in @a upload_data
- * @return MHD result code
- */
-int
-TMH_REFRESH_handler_refresh_melt (struct TMH_RequestHandler *rh,
- struct MHD_Connection *connection,
- void **connection_cls,
- const char *upload_data,
- size_t *upload_data_size);
-
-
-/**
- * Handle a "/refresh/reveal" request. This time, the client reveals
- * the private transfer keys except for the cut-and-choose value
- * returned from "/refresh/commit". This function parses the revealed
- * keys and secrets and ultimately passes everything to
- * #TMH_DB_execute_refresh_reveal() which will verify that the
- * revealed information is valid then returns the signed refreshed
- * coins.
- *
- * @param rh context of the handler
- * @param connection the MHD connection to handle
- * @param[in,out] connection_cls the connection's closure (can be updated)
- * @param upload_data upload data
- * @param[in,out] upload_data_size number of bytes (left) in @a upload_data
- * @return MHD result code
- */
-int
-TMH_REFRESH_handler_refresh_reveal (struct TMH_RequestHandler *rh,
- struct MHD_Connection *connection,
- void **connection_cls,
- const char *upload_data,
- size_t *upload_data_size);
-
-
-/**
- * Handle a "/refresh/link" request
- *
- * @param rh context of the handler
- * @param connection the MHD connection to handle
- * @param[in,out] connection_cls the connection's closure (can be updated)
- * @param upload_data upload data
- * @param[in,out] upload_data_size number of bytes (left) in @a upload_data
- * @return MHD result code
- */
-int
-TMH_REFRESH_handler_refresh_link (struct TMH_RequestHandler *rh,
- struct MHD_Connection *connection,
- void **connection_cls,
- const char *upload_data,
- size_t *upload_data_size);
-
-
-#endif
diff --git a/src/backend/taler-mint-httpd_responses.c b/src/backend/taler-mint-httpd_responses.c
index 57b233e7..a2a49c03 100644
--- a/src/backend/taler-mint-httpd_responses.c
+++ b/src/backend/taler-mint-httpd_responses.c
@@ -26,7 +26,6 @@
#include "taler-mint-httpd_responses.h"
#include "taler_util.h"
#include <gnunet/gnunet_util_lib.h>
-#include "taler-mint-httpd_keystate.h"
/**
@@ -107,104 +106,6 @@ TMH_RESPONSE_reply_json_pack (struct MHD_Connection *connection,
return ret;
}
-
-/**
- * Send a response indicating an invalid argument.
- *
- * @param connection the MHD connection to use
- * @param param_name the parameter that is invalid
- * @return a MHD result code
- */
-int
-TMH_RESPONSE_reply_arg_invalid (struct MHD_Connection *connection,
- const char *param_name)
-{
- return TMH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_BAD_REQUEST,
- "{s:s, s:s}",
- "error", "invalid parameter",
- "parameter", param_name);
-}
-
-
-/**
- * Send a response indicating an argument refering to a
- * resource unknown to the mint (i.e. unknown reserve or
- * denomination key).
- *
- * @param connection the MHD connection to use
- * @param param_name the parameter that is invalid
- * @return a MHD result code
- */
-int
-TMH_RESPONSE_reply_arg_unknown (struct MHD_Connection *connection,
- const char *param_name)
-{
- return TMH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_NOT_FOUND,
- "{s:s, s:s}",
- "error", "unknown entity referenced",
- "parameter", param_name);
-}
-
-
-/**
- * Send a response indicating an invalid signature.
- *
- * @param connection the MHD connection to use
- * @param param_name the parameter that is invalid
- * @return a MHD result code
- */
-int
-TMH_RESPONSE_reply_signature_invalid (struct MHD_Connection *connection,
- const char *param_name)
-{
- return TMH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_UNAUTHORIZED,
- "{s:s, s:s}",
- "error", "invalid signature",
- "parameter", param_name);
-}
-
-
-/**
- * Send a response indicating a missing argument.
- *
- * @param connection the MHD connection to use
- * @param param_name the parameter that is missing
- * @return a MHD result code
- */
-int
-TMH_RESPONSE_reply_arg_missing (struct MHD_Connection *connection,
- const char *param_name)
-{
- return TMH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_BAD_REQUEST,
- "{ s:s, s:s}",
- "error", "missing parameter",
- "parameter", param_name);
-}
-
-
-/**
- * Send a response indicating permission denied.
- *
- * @param connection the MHD connection to use
- * @param hint hint about why access was denied
- * @return a MHD result code
- */
-int
-TMH_RESPONSE_reply_permission_denied (struct MHD_Connection *connection,
- const char *hint)
-{
- return TMH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_FORBIDDEN,
- "{s:s, s:s}",
- "error", "permission denied",
- "hint", hint);
-}
-
-
/**
* Send a response indicating an internal error.
*
@@ -223,58 +124,6 @@ TMH_RESPONSE_reply_internal_error (struct MHD_Connection *connection,
"hint", hint);
}
-
-/**
- * Send a response indicating an external error.
- *
- * @param connection the MHD connection to use
- * @param hint hint about the error's nature
- * @return a MHD result code
- */
-int
-TMH_RESPONSE_reply_external_error (struct MHD_Connection *connection,
- const char *hint)
-{
- return TMH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_BAD_REQUEST,
- "{s:s, s:s}",
- "error", "client error",
- "hint", hint);
-}
-
-
-/**
- * Send a response indicating an error committing a
- * transaction (concurrent interference).
- *
- * @param connection the MHD connection to use
- * @return a MHD result code
- */
-int
-TMH_RESPONSE_reply_commit_error (struct MHD_Connection *connection)
-{
- return TMH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_BAD_REQUEST,
- "{s:s}",
- "error", "commit failure");
-}
-
-
-/**
- * Send a response indicating a failure to talk to the Mint's
- * database.
- *
- * @param connection the MHD connection to use
- * @return a MHD result code
- */
-int
-TMH_RESPONSE_reply_internal_db_error (struct MHD_Connection *connection)
-{
- return TMH_RESPONSE_reply_internal_error (connection,
- "Failed to connect to database");
-}
-
-
/**
* Send a response indicating that the request was too big.
*
@@ -316,682 +165,4 @@ TMH_RESPONSE_reply_invalid_json (struct MHD_Connection *connection)
"invalid json");
}
-
-/**
- * Send confirmation of deposit success to client. This function
- * will create a signed message affirming the given information
- * and return it to the client. By this, the mint affirms that
- * the coin had sufficient (residual) value for the specified
- * transaction and that it will execute the requested deposit
- * operation with the given wiring details.
- *
- * @param connection connection to the client
- * @param coin_pub public key of the coin
- * @param h_wire hash of wire details
- * @param h_contract hash of contract details
- * @param transaction_id transaction ID
- * @param timestamp client's timestamp
- * @param refund_deadline until when this deposit be refunded
- * @param merchant merchant public key
- * @param amount_without_fee fraction of coin value to deposit, without the fee
- * @return MHD result code
- */
-int
-TMH_RESPONSE_reply_deposit_success (struct MHD_Connection *connection,
- const struct TALER_CoinSpendPublicKeyP *coin_pub,
- const struct GNUNET_HashCode *h_wire,
- const struct GNUNET_HashCode *h_contract,
- uint64_t transaction_id,
- struct GNUNET_TIME_Absolute timestamp,
- struct GNUNET_TIME_Absolute refund_deadline,
- const struct TALER_MerchantPublicKeyP *merchant,
- const struct TALER_Amount *amount_without_fee)
-{
- struct TALER_DepositConfirmationPS dc;
- struct TALER_MintPublicKeyP pub;
- struct TALER_MintSignatureP sig;
-
- dc.purpose.purpose = htonl (TALER_SIGNATURE_MINT_CONFIRM_DEPOSIT);
- dc.purpose.size = htonl (sizeof (struct TALER_DepositConfirmationPS));
- dc.h_contract = *h_contract;
- dc.h_wire = *h_wire;
- dc.transaction_id = GNUNET_htonll (transaction_id);
- dc.timestamp = GNUNET_TIME_absolute_hton (timestamp);
- dc.refund_deadline = GNUNET_TIME_absolute_hton (refund_deadline);
- TALER_amount_hton (&dc.amount_without_fee,
- amount_without_fee);
- dc.coin_pub = *coin_pub;
- dc.merchant = *merchant;
- TMH_KS_sign (&dc.purpose,
- &pub,
- &sig);
- return TMH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_OK,
- "{s:s, s:o, s:o}",
- "status", "DEPOSIT_OK",
- "sig", TALER_json_from_data (&sig,
- sizeof (sig)),
- "pub", TALER_json_from_data (&pub,
- sizeof (pub)));
-}
-
-
-/**
- * Compile the transaction history of a coin into a JSON object.
- *
- * @param tl transaction history to JSON-ify
- * @return json representation of the @a rh
- */
-static json_t *
-compile_transaction_history (const struct TALER_MINTDB_TransactionList *tl)
-{
- json_t *transaction;
- const char *type;
- struct TALER_Amount value;
- json_t *history;
- const struct TALER_MINTDB_TransactionList *pos;
-
- history = json_array ();
- for (pos = tl; NULL != pos; pos = pos->next)
- {
- switch (pos->type)
- {
- case TALER_MINTDB_TT_DEPOSIT:
- {
- struct TALER_DepositRequestPS dr;
- const struct TALER_MINTDB_Deposit *deposit = pos->details.deposit;
-
- type = "deposit";
- value = deposit->amount_with_fee;
- dr.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_DEPOSIT);
- dr.purpose.size = htonl (sizeof (struct TALER_DepositRequestPS));
- dr.h_contract = deposit->h_contract;
- dr.h_wire = deposit->h_wire;
- dr.timestamp = GNUNET_TIME_absolute_hton (deposit->timestamp);
- dr.refund_deadline = GNUNET_TIME_absolute_hton (deposit->refund_deadline);
- dr.transaction_id = GNUNET_htonll (deposit->transaction_id);
- TALER_amount_hton (&dr.amount_with_fee,
- &deposit->amount_with_fee);
- TALER_amount_hton (&dr.deposit_fee,
- &deposit->deposit_fee);
- dr.merchant = deposit->merchant_pub;
- dr.coin_pub = deposit->coin.coin_pub;
- transaction = TALER_json_from_eddsa_sig (&dr.purpose,
- &deposit->csig.eddsa_signature);
- break;
- }
- case TALER_MINTDB_TT_REFRESH_MELT:
- {
- struct TALER_RefreshMeltCoinAffirmationPS ms;
- const struct TALER_MINTDB_RefreshMelt *melt = pos->details.melt;
-
- type = "melt";
- value = melt->amount_with_fee;
- ms.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_MELT);
- ms.purpose.size = htonl (sizeof (struct TALER_RefreshMeltCoinAffirmationPS));
- ms.session_hash = melt->session_hash;
- TALER_amount_hton (&ms.amount_with_fee,
- &melt->amount_with_fee);
- TALER_amount_hton (&ms.melt_fee,
- &melt->melt_fee);
- ms.coin_pub = melt->coin.coin_pub;
- transaction = TALER_json_from_eddsa_sig (&ms.purpose,
- &melt->coin_sig.eddsa_signature);
- }
- break;
- case TALER_MINTDB_TT_LOCK:
- {
- type = "lock";
- value = pos->details.lock->amount;
- transaction = NULL;
- GNUNET_break (0); /* #3625: Lock NOT implemented! */
- break;
- }
- default:
- GNUNET_assert (0);
- }
- json_array_append_new (history,
- json_pack ("{s:s, s:o, s:o}",
- "type", type,
- "amount", TALER_json_from_amount (&value),
- "signature", transaction));
- }
- return history;
-}
-
-
-/**
- * Send proof that a /deposit request is invalid to client. This
- * function will create a message with all of the operations affecting
- * the coin that demonstrate that the coin has insufficient value.
- *
- * @param connection connection to the client
- * @param tl transaction list to use to build reply
- * @return MHD result code
- */
-int
-TMH_RESPONSE_reply_deposit_insufficient_funds (struct MHD_Connection *connection,
- const struct TALER_MINTDB_TransactionList *tl)
-{
- json_t *history;
-
- history = compile_transaction_history (tl);
- return TMH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_FORBIDDEN,
- "{s:s, s:o}",
- "error", "insufficient funds",
- "history", history);
-}
-
-
-/**
- * Compile the history of a reserve into a JSON object
- * and calculate the total balance.
- *
- * @param rh reserve history to JSON-ify
- * @param[out] balance set to current reserve balance
- * @return json representation of the @a rh, NULL on error
- */
-static json_t *
-compile_reserve_history (const struct TALER_MINTDB_ReserveHistory *rh,
- struct TALER_Amount *balance)
-{
- struct TALER_Amount deposit_total;
- struct TALER_Amount withdraw_total;
- struct TALER_Amount value;
- json_t *json_history;
- json_t *transaction;
- int ret;
- const struct TALER_MINTDB_ReserveHistory *pos;
- struct TALER_WithdrawRequestPS wr;
-
- json_history = json_array ();
- ret = 0;
- for (pos = rh; NULL != pos; pos = pos->next)
- {
- switch (pos->type)
- {
- case TALER_MINTDB_RO_BANK_TO_MINT:
- if (0 == ret)
- deposit_total = pos->details.bank->amount;
- else
- if (GNUNET_OK !=
- TALER_amount_add (&deposit_total,
- &deposit_total,
- &pos->details.bank->amount))
- {
- json_decref (json_history);
- return NULL;
- }
- ret = 1;
- json_array_append_new (json_history,
- json_pack ("{s:s, s:O, s:o}",
- "type", "DEPOSIT",
- "wire", pos->details.bank->wire,
- "amount", TALER_json_from_amount (&pos->details.bank->amount)));
- break;
- case TALER_MINTDB_RO_WITHDRAW_COIN:
- break;
- }
- }
-
- ret = 0;
- for (pos = rh; NULL != pos; pos = pos->next)
- {
- switch (pos->type)
- {
- case TALER_MINTDB_RO_BANK_TO_MINT:
- break;
- case TALER_MINTDB_RO_WITHDRAW_COIN:
- value = pos->details.withdraw->amount_with_fee;
- if (0 == ret)
- {
- withdraw_total = value;
- }
- else
- {
- if (GNUNET_OK !=
- TALER_amount_add (&withdraw_total,
- &withdraw_total,
- &value))
- {
- json_decref (json_history);
- return NULL;
- }
- }
- ret = 1;
- wr.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW);
- wr.purpose.size = htonl (sizeof (struct TALER_WithdrawRequestPS));
- wr.reserve_pub = pos->details.withdraw->reserve_pub;
- TALER_amount_hton (&wr.amount_with_fee,
- &value);
- TALER_amount_hton (&wr.withdraw_fee,
- &pos->details.withdraw->withdraw_fee);
- GNUNET_CRYPTO_rsa_public_key_hash (pos->details.withdraw->denom_pub.rsa_public_key,
- &wr.h_denomination_pub);
- wr.h_coin_envelope = pos->details.withdraw->h_coin_envelope;
-
- transaction = TALER_json_from_eddsa_sig (&wr.purpose,
- &pos->details.withdraw->reserve_sig.eddsa_signature);
-
- json_array_append_new (json_history,
- json_pack ("{s:s, s:o, s:o}",
- "type", "WITHDRAW",
- "signature", transaction,
- "amount", TALER_json_from_amount (&value)));
- break;
- }
- }
- if (0 == ret)
- {
- /* did not encounter any withdraw operations, set to zero */
- TALER_amount_get_zero (deposit_total.currency,
- &withdraw_total);
- }
- if (GNUNET_SYSERR ==
- TALER_amount_subtract (balance,
- &deposit_total,
- &withdraw_total))
- {
- GNUNET_break (0);
- json_decref (json_history);
- return NULL;
- }
-
- return json_history;
-}
-
-
-/**
- * Send reserve status information to client.
- *
- * @param connection connection to the client
- * @param rh reserve history to return
- * @return MHD result code
- */
-int
-TMH_RESPONSE_reply_withdraw_status_success (struct MHD_Connection *connection,
- const struct TALER_MINTDB_ReserveHistory *rh)
-{
- json_t *json_balance;
- json_t *json_history;
- struct TALER_Amount balance;
-
- json_history = compile_reserve_history (rh,
- &balance);
- if (NULL == json_history)
- return TMH_RESPONSE_reply_internal_error (connection,
- "balance calculation failure");
- json_balance = TALER_json_from_amount (&balance);
- return TMH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_OK,
- "{s:o, s:o}",
- "balance", json_balance,
- "history", json_history);
-}
-
-
-/**
- * Send reserve status information to client with the
- * message that we have insufficient funds for the
- * requested /withdraw/sign operation.
- *
- * @param connection connection to the client
- * @param rh reserve history to return
- * @return MHD result code
- */
-int
-TMH_RESPONSE_reply_withdraw_sign_insufficient_funds (struct MHD_Connection *connection,
- const struct TALER_MINTDB_ReserveHistory *rh)
-{
- json_t *json_balance;
- json_t *json_history;
- struct TALER_Amount balance;
-
- json_history = compile_reserve_history (rh,
- &balance);
- if (NULL == json_history)
- return TMH_RESPONSE_reply_internal_error (connection,
- "balance calculation failure");
- json_balance = TALER_json_from_amount (&balance);
- return TMH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_PAYMENT_REQUIRED,
- "{s:s, s:o, s:o}",
- "error", "Insufficient funds",
- "balance", json_balance,
- "history", json_history);
-}
-
-
-/**
- * Send blinded coin information to client.
- *
- * @param connection connection to the client
- * @param collectable blinded coin to return
- * @return MHD result code
- */
-int
-TMH_RESPONSE_reply_withdraw_sign_success (struct MHD_Connection *connection,
- const struct TALER_MINTDB_CollectableBlindcoin *collectable)
-{
- json_t *sig_json;
-
- sig_json = TALER_json_from_rsa_signature (collectable->sig.rsa_signature);
- return TMH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_OK,
- "{s:o}",
- "ev_sig", sig_json);
-}
-
-
-/**
- * Send a response for a failed "/refresh/melt" request. The
- * transaction history of the given coin demonstrates that the
- * @a residual value of the coin is below the @a requested
- * contribution of the coin for the melt. Thus, the mint
- * refuses the melt operation.
- *
- * @param connection the connection to send the response to
- * @param coin_pub public key of the coin
- * @param coin_value original value of the coin
- * @param tl transaction history for the coin
- * @param requested how much this coin was supposed to contribute
- * @param residual remaining value of the coin (after subtracting @a tl)
- * @return a MHD result code
- */
-int
-TMH_RESPONSE_reply_refresh_melt_insufficient_funds (struct MHD_Connection *connection,
- const struct TALER_CoinSpendPublicKeyP *coin_pub,
- struct TALER_Amount coin_value,
- struct TALER_MINTDB_TransactionList *tl,
- struct TALER_Amount requested,
- struct TALER_Amount residual)
-{
- json_t *history;
-
- history = compile_transaction_history (tl);
- return TMH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_NOT_FOUND,
- "{s:s, s:o, s:o, s:o, s:o, s:o}",
- "error", "insufficient funds",
- "coin-pub", TALER_json_from_data (coin_pub,
- sizeof (struct TALER_CoinSpendPublicKeyP)),
- "original-value", TALER_json_from_amount (&coin_value),
- "residual-value", TALER_json_from_amount (&residual),
- "requested-value", TALER_json_from_amount (&requested),
- "history", history);
-}
-
-
-/**
- * Send a response to a "/refresh/melt" request.
- *
- * @param connection the connection to send the response to
- * @param session_hash hash of the refresh session
- * @param noreveal_index which index will the client not have to reveal
- * @return a MHD status code
- */
-int
-TMH_RESPONSE_reply_refresh_melt_success (struct MHD_Connection *connection,
- const struct GNUNET_HashCode *session_hash,
- uint16_t noreveal_index)
-{
- struct TALER_RefreshMeltConfirmationPS body;
- struct TALER_MintPublicKeyP pub;
- struct TALER_MintSignatureP sig;
- json_t *sig_json;
-
- body.purpose.size = htonl (sizeof (struct TALER_RefreshMeltConfirmationPS));
- body.purpose.purpose = htonl (TALER_SIGNATURE_MINT_CONFIRM_MELT);
- body.session_hash = *session_hash;
- body.noreveal_index = htons (noreveal_index);
- TMH_KS_sign (&body.purpose,
- &pub,
- &sig);
- sig_json = TALER_json_from_data (&sig,
- sizeof (sig));
- GNUNET_assert (NULL != sig_json);
- return TMH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_OK,
- "{s:i, s:o, s:o}",
- "noreveal_index", (int) noreveal_index,
- "mint_sig", sig_json,
- "mint_pub", TALER_json_from_data (&pub,
- sizeof (pub)));
-}
-
-
-/**
- * Send a response for "/refresh/reveal".
- *
- * @param connection the connection to send the response to
- * @param num_newcoins number of new coins for which we reveal data
- * @param sigs array of @a num_newcoins signatures revealed
- * @return a MHD result code
- */
-int
-TMH_RESPONSE_reply_refresh_reveal_success (struct MHD_Connection *connection,
- unsigned int num_newcoins,
- const struct TALER_DenominationSignature *sigs)
-{
- int newcoin_index;
- json_t *root;
- json_t *list;
- int ret;
-
- root = json_object ();
- list = json_array ();
- json_object_set_new (root,
- "ev_sigs",
- list);
- for (newcoin_index = 0; newcoin_index < num_newcoins; newcoin_index++)
- json_array_append_new (list,
- TALER_json_from_rsa_signature (sigs[newcoin_index].rsa_signature));
- ret = TMH_RESPONSE_reply_json (connection,
- root,
- MHD_HTTP_OK);
- json_decref (root);
- return ret;
-}
-
-
-/**
- * Send a response for a failed "/refresh/reveal", where the
- * revealed value(s) do not match the original commitment.
- *
- * @param connection the connection to send the response to
- * @param mc all information about the original commitment
- * @param off offset in the array of kappa-commitments where
- * the missmatch was detected
- * @param j index of the coin for which the missmatch was
- * detected
- * @param missmatch_object name of the object that was
- * bogus (i.e. "transfer key").
- * @return a MHD result code
- */
-int
-TMH_RESPONSE_reply_refresh_reveal_missmatch (struct MHD_Connection *connection,
- const struct TALER_MINTDB_MeltCommitment *mc,
- unsigned int off,
- unsigned int j,
- const char *missmatch_object)
-{
- json_t *info_old;
- json_t *info_new;
- json_t *info_commit;
- json_t *info_links;
- unsigned int i;
- unsigned int k;
-
- info_old = json_array ();
- for (i=0;i<mc->num_oldcoins;i++)
- {
- const struct TALER_MINTDB_RefreshMelt *rm;
- json_t *rm_json;
-
- rm = &mc->melts[i];
- rm_json = json_object ();
- json_object_set_new (rm_json,
- "coin_sig",
- TALER_json_from_data (&rm->coin_sig,
- sizeof (struct TALER_CoinSpendSignatureP)));
- json_object_set_new (rm_json,
- "coin_pub",
- TALER_json_from_data (&rm->coin.coin_pub,
- sizeof (struct TALER_CoinSpendPublicKeyP)));
- json_object_set_new (rm_json,
- "melt_amount_with_fee",
- TALER_json_from_amount (&rm->amount_with_fee));
- json_object_set_new (rm_json,
- "melt_fee",
- TALER_json_from_amount (&rm->melt_fee));
- json_array_append_new (info_old,
- rm_json);
- }
- info_new = json_array ();
- for (i=0;i<mc->num_newcoins;i++)
- {
- const struct TALER_DenominationPublicKey *pk;
-
- pk = &mc->denom_pubs[i];
- json_array_append_new (info_new,
- TALER_json_from_rsa_public_key (pk->rsa_public_key));
-
- }
- info_commit = json_array ();
- info_links = json_array ();
- for (k=0;k<TALER_CNC_KAPPA;k++)
- {
- json_t *info_commit_k;
- json_t *info_link_k;
-
- info_commit_k = json_array ();
- for (i=0;i<mc->num_newcoins;i++)
- {
- const struct TALER_MINTDB_RefreshCommitCoin *cc;
- json_t *cc_json;
-
- cc = &mc->commit_coins[k][i];
- cc_json = json_object ();
- json_object_set_new (cc_json,
- "coin_ev",
- TALER_json_from_data (cc->coin_ev,
- cc->coin_ev_size));
- json_object_set_new (cc_json,
- "coin_priv_enc",
- TALER_json_from_data (cc->refresh_link->coin_priv_enc,
- sizeof (struct TALER_CoinSpendPrivateKeyP)));
- json_object_set_new (cc_json,
- "blinding_key_enc",
- TALER_json_from_data (cc->refresh_link->blinding_key_enc,
- cc->refresh_link->blinding_key_enc_size));
-
- json_array_append_new (info_commit_k,
- cc_json);
- }
- json_array_append_new (info_commit,
- info_commit_k);
- info_link_k = json_array ();
- for (i=0;i<mc->num_newcoins;i++)
- {
- const struct TALER_MINTDB_RefreshCommitLinkP *cl;
- json_t *cl_json;
-
- cl = &mc->commit_links[k][i];
- cl_json = json_object ();
- json_object_set_new (cl_json,
- "transfer_pub",
- TALER_json_from_data (&cl->transfer_pub,
- sizeof (struct TALER_TransferPublicKeyP)));
- json_object_set_new (cl_json,
- "shared_secret_enc",
- TALER_json_from_data (&cl->shared_secret_enc,
- sizeof (struct TALER_EncryptedLinkSecretP)));
- json_array_append_new (info_link_k,
- cl_json);
- }
- json_array_append_new (info_links,
- info_link_k);
- }
- return TMH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_CONFLICT,
- "{s:s, s:i, s:i, s:o, s:o, s:o, s:o, s:s}",
- "error", "commitment violation",
- "offset", (int) off,
- "index", (int) j,
- "oldcoin_infos", info_old,
- "newcoin_infos", info_new,
- "commit_infos", info_commit,
- "link_infos", info_links,
- "object", missmatch_object);
-}
-
-
-/**
- * Send a response for "/refresh/link".
- *
- * @param connection the connection to send the response to
- * @param num_sessions number of sessions the coin was used in
- * @param sessions array of @a num_session entries with
- * information for each session
- * @return a MHD result code
- */
-int
-TMH_RESPONSE_reply_refresh_link_success (struct MHD_Connection *connection,
- unsigned int num_sessions,
- const struct TMH_RESPONSE_LinkSessionInfo *sessions)
-{
- json_t *root;
- json_t *mlist;
- int res;
- unsigned int i;
-
- mlist = json_array ();
- for (i=0;i<num_sessions;i++)
- {
- const struct TALER_MINTDB_LinkDataList *pos;
- json_t *list = json_array ();
-
- for (pos = sessions[i].ldl; NULL != pos; pos = pos->next)
- {
- json_t *obj;
-
- obj = json_object ();
- json_object_set_new (obj,
- "link_enc",
- TALER_json_from_data (pos->link_data_enc->coin_priv_enc,
- sizeof (struct TALER_CoinSpendPrivateKeyP) +
- pos->link_data_enc->blinding_key_enc_size));
- json_object_set_new (obj,
- "denom_pub",
- TALER_json_from_rsa_public_key (pos->denom_pub.rsa_public_key));
- json_object_set_new (obj,
- "ev_sig",
- TALER_json_from_rsa_signature (pos->ev_sig.rsa_signature));
- json_array_append_new (list,
- obj);
- }
- root = json_object ();
- json_object_set_new (root,
- "new_coins",
- list);
- json_object_set_new (root,
- "transfer_pub",
- TALER_json_from_data (&sessions[i].transfer_pub,
- sizeof (struct TALER_TransferPublicKeyP)));
- json_object_set_new (root,
- "secret_enc",
- TALER_json_from_data (&sessions[i].shared_secret_enc,
- sizeof (struct TALER_EncryptedLinkSecretP)));
- json_array_append_new (mlist,
- root);
- }
- res = TMH_RESPONSE_reply_json (connection,
- mlist,
- MHD_HTTP_OK);
- json_decref (mlist);
- return res;
-}
-
-
/* end of taler-mint-httpd_responses.c */
diff --git a/src/backend/taler-mint-httpd_withdraw.c b/src/backend/taler-mint-httpd_withdraw.c
deleted file mode 100644
index 4f558164..00000000
--- a/src/backend/taler-mint-httpd_withdraw.c
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2014,2015 GNUnet e.V.
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU Affero General Public License as published by the Free Software
- 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 Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License along with
- TALER; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/>
-*/
-/**
- * @file taler-mint-httpd_withdraw.c
- * @brief Handle /withdraw/ requests
- * @author Florian Dold
- * @author Benedikt Mueller
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include <gnunet/gnunet_util_lib.h>
-#include <jansson.h>
-#include "taler-mint-httpd_withdraw.h"
-#include "taler-mint-httpd_parsing.h"
-#include "taler-mint-httpd_responses.h"
-#include "taler-mint-httpd_keystate.h"
-
-
-/**
- * Handle a "/withdraw/status" request. Parses the
- * given "reserve_pub" argument (which should contain the
- * EdDSA public key of a reserve) and then respond with the
- * status of the reserve.
- *
- * @param rh context of the handler
- * @param connection the MHD connection to handle
- * @param[in,out] connection_cls the connection's closure (can be updated)
- * @param upload_data upload data
- * @param[in,out] upload_data_size number of bytes (left) in @a upload_data
- * @return MHD result code
- */
-int
-TMH_WITHDRAW_handler_withdraw_status (struct TMH_RequestHandler *rh,
- struct MHD_Connection *connection,
- void **connection_cls,
- const char *upload_data,
- size_t *upload_data_size)
-{
- struct TALER_ReservePublicKeyP reserve_pub;
- int res;
-
- res = TMH_PARSE_mhd_request_arg_data (connection,
- "reserve_pub",
- &reserve_pub,
- sizeof (struct TALER_ReservePublicKeyP));
- if (GNUNET_SYSERR == res)
- return MHD_NO; /* internal error */
- if (GNUNET_NO == res)
- return MHD_YES; /* parse error */
- return TMH_DB_execute_withdraw_status (connection,
- &reserve_pub);
-}
-
-
-/**
- * Handle a "/withdraw/sign" request. Parses the "reserve_pub"
- * EdDSA key of the reserve and the requested "denom_pub" which
- * specifies the key/value of the coin to be withdrawn, and checks
- * that the signature "reserve_sig" makes this a valid withdrawl
- * request from the specified reserve. If so, the envelope
- * with the blinded coin "coin_ev" is passed down to execute the
- * withdrawl operation.
- *
- * @param rh context of the handler
- * @param connection the MHD connection to handle
- * @param[in,out] connection_cls the connection's closure (can be updated)
- * @param upload_data upload data
- * @param[in,out] upload_data_size number of bytes (left) in @a upload_data
- * @return MHD result code
- */
-int
-TMH_WITHDRAW_handler_withdraw_sign (struct TMH_RequestHandler *rh,
- struct MHD_Connection *connection,
- void **connection_cls,
- const char *upload_data,
- size_t *upload_data_size)
-{
- json_t *root;
- struct TALER_WithdrawRequestPS wsrd;
- int res;
- struct TALER_DenominationPublicKey denomination_pub;
- char *blinded_msg;
- size_t blinded_msg_len;
- struct TALER_Amount amount;
- struct TALER_Amount amount_with_fee;
- struct TALER_Amount fee_withdraw;
- struct TALER_ReserveSignatureP signature;
- struct TALER_MINTDB_DenominationKeyIssueInformation *dki;
- struct TMH_KS_StateHandle *ks;
-
- struct TMH_PARSE_FieldSpecification spec[] = {
- TMH_PARSE_member_variable ("coin_ev", (void **) &blinded_msg, &blinded_msg_len),
- TMH_PARSE_member_fixed ("reserve_pub", &wsrd.reserve_pub),
- TMH_PARSE_member_fixed ("reserve_sig", &signature),
- TMH_PARSE_member_denomination_public_key ("denom_pub", &denomination_pub),
- TMH_PARSE_MEMBER_END
- };
-
- res = TMH_PARSE_post_json (connection,
- connection_cls,
- upload_data,
- upload_data_size,
- &root);
- if (GNUNET_SYSERR == res)
- return MHD_NO;
- if ( (GNUNET_NO == res) || (NULL == root) )
- return MHD_YES;
- res = TMH_PARSE_json_data (connection,
- root,
- spec);
- json_decref (root);
- if (GNUNET_OK != res)
- return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES;
- ks = TMH_KS_acquire ();
- dki = TMH_KS_denomination_key_lookup (ks,
- &denomination_pub,
- TMH_KS_DKU_WITHDRAW);
- if (NULL == dki)
- {
- TMH_PARSE_release_data (spec);
- return TMH_RESPONSE_reply_arg_unknown (connection,
- "denom_pub");
- }
- TALER_amount_ntoh (&amount,
- &dki->issue.properties.value);
- TALER_amount_ntoh (&fee_withdraw,
- &dki->issue.properties.fee_withdraw);
- GNUNET_assert (GNUNET_OK ==
- TALER_amount_add (&amount_with_fee,
- &amount,
- &fee_withdraw));
- TALER_amount_hton (&wsrd.amount_with_fee,
- &amount_with_fee);
- TALER_amount_hton (&wsrd.withdraw_fee,
- &fee_withdraw);
- TMH_KS_release (ks);
- /* verify signature! */
- wsrd.purpose.size = htonl (sizeof (struct TALER_WithdrawRequestPS));
- wsrd.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW);
-
- GNUNET_CRYPTO_rsa_public_key_hash (denomination_pub.rsa_public_key,
- &wsrd.h_denomination_pub);
- GNUNET_CRYPTO_hash (blinded_msg,
- blinded_msg_len,
- &wsrd.h_coin_envelope);
- if (GNUNET_OK !=
- GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW,
- &wsrd.purpose,
- &signature.eddsa_signature,
- &wsrd.reserve_pub.eddsa_pub))
- {
- TALER_LOG_WARNING ("Client supplied invalid signature for /withdraw/sign request\n");
- TMH_PARSE_release_data (spec);
- return TMH_RESPONSE_reply_signature_invalid (connection,
- "reserve_sig");
- }
- res = TMH_DB_execute_withdraw_sign (connection,
- &wsrd.reserve_pub,
- &denomination_pub,
- blinded_msg,
- blinded_msg_len,
- &signature);
- TMH_PARSE_release_data (spec);
- return res;
-}
-
-/* end of taler-mint-httpd_withdraw.c */
diff --git a/src/backend/taler-mint-httpd_withdraw.h b/src/backend/taler-mint-httpd_withdraw.h
deleted file mode 100644
index 668178b1..00000000
--- a/src/backend/taler-mint-httpd_withdraw.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2014 GNUnet e.V.
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU Affero General Public License as published by the Free Software
- 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 Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License along with
- TALER; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/>
-*/
-/**
- * @file taler-mint-httpd_withdraw.h
- * @brief Handle /withdraw/ requests
- * @author Florian Dold
- * @author Benedikt Mueller
- * @author Christian Grothoff
- */
-#ifndef TALER_MINT_HTTPD_WITHDRAW_H
-#define TALER_MINT_HTTPD_WITHDRAW_H
-
-#include <microhttpd.h>
-#include "taler-mint-httpd.h"
-
-/**
- * Handle a "/withdraw/status" request. Parses the
- * given "reserve_pub" argument (which should contain the
- * EdDSA public key of a reserve) and then respond with the
- * status of the reserve.
- *
- * @param rh context of the handler
- * @param connection the MHD connection to handle
- * @param[in,out] connection_cls the connection's closure (can be updated)
- * @param upload_data upload data
- * @param[in,out] upload_data_size number of bytes (left) in @a upload_data
- * @return MHD result code
- */
-int
-TMH_WITHDRAW_handler_withdraw_status (struct TMH_RequestHandler *rh,
- struct MHD_Connection *connection,
- void **connection_cls,
- const char *upload_data,
- size_t *upload_data_size);
-
-
-/**
- * Handle a "/withdraw/sign" request. Parses the "reserve_pub"
- * EdDSA key of the reserve and the requested "denom_pub" which
- * specifies the key/value of the coin to be withdrawn, and checks
- * that the signature "reserve_sig" makes this a valid withdrawl
- * request from the specified reserve. If so, the envelope
- * with the blinded coin "coin_ev" is passed down to execute the
- * withdrawl operation.
- *
- * @param rh context of the handler
- * @param connection the MHD connection to handle
- * @param[in,out] connection_cls the connection's closure (can be updated)
- * @param upload_data upload data
- * @param[in,out] upload_data_size number of bytes (left) in @a upload_data
- * @return MHD result code
- */
-int
-TMH_WITHDRAW_handler_withdraw_sign (struct TMH_RequestHandler *rh,
- struct MHD_Connection *connection,
- void **connection_cls,
- const char *upload_data,
- size_t *upload_data_size);
-
-#endif