sign /deposit reply so that merchant has proof that mint accepted it
This commit is contained in:
parent
e19f1906a3
commit
2e0e30291c
@ -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
|
||||
*/
|
||||
|
@ -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,
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user