scaffolding work towards #3712

This commit is contained in:
Christian Grothoff 2015-04-11 21:29:15 +02:00
parent 8b32125223
commit 4f078c7666
7 changed files with 218 additions and 28 deletions

View File

@ -24,6 +24,7 @@
#include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_util_lib.h>
#include "taler_util.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 * @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 * to decrypt the respective refresh links for the new coins in the
* `struct TALER_MINTDB_RefreshCommitCoin`. * `struct TALER_MINTDB_RefreshCommitCoin`.
*/ */
@ -518,6 +519,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). * @brief Handle for a database session (per-thread, for transactions).
*/ */
@ -954,6 +993,32 @@ struct TALER_MINTDB_Plugin
struct TALER_MINTDB_RefreshCommitLinkP *links); struct TALER_MINTDB_RefreshCommitLinkP *links);
/**
* 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 * Insert signature of a new coin generated during refresh into
* the database indexed by the refresh session and the index * the database indexed by the refresh session and the index

View File

@ -743,6 +743,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 * Check if the given @a transfer_privs correspond to an honest
* commitment for the given session. * commitment for the given session.
@ -811,13 +859,12 @@ check_commitment (struct MHD_Connection *connection,
GNUNET_log (GNUNET_ERROR_TYPE_ERROR, GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"transfer keys do not match\n"); "transfer keys do not match\n");
GNUNET_free (commit_links); GNUNET_free (commit_links);
/* FIXME: return more specific error with original signature (#3712) */ return send_melt_commitment_error (connection,
return (MHD_YES == session,
TMH_RESPONSE_reply_refresh_reveal_missmatch (connection, session_hash,
off, off,
j, j,
"transfer key")) "transfer key");
? GNUNET_NO : GNUNET_SYSERR;
} }
/* We're converting key types here, which is not very nice /* 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, GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"shared secrets do not match\n"); "shared secrets do not match\n");
GNUNET_free (commit_links); GNUNET_free (commit_links);
/* FIXME: return more specific error with original signature (#3712) */ return send_melt_commitment_error (connection,
return (MHD_YES == session,
TMH_RESPONSE_reply_refresh_reveal_missmatch (connection, session_hash,
off, off,
j, j,
"transfer secret")) "transfer secret");
? GNUNET_NO : GNUNET_SYSERR;
} }
} }
GNUNET_break (GNUNET_YES == secret_initialized); 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", "blind envelope does not match for k=%u, old=%d\n",
off, off,
(int) j); (int) j);
/* FIXME: return more specific error with original signature (#3712) */
GNUNET_free (commit_coins); GNUNET_free (commit_coins);
return (MHD_YES == return send_melt_commitment_error (connection,
TMH_RESPONSE_reply_refresh_reveal_missmatch (connection, session,
session_hash,
off, off,
j, j,
"envelope")) "envelope");
? GNUNET_NO : GNUNET_SYSERR;
} }
GNUNET_free (buf); GNUNET_free (buf);
} }

View File

@ -61,7 +61,6 @@ handle_refresh_melt_binary (struct MHD_Connection *connection,
const struct GNUNET_HashCode *session_hash, const struct GNUNET_HashCode *session_hash,
struct TALER_MINTDB_RefreshCommitCoin *const* commit_coin, struct TALER_MINTDB_RefreshCommitCoin *const* commit_coin,
struct TALER_MINTDB_RefreshCommitLinkP *const* commit_link) struct TALER_MINTDB_RefreshCommitLinkP *const* commit_link)
{ {
unsigned int i; unsigned int i;
struct TMH_KS_StateHandle *key_state; struct TMH_KS_StateHandle *key_state;
@ -509,6 +508,7 @@ handle_refresh_melt_json (struct MHD_Connection *connection,
free_commit_coins (commit_coin, free_commit_coins (commit_coin,
TALER_CNC_KAPPA, TALER_CNC_KAPPA,
num_newcoins); num_newcoins);
GNUNET_free (link_enc);
return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES; return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES;
} }
rcc->refresh_link rcc->refresh_link
@ -517,6 +517,7 @@ handle_refresh_melt_json (struct MHD_Connection *connection,
GNUNET_CRYPTO_hash_context_read (hash_context, GNUNET_CRYPTO_hash_context_read (hash_context,
link_enc, link_enc,
link_enc_size); link_enc_size);
GNUNET_free (link_enc);
} }
} }

View File

@ -776,9 +776,10 @@ TMH_RESPONSE_reply_refresh_reveal_success (struct MHD_Connection *connection,
* *
* FIXME: should also include the client's signature over * FIXME: should also include the client's signature over
* the original reveal operation and the data that was signed * 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 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 * @param off offset in the array of kappa-commitments where
* the missmatch was detected * the missmatch was detected
* @param j index of the coin for which the missmatch was * @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 int
TMH_RESPONSE_reply_refresh_reveal_missmatch (struct MHD_Connection *connection, TMH_RESPONSE_reply_refresh_reveal_missmatch (struct MHD_Connection *connection,
const struct TALER_MINTDB_MeltCommitment *mc,
unsigned int off, unsigned int off,
unsigned int j, unsigned int j,
const char *missmatch_object) const char *missmatch_object)

View File

@ -316,11 +316,8 @@ TMH_RESPONSE_reply_refresh_reveal_success (struct MHD_Connection *connection,
* Send a response for a failed "/refresh/reveal", where the * Send a response for a failed "/refresh/reveal", where the
* revealed value(s) do not match the original commitment. * 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 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 * @param off offset in the array of kappa-commitments where
* the missmatch was detected * the missmatch was detected
* @param j index of the coin for which the missmatch was * @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 int
TMH_RESPONSE_reply_refresh_reveal_missmatch (struct MHD_Connection *connection, TMH_RESPONSE_reply_refresh_reveal_missmatch (struct MHD_Connection *connection,
const struct TALER_MINTDB_MeltCommitment *mc,
unsigned int off, unsigned int off,
unsigned int j, unsigned int j,
const char *missmatch_object); const char *missmatch_object);

View File

@ -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 */ /* end of plugin_mintdb_common.c */

View File

@ -2005,6 +2005,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 * Insert signature of a new coin generated during refresh into
* the database indexed by the refresh session and the index * the database indexed by the refresh session and the index
@ -2324,6 +2370,8 @@ libtaler_plugin_mintdb_postgres_init (void *cls)
plugin->get_refresh_commit_coins = &postgres_get_refresh_commit_coins; plugin->get_refresh_commit_coins = &postgres_get_refresh_commit_coins;
plugin->insert_refresh_commit_links = &postgres_insert_refresh_commit_links; plugin->insert_refresh_commit_links = &postgres_insert_refresh_commit_links;
plugin->get_refresh_commit_links = &postgres_get_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->insert_refresh_collectable = &postgres_insert_refresh_collectable;
plugin->get_link_data_list = &postgres_get_link_data_list; plugin->get_link_data_list = &postgres_get_link_data_list;
plugin->free_link_data_list = &common_free_link_data_list; plugin->free_link_data_list = &common_free_link_data_list;