aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/include/taler_signatures.h39
-rw-r--r--src/mint/mint.h48
-rw-r--r--src/mint/mint_db.c237
-rw-r--r--src/mint/mint_db.h116
-rw-r--r--src/mint/taler-mint-httpd_db.c151
-rw-r--r--src/mint/taler-mint-httpd_db.h6
-rw-r--r--src/mint/taler-mint-httpd_refresh.c3
-rw-r--r--src/mint/taler-mint-httpd_responses.c26
-rw-r--r--src/mint/taler-mint-httpd_responses.h10
9 files changed, 367 insertions, 269 deletions
diff --git a/src/include/taler_signatures.h b/src/include/taler_signatures.h
index 84968582e..0518af3f0 100644
--- a/src/include/taler_signatures.h
+++ b/src/include/taler_signatures.h
@@ -234,6 +234,36 @@ 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.
+ */
+struct RefreshMeltResponseSignatureBody
+{
+ /**
+ * Purpose is #TALER_SIGNATURE_REFRESH_MELT_RESPONSE.
+ */
+ struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
+
+ /**
+ * Signature of the client over the melt request (thereby
+ * indirectly including all of the information the client
+ * sent).
+ */
+ struct GNUNET_CRYPTO_EddsaSignature melt_client_signature;
+
+ /**
+ * Public key of the refresh session for which
+ * @e melt_client_signature must be a valid signature.
+ */
+ struct GNUNET_CRYPTO_EddsaPublicKey session_key;
+};
+
+
+
+
+
+/**
* FIXME
*/
struct TALER_MINT_SignKeyIssue
@@ -296,15 +326,6 @@ struct RefreshCommitResponseSignatureBody
};
-/**
- * FIXME
- */
-struct RefreshMeltResponseSignatureBody
-{
- struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
- struct GNUNET_HashCode melt_response_hash;
-};
-
/**
* FIXME
diff --git a/src/mint/mint.h b/src/mint/mint.h
index 1e1221157..e2d559701 100644
--- a/src/mint/mint.h
+++ b/src/mint/mint.h
@@ -36,54 +36,6 @@
-/**
- * Global information for a refreshing session.
- */
-struct RefreshSession
-{
- /**
- * Signature over the commitments by the client.
- */
- struct GNUNET_CRYPTO_EddsaSignature commit_sig;
-
- /**
- * Public key of the refreshing session, used to sign
- * the client's commit message.
- */
- struct GNUNET_CRYPTO_EddsaPublicKey session_pub;
-
- /**
- * Number of coins we are melting.
- */
- uint16_t num_oldcoins;
-
- /**
- * Number of new coins we are creating.
- */
- uint16_t num_newcoins;
-
- /**
- * Number of parallel operations we perform for the cut and choose.
- * (must be greater or equal to three for security).
- */
- uint16_t kappa;
-
- /**
- * Index (smaller @e kappa) which the mint has chosen to not
- * have revealed during cut and choose.
- */
- uint16_t noreveal_index;
-
- /**
- * FIXME.
- */
- int has_commit_sig;
-
- /**
- * FIXME.
- */
- uint8_t reveal_ok;
-};
diff --git a/src/mint/mint_db.c b/src/mint/mint_db.c
index 5c52948e6..67cf4b352 100644
--- a/src/mint/mint_db.c
+++ b/src/mint/mint_db.c
@@ -582,76 +582,6 @@ TALER_MINT_DB_insert_refresh_order (PGconn *db_conn,
int
-TALER_MINT_DB_get_refresh_session (PGconn *db_conn,
- const struct GNUNET_CRYPTO_EddsaPublicKey *refresh_session_pub,
- struct RefreshSession *session)
-{
- int res;
- struct TALER_DB_QueryParam params[] = {
- TALER_DB_QUERY_PARAM_PTR(refresh_session_pub),
- TALER_DB_QUERY_PARAM_END
- };
-
- PGresult *result = TALER_DB_exec_prepared (db_conn, "get_refresh_session", params);
-
- if (PGRES_TUPLES_OK != PQresultStatus (result))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Query failed: %s\n",
- PQresultErrorMessage (result));
- PQclear (result);
- return GNUNET_SYSERR;
- }
-
- if (0 == PQntuples (result))
- return GNUNET_NO;
-
- GNUNET_assert (1 == PQntuples (result));
-
- /* We're done if the caller is only interested in
- * whether the session exists or not */
-
- if (NULL == session)
- return GNUNET_YES;
-
- memset (session, 0, sizeof (struct RefreshSession));
-
- session->session_pub = *refresh_session_pub;
-
- struct TALER_DB_ResultSpec rs[] = {
- TALER_DB_RESULT_SPEC("num_oldcoins", &session->num_oldcoins),
- TALER_DB_RESULT_SPEC("num_newcoins", &session->num_newcoins),
- TALER_DB_RESULT_SPEC("kappa", &session->kappa),
- TALER_DB_RESULT_SPEC("noreveal_index", &session->noreveal_index),
- TALER_DB_RESULT_SPEC("reveal_ok", &session->reveal_ok),
- TALER_DB_RESULT_SPEC_END
- };
-
- res = TALER_DB_extract_result (result, rs, 0);
-
- if (GNUNET_OK != res)
- {
- GNUNET_break (0);
- PQclear (result);
- 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);
- session->noreveal_index = ntohs (session->noreveal_index);
-
- PQclear (result);
- return GNUNET_YES;
-}
-
-
-int
TALER_MINT_DB_get_known_coin (PGconn *db_conn,
const struct GNUNET_CRYPTO_EcdsaPublicKey *coin_pub,
struct KnownCoin *known_coin)
@@ -744,34 +674,6 @@ TALER_MINT_DB_get_known_coin (PGconn *db_conn,
int
-TALER_MINT_DB_create_refresh_session (PGconn *db_conn,
- const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub)
-{
- uint16_t noreveal_index;
- struct TALER_DB_QueryParam params[] = {
- TALER_DB_QUERY_PARAM_PTR(session_pub),
- TALER_DB_QUERY_PARAM_PTR(&noreveal_index),
- TALER_DB_QUERY_PARAM_END
- };
-
- noreveal_index = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 1<<15);
- noreveal_index = htonl (noreveal_index);
-
- PGresult *result = TALER_DB_exec_prepared (db_conn, "insert_refresh_session", params);
-
- if (PGRES_COMMAND_OK != PQresultStatus (result))
- {
- break_db_err (result);
- PQclear (result);
- return GNUNET_SYSERR;
- }
-
- PQclear (result);
- return GNUNET_OK;
-}
-
-
-int
TALER_MINT_DB_set_commit_signature (PGconn *db_conn,
const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub,
const struct GNUNET_CRYPTO_EddsaSignature *commit_sig)
@@ -1882,6 +1784,145 @@ TALER_MINT_DB_insert_deposit (PGconn *db_conn,
/**
+ * Lookup refresh session data under the given public key.
+ *
+ * @param db_conn database handle to use
+ * @param refresh_session_pub public key to use for the lookup
+ * @param session[OUT] where to store the result
+ * @return #GNUNET_YES on success,
+ * #GNUNET_NO if not found,
+ * #GNUNET_SYSERR on DB failure
+ */
+int
+TALER_MINT_DB_get_refresh_session (PGconn *db_conn,
+ const struct GNUNET_CRYPTO_EddsaPublicKey *refresh_session_pub,
+ struct RefreshSession *session)
+{
+ // FIXME: check logic!
+ int res;
+ struct TALER_DB_QueryParam params[] = {
+ TALER_DB_QUERY_PARAM_PTR(refresh_session_pub),
+ TALER_DB_QUERY_PARAM_END
+ };
+
+ PGresult *result = TALER_DB_exec_prepared (db_conn, "get_refresh_session", params);
+
+ if (PGRES_TUPLES_OK != PQresultStatus (result))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Query failed: %s\n",
+ PQresultErrorMessage (result));
+ PQclear (result);
+ return GNUNET_SYSERR;
+ }
+
+ if (0 == PQntuples (result))
+ return GNUNET_NO;
+
+ GNUNET_assert (1 == PQntuples (result));
+
+ /* We're done if the caller is only interested in
+ * whether the session exists or not */
+
+ if (NULL == session)
+ return GNUNET_YES;
+
+ memset (session, 0, sizeof (struct RefreshSession));
+
+ struct TALER_DB_ResultSpec rs[] = {
+ TALER_DB_RESULT_SPEC("num_oldcoins", &session->num_oldcoins),
+ TALER_DB_RESULT_SPEC("num_newcoins", &session->num_newcoins),
+ TALER_DB_RESULT_SPEC("kappa", &session->kappa),
+ TALER_DB_RESULT_SPEC("noreveal_index", &session->noreveal_index),
+ TALER_DB_RESULT_SPEC_END
+ };
+
+ res = TALER_DB_extract_result (result, rs, 0);
+
+ if (GNUNET_OK != res)
+ {
+ GNUNET_break (0);
+ PQclear (result);
+ 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);
+ session->noreveal_index = ntohs (session->noreveal_index);
+
+ PQclear (result);
+ return GNUNET_YES;
+}
+
+
+/**
+ * Store new refresh session data under the given public key.
+ *
+ * @param db_conn database handle to use
+ * @param refresh_session_pub public key to use to locate the session
+ * @param session session data to store
+ * @return #GNUNET_YES on success,
+ * #GNUNET_SYSERR on DB failure
+ */
+int
+TALER_MINT_DB_create_refresh_session (PGconn *db_conn,
+ const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub,
+ const struct RefreshSession *session)
+{
+ // FIXME: actually store session data!
+ uint16_t noreveal_index;
+ struct TALER_DB_QueryParam params[] = {
+ TALER_DB_QUERY_PARAM_PTR(session_pub),
+ TALER_DB_QUERY_PARAM_PTR(&noreveal_index),
+ TALER_DB_QUERY_PARAM_END
+ };
+
+ noreveal_index = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 1<<15);
+ noreveal_index = htonl (noreveal_index);
+
+ PGresult *result = TALER_DB_exec_prepared (db_conn, "insert_refresh_session", params);
+
+ if (PGRES_COMMAND_OK != PQresultStatus (result))
+ {
+ break_db_err (result);
+ PQclear (result);
+ return GNUNET_SYSERR;
+ }
+
+ PQclear (result);
+ return GNUNET_OK;
+}
+
+
+/**
+ * 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;
+}
+
+
+/**
* Test if the given /refresh/melt request is known to us.
*
* @param db_conn database connection
diff --git a/src/mint/mint_db.h b/src/mint/mint_db.h
index 57b74f46e..e53df8ac2 100644
--- a/src/mint/mint_db.h
+++ b/src/mint/mint_db.h
@@ -44,10 +44,9 @@ TALER_MINT_DB_insert_refresh_order (PGconn *db_conn,
const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub,
const struct GNUNET_CRYPTO_rsa_PublicKey *denom_pub);
-int
-TALER_MINT_DB_get_refresh_session (PGconn *db_conn,
- const struct GNUNET_CRYPTO_EddsaPublicKey *refresh_session_pub,
- struct RefreshSession *r_session);
+
+
+
/**
@@ -86,10 +85,6 @@ TALER_MINT_DB_insert_known_coin (PGconn *db_conn,
const struct KnownCoin *known_coin);
-int
-TALER_MINT_DB_create_refresh_session (PGconn *db_conn,
- const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub);
-
/**
* Store the commitment to the given (encrypted) refresh link data
@@ -521,10 +516,111 @@ TALER_MINT_DB_insert_deposit (PGconn *db_conn,
const struct Deposit *deposit);
+
+/**
+ * Global information for a refreshing session. Includes
+ * dimensions of the operation, security parameters and
+ * client signatures from "/refresh/melt" and "/refresh/commit".
+ */
+struct RefreshSession
+{
+ /**
+ * Signature over the commitments by the client,
+ * only valid if @e has_commit_sig is set.
+ */
+ struct GNUNET_CRYPTO_EddsaSignature commit_sig;
+
+ /**
+ * Signature over the melt by the client.
+ */
+ struct GNUNET_CRYPTO_EddsaSignature melt_sig;
+
+ /**
+ * Number of coins we are melting.
+ */
+ uint16_t num_oldcoins;
+
+ /**
+ * Number of new coins we are creating.
+ */
+ uint16_t num_newcoins;
+
+ /**
+ * Number of parallel operations we perform for the cut and choose.
+ * (must be greater or equal to three for security). 0 if not yet
+ * known.
+ */
+ uint16_t kappa;
+
+ /**
+ * 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.
+ */
+ 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;
+
+};
+
+
+/**
+ * Lookup refresh session data under the given public key.
+ *
+ * @param db_conn database handle to use
+ * @param refresh_session_pub public key to use for the lookup
+ * @param session[OUT] where to store the result
+ * @return #GNUNET_YES on success,
+ * #GNUNET_NO if not found,
+ * #GNUNET_SYSERR on DB failure
+ */
+int
+TALER_MINT_DB_get_refresh_session (PGconn *db_conn,
+ const struct GNUNET_CRYPTO_EddsaPublicKey *refresh_session_pub,
+ struct RefreshSession *session);
+
+
+/**
+ * Store new refresh session data under the given public key.
+ *
+ * @param db_conn database handle to use
+ * @param refresh_session_pub public key to use to locate the session
+ * @param session session data to store
+ * @return #GNUNET_YES on success,
+ * #GNUNET_SYSERR on DB failure
+ */
+int
+TALER_MINT_DB_create_refresh_session (PGconn *db_conn,
+ const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub,
+ const struct RefreshSession *session);
+
+
+/**
+ * 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 a /refresh/melt operation.
+ * Specification for coin in a /refresh/melt operation.
*/
-struct RefreshMelt
+struct RefreshMelt /* FIXME: name to make it clearer this is about ONE coin! */
{
/**
* Information about the coin that is being melted.
diff --git a/src/mint/taler-mint-httpd_db.c b/src/mint/taler-mint-httpd_db.c
index eae37199b..2f6ca0137 100644
--- a/src/mint/taler-mint-httpd_db.c
+++ b/src/mint/taler-mint-httpd_db.c
@@ -602,6 +602,8 @@ refresh_accept_melts (struct MHD_Connection *connection,
*
* @param connection the MHD connection to handle
* @param refresh_session_pub public key of the refresh session
+ * @param client_signature signature of the client (matching @a refresh_session_pub)
+ * over the melting request
* @param num_new_denoms number of entries in @a denom_pubs
* @param denum_pubs public keys of the coins we want to withdraw in the end
* @param coin_count number of entries in @a coin_public_infos
@@ -611,6 +613,7 @@ refresh_accept_melts (struct MHD_Connection *connection,
int
TALER_MINT_db_execute_refresh_melt (struct MHD_Connection *connection,
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,
@@ -622,57 +625,48 @@ TALER_MINT_db_execute_refresh_melt (struct MHD_Connection *connection,
PGconn *db_conn;
int res;
- /* We incrementally update the db with other parameters in a transaction.
- * The transaction is aborted if some parameter does not validate. */
-
- /* Send response immediately if we already know the session.
- * Do _not_ care about fields other than session_pub in this case. */
-
if (NULL == (db_conn = TALER_MINT_DB_get_connection ()))
{
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,
- NULL);
+ &session);
if (GNUNET_YES == res)
{
- if (GNUNET_OK !=
- (res = TALER_MINT_DB_get_refresh_session (db_conn,
- refresh_session_pub,
- &session)))
- {
- // FIXME: send internal error
- GNUNET_break (0);
- return MHD_NO;
- }
+ TALER_MINT_DB_rollback (db_conn);
return TALER_MINT_reply_refresh_melt_success (connection,
- &session,
+ &session.melt_sig,
refresh_session_pub);
}
if (GNUNET_SYSERR == res)
{
- // FIXME: return 'internal error'?
- GNUNET_break (0);
- return MHD_NO;
+ TALER_MINT_DB_rollback (db_conn);
+ 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);
- }
- if (GNUNET_OK != TALER_MINT_DB_create_refresh_session (db_conn,
- refresh_session_pub))
+ session.melt_sig = *client_signature;
+ session.num_oldcoins = coin_count;
+ session.num_newcoins = num_new_denoms;
+ session.kappa = 0; /* FIXME: should be chosen by mint per config! */
+ 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)))
{
- // FIXME: return 'internal error'?
- GNUNET_break (0);
TALER_MINT_DB_rollback (db_conn);
- return MHD_NO;
+ return TALER_MINT_reply_internal_db_error (connection);
}
/* The next two operations must see the same key state,
@@ -725,7 +719,7 @@ TALER_MINT_db_execute_refresh_melt (struct MHD_Connection *connection,
return MHD_NO;
}
return TALER_MINT_reply_refresh_melt_success (connection,
- &session,
+ client_signature,
refresh_session_pub);
@@ -741,6 +735,8 @@ TALER_MINT_db_execute_refresh_melt (struct MHD_Connection *connection,
* @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
@@ -754,6 +750,7 @@ TALER_MINT_db_execute_refresh_melt (struct MHD_Connection *connection,
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,
@@ -773,12 +770,35 @@ TALER_MINT_db_execute_refresh_commit (struct MHD_Connection *connection,
return TALER_MINT_reply_internal_db_error (connection);
}
- /* Send response immediately if we already know the session.
- * Do _not_ care about fields other than session_pub in this case. */
-
+ 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 (GNUNET_YES == refresh_session.has_commit_sig)
+ {
+ TALER_MINT_DB_rollback (db_conn);
+ res = TALER_MINT_reply_refresh_commit_success (connection,
+ &refresh_session);
+ return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES;
+ }
+
+
// FIXME: this should check that kappa and num_newcoins match
// our expectations from refresh_session!
@@ -814,47 +834,20 @@ TALER_MINT_db_execute_refresh_commit (struct MHD_Connection *connection,
}
}
-
-
-
-
- if ( (GNUNET_YES == res) &&
- (GNUNET_YES == refresh_session.has_commit_sig) )
- {
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "sending cached commit response\n");
- res = TALER_MINT_reply_refresh_commit_success (connection,
- &refresh_session);
- GNUNET_break (res != GNUNET_SYSERR);
- return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES;
- }
- if (GNUNET_SYSERR == res)
- {
- // FIXME: return 'internal error'?
- GNUNET_break (0);
- return MHD_NO;
- }
+ refresh_session.noreveal_index
+ = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_STRONG,
+ refresh_session.kappa);
if (GNUNET_OK !=
- TALER_MINT_DB_transaction (db_conn))
+ (res = TALER_MINT_DB_update_refresh_session (db_conn,
+ refresh_session_pub,
+ refresh_session.noreveal_index,
+ commit_client_sig)))
{
- GNUNET_break (0);
+ TALER_MINT_DB_rollback (db_conn);
return TALER_MINT_reply_internal_db_error (connection);
}
- /* Re-fetch the session information from the database,
- * in case a concurrent transaction modified it. */
-
- res = TALER_MINT_DB_get_refresh_session (db_conn,
- refresh_session_pub,
- &refresh_session);
- if (GNUNET_OK != res)
- {
- // FIXME: return 'internal error'?
- GNUNET_break (GNUNET_SYSERR != res);
- TALER_MINT_DB_rollback (db_conn);
- return MHD_NO;
- }
if (GNUNET_OK !=
TALER_MINT_DB_commit (db_conn))
@@ -943,24 +936,14 @@ TALER_MINT_db_execute_refresh_reveal (struct MHD_Connection *connection,
return TALER_MINT_reply_internal_db_error (connection);
}
- /* Send response immediately if we already know the session,
- * and the session commited already.
- * Do _not_ care about fields other than session_pub in this case. */
-
res = TALER_MINT_DB_get_refresh_session (db_conn,
refresh_session_pub,
&refresh_session);
- if (GNUNET_YES == res && 0 != refresh_session.reveal_ok)
- return helper_refresh_reveal_send_response (connection,
- db_conn,
- &refresh_session,
- refresh_session_pub);
+ if (GNUNET_NO == res)
+ return TALER_MINT_reply_arg_invalid (connection,
+ "session_pub");
if (GNUNET_SYSERR == res)
- {
- GNUNET_break (0);
- // FIXME: return 'internal error'?
- return MHD_NO;
- }
+ return TALER_MINT_reply_internal_db_error (connection);
/* Check that the transfer private keys match their commitments.
* Then derive the shared secret for each kappa, and check that they match. */
diff --git a/src/mint/taler-mint-httpd_db.h b/src/mint/taler-mint-httpd_db.h
index e53d1b8ef..4b9aa1fe0 100644
--- a/src/mint/taler-mint-httpd_db.h
+++ b/src/mint/taler-mint-httpd_db.h
@@ -91,6 +91,8 @@ TALER_MINT_db_execute_withdraw_sign (struct MHD_Connection *connection,
*
* @param connection the MHD connection to handle
* @param refresh_session_pub public key of the refresh session
+ * @param client_signature signature of the client (matching @a refresh_session_pub)
+ * over the melting request
* @param num_new_denoms number of entries in @a denom_pubs
* @param denum_pubs array of public denomination keys for the refresh (?)
* @param coin_count number of entries in @a coin_public_infos
@@ -100,6 +102,7 @@ TALER_MINT_db_execute_withdraw_sign (struct MHD_Connection *connection,
int
TALER_MINT_db_execute_refresh_melt (struct MHD_Connection *connection,
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,
@@ -115,6 +118,8 @@ TALER_MINT_db_execute_refresh_melt (struct MHD_Connection *connection,
* @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
* @param num_newcoins size of y-dimension of @commit_link array
@@ -129,6 +134,7 @@ TALER_MINT_db_execute_refresh_melt (struct MHD_Connection *connection,
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,
diff --git a/src/mint/taler-mint-httpd_refresh.c b/src/mint/taler-mint-httpd_refresh.c
index e7497327b..1267ca48b 100644
--- a/src/mint/taler-mint-httpd_refresh.c
+++ b/src/mint/taler-mint-httpd_refresh.c
@@ -242,8 +242,10 @@ handle_refresh_melt_binary (struct MHD_Connection *connection,
"error", "value mismatch");
}
+ /* FIXME: we must also store the signature over the melt! (#3635) */
return TALER_MINT_db_execute_refresh_melt (connection,
refresh_session_pub,
+ NULL, /* FIXME: #3635! */
num_new_denoms,
denom_pubs,
coin_count,
@@ -715,6 +717,7 @@ handle_refresh_commit_json (struct MHD_Connection *connection,
/* 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,
diff --git a/src/mint/taler-mint-httpd_responses.c b/src/mint/taler-mint-httpd_responses.c
index 892b92ca7..de0736bdc 100644
--- a/src/mint/taler-mint-httpd_responses.c
+++ b/src/mint/taler-mint-httpd_responses.c
@@ -518,43 +518,37 @@ TALER_MINT_reply_withdraw_sign_success (struct MHD_Connection *connection,
/**
- * Send a response for "/refresh/melt".
+ * 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.
*
* @param connection the connection to send the response to
- * @param db_conn the database connection to fetch values from
+ * @param signature the client's signature over the melt request
* @param session_pub the refresh session public key.
* @return a MHD result code
*/
int
TALER_MINT_reply_refresh_melt_success (struct MHD_Connection *connection,
- const struct RefreshSession *session,
+ const struct GNUNET_CRYPTO_EddsaSignature *signature,
const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub)
{
int ret;
- json_t *list;
- struct GNUNET_HashContext *hash_context;
struct RefreshMeltResponseSignatureBody body;
struct GNUNET_CRYPTO_EddsaSignature sig;
json_t *sig_json;
- list = json_array ();
- hash_context = GNUNET_CRYPTO_hash_context_start ();
body.purpose.size = htonl (sizeof (struct RefreshMeltResponseSignatureBody));
body.purpose.purpose = htonl (TALER_SIGNATURE_REFRESH_MELT_RESPONSE);
- /* FIXME: should we not add something to the hash_context in the meantime? */
- GNUNET_CRYPTO_hash_context_finish (hash_context,
- &body.melt_response_hash);
+ body.melt_client_signature = *signature;
+ body.session_key = *session_pub;
TALER_MINT_keys_sign (&body.purpose,
&sig);
sig_json = TALER_JSON_from_sig (&body.purpose, &sig);
- GNUNET_assert (NULL != sig_json);
ret = TALER_MINT_reply_json_pack (connection,
MHD_HTTP_OK,
- "{s:o, s:o}",
- "signature", sig_json,
- "blind_session_pubs", list);
+ "{s:o}",
+ "signature", sig_json);
json_decref (sig_json);
- json_decref (list);
return ret;
}
@@ -570,7 +564,7 @@ TALER_MINT_reply_refresh_melt_success (struct MHD_Connection *connection,
*/
int
TALER_MINT_reply_refresh_commit_success (struct MHD_Connection *connection,
- struct RefreshSession *refresh_session)
+ const struct RefreshSession *refresh_session)
{
struct RefreshCommitResponseSignatureBody body;
struct GNUNET_CRYPTO_EddsaSignature sig;
diff --git a/src/mint/taler-mint-httpd_responses.h b/src/mint/taler-mint-httpd_responses.h
index ebe1038fd..6cf934094 100644
--- a/src/mint/taler-mint-httpd_responses.h
+++ b/src/mint/taler-mint-httpd_responses.h
@@ -245,20 +245,22 @@ TALER_MINT_reply_withdraw_sign_success (struct MHD_Connection *connection,
*/
int
TALER_MINT_reply_refresh_commit_success (struct MHD_Connection *connection,
- struct RefreshSession *refresh_session);
+ const struct RefreshSession *refresh_session);
/**
- * Send a response for "/refresh/melt".
+ * 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.
*
* @param connection the connection to send the response to
- * @param session session data to generate reply from
+ * @param signature the client's signature over the melt request
* @param session_pub the refresh session public key.
* @return a MHD result code
*/
int
TALER_MINT_reply_refresh_melt_success (struct MHD_Connection *connection,
- const struct RefreshSession *session,
+ const struct GNUNET_CRYPTO_EddsaSignature *signature,
const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub);