aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2015-01-28 19:48:41 +0100
committerChristian Grothoff <christian@grothoff.org>2015-01-28 19:48:41 +0100
commit2e0e30291c4e490389f85bbd4973374f0adf22f4 (patch)
tree8d5f306cb967e7e7ab137b133206c7414bbb6f35
parente19f1906a3363f0f49553d35d95429c92bec29d4 (diff)
sign /deposit reply so that merchant has proof that mint accepted it
-rw-r--r--src/include/taler_signatures.h57
-rw-r--r--src/mint/taler-mint-httpd.c30
-rw-r--r--src/mint/taler-mint-httpd.h5
-rw-r--r--src/mint/taler-mint-httpd_deposit.c12
-rw-r--r--src/mint/taler-mint-httpd_responses.c60
-rw-r--r--src/util/json.c3
6 files changed, 137 insertions, 30 deletions
diff --git a/src/include/taler_signatures.h b/src/include/taler_signatures.h
index e72c2ed61..84968582e 100644
--- a/src/include/taler_signatures.h
+++ b/src/include/taler_signatures.h
@@ -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;
@@ -183,6 +189,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
*/
struct TALER_MINT_SignKeyIssue
diff --git a/src/mint/taler-mint-httpd.c b/src/mint/taler-mint-httpd.c
index cde603168..fb5ce4405 100644
--- a/src/mint/taler-mint-httpd.c
+++ b/src/mint/taler-mint-httpd.c
@@ -56,6 +56,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.
*/
static struct MHD_Daemon *mydaemon;
@@ -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,
diff --git a/src/mint/taler-mint-httpd.h b/src/mint/taler-mint-httpd.h
index cff2859db..ed56b048d 100644
--- a/src/mint/taler-mint-httpd.h
+++ b/src/mint/taler-mint-httpd.h
@@ -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.
diff --git a/src/mint/taler-mint-httpd_deposit.c b/src/mint/taler-mint-httpd_deposit.c
index ee9f76d5d..0bd1134a6 100644
--- a/src/mint/taler-mint-httpd_deposit.c
+++ b/src/mint/taler-mint-httpd_deposit.c
@@ -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);
diff --git a/src/mint/taler-mint-httpd_responses.c b/src/mint/taler-mint-httpd_responses.c
index 8a0d7e797..58addf98d 100644
--- a/src/mint/taler-mint-httpd_responses.c
+++ b/src/mint/taler-mint-httpd_responses.c
@@ -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;
}
diff --git a/src/util/json.c b/src/util/json.c
index d66c95c43..120e1be5c 100644
--- a/src/util/json.c
+++ b/src/util/json.c
@@ -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;