working on cleaning up /refresh/melt logic
This commit is contained in:
parent
8ca555500f
commit
090ddf170b
@ -233,6 +233,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
|
||||
*/
|
||||
@ -296,15 +326,6 @@ struct RefreshCommitResponseSignatureBody
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* FIXME
|
||||
*/
|
||||
struct RefreshMeltResponseSignatureBody
|
||||
{
|
||||
struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
|
||||
struct GNUNET_HashCode melt_response_hash;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* FIXME
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
@ -581,76 +581,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,
|
||||
@ -743,34 +673,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,
|
||||
@ -1881,6 +1783,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.
|
||||
*
|
||||
|
@ -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);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Specification for a /refresh/melt operation.
|
||||
* Global information for a refreshing session. Includes
|
||||
* dimensions of the operation, security parameters and
|
||||
* client signatures from "/refresh/melt" and "/refresh/commit".
|
||||
*/
|
||||
struct RefreshMelt
|
||||
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 coin in a /refresh/melt operation.
|
||||
*/
|
||||
struct RefreshMelt /* FIXME: name to make it clearer this is about ONE coin! */
|
||||
{
|
||||
/**
|
||||
* Information about the coin that is being melted.
|
||||
|
@ -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);
|
||||
}
|
||||
res = TALER_MINT_DB_get_refresh_session (db_conn,
|
||||
refresh_session_pub,
|
||||
NULL);
|
||||
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;
|
||||
}
|
||||
return TALER_MINT_reply_refresh_melt_success (connection,
|
||||
&session,
|
||||
refresh_session_pub);
|
||||
}
|
||||
if (GNUNET_SYSERR == res)
|
||||
{
|
||||
// FIXME: return 'internal error'?
|
||||
GNUNET_break (0);
|
||||
return MHD_NO;
|
||||
}
|
||||
|
||||
|
||||
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))
|
||||
res = TALER_MINT_DB_get_refresh_session (db_conn,
|
||||
refresh_session_pub,
|
||||
&session);
|
||||
if (GNUNET_YES == res)
|
||||
{
|
||||
// FIXME: return 'internal error'?
|
||||
GNUNET_break (0);
|
||||
TALER_MINT_DB_rollback (db_conn);
|
||||
return MHD_NO;
|
||||
return TALER_MINT_reply_refresh_melt_success (connection,
|
||||
&session.melt_sig,
|
||||
refresh_session_pub);
|
||||
}
|
||||
if (GNUNET_SYSERR == res)
|
||||
{
|
||||
TALER_MINT_DB_rollback (db_conn);
|
||||
return TALER_MINT_reply_internal_db_error (connection);
|
||||
}
|
||||
|
||||
|
||||
|
||||
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)))
|
||||
{
|
||||
TALER_MINT_DB_rollback (db_conn);
|
||||
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. */
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user