diff options
-rw-r--r-- | src/include/taler_mintdb_plugin.h | 67 | ||||
-rw-r--r-- | src/mint/taler-mint-httpd_db.c | 87 | ||||
-rw-r--r-- | src/mint/taler-mint-httpd_refresh.c | 3 | ||||
-rw-r--r-- | src/mint/taler-mint-httpd_responses.c | 4 | ||||
-rw-r--r-- | src/mint/taler-mint-httpd_responses.h | 6 | ||||
-rw-r--r-- | src/mintdb/plugin_mintdb_common.c | 31 | ||||
-rw-r--r-- | src/mintdb/plugin_mintdb_postgres.c | 48 |
7 files changed, 218 insertions, 28 deletions
diff --git a/src/include/taler_mintdb_plugin.h b/src/include/taler_mintdb_plugin.h index 505e86bb3..307b75645 100644 --- a/src/include/taler_mintdb_plugin.h +++ b/src/include/taler_mintdb_plugin.h @@ -24,6 +24,7 @@ #include <gnunet/gnunet_util_lib.h> #include "taler_util.h" +#include "taler_signatures.h" /** @@ -378,7 +379,7 @@ GNUNET_NETWORK_STRUCT_BEGIN /** * @brief For each (old) coin being melted, we have a `struct - * RefreshCommitLink` that allows the user to find the shared secret + * RefreshCommitLinkP` that allows the user to find the shared secret * to decrypt the respective refresh links for the new coins in the * `struct TALER_MINTDB_RefreshCommitCoin`. */ @@ -519,6 +520,44 @@ struct TALER_MINTDB_TransactionList /** + * @brief All of the information from a /refresh/melt commitment. + */ +struct TALER_MINTDB_MeltCommitment +{ + + /** + * Number of coins we are melting. + */ + uint16_t num_oldcoins; + + /** + * Number of new coins we are creating. + */ + uint16_t num_newcoins; + + /** + * Array of @e num_oldcoins melt operation details. + */ + struct TALER_MINTDB_RefreshMelt *melts; + + /** + * Array of @e num_newcoins denomination keys + */ + struct TALER_DenominationPublicKey *denom_pubs; + + /** + * 2D-Array of #TALER_CNC_KAPPA and @e num_newcoins commitments. + */ + struct TALER_MINTDB_RefreshCommitCoin *commit_coins[TALER_CNC_KAPPA]; + + /** + * 2D-Array of #TALER_CNC_KAPPA and @e new_oldcoins links. + */ + struct TALER_MINTDB_RefreshCommitLinkP *commit_links[TALER_CNC_KAPPA]; +}; + + +/** * @brief Handle for a database session (per-thread, for transactions). */ struct TALER_MINTDB_Session; @@ -955,6 +994,32 @@ struct TALER_MINTDB_Plugin /** + * Get all of the information from the given melt commit operation. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param sesssion database connection to use + * @param session_hash hash to identify refresh session + * @return NULL if the @a session_hash does not correspond to any known melt + * operation + */ + struct TALER_MINTDB_MeltCommitment * + (*get_melt_commitment) (void *cls, + struct TALER_MINTDB_Session *sesssion, + const struct GNUNET_HashCode *session_hash); + + + /** + * Free information about a melt commitment. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param mc melt commitment data to free + */ + void + (*free_melt_commitment) (void *cls, + struct TALER_MINTDB_MeltCommitment *mc); + + + /** * Insert signature of a new coin generated during refresh into * the database indexed by the refresh session and the index * of the coin. This data is later used should an old coin diff --git a/src/mint/taler-mint-httpd_db.c b/src/mint/taler-mint-httpd_db.c index 742868272..11bd60f7b 100644 --- a/src/mint/taler-mint-httpd_db.c +++ b/src/mint/taler-mint-httpd_db.c @@ -744,6 +744,54 @@ TMH_DB_execute_refresh_melt (struct MHD_Connection *connection, /** + * Send an error response with the details of the original melt + * commitment and the location of the mismatch. + * + * @param connection the MHD connection to handle + * @param session database connection to use + * @param session_hash hash of session to query + * @param off commitment offset to check + * @param index index of the mismatch + * @param object_name name of the object with the problem + * @return #GNUNET_NO if we generated the error message + * #GNUNET_SYSERR if we could not even generate an error message + */ +static int +send_melt_commitment_error (struct MHD_Connection *connection, + struct TALER_MINTDB_Session *session, + const struct GNUNET_HashCode *session_hash, + unsigned int off, + unsigned int index, + const char *object_name) +{ + struct TALER_MINTDB_MeltCommitment *mc; + int ret; + + mc = TMH_plugin->get_melt_commitment (TMH_plugin->cls, + session, + session_hash); + if (NULL == mc) + { + GNUNET_break (0); + return (MHD_YES == + TMH_RESPONSE_reply_internal_error (connection, + "Melt commitment assembly")) + ? GNUNET_NO : GNUNET_SYSERR; + } + ret = (MHD_YES == + TMH_RESPONSE_reply_refresh_reveal_missmatch (connection, + mc, + off, + index, + object_name)) + ? GNUNET_NO : GNUNET_SYSERR; + TMH_plugin->free_melt_commitment (TMH_plugin->cls, + mc); + return ret; +} + + +/** * Check if the given @a transfer_privs correspond to an honest * commitment for the given session. * Checks that the transfer private keys match their commitments. @@ -811,13 +859,12 @@ check_commitment (struct MHD_Connection *connection, GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "transfer keys do not match\n"); GNUNET_free (commit_links); - /* FIXME: return more specific error with original signature (#3712) */ - return (MHD_YES == - TMH_RESPONSE_reply_refresh_reveal_missmatch (connection, - off, - j, - "transfer key")) - ? GNUNET_NO : GNUNET_SYSERR; + return send_melt_commitment_error (connection, + session, + session_hash, + off, + j, + "transfer key"); } /* We're converting key types here, which is not very nice @@ -858,13 +905,12 @@ check_commitment (struct MHD_Connection *connection, GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "shared secrets do not match\n"); GNUNET_free (commit_links); - /* FIXME: return more specific error with original signature (#3712) */ - return (MHD_YES == - TMH_RESPONSE_reply_refresh_reveal_missmatch (connection, - off, - j, - "transfer secret")) - ? GNUNET_NO : GNUNET_SYSERR; + return send_melt_commitment_error (connection, + session, + session_hash, + off, + j, + "transfer secret"); } } GNUNET_break (GNUNET_YES == secret_initialized); @@ -935,14 +981,13 @@ check_commitment (struct MHD_Connection *connection, "blind envelope does not match for k=%u, old=%d\n", off, (int) j); - /* FIXME: return more specific error with original signature (#3712) */ GNUNET_free (commit_coins); - return (MHD_YES == - TMH_RESPONSE_reply_refresh_reveal_missmatch (connection, - off, - j, - "envelope")) - ? GNUNET_NO : GNUNET_SYSERR; + return send_melt_commitment_error (connection, + session, + session_hash, + off, + j, + "envelope"); } GNUNET_free (buf); } diff --git a/src/mint/taler-mint-httpd_refresh.c b/src/mint/taler-mint-httpd_refresh.c index 805d4f9c5..38af09d85 100644 --- a/src/mint/taler-mint-httpd_refresh.c +++ b/src/mint/taler-mint-httpd_refresh.c @@ -61,7 +61,6 @@ handle_refresh_melt_binary (struct MHD_Connection *connection, const struct GNUNET_HashCode *session_hash, struct TALER_MINTDB_RefreshCommitCoin *const* commit_coin, struct TALER_MINTDB_RefreshCommitLinkP *const* commit_link) - { unsigned int i; struct TMH_KS_StateHandle *key_state; @@ -509,6 +508,7 @@ handle_refresh_melt_json (struct MHD_Connection *connection, free_commit_coins (commit_coin, TALER_CNC_KAPPA, num_newcoins); + GNUNET_free (link_enc); return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES; } rcc->refresh_link @@ -517,6 +517,7 @@ handle_refresh_melt_json (struct MHD_Connection *connection, GNUNET_CRYPTO_hash_context_read (hash_context, link_enc, link_enc_size); + GNUNET_free (link_enc); } } diff --git a/src/mint/taler-mint-httpd_responses.c b/src/mint/taler-mint-httpd_responses.c index c567103f0..57170e0b8 100644 --- a/src/mint/taler-mint-httpd_responses.c +++ b/src/mint/taler-mint-httpd_responses.c @@ -776,9 +776,10 @@ TMH_RESPONSE_reply_refresh_reveal_success (struct MHD_Connection *connection, * * FIXME: should also include the client's signature over * the original reveal operation and the data that was signed - * over eventually... (#3712) + * over eventually... (#3712) -- need to use @a mc! * * @param connection the connection to send the response to + * @param mc all information about the original commitment * @param off offset in the array of kappa-commitments where * the missmatch was detected * @param j index of the coin for which the missmatch was @@ -789,6 +790,7 @@ TMH_RESPONSE_reply_refresh_reveal_success (struct MHD_Connection *connection, */ int TMH_RESPONSE_reply_refresh_reveal_missmatch (struct MHD_Connection *connection, + const struct TALER_MINTDB_MeltCommitment *mc, unsigned int off, unsigned int j, const char *missmatch_object) diff --git a/src/mint/taler-mint-httpd_responses.h b/src/mint/taler-mint-httpd_responses.h index cedb90d36..ab062c2a7 100644 --- a/src/mint/taler-mint-httpd_responses.h +++ b/src/mint/taler-mint-httpd_responses.h @@ -316,11 +316,8 @@ TMH_RESPONSE_reply_refresh_reveal_success (struct MHD_Connection *connection, * Send a response for a failed "/refresh/reveal", where the * revealed value(s) do not match the original commitment. * - * FIXME: should also include the client's signature over - * the original reveal operation and the data that was signed - * over eventually... (#3712) - * * @param connection the connection to send the response to + * @param mc all information about the original commitment * @param off offset in the array of kappa-commitments where * the missmatch was detected * @param j index of the coin for which the missmatch was @@ -331,6 +328,7 @@ TMH_RESPONSE_reply_refresh_reveal_success (struct MHD_Connection *connection, */ int TMH_RESPONSE_reply_refresh_reveal_missmatch (struct MHD_Connection *connection, + const struct TALER_MINTDB_MeltCommitment *mc, unsigned int off, unsigned int j, const char *missmatch_object); diff --git a/src/mintdb/plugin_mintdb_common.c b/src/mintdb/plugin_mintdb_common.c index 2bd789472..f380d7da0 100644 --- a/src/mintdb/plugin_mintdb_common.c +++ b/src/mintdb/plugin_mintdb_common.c @@ -115,4 +115,35 @@ common_free_coin_transaction_list (void *cls, } } + +/** + * Free melt commitment data. + * + * @param cls the @e cls of this struct with the plugin-specific state (unused) + * @param mc data structure to free + */ +static void +common_free_melt_commitment (void *cls, + struct TALER_MINTDB_MeltCommitment *mc) +{ + unsigned int i; + unsigned int k; + + GNUNET_free (mc->melts); + for (i=0;i<mc->num_newcoins;i++) + GNUNET_CRYPTO_rsa_public_key_free (mc->denom_pubs[i].rsa_public_key); + GNUNET_free (mc->denom_pubs); + for (k=0;k<TALER_CNC_KAPPA;k++) + { + for (i=0;i<mc->num_newcoins;i++) + { + GNUNET_free (mc->commit_coins[k][i].refresh_link); + GNUNET_free (mc->commit_coins[k][i].coin_ev); + } + GNUNET_free (mc->commit_coins[k]); + GNUNET_free (mc->commit_links[k]); + } + GNUNET_free (mc); +} + /* end of plugin_mintdb_common.c */ diff --git a/src/mintdb/plugin_mintdb_postgres.c b/src/mintdb/plugin_mintdb_postgres.c index b9c9dc75e..19ae3a3bd 100644 --- a/src/mintdb/plugin_mintdb_postgres.c +++ b/src/mintdb/plugin_mintdb_postgres.c @@ -2006,6 +2006,52 @@ postgres_get_refresh_commit_links (void *cls, /** + * Get all of the information from the given melt commit operation. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param sesssion database connection to use + * @param session_hash hash to identify refresh session + * @return NULL if the @a session_hash does not correspond to any known melt + * operation + */ +static struct TALER_MINTDB_MeltCommitment * +postgres_get_melt_commitment (void *cls, + struct TALER_MINTDB_Session *sesssion, + const struct GNUNET_HashCode *session_hash) +{ + // FIXME: needs to be implemented! +#if 0 + struct TALER_MINTDB_MeltCommitment *mc; + unsigned int k; + unsigned int i; + + mc = GNUNET_new (struct TALER_MINTDB_MeltCommitment); + mc->num_newcoins = ; + mc->num_oldcoins = ; + mc->denom_pubs = GNUNET_malloc (mc->num_newcoins * + sizeof (struct TALER_DenominationPublicKey)); + mc->melts = GNUNET_malloc (mc->num_oldcoins * + sizeof (struct TALER_MINTDB_RefreshMelt)); + for (k=0;k<TALER_CNC_KAPPA;k++) + { + mc->commit_coins[k] = GNUNET_malloc (mc->num_newcoins * + sizeof (struct TALER_MINTDB_RefreshCommitCoin)); + for (i=0;i<mc->num_newcoins;i++) + { + mc->commit_coins[k][i].refresh_link = ; // malloc... + mc->commit_coins[k][i].coin_ev = ; // malloc... + } + mc->commit_links[k] = GNUNET_malloc (mc->num_oldcoins * + sizeof (struct TALER_MINTDB_RefreshCommitLinkP)); + } + + return mc; +#endif + return NULL; +} + + +/** * Insert signature of a new coin generated during refresh into * the database indexed by the refresh session and the index * of the coin. This data is later used should an old coin @@ -2324,6 +2370,8 @@ libtaler_plugin_mintdb_postgres_init (void *cls) plugin->get_refresh_commit_coins = &postgres_get_refresh_commit_coins; plugin->insert_refresh_commit_links = &postgres_insert_refresh_commit_links; plugin->get_refresh_commit_links = &postgres_get_refresh_commit_links; + plugin->get_melt_commitment = &postgres_get_melt_commitment; + plugin->free_melt_commitment = &common_free_melt_commitment; plugin->insert_refresh_collectable = &postgres_insert_refresh_collectable; plugin->get_link_data_list = &postgres_get_link_data_list; plugin->free_link_data_list = &common_free_link_data_list; |