aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2015-03-10 16:15:14 +0100
committerChristian Grothoff <christian@grothoff.org>2015-03-10 16:15:14 +0100
commitc2c8646a83c07662e1246f768c23e71c687ddcb0 (patch)
tree3ea5a96e43fda20b9ecb10485bbc05b0749eff33 /src
parent07f18f16601cc4757c0c2658ad501497b07cebee (diff)
combining /mint/melt and /mint/commit
Diffstat (limited to 'src')
-rw-r--r--src/include/taler_signatures.h65
-rw-r--r--src/mint/mint_db.c27
-rw-r--r--src/mint/mint_db.h27
-rw-r--r--src/mint/taler-mint-httpd.c6
-rw-r--r--src/mint/taler-mint-httpd_db.c209
-rw-r--r--src/mint/taler-mint-httpd_db.h49
-rw-r--r--src/mint/taler-mint-httpd_refresh.c381
-rw-r--r--src/mint/taler-mint-httpd_refresh.h24
-rw-r--r--src/mint/taler-mint-httpd_responses.c122
-rw-r--r--src/mint/taler-mint-httpd_responses.h45
10 files changed, 354 insertions, 601 deletions
diff --git a/src/include/taler_signatures.h b/src/include/taler_signatures.h
index bf39c0aba..9e3068a78 100644
--- a/src/include/taler_signatures.h
+++ b/src/include/taler_signatures.h
@@ -56,30 +56,25 @@
#define TALER_SIGNATURE_WITHDRAW 4
/**
- * Signature where the refresh session confirms
- * the list of melted coins and requested denominations.
+ * Signature using a coin key confirming the melting of
+ * a coin.
*/
-#define TALER_SIGNATURE_REFRESH_MELT 5
+#define TALER_SIGNATURE_REFRESH_MELT_COIN 5
/**
* Signature where the refresh session confirms
* the commits.
*/
-#define TALER_SIGNATURE_REFRESH_COMMIT 6
+#define TALER_SIGNATURE_REFRESH_MELT 6
/**
* Signature where the mint (current signing key)
- * confirms the list of blind session keys.
+ * confirms the no-reveal index for cut-and-choose and
+ * the validity of the melted coins.
*/
#define TALER_SIGNATURE_REFRESH_MELT_RESPONSE 7
/**
- * Signature where the mint (current signing key)
- * confirms the no-reveal index for cut-and-choose.
- */
-#define TALER_SIGNATURE_REFRESH_COMMIT_RESPONSE 8
-
-/**
* Signature where coins confirm that they want
* to be melted into a certain session.
*/
@@ -234,18 +229,22 @@ struct TALER_DepositConfirmation
/**
- * Format of the block signed by the Mint in response to
- * a successful "/refresh/melt" request. Hereby the mint
- * affirms that all of the coins were successfully melted.
+ * Message signed by a coin to indicate that the coin should
+ * be melted.
*/
-struct RefreshMeltResponseSignatureBody
+struct RefreshMeltSignatureBody
{
/**
- * Purpose is #TALER_SIGNATURE_REFRESH_MELT_RESPONSE.
+ * Purpose is #TALER_SIGNATURE_REFRESH_MELT_COIN.
*/
struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
/**
+ * Which melting operation should the coin become a part of.
+ */
+ struct GNUNET_HashCode melt_hash;
+
+ /**
* Signature of the client over the melt request (thereby
* indirectly including all of the information the client
* sent).
@@ -259,30 +258,6 @@ struct RefreshMeltResponseSignatureBody
struct GNUNET_CRYPTO_EddsaPublicKey session_key;
/**
- * Security parameter requested for the commitments.
- */
- uint32_t kappa GNUNET_PACKED;
-
-};
-
-
-/**
- * Message signed by a coin to indicate that the coin should
- * be melted.
- */
-struct RefreshMeltSignatureBody
-{
- /**
- * Purpose is #TALER_SIGNATURE_REFRESH_MELT.
- */
- struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
-
- /**
- * Which melting operation should the coin become a part of.
- */
- struct GNUNET_HashCode melt_hash;
-
- /**
* How much of the value of the coin should 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.
@@ -298,7 +273,7 @@ struct RefreshMeltSignatureBody
struct RefreshCommitSignatureBody
{
/**
- * Purpose is #TALER_SIGNATURE_REFRESH_COMMIT.
+ * Purpose is #TALER_SIGNATURE_REFRESH_MELT.
*/
struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
@@ -310,10 +285,12 @@ struct RefreshCommitSignatureBody
/**
- * Message signed by the mint, committing it to a particular
- * index to not be revealed during the refresh.
+ * Format of the block signed by the Mint in response to a successful
+ * "/refresh/melt" request. Hereby the mint affirms that all of the
+ * coins were successfully melted. This also commits the mint to a
+ * particular index to not be revealed during the refresh.
*/
-struct RefreshCommitResponseSignatureBody
+struct RefreshMeltResponseSignatureBody
{
/**
* Purpose is #TALER_SIGNATURE_REFRESH_MELT_RESPONSE.
diff --git a/src/mint/mint_db.c b/src/mint/mint_db.c
index 53d35b33d..848f9e045 100644
--- a/src/mint/mint_db.c
+++ b/src/mint/mint_db.c
@@ -1417,11 +1417,6 @@ TALER_MINT_DB_get_refresh_session (PGconn *db_conn,
return GNUNET_SYSERR;
}
- if (TALER_DB_field_isnull (result, 0, "session_commit_sig"))
- session->has_commit_sig = GNUNET_NO;
- else
- session->has_commit_sig = GNUNET_YES;
-
session->num_oldcoins = ntohs (session->num_oldcoins);
session->num_newcoins = ntohs (session->num_newcoins);
session->kappa = ntohs (session->kappa);
@@ -1472,28 +1467,6 @@ TALER_MINT_DB_create_refresh_session (PGconn *db_conn,
/**
- * Update new refresh session with the new state after the
- * /refresh/commit operation.
- *
- * @param db_conn database handle to use
- * @param refresh_session_pub public key to use to locate the session
- * @param noreveal_index index chosen for the client to not reveal
- * @param commit_client_sig signature of the client over its commitment
- * @return #GNUNET_YES on success,
- * #GNUNET_SYSERR on DB failure
- */
-int
-TALER_MINT_DB_update_refresh_session (PGconn *db_conn,
- const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub,
- uint16_t noreveal_index,
- const struct GNUNET_CRYPTO_EddsaSignature *commit_client_sig)
-{
- // FIXME: implement!
- return GNUNET_SYSERR;
-}
-
-
-/**
* Store the given /refresh/melt request in the database.
*
* @param db_conn database connection
diff --git a/src/mint/mint_db.h b/src/mint/mint_db.h
index 403e1f394..9818172af 100644
--- a/src/mint/mint_db.h
+++ b/src/mint/mint_db.h
@@ -474,17 +474,10 @@ struct RefreshSession
/**
* Index (smaller @e kappa) which the mint has chosen to not
- * have revealed during cut and choose. Only valid if
- * @e has_commit_sig is set to #GNUNET_YES.
+ * have revealed during cut and choose.
*/
uint16_t noreveal_index;
- /**
- * #GNUNET_YES if we have accepted the /refresh/commit and
- * thus the @e commit_sig is valid.
- */
- int has_commit_sig;
-
};
@@ -520,24 +513,6 @@ TALER_MINT_DB_create_refresh_session (PGconn *db_conn,
/**
- * Update new refresh session with the new state after the
- * /refresh/commit operation.
- *
- * @param db_conn database handle to use
- * @param refresh_session_pub public key to use to locate the session
- * @param noreveal_index index chosen for the client to not reveal
- * @param commit_client_sig signature of the client over its commitment
- * @return #GNUNET_YES on success,
- * #GNUNET_SYSERR on DB failure
- */
-int
-TALER_MINT_DB_update_refresh_session (PGconn *db_conn,
- const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub,
- uint16_t noreveal_index,
- const struct GNUNET_CRYPTO_EddsaSignature *commit_client_sig);
-
-
-/**
* Specification for coin in a /refresh/melt operation.
*/
struct RefreshMelt
diff --git a/src/mint/taler-mint-httpd.c b/src/mint/taler-mint-httpd.c
index 281f58f1b..3b1512ff1 100644
--- a/src/mint/taler-mint-httpd.c
+++ b/src/mint/taler-mint-httpd.c
@@ -152,12 +152,6 @@ handle_mhd_request (void *cls,
{ "/refresh/melt", NULL, "text/plain",
"Only POST is allowed", 0,
&TALER_MINT_handler_send_json_pack_error, MHD_HTTP_METHOD_NOT_ALLOWED },
- { "/refresh/commit", MHD_HTTP_METHOD_POST, "application/json",
- NULL, 0,
- &TALER_MINT_handler_refresh_commit, MHD_HTTP_OK },
- { "/refresh/commit", NULL, "text/plain",
- "Only POST is allowed", 0,
- &TALER_MINT_handler_send_json_pack_error, MHD_HTTP_METHOD_NOT_ALLOWED },
{ "/refresh/reveal", MHD_HTTP_METHOD_POST, "application/json",
NULL, 0,
&TALER_MINT_handler_refresh_melt, MHD_HTTP_OK },
diff --git a/src/mint/taler-mint-httpd_db.c b/src/mint/taler-mint-httpd_db.c
index d9a172a40..4423433b8 100644
--- a/src/mint/taler-mint-httpd_db.c
+++ b/src/mint/taler-mint-httpd_db.c
@@ -151,7 +151,7 @@ TALER_MINT_db_execute_deposit (struct MHD_Connection *connection,
if (0 < TALER_amount_cmp (spent, value))
{
TALER_MINT_DB_rollback (db_conn);
- ret = TALER_MINT_reply_insufficient_funds (connection,
+ ret = TALER_MINT_reply_deposit_insufficient_funds (connection,
tl);
TALER_MINT_DB_free_coin_transaction_list (tl);
return ret;
@@ -435,8 +435,10 @@ refresh_accept_melts (struct MHD_Connection *connection,
{
struct TALER_MINT_DenomKeyIssue *dki;
struct TALER_MINT_DB_TransactionList *tl;
- struct TALER_Amount coin_gain;
+ struct TALER_Amount coin_value;
+ struct TALER_Amount coin_residual;
struct RefreshMelt melt;
+ int res;
dki = &TALER_MINT_get_denom_key (key_state,
coin_public_info->denom_pub)->issue;
@@ -450,25 +452,30 @@ refresh_accept_melts (struct MHD_Connection *connection,
"denom not found"))
? GNUNET_NO : GNUNET_SYSERR;
- coin_gain = TALER_amount_ntoh (dki->value);
+ coin_value = TALER_amount_ntoh (dki->value);
tl = TALER_MINT_DB_get_coin_transactions (db_conn,
&coin_public_info->coin_pub);
/* FIXME: #3636: compute how much value is left with this coin and
- compare to `expected_value`! (subtract from "coin_gain") */
- TALER_MINT_DB_free_coin_transaction_list (tl);
-
+ compare to `expected_value`! (subtract from "coin_value") */
+ coin_residual = coin_value;
/* Refuse to refresh when the coin does not have enough money left to
* pay the refreshing fees of the coin. */
- if (TALER_amount_cmp (coin_gain,
+ if (TALER_amount_cmp (coin_residual,
coin_details->melt_amount) < 0)
- return (MHD_YES ==
- TALER_MINT_reply_json_pack (connection,
- MHD_HTTP_NOT_FOUND,
- "{s:s}",
- "error", "depleted")) ? GNUNET_NO : GNUNET_SYSERR;
-
-
+ {
+ res = (MHD_YES ==
+ TALER_MINT_reply_refresh_melt_insufficient_funds (connection,
+ &coin_public_info->coin_pub,
+ coin_value,
+ tl,
+ coin_details->melt_amount,
+ coin_residual))
+ ? GNUNET_NO : GNUNET_SYSERR;
+ TALER_MINT_DB_free_coin_transaction_list (tl);
+ return res;
+ }
+ TALER_MINT_DB_free_coin_transaction_list (tl);
melt.coin = *coin_public_info;
melt.coin_sig = coin_details->melt_sig;
@@ -494,6 +501,8 @@ refresh_accept_melts (struct MHD_Connection *connection,
* required value left and if so, store that they have been
* melted and confirm the melting operation to the client.
*
+ * FIXME: some arguments are redundant here...
+ *
* @param connection the MHD connection to handle
* @param melt_hash hash code of the session the coins are melted into
* @param refresh_session_pub public key of the refresh session
@@ -504,6 +513,15 @@ refresh_accept_melts (struct MHD_Connection *connection,
* @param coin_count number of entries in @a coin_public_infos and @a coin_melt_details
* @param coin_public_infos information about the coins to melt
* @param coin_melt_details signatures and (residual) value of the respective coin should be melted
+ * @param commit_client_sig signature of the client over this commitment
+ * @param kappa size of x-dimension of @commit_coin and @commit_link arrays
+ * @param num_oldcoins size of y-dimension of @commit_link array
+ * @param num_newcoins size of y-dimension of @commit_coin array
+ * @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
@@ -515,13 +533,20 @@ TALER_MINT_db_execute_refresh_melt (struct MHD_Connection *connection,
struct GNUNET_CRYPTO_rsa_PublicKey *const*denom_pubs,
unsigned int coin_count,
const struct TALER_CoinPublicInfo *coin_public_infos,
- const struct MeltDetails *coin_melt_details)
+ const struct MeltDetails *coin_melt_details,
+ const struct GNUNET_CRYPTO_EddsaSignature *commit_client_sig,
+ unsigned int kappa,
+ unsigned int num_oldcoins,
+ unsigned int num_newcoins,
+ struct RefreshCommitCoin *const* commit_coin,
+ struct RefreshCommitLink *const* commit_link)
{
struct MintKeyState *key_state;
struct RefreshSession session;
PGconn *db_conn;
int res;
unsigned int i;
+ unsigned int j;
if (NULL == (db_conn = TALER_MINT_DB_get_connection (GNUNET_NO)))
{
@@ -540,10 +565,10 @@ TALER_MINT_db_execute_refresh_melt (struct MHD_Connection *connection,
if (GNUNET_YES == res)
{
TALER_MINT_DB_rollback (db_conn);
- return TALER_MINT_reply_refresh_melt_success (connection,
- &session.melt_sig,
- refresh_session_pub,
- session.kappa);
+ res = TALER_MINT_reply_refresh_melt_success (connection,
+ &session.session_hash,
+ session.noreveal_index);
+ return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES;
}
if (GNUNET_SYSERR == res)
{
@@ -586,116 +611,6 @@ TALER_MINT_db_execute_refresh_melt (struct MHD_Connection *connection,
}
}
- /* store 'global' session data */
- session.melt_sig = *client_signature;
- session.session_hash = *melt_hash;
- session.num_oldcoins = coin_count;
- session.num_newcoins = num_new_denoms;
- session.kappa = KAPPA;
- session.noreveal_index = UINT16_MAX;
- session.has_commit_sig = GNUNET_NO;
- if (GNUNET_OK !=
- (res = TALER_MINT_DB_create_refresh_session (db_conn,
- refresh_session_pub,
- &session)))
- {
- TALER_MINT_DB_rollback (db_conn);
- return TALER_MINT_reply_internal_db_error (connection);
- }
-
- if (GNUNET_OK !=
- TALER_MINT_DB_commit (db_conn))
- {
- LOG_WARNING ("/refresh/melt transaction commit failed\n");
- return TALER_MINT_reply_commit_error (connection);
- }
- return TALER_MINT_reply_refresh_melt_success (connection,
- client_signature,
- refresh_session_pub,
- session.kappa);
-}
-
-
-/**
- * Execute a "/refresh/commit". The client is committing to @a kappa
- * sets of transfer keys, and linkage information for a refresh
- * operation. Confirm that the commit matches the melts of an
- * existing @a refresh_session_pub, store the refresh session commit
- * data and then return the client a challenge specifying which of the
- * @a kappa sets of private transfer keys should not be revealed.
- *
- * @param connection the MHD connection to handle
- * @param refresh_session public key of the session
- * @param commit_client_sig signature of the client over this commitment
- * @param kappa size of x-dimension of @commit_coin and @commit_link arrays
- * @param num_oldcoins size of y-dimension of @commit_link array
- * @param num_newcoins size of y-dimension of @commit_coin array
- * @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
-TALER_MINT_db_execute_refresh_commit (struct MHD_Connection *connection,
- const struct GNUNET_CRYPTO_EddsaPublicKey *refresh_session_pub,
- const struct GNUNET_CRYPTO_EddsaSignature *commit_client_sig,
- unsigned int kappa,
- unsigned int num_oldcoins,
- unsigned int num_newcoins,
- struct RefreshCommitCoin *const*commit_coin,
- struct RefreshCommitLink *const*commit_link)
-
-{
- PGconn *db_conn;
- struct RefreshSession refresh_session;
- unsigned int i;
- unsigned int j;
- int res;
-
- if (NULL == (db_conn = TALER_MINT_DB_get_connection (GNUNET_NO)))
- {
- GNUNET_break (0);
- return TALER_MINT_reply_internal_db_error (connection);
- }
-
- if (GNUNET_OK !=
- TALER_MINT_DB_transaction (db_conn))
- {
- GNUNET_break (0);
- return TALER_MINT_reply_internal_db_error (connection);
- }
- res = TALER_MINT_DB_get_refresh_session (db_conn,
- refresh_session_pub,
- &refresh_session);
- if (GNUNET_SYSERR == res)
- {
- TALER_MINT_DB_rollback (db_conn);
- return TALER_MINT_reply_internal_db_error (connection);
- }
- if (GNUNET_NO == res)
- {
- TALER_MINT_DB_rollback (db_conn);
- return TALER_MINT_reply_arg_invalid (connection,
- "session_pub");
- }
- if ( (refresh_session.kappa != kappa) ||
- (refresh_session.num_newcoins != num_newcoins) ||
- (refresh_session.num_oldcoins != num_oldcoins) )
- {
- TALER_MINT_DB_rollback (db_conn);
- return TALER_MINT_reply_arg_invalid (connection,
- "dimensions");
- }
- if (GNUNET_YES == refresh_session.has_commit_sig)
- {
- TALER_MINT_DB_rollback (db_conn);
- res = TALER_MINT_reply_refresh_commit_success (connection,
- &refresh_session.session_hash,
- refresh_session.noreveal_index);
- return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES;
- }
for (i = 0; i < kappa; i++)
{
for (j = 0; j < num_newcoins; j++)
@@ -729,31 +644,36 @@ TALER_MINT_db_execute_refresh_commit (struct MHD_Connection *connection,
}
}
- refresh_session.noreveal_index
- = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_STRONG,
- refresh_session.kappa);
+ /* store 'global' session data */
+ session.melt_sig = *client_signature;
+ session.session_hash = *melt_hash;
+ session.num_oldcoins = coin_count;
+ session.num_newcoins = num_new_denoms;
+ session.kappa = KAPPA; // FIXME...
+ session.noreveal_index
+ = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_STRONG,
+ session.kappa);
if (GNUNET_OK !=
- (res = TALER_MINT_DB_update_refresh_session (db_conn,
+ (res = TALER_MINT_DB_create_refresh_session (db_conn,
refresh_session_pub,
- refresh_session.noreveal_index,
- commit_client_sig)))
+ &session)))
{
TALER_MINT_DB_rollback (db_conn);
return TALER_MINT_reply_internal_db_error (connection);
}
+
if (GNUNET_OK !=
TALER_MINT_DB_commit (db_conn))
{
- LOG_WARNING ("/refresh/commit transaction commit failed\n");
+ LOG_WARNING ("/refresh/melt transaction commit failed\n");
return TALER_MINT_reply_commit_error (connection);
}
-
- return TALER_MINT_reply_refresh_commit_success (connection,
- &refresh_session.session_hash,
- refresh_session.noreveal_index);
+ return TALER_MINT_reply_refresh_melt_success (connection,
+ &session.session_hash,
+ session.noreveal_index);
}
@@ -1061,15 +981,6 @@ TALER_MINT_db_execute_refresh_reveal (struct MHD_Connection *connection,
return TALER_MINT_reply_internal_db_error (connection);
}
- if ( (refresh_session.noreveal_index >= refresh_session.kappa) ||
- (GNUNET_NO == refresh_session.has_commit_sig) )
- {
- GNUNET_break (UINT16_MAX == refresh_session.noreveal_index);
- GNUNET_break (GNUNET_NO == refresh_session.has_commit_sig);
- return TALER_MINT_reply_external_error (connection,
- "/refresh/commit must be executed first");
- }
-
melts = GNUNET_malloc (refresh_session.num_oldcoins *
sizeof (struct RefreshMelt));
for (j=0;j<refresh_session.num_oldcoins;j++)
diff --git a/src/mint/taler-mint-httpd_db.h b/src/mint/taler-mint-httpd_db.h
index dcd5e6fa0..2a26de9b4 100644
--- a/src/mint/taler-mint-httpd_db.h
+++ b/src/mint/taler-mint-httpd_db.h
@@ -107,6 +107,8 @@ struct MeltDetails
* required value left and if so, store that they have been
* melted and confirm the melting operation to the client.
*
+ * FIXME: some arguments are redundant here...
+ *
* @param connection the MHD connection to handle
* @param melt_hash hash code of the session the coins are melted into
* @param refresh_session_pub public key of the refresh session
@@ -117,30 +119,6 @@ struct MeltDetails
* @param coin_count number of entries in @a coin_public_infos and @ a coin_melt_details
* @param coin_public_infos information about the coins to melt
* @param coin_melt_details signatures and (residual) value of the respective coin should be melted
- * @return MHD result code
- */
-int
-TALER_MINT_db_execute_refresh_melt (struct MHD_Connection *connection,
- const struct GNUNET_HashCode *melt_hash,
- const struct GNUNET_CRYPTO_EddsaPublicKey *refresh_session_pub,
- const struct GNUNET_CRYPTO_EddsaSignature *client_signature,
- unsigned int num_new_denoms,
- struct GNUNET_CRYPTO_rsa_PublicKey *const*denom_pubs,
- unsigned int coin_count,
- const struct TALER_CoinPublicInfo *coin_public_infos,
- const struct MeltDetails *coin_melt_details);
-
-
-/**
- * Execute a "/refresh/commit". The client is committing to @a kappa
- * sets of transfer keys, and linkage information for a refresh
- * operation. Confirm that the commit matches the melts of an
- * existing @a refresh_session_pub, store the refresh session commit
- * data and then return the client a challenge specifying which of the
- * @a kappa sets of private transfer keys should not be revealed.
- *
- * @param connection the MHD connection to handle
- * @param refresh_session public key of the session
* @param commit_client_sig signature of the client over this commitment
* @param kappa size of x-dimension of @commit_coin and @commit_link arrays
* @param num_oldcoins size of y-dimension of @commit_coin array
@@ -154,14 +132,21 @@ TALER_MINT_db_execute_refresh_melt (struct MHD_Connection *connection,
*/
// FIXME: see #3635.
int
-TALER_MINT_db_execute_refresh_commit (struct MHD_Connection *connection,
- const struct GNUNET_CRYPTO_EddsaPublicKey *refresh_session_pub,
- const struct GNUNET_CRYPTO_EddsaSignature *commit_client_sig,
- unsigned int kappa,
- unsigned int num_oldcoins,
- unsigned int num_newcoins,
- struct RefreshCommitCoin *const* commit_coin,
- struct RefreshCommitLink *const* commit_link);
+TALER_MINT_db_execute_refresh_melt (struct MHD_Connection *connection,
+ const struct GNUNET_HashCode *melt_hash,
+ const struct GNUNET_CRYPTO_EddsaPublicKey *refresh_session_pub,
+ const struct GNUNET_CRYPTO_EddsaSignature *client_signature,
+ unsigned int num_new_denoms,
+ struct GNUNET_CRYPTO_rsa_PublicKey *const*denom_pubs,
+ unsigned int coin_count,
+ const struct TALER_CoinPublicInfo *coin_public_infos,
+ const struct MeltDetails *coin_melt_details,
+ const struct GNUNET_CRYPTO_EddsaSignature *commit_client_sig,
+ unsigned int kappa,
+ unsigned int num_oldcoins,
+ unsigned int num_newcoins,
+ struct RefreshCommitCoin *const* commit_coin,
+ struct RefreshCommitLink *const* commit_link);
/**
diff --git a/src/mint/taler-mint-httpd_refresh.c b/src/mint/taler-mint-httpd_refresh.c
index cfb3ba0f5..d7b670749 100644
--- a/src/mint/taler-mint-httpd_refresh.c
+++ b/src/mint/taler-mint-httpd_refresh.c
@@ -151,6 +151,15 @@ request_json_check_signature (struct MHD_Connection *connection,
* @param coin_public_infos array with @a coin_count entries about the coins
* @param coin_melt_details array with @a coin_count entries with melting details
* @param melt_sig_json signature affirming the overall melt operation
+ * @param commit_client_sig signature of the client over this commitment
+ * @param kappa size of x-dimension of @commit_coin and @commit_link arrays
+ * @param num_oldcoins size of y-dimension of @commit_coin array
+ * @param num_newcoins size of y-dimension of @commit_link array
+ * @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
@@ -161,7 +170,14 @@ handle_refresh_melt_binary (struct MHD_Connection *connection,
unsigned int coin_count,
struct TALER_CoinPublicInfo *coin_public_infos,
const struct MeltDetails *coin_melt_details,
- const json_t *melt_sig_json)
+ const json_t *melt_sig_json,
+ const struct GNUNET_CRYPTO_EddsaSignature *commit_client_sig,
+ unsigned int kappa,
+ unsigned int num_oldcoins,
+ unsigned int num_newcoins,
+ struct RefreshCommitCoin *const* commit_coin,
+ struct RefreshCommitLink *const* commit_link)
+
{
int res;
unsigned int i;
@@ -256,7 +272,13 @@ handle_refresh_melt_binary (struct MHD_Connection *connection,
denom_pubs,
coin_count,
coin_public_infos,
- coin_melt_details);
+ coin_melt_details,
+ NULL /* FIXME: 3635! */,
+ kappa,
+ num_oldcoins,
+ num_newcoins,
+ commit_coin,
+ commit_link);
}
@@ -364,6 +386,58 @@ get_and_verify_coin_public_info (struct MHD_Connection *connection,
/**
+ * 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 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_coin array to release
+ * @param kappa size of 1st dimension
+ * @param num_old_coins size of 2nd dimension
+ */
+static void
+free_commit_links (struct RefreshCommitLink **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
@@ -375,6 +449,14 @@ get_and_verify_coin_public_info (struct MHD_Connection *connection,
* @param new_denoms array of denomination keys
* @param melt_coins array of coins to melt
* @param melt_sig_json signature affirming the melt operation
+ * @param commit_signature signature over the commit
+ * @param kappa security parameter for cut and choose
+ * @param num_oldcoins number of coins that are being melted
+ * @param transfer_pubs @a kappa-dimensional array of @a num_oldcoins transfer keys
+ * @param secret_encs @a kappa-dimensional array of @a num_oldcoins secrets
+ * @param num_newcoins number of coins that the refresh will generate
+ * @param coin_envs @a kappa-dimensional array of @a num_newcoins envelopes to sign
+ * @param link_encs @a kappa-dimensional array of @a num_newcoins encrypted links
* @return MHD result code
*/
static int
@@ -382,7 +464,16 @@ handle_refresh_melt_json (struct MHD_Connection *connection,
const struct GNUNET_CRYPTO_EddsaPublicKey *refresh_session_pub,
const json_t *new_denoms,
const json_t *melt_coins,
- const json_t *melt_sig_json)
+ const json_t *melt_sig_json,
+ const json_t *commit_signature,
+ unsigned int kappa,
+ 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;
@@ -392,6 +483,11 @@ handle_refresh_melt_json (struct MHD_Connection *connection,
struct TALER_CoinPublicInfo *coin_public_infos;
struct MeltDetails *coin_melt_details;
unsigned int coin_count;
+ struct GNUNET_HashCode commit_hash;
+ struct GNUNET_HashContext *hash_context;
+ struct RefreshCommitSignatureBody body;
+ struct RefreshCommitCoin *commit_coin[kappa];
+ struct RefreshCommitLink *commit_link[kappa];
num_new_denoms = json_array_size (new_denoms);
denom_pubs = GNUNET_malloc (num_new_denoms *
@@ -441,180 +537,6 @@ handle_refresh_melt_json (struct MHD_Connection *connection,
}
}
- res = handle_refresh_melt_binary (connection,
- refresh_session_pub,
- num_new_denoms,
- denom_pubs,
- coin_count,
- coin_public_infos,
- coin_melt_details,
- melt_sig_json);
- for (j=0;j<coin_count;j++)
- {
- GNUNET_CRYPTO_rsa_public_key_free (coin_public_infos[j].denom_pub);
- GNUNET_CRYPTO_rsa_signature_free (coin_public_infos[j].denom_sig);
- }
- GNUNET_free (coin_public_infos);
- for (j=0;j<num_new_denoms;j++)
- {
- GNUNET_CRYPTO_rsa_public_key_free (denom_pubs[j]);
- }
- 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_referesh_melt_json()
- * to validate the melted coins, the signature and execute the melt
- * using TALER_MINT_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
-TALER_MINT_handler_refresh_melt (struct 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 *melt_sig_json;
- struct GNUNET_CRYPTO_EddsaPublicKey refresh_session_pub;
- int res;
- struct GNUNET_MINT_ParseFieldSpec spec[] = {
- TALER_MINT_PARSE_FIXED ("session_pub", &refresh_session_pub),
- TALER_MINT_PARSE_ARRAY ("new_denoms", &new_denoms),
- TALER_MINT_PARSE_ARRAY ("melt_coins", &melt_coins),
- TALER_MINT_PARSE_ARRAY ("melt_signature", &melt_sig_json),
- TALER_MINT_PARSE_END
- };
-
- res = TALER_MINT_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 = TALER_MINT_parse_json_data (connection,
- root,
- spec);
- json_decref (root);
- if (GNUNET_OK != res)
- return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES;
- res = handle_refresh_melt_json (connection,
- &refresh_session_pub,
- new_denoms,
- melt_coins,
- melt_sig_json);
- TALER_MINT_release_parsed_data (spec);
- return res;
-}
-
-
-/**
- * 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 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_coin array to release
- * @param kappa size of 1st dimension
- * @param num_old_coins size of 2nd dimension
- */
-static void
-free_commit_links (struct RefreshCommitLink **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/commit" request. We have the individual JSON
- * arrays, now we need to parse their contents and verify the
- * commit signature. Then we can commit the data to the database.
- *
- * @param connection the MHD connection to handle
- * @param refresh_session_pub public key of the refresh session
- * @param commit_signature signature over the commit
- * @param kappa security parameter for cut and choose
- * @param num_oldcoins number of coins that are being melted
- * @param transfer_pubs @a kappa-dimensional array of @a num_oldcoins transfer keys
- * @param secret_encs @a kappa-dimensional array of @a num_oldcoins secrets
- * @param num_newcoins number of coins that the refresh will generate
- * @param coin_envs @a kappa-dimensional array of @a num_newcoins envelopes to sign
- * @param link_encs @a kappa-dimensional array of @a num_newcoins encrypted links
- * @return MHD result code
- */
-static int
-handle_refresh_commit_json (struct MHD_Connection *connection,
- const struct GNUNET_CRYPTO_EddsaPublicKey *refresh_session_pub,
- const json_t *commit_signature,
- unsigned int kappa,
- 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)
-{
- struct GNUNET_HashCode commit_hash;
- struct GNUNET_HashContext *hash_context;
- struct RefreshCommitSignatureBody body;
- struct RefreshCommitCoin *commit_coin[kappa];
- struct RefreshCommitLink *commit_link[kappa];
- unsigned int i;
- unsigned int j;
- int res;
/* parse JSON arrays into 2d binary arrays and hash everything
together for the signature check */
@@ -721,7 +643,7 @@ handle_refresh_commit_json (struct MHD_Connection *connection,
GNUNET_CRYPTO_hash_context_finish (hash_context, &commit_hash);
/* verify commit signature */
- body.purpose.purpose = htonl (TALER_SIGNATURE_REFRESH_COMMIT);
+ body.purpose.purpose = htonl (TALER_SIGNATURE_REFRESH_MELT);
body.purpose.size = htonl (sizeof (struct RefreshCommitSignatureBody));
body.commit_hash = commit_hash;
@@ -738,29 +660,43 @@ handle_refresh_commit_json (struct MHD_Connection *connection,
/* execute commit */
/* FIXME: we must also store the signature! (#3635) */
- res = TALER_MINT_db_execute_refresh_commit (connection,
- refresh_session_pub,
- NULL /* FIXME: 3635! */,
- kappa,
- num_oldcoins,
- num_newcoins,
- commit_coin,
- commit_link);
+ res = handle_refresh_melt_binary (connection,
+ refresh_session_pub,
+ num_new_denoms,
+ denom_pubs,
+ coin_count,
+ coin_public_infos,
+ coin_melt_details,
+ melt_sig_json,
+ NULL /* FIXME: 3635! */,
+ kappa,
+ num_oldcoins,
+ num_newcoins,
+ commit_coin,
+ commit_link);
free_commit_coins (commit_coin, kappa, num_newcoins);
free_commit_links (commit_link, kappa, num_oldcoins);
-
+ for (j=0;j<coin_count;j++)
+ {
+ GNUNET_CRYPTO_rsa_public_key_free (coin_public_infos[j].denom_pub);
+ GNUNET_CRYPTO_rsa_signature_free (coin_public_infos[j].denom_sig);
+ }
+ GNUNET_free (coin_public_infos);
+ for (j=0;j<num_new_denoms;j++)
+ {
+ GNUNET_CRYPTO_rsa_public_key_free (denom_pubs[j]);
+ }
+ GNUNET_free (coin_melt_details);
+ GNUNET_free (denom_pubs);
return res;
}
/**
- * Handle a "/refresh/commit" request. Parses the top-level JSON to
- * determine the dimensions of the problem and then handles handing
- * off to #handle_refresh_commit_json() to parse the details of the
- * JSON arguments. Once the signature has been verified, the
- * commit data is written to the database via
- * #TALER_MINT_db_execute_refresh_commit() and the reveal parameter
- * is then returned to the client.
+ * Handle a "/refresh/melt" request. Parses the request into the JSON
+ * components and then hands things of to #handle_referesh_melt_json()
+ * to validate the melted coins, the signature and execute the melt
+ * using TALER_MINT_db_execute_refresh_melt().
*
* @param rh context of the handler
* @param connection the MHD connection to handle
@@ -768,28 +704,34 @@ handle_refresh_commit_json (struct MHD_Connection *connection,
* @param upload_data upload data
* @param[IN|OUT] upload_data_size number of bytes (left) in @a upload_data
* @return MHD result code
- */
+ */
int
-TALER_MINT_handler_refresh_commit (struct RequestHandler *rh,
- struct MHD_Connection *connection,
- void **connection_cls,
- const char *upload_data,
- size_t *upload_data_size)
+TALER_MINT_handler_refresh_melt (struct RequestHandler *rh,
+ struct MHD_Connection *connection,
+ void **connection_cls,
+ const char *upload_data,
+ size_t *upload_data_size)
{
- struct GNUNET_CRYPTO_EddsaPublicKey refresh_session_pub;
- int res;
- unsigned int kappa;
- unsigned int num_oldcoins;
- unsigned int num_newcoins;
json_t *root;
+ json_t *new_denoms;
+ json_t *melt_coins;
+ json_t *melt_sig_json;
json_t *coin_evs;
json_t *link_encs;
json_t *transfer_pubs;
json_t *secret_encs;
- json_t *coin_detail;
json_t *commit_sig_json;
+ unsigned int kappa;
+ unsigned int num_oldcoins;
+ unsigned int num_newcoins;
+ json_t *coin_detail;
+ struct GNUNET_CRYPTO_EddsaPublicKey refresh_session_pub;
+ int res;
struct GNUNET_MINT_ParseFieldSpec spec[] = {
TALER_MINT_PARSE_FIXED ("session_pub", &refresh_session_pub),
+ TALER_MINT_PARSE_ARRAY ("new_denoms", &new_denoms),
+ TALER_MINT_PARSE_ARRAY ("melt_coins", &melt_coins),
+ TALER_MINT_PARSE_ARRAY ("melt_signature", &melt_sig_json),
TALER_MINT_PARSE_ARRAY ("coin_evs", &coin_evs),
TALER_MINT_PARSE_ARRAY ("link_encs", &link_encs),
TALER_MINT_PARSE_ARRAY ("transfer_pubs", &transfer_pubs),
@@ -852,16 +794,21 @@ TALER_MINT_handler_refresh_commit (struct RequestHandler *rh,
return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES;
}
num_oldcoins = json_array_size (coin_detail);
- res = handle_refresh_commit_json (connection,
- &refresh_session_pub,
- commit_sig_json,
- kappa,
- num_oldcoins,
- transfer_pubs,
- secret_encs,
- num_newcoins,
- coin_evs,
- link_encs);
+
+ res = handle_refresh_melt_json (connection,
+ &refresh_session_pub,
+ new_denoms,
+ melt_coins,
+ melt_sig_json,
+ commit_sig_json,
+ kappa,
+ num_oldcoins,
+ transfer_pubs,
+ secret_encs,
+ num_newcoins,
+ coin_evs,
+ link_encs);
+
TALER_MINT_release_parsed_data (spec);
return res;
}
@@ -931,7 +878,7 @@ handle_refresh_reveal_json (struct MHD_Connection *connection,
/**
* 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
+ * returned from "/refresh/melt". This function parses the revealed
* keys and secrets and ultimately passes everything to
* #TALER_MINT_db_execute_refresh_reveal() which will verify that the
* revealed information is valid then returns the signed refreshed
diff --git a/src/mint/taler-mint-httpd_refresh.h b/src/mint/taler-mint-httpd_refresh.h
index 80bad6c5c..c1f69e1de 100644
--- a/src/mint/taler-mint-httpd_refresh.h
+++ b/src/mint/taler-mint-httpd_refresh.h
@@ -50,30 +50,6 @@ TALER_MINT_handler_refresh_melt (struct RequestHandler *rh,
/**
- * Handle a "/refresh/commit" request. Parses the top-level JSON to
- * determine the dimensions of the problem and then handles handing
- * off to #handle_refresh_commit_json() to parse the details of the
- * JSON arguments. Once the signature has been verified, the
- * commit data is written to the database via
- * #TALER_MINT_db_execute_refresh_commit() and the cut-and-choose value
- * is then returned to the client.
- *
- * @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
-TALER_MINT_handler_refresh_commit (struct 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
diff --git a/src/mint/taler-mint-httpd_responses.c b/src/mint/taler-mint-httpd_responses.c
index 21e208115..83c81e800 100644
--- a/src/mint/taler-mint-httpd_responses.c
+++ b/src/mint/taler-mint-httpd_responses.c
@@ -315,27 +315,20 @@ TALER_MINT_reply_deposit_success (struct MHD_Connection *connection,
return ret;
}
-
/**
- * Send proof that a /deposit, /refresh/melt or /lock 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.
+ * Compile the transaction history of a coin into a JSON object.
*
- * @param connection connection to the client
- * @param tl transaction list to use to build reply
- * @return MHD result code
+ * @param tl transaction history to JSON-ify
+ * @return json representation of the @a rh
*/
-int
-TALER_MINT_reply_insufficient_funds (struct MHD_Connection *connection,
- const struct TALER_MINT_DB_TransactionList *tl)
+static json_t *
+compile_transaction_history (const struct TALER_MINT_DB_TransactionList *tl)
{
- const struct TALER_MINT_DB_TransactionList *pos;
- int ret;
- json_t *history;
json_t *transaction;
const char *type;
struct TALER_Amount value;
+ json_t *history;
+ const struct TALER_MINT_DB_TransactionList *pos;
history = json_array ();
for (pos = tl; NULL != pos; pos = pos->next)
@@ -392,13 +385,31 @@ TALER_MINT_reply_insufficient_funds (struct MHD_Connection *connection,
"amount", TALER_JSON_from_amount (value),
"signature", transaction));
}
+ return history;
+}
- ret = TALER_MINT_reply_json_pack (connection,
- MHD_HTTP_FORBIDDEN,
- "{s:s, s:o}",
- "error", "insufficient funds",
- "history", history);
- return ret;
+
+/**
+ * Send proof that a /withdraw 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
+TALER_MINT_reply_deposit_insufficient_funds (struct MHD_Connection *connection,
+ const struct TALER_MINT_DB_TransactionList *tl)
+{
+ json_t *history;
+
+ history = compile_transaction_history (tl);
+ return TALER_MINT_reply_json_pack (connection,
+ MHD_HTTP_FORBIDDEN,
+ "{s:s, s:o}",
+ "error", "insufficient funds",
+ "history", history);
}
@@ -589,47 +600,46 @@ TALER_MINT_reply_withdraw_sign_success (struct MHD_Connection *connection,
/**
- * Send a response for "/refresh/melt". Essentially we sign
- * over the client's signature and public key, thereby
- * demonstrating that we accepted all of the client's coins.
+ * 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 signature the client's signature over the melt request
- * @param session_pub the refresh session public key.
- * @param kappa security parameter to use for cut and choose
+ * @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
-TALER_MINT_reply_refresh_melt_success (struct MHD_Connection *connection,
- const struct GNUNET_CRYPTO_EddsaSignature *signature,
- const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub,
- unsigned int kappa)
+TALER_MINT_reply_refresh_melt_insufficient_funds (struct MHD_Connection *connection,
+ const struct GNUNET_CRYPTO_EcdsaPublicKey *coin_pub,
+ struct TALER_Amount coin_value,
+ struct TALER_MINT_DB_TransactionList *tl,
+ struct TALER_Amount requested,
+ struct TALER_Amount residual)
{
- int ret;
- struct RefreshMeltResponseSignatureBody body;
- struct GNUNET_CRYPTO_EddsaSignature sig;
- json_t *sig_json;
+ json_t *history;
- body.purpose.size = htonl (sizeof (struct RefreshMeltResponseSignatureBody));
- body.purpose.purpose = htonl (TALER_SIGNATURE_REFRESH_MELT_RESPONSE);
- body.melt_client_signature = *signature;
- body.session_key = *session_pub;
- body.kappa = htonl (kappa);
- TALER_MINT_keys_sign (&body.purpose,
- &sig);
- sig_json = TALER_JSON_from_eddsa_sig (&body.purpose, &sig);
- ret = TALER_MINT_reply_json_pack (connection,
- MHD_HTTP_OK,
- "{s:o, s:i}",
- "signature", sig_json,
- "kappa", (int) kappa);
- json_decref (sig_json);
- return ret;
+ history = compile_transaction_history (tl);
+ return TALER_MINT_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 GNUNET_CRYPTO_EcdsaPublicKey)),
+ "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/commit" request.
+ * 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
@@ -637,17 +647,17 @@ TALER_MINT_reply_refresh_melt_success (struct MHD_Connection *connection,
* @return a MHD status code
*/
int
-TALER_MINT_reply_refresh_commit_success (struct MHD_Connection *connection,
- const struct GNUNET_HashCode *session_hash,
- uint16_t noreveal_index)
+TALER_MINT_reply_refresh_melt_success (struct MHD_Connection *connection,
+ const struct GNUNET_HashCode *session_hash,
+ uint16_t noreveal_index)
{
- struct RefreshCommitResponseSignatureBody body;
+ struct RefreshMeltResponseSignatureBody body;
struct GNUNET_CRYPTO_EddsaSignature sig;
json_t *sig_json;
int ret;
- body.purpose.size = htonl (sizeof (struct RefreshCommitResponseSignatureBody));
- body.purpose.purpose = htonl (TALER_SIGNATURE_REFRESH_COMMIT_RESPONSE);
+ body.purpose.size = htonl (sizeof (struct RefreshMeltResponseSignatureBody));
+ body.purpose.purpose = htonl (TALER_SIGNATURE_REFRESH_MELT_RESPONSE);
body.session_hash = *session_hash;
body.noreveal_index = htons (noreveal_index);
TALER_MINT_keys_sign (&body.purpose,
diff --git a/src/mint/taler-mint-httpd_responses.h b/src/mint/taler-mint-httpd_responses.h
index abfb4318c..7d0824c88 100644
--- a/src/mint/taler-mint-httpd_responses.h
+++ b/src/mint/taler-mint-httpd_responses.h
@@ -194,18 +194,17 @@ TALER_MINT_reply_deposit_success (struct MHD_Connection *connection,
/**
- * Send proof that a /deposit, /refresh/melt or /lock 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.
+ * 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
-TALER_MINT_reply_insufficient_funds (struct MHD_Connection *connection,
- const struct TALER_MINT_DB_TransactionList *tl);
+TALER_MINT_reply_deposit_insufficient_funds (struct MHD_Connection *connection,
+ const struct TALER_MINT_DB_TransactionList *tl);
/**
@@ -247,7 +246,7 @@ TALER_MINT_reply_withdraw_sign_success (struct MHD_Connection *connection,
/**
- * Send a response to a "/refresh/commit" request.
+ * Send a confirmation response to a "/refresh/melt" request.
*
* @param connection the connection to send the response to
* @param session_hash hash of the refresh session
@@ -255,27 +254,33 @@ TALER_MINT_reply_withdraw_sign_success (struct MHD_Connection *connection,
* @return a MHD status code
*/
int
-TALER_MINT_reply_refresh_commit_success (struct MHD_Connection *connection,
- const struct GNUNET_HashCode *session_hash,
- uint16_t noreveal_index);
+TALER_MINT_reply_refresh_melt_success (struct MHD_Connection *connection,
+ const struct GNUNET_HashCode *session_hash,
+ uint16_t noreveal_index);
/**
- * Send a response for "/refresh/melt". Essentially we sign
- * over the client's signature and public key, thereby
- * demonstrating that we accepted all of the client's coins.
+ * 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 signature the client's signature over the melt request
- * @param session_pub the refresh session public key.
- * @param kappa security parameter to use for cut and choose
+ * @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
-TALER_MINT_reply_refresh_melt_success (struct MHD_Connection *connection,
- const struct GNUNET_CRYPTO_EddsaSignature *signature,
- const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub,
- unsigned int kappa);
+TALER_MINT_reply_refresh_melt_insufficient_funds (struct MHD_Connection *connection,
+ const struct GNUNET_CRYPTO_EcdsaPublicKey *coin_pub,
+ struct TALER_Amount coin_value,
+ struct TALER_MINT_DB_TransactionList *tl,
+ struct TALER_Amount requested,
+ struct TALER_Amount residual);
/**