sign /deposit reply so that merchant has proof that mint accepted it

This commit is contained in:
Christian Grothoff 2015-01-28 19:48:41 +01:00
parent e19f1906a3
commit 2e0e30291c
6 changed files with 137 additions and 30 deletions

View File

@ -85,6 +85,12 @@
*/
#define TALER_SIGNATURE_REFRESH_MELT_CONFIRM 9
/**
* Signature where the Mint confirms a deposit request.
*/
#define TALER_SIGNATURE_MINT_DEPOSIT 10
/***********************/
/* Merchant signatures */
/***********************/
@ -101,12 +107,12 @@
/**
* Signature made by the wallet of a user to confirm a deposit permission
*/
#define TALER_SIGNATURE_DEPOSIT 201
#define TALER_SIGNATURE_WALLET_DEPOSIT 201
/**
* Signature made by the wallet of a user to confirm a incremental deposit permission
*/
#define TALER_SIGNATURE_INCREMENTAL_DEPOSIT 202
#define TALER_SIGNATURE_INCREMENTAL_WALLET_DEPOSIT 202
@ -149,7 +155,7 @@ struct TALER_WithdrawRequest
struct TALER_DepositRequest
{
/**
* Purpose must be #TALER_SIGNATURE_DEPOSIT
* Purpose must be #TALER_SIGNATURE_WALLET_DEPOSIT
*/
struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
@ -182,6 +188,51 @@ struct TALER_DepositRequest
};
/**
* Format used to generate the signature on a confirmation
* from the mint that a deposit request succeeded.
*/
struct TALER_DepositConfirmation
{
/**
* Purpose must be #TALER_SIGNATURE_MINT_DEPOSIT
*/
struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
/**
* Hash over the contract for which this deposit is made.
*/
struct GNUNET_HashCode h_contract;
/**
* Hash over the wiring information of the merchant.
*/
struct GNUNET_HashCode h_wire;
/**
* Merchant-generated transaction ID to detect duplicate
* transactions.
*/
uint64_t transaction_id GNUNET_PACKED;
/**
* Amount to be deposited.
*/
struct TALER_AmountNBO amount;
/**
* The coin's public key.
*/
struct GNUNET_CRYPTO_EcdsaPublicKey coin_pub;
/**
* The Merachant's public key.
*/
struct GNUNET_CRYPTO_EddsaPublicKey merchant;
};
/**
* FIXME
*/

View File

@ -55,6 +55,11 @@ struct GNUNET_CONFIGURATION_Handle *cfg;
*/
struct GNUNET_CRYPTO_EddsaPublicKey master_pub;
/**
* Private key of the mint we use to sign messages.
*/
struct GNUNET_CRYPTO_EddsaPrivateKey mint_priv;
/**
* The HTTP Daemon.
*/
@ -223,7 +228,7 @@ handle_mhd_request (void *cls,
* server into the corresponding global variables.
*
* @param param mint_directory the mint's directory
* @return GNUNET_OK on success
* @return #GNUNET_OK on success
*/
static int
mint_serve_process_config (const char *mint_directory)
@ -231,6 +236,7 @@ mint_serve_process_config (const char *mint_directory)
unsigned long long port;
unsigned long long kappa;
char *master_pub_str;
char *mint_priv_str;
char *db_cfg;
cfg = TALER_config_load (mint_directory);
@ -256,8 +262,30 @@ mint_serve_process_config (const char *mint_directory)
{
fprintf (stderr,
"Invalid master public key given in mint configuration.");
GNUNET_free (master_pub_str);
return GNUNET_NO;
}
GNUNET_free (master_pub_str);
if (GNUNET_OK !=
GNUNET_CONFIGURATION_get_value_string (cfg,
"mint", "mint_priv",
&mint_priv_str))
{
fprintf (stderr,
"No master public key given in mint configuration.");
return GNUNET_NO;
}
if (GNUNET_OK !=
GNUNET_CRYPTO_eddsa_private_key_from_string (mint_priv_str,
strlen (mint_priv_str),
&mint_priv))
{
fprintf (stderr,
"Invalid mint private key given in mint configuration.");
GNUNET_free (mint_priv_str);
return GNUNET_NO;
}
GNUNET_free (mint_priv_str);
if (GNUNET_OK !=
GNUNET_CONFIGURATION_get_value_string (cfg,

View File

@ -48,6 +48,11 @@ extern char *mintdir;
*/
extern struct GNUNET_CRYPTO_EddsaPublicKey master_pub;
/**
* Private key of the mint we use to sign messages.
*/
extern struct GNUNET_CRYPTO_EddsaPrivateKey mint_priv;
/**
* Struct describing an URL and the handler for it.

View File

@ -60,7 +60,7 @@ verify_and_execute_deposit (struct MHD_Connection *connection,
struct MintKeyState *key_state;
struct TALER_DepositRequest dr;
dr.purpose.purpose = htonl (TALER_SIGNATURE_DEPOSIT);
dr.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_DEPOSIT);
dr.purpose.size = htonl (sizeof (struct TALER_DepositRequest));
dr.h_contract = deposit->h_contract;
dr.h_wire = deposit->h_wire;
@ -68,7 +68,7 @@ verify_and_execute_deposit (struct MHD_Connection *connection,
dr.amount = TALER_amount_hton (deposit->amount);
dr.coin_pub = deposit->coin.coin_pub;
if (GNUNET_OK !=
GNUNET_CRYPTO_ecdsa_verify (TALER_SIGNATURE_DEPOSIT,
GNUNET_CRYPTO_ecdsa_verify (TALER_SIGNATURE_WALLET_DEPOSIT,
&dr.purpose,
&deposit->csig,
&deposit->coin.coin_pub))
@ -101,8 +101,8 @@ verify_and_execute_deposit (struct MHD_Connection *connection,
*
* @param connection the MHD connection to handle
* @param root root of the posted JSON
* @param purpose is this a #TALER_SIGNATURE_DEPOSIT or
* #TALER_SIGNATURE_INCREMENTAL_DEPOSIT // FIXME: bad type, use enum!
* @param purpose is this a #TALER_SIGNATURE_WALLET_DEPOSIT or
* #TALER_SIGNATURE_INCREMENTAL_WALLET_DEPOSIT // FIXME: bad type, use enum!
* @param amount how much should be deposited
* @param wire json describing the wire details (?)
* @return MHD result code
@ -258,9 +258,9 @@ TALER_MINT_handler_deposit (struct RequestHandler *rh,
}
/* FIXME: use array search and enum, this is ugly */
if (0 == strcmp ("DIRECT_DEPOSIT", deposit_type))
purpose = TALER_SIGNATURE_DEPOSIT;
purpose = TALER_SIGNATURE_WALLET_DEPOSIT;
else if (0 == strcmp ("INCREMENTAL_DEPOSIT", deposit_type))
purpose = TALER_SIGNATURE_INCREMENTAL_DEPOSIT;
purpose = TALER_SIGNATURE_INCREMENTAL_WALLET_DEPOSIT;
else
{
GNUNET_break_op (0);

View File

@ -24,8 +24,6 @@
* @author Christian Grothoff
*
* TODO:
* - when generating /deposit reply, do include signature of mint
* to say that we accepted it (check reply format)
* - when generating /withdraw/status reply, which signature do
* we use there? Might want to instead return *all* signatures on the
* existig withdraw operations, instead of Mint's signature
@ -275,14 +273,36 @@ TALER_MINT_reply_deposit_success (struct MHD_Connection *connection,
const struct GNUNET_CRYPTO_EddsaPublicKey *merchant,
const struct TALER_Amount *amount)
{
// FIXME: return more information here,
// including in particular a signature over
// the deposit data from the mint!
return TALER_MINT_reply_json_pack (connection,
MHD_HTTP_OK,
"{s:s}",
"status",
"DEPOSIT_OK");
struct TALER_DepositConfirmation dc;
struct GNUNET_CRYPTO_EddsaSignature sig;
json_t *sig_json;
int ret;
dc.purpose.purpose = htonl (TALER_SIGNATURE_MINT_DEPOSIT);
dc.purpose.size = htonl (sizeof (struct TALER_DepositConfirmation));
dc.h_contract = *h_contract;
dc.h_wire = *h_wire;
dc.transaction_id = GNUNET_htonll (transaction_id);
dc.amount = TALER_amount_hton (*amount);
dc.coin_pub = *coin_pub;
dc.merchant = *merchant;
if (GNUNET_OK !=
GNUNET_CRYPTO_eddsa_sign (&mint_priv,
&dc.purpose,
&sig))
{
LOG_WARNING ("Failed to create EdDSA signature using my private key\n");
return TALER_MINT_reply_internal_error (connection,
"Failed to EdDSA-sign response\n");
}
sig_json = TALER_JSON_from_sig (&dc.purpose, &sig);
ret = TALER_MINT_reply_json_pack (connection,
MHD_HTTP_OK,
"{s:s, s:o}",
"status", "DEPOSIT_OK",
"signature", sig_json);
json_decref (sig_json);
return ret;
}
@ -356,30 +376,32 @@ TALER_MINT_reply_refresh_melt_success (struct MHD_Connection *connection,
const struct RefreshSession *session,
const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub)
{
json_t *root;
int ret;
json_t *list;
struct GNUNET_HashContext *hash_context;
struct RefreshMeltResponseSignatureBody body;
struct GNUNET_CRYPTO_EddsaSignature sig;
json_t *sig_json;
root = json_object ();
list = json_array ();
json_object_set_new (root, "blind_session_pubs", list);
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);
GNUNET_CRYPTO_hash_context_finish (hash_context,
&body.melt_response_hash);
TALER_MINT_keys_sign (&body.purpose,
&sig);
sig_json = TALER_JSON_from_sig (&body.purpose, &sig);
GNUNET_assert (NULL != sig_json);
json_object_set (root, "signature", sig_json);
return TALER_MINT_reply_json (connection,
root,
MHD_HTTP_OK);
ret = TALER_MINT_reply_json_pack (connection,
MHD_HTTP_OK,
"{s:o, s:o}",
"signature", sig_json,
"blind_session_pubs", list);
json_decref (sig_json);
json_decref (list);
return ret;
}

View File

@ -112,7 +112,8 @@ TALER_JSON_from_sig (const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose,
el = json_integer ((json_int_t) ntohl (purpose->purpose));
json_object_set_new (root, "purpose", el);
el = TALER_JSON_from_data (signature, sizeof (struct GNUNET_CRYPTO_EddsaSignature));
el = TALER_JSON_from_data (signature,
sizeof (struct GNUNET_CRYPTO_EddsaSignature));
json_object_set_new (root, "sig", el);
return root;