aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/include/taler_signatures.h40
-rw-r--r--src/include/taler_util.h19
-rw-r--r--src/mint/mint.h189
-rw-r--r--src/mint/mint_common.c30
-rw-r--r--src/mint/mint_db.c10
-rw-r--r--src/mint/taler-mint-dbinit.c17
-rw-r--r--src/mint/taler-mint-httpd.c2
-rw-r--r--src/mint/taler-mint-httpd_db.c5
-rw-r--r--src/mint/taler-mint-httpd_deposit.c67
-rw-r--r--src/mint/taler-mint-httpd_parsing.c84
-rw-r--r--src/mint/taler-mint-httpd_parsing.h18
-rw-r--r--src/mint/taler-mint-httpd_responses.c20
-rw-r--r--src/mint/taler-mint-httpd_responses.h12
-rw-r--r--src/mint/taler-mint-keycheck.c3
-rw-r--r--src/mint/taler-mint-keyup.c2
-rw-r--r--src/mint/taler-mint-reservemod.c23
-rw-r--r--src/mint/test_mint_deposits.c7
-rw-r--r--src/util/util.c31
18 files changed, 400 insertions, 179 deletions
diff --git a/src/include/taler_signatures.h b/src/include/taler_signatures.h
index 90fa421c3..e72c2ed61 100644
--- a/src/include/taler_signatures.h
+++ b/src/include/taler_signatures.h
@@ -29,6 +29,7 @@
#define TALER_SIGNATURES_H
#include <gnunet/gnunet_util_lib.h>
+#include "taler_util.h"
/**
* Purpose for signing public keys signed
@@ -141,6 +142,45 @@ struct TALER_WithdrawRequest
};
+/**
+ * Format used to generate the signature on a request to deposit
+ * a coin into the account of a merchant.
+ */
+struct TALER_DepositRequest
+{
+ /**
+ * Purpose must be #TALER_SIGNATURE_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;
+
+};
+
/**
* FIXME
diff --git a/src/include/taler_util.h b/src/include/taler_util.h
index 2c5faaa52..ab5ee11df 100644
--- a/src/include/taler_util.h
+++ b/src/include/taler_util.h
@@ -73,14 +73,27 @@ void
TALER_gcrypt_init (void);
+/**
+ * Load configuration by parsing all configuration
+ * files in the given directory.
+ *
+ * @param base_dir directory with the configuration files
+ * @return NULL on error, otherwise configuration
+ */
+struct GNUNET_CONFIGURATION_Handle *
+TALER_config_load (const char *base_dir);
+
+
+
/* *********************** Amount management ****************** */
/**
* Number of characters (plus 1 for 0-termination) we use to
- * represent currency names (i.e. EUR, USD, etc.).
+ * represent currency names (i.e. EUR, USD, etc.). We use
+ * 8 for alignment (!).
*/
-#define TALER_CURRENCY_LEN 4
+#define TALER_CURRENCY_LEN 8
GNUNET_NETWORK_STRUCT_BEGIN
@@ -127,7 +140,7 @@ struct TALER_Amount
/**
* Currency string, left adjusted and padded with zeros.
*/
- char currency[4];
+ char currency[TALER_CURRENCY_LEN];
};
diff --git a/src/mint/mint.h b/src/mint/mint.h
index 05e966e1c..0a0e00d04 100644
--- a/src/mint/mint.h
+++ b/src/mint/mint.h
@@ -35,6 +35,11 @@
#define DIR_SIGNKEYS "signkeys"
#define DIR_DENOMKEYS "denomkeys"
+/**
+ * For now, we just do EUR. Should become configurable
+ * in the future!
+ */
+#define MINT_CURRENCY "EUR"
/**
* On disk format used for a mint signing key.
@@ -63,7 +68,9 @@ struct TALER_MINT_DenomKeyIssuePriv
/**
- * Public information about a coin.
+ * Public information about a coin (including the public key
+ * of the coin, the denomination key and the signature with
+ * the denomination key).
*/
struct TALER_CoinPublicInfo
{
@@ -119,6 +126,92 @@ struct CollectableBlindcoin
/**
+ * Specification for a /deposit operation.
+ */
+struct Deposit
+{
+ /**
+ * Information about the coin that is being deposited.
+ */
+ struct TALER_CoinPublicInfo coin;
+
+ /**
+ * ECDSA signature affirming that the customer intends
+ * this coin to be deposited at the merchant identified
+ * by @e h_wire in relation to the contract identified
+ * by @e h_contract.
+ */
+ struct GNUNET_CRYPTO_EcdsaSignature csig;
+
+ /**
+ * Public key of the merchant. Enables later identification
+ * of the merchant in case of a need to rollback transactions.
+ */
+ struct GNUNET_CRYPTO_EddsaPublicKey merchant_pub;
+
+ /**
+ * Hash over the contract between merchant and customer
+ * (remains unknown to the Mint).
+ */
+ struct GNUNET_HashCode h_contract;
+
+ /**
+ * Hash of the (canonical) representation of @e wire, used
+ * to check the signature on the request. Generated by
+ * the mint from the detailed wire data provided by the
+ * merchant.
+ */
+ struct GNUNET_HashCode h_wire;
+
+ /**
+ * Detailed wire information for executing the transaction.
+ */
+ const json_t *wire;
+
+ /**
+ * Merchant-generated transaction ID to detect duplicate
+ * transactions.
+ */
+ uint64_t transaction_id;
+
+ /**
+ * Fraction of the coin's remaining value to be deposited.
+ * The coin is identified by @e coin_pub.
+ */
+ struct TALER_Amount amount;
+
+ /**
+ * Type of the deposit (also purpose of the signature). Either
+ * #TALER_SIGNATURE_DEPOSIT or #TALER_SIGNATURE_INCREMENTAL_DEPOSIT.
+ */
+ uint32_t purpose; // FIXME: bad type, use ENUM!
+
+
+};
+
+
+
+/**
+ * FIXME
+ */
+struct KnownCoin
+{
+ struct TALER_CoinPublicInfo public_info;
+
+ /**
+ * Refreshing session, only valid if
+ * is_refreshed==1.
+ */
+ struct GNUNET_CRYPTO_EddsaPublicKey refresh_session_pub;
+
+ struct TALER_Amount expended_balance;
+
+ int is_refreshed;
+
+};
+
+
+/**
* Global information for a refreshing session.
*/
struct RefreshSession
@@ -168,6 +261,9 @@ struct RefreshSession
};
+
+
+
/**
* For each (old) coin being melted, we have a `struct
* RefreshCommitLink` that allows the user to find the shared secret
@@ -214,89 +310,8 @@ struct RefreshCommitCoin
};
-/**
- * FIXME
- */
-struct KnownCoin
-{
- struct TALER_CoinPublicInfo public_info;
-
- /**
- * Refreshing session, only valid if
- * is_refreshed==1.
- */
- struct GNUNET_CRYPTO_EddsaPublicKey refresh_session_pub;
-
- struct TALER_Amount expended_balance;
- int is_refreshed;
-};
-
-
-/**
- * Specification for a /deposit operation.
- */
-struct Deposit
-{
- /**
- * Information about the coin that is being deposited.
- */
- struct TALER_CoinPublicInfo coin;
-
- /**
- * EdDSA signature affirming that the customer intends
- * this coin to be deposited at the merchant identified
- * by @e h_wire in relation to the contract identified
- * by @e h_contract.
- */
- struct GNUNET_CRYPTO_EddsaSignature csig;
-
- /**
- * Public key of the merchant. Enables later identification
- * of the merchant in case of a need to rollback transactions.
- */
- struct GNUNET_CRYPTO_EddsaPublicKey merchant_pub;
-
- /**
- * Hash over the contract between merchant and customer
- * (remains unknown to the Mint).
- */
- struct GNUNET_HashCode h_contract;
-
- /**
- * Hash of the (canonical) representation of @e wire, used
- * to check the signature on the request. Generated by
- * the mint from the detailed wire data provided by the
- * merchant.
- */
- struct GNUNET_HashCode h_wire;
-
- /**
- * Detailed wire information for executing the transaction.
- */
- const json_t *wire;
-
- /**
- * Merchant-generated transaction ID to detect duplicate
- * transactions.
- */
- uint64_t transaction_id;
-
- /**
- * Fraction of the coin's remaining value to be deposited.
- * The coin is identified by @e coin_pub.
- */
- struct TALER_AmountNBO amount;
-
- /**
- * Type of the deposit (also purpose of the signature). Either
- * #TALER_SIGNATURE_DEPOSIT or #TALER_SIGNATURE_INCREMENTAL_DEPOSIT.
- */
- uint32_t purpose; // FIXME: bad type, use ENUM!
-
-
-};
/**
@@ -412,16 +427,6 @@ TALER_MINT_read_denom_key (const char *filename,
struct TALER_MINT_DenomKeyIssuePriv *dki);
-/**
- * Load the configuration for the mint in the given
- * directory.
- *
- * @param mint_base_dir the mint's base directory
- * @return the mint configuratin, or NULL on error
- */
-struct GNUNET_CONFIGURATION_Handle *
-TALER_MINT_config_load (const char *mint_base_dir);
-
int
TALER_TALER_DB_extract_amount (PGresult *result,
diff --git a/src/mint/mint_common.c b/src/mint/mint_common.c
index bb55f30c4..f0ee09110 100644
--- a/src/mint/mint_common.c
+++ b/src/mint/mint_common.c
@@ -231,27 +231,11 @@ TALER_MINT_denomkeys_iterate (const char *mint_base_dir,
}
-struct GNUNET_CONFIGURATION_Handle *
-TALER_MINT_config_load (const char *mint_base_dir)
-{
- struct GNUNET_CONFIGURATION_Handle *cfg;
- char *cfg_dir;
- int res;
-
- res = GNUNET_asprintf (&cfg_dir, "%s" DIR_SEPARATOR_STR "config", mint_base_dir);
- GNUNET_assert (res > 0);
-
- cfg = GNUNET_CONFIGURATION_create ();
- res = GNUNET_CONFIGURATION_load_from (cfg, cfg_dir);
- GNUNET_free (cfg_dir);
- if (GNUNET_OK != res)
- return NULL;
- return cfg;
-}
-
int
-TALER_TALER_DB_extract_amount_nbo (PGresult *result, unsigned int row,
- int indices[3], struct TALER_AmountNBO *denom_nbo)
+TALER_TALER_DB_extract_amount_nbo (PGresult *result,
+ unsigned int row,
+ int indices[3],
+ struct TALER_AmountNBO *denom_nbo)
{
if ((indices[0] < 0) || (indices[1] < 0) || (indices[2] < 0))
return GNUNET_NO;
@@ -270,8 +254,10 @@ TALER_TALER_DB_extract_amount_nbo (PGresult *result, unsigned int row,
int
-TALER_TALER_DB_extract_amount (PGresult *result, unsigned int row,
- int indices[3], struct TALER_Amount *denom)
+TALER_TALER_DB_extract_amount (PGresult *result,
+ unsigned int row,
+ int indices[3],
+ struct TALER_Amount *denom)
{
struct TALER_AmountNBO denom_nbo;
int res;
diff --git a/src/mint/mint_db.c b/src/mint/mint_db.c
index 4c836bf92..c07490805 100644
--- a/src/mint/mint_db.c
+++ b/src/mint/mint_db.c
@@ -1925,11 +1925,11 @@ TALER_MINT_DB_get_deposit (PGconn *db_conn,
EXITIF (GNUNET_OK !=
TALER_DB_extract_result (result, rs, 0));
EXITIF (GNUNET_OK !=
- TALER_DB_extract_amount_nbo (result, 0,
- "amount_value",
- "amount_fraction",
- "amount_currency",
- &deposit->amount));
+ TALER_DB_extract_amount (result, 0,
+ "amount_value",
+ "amount_fraction",
+ "amount_currency",
+ &deposit->amount));
deposit->coin.denom_sig
= GNUNET_CRYPTO_rsa_signature_decode (denom_sig_buf,
denom_sig_buf_size);
diff --git a/src/mint/taler-mint-dbinit.c b/src/mint/taler-mint-dbinit.c
index d877f62c6..3d080b523 100644
--- a/src/mint/taler-mint-dbinit.c
+++ b/src/mint/taler-mint-dbinit.c
@@ -95,7 +95,7 @@ TALER_MINT_init_withdraw_tables (PGconn *conn)
}
PQclear (result);
- result = PQexec (conn,
+ result = PQexec (conn,
"CREATE TABLE IF NOT EXISTS refresh_sessions "
"("
" session_pub BYTEA PRIMARY KEY CHECK (length(session_pub) = 32)"
@@ -113,7 +113,7 @@ TALER_MINT_init_withdraw_tables (PGconn *conn)
}
PQclear (result);
- result = PQexec (conn,
+ result = PQexec (conn,
"CREATE TABLE IF NOT EXISTS refresh_order "
"( "
" session_pub BYTEA NOT NULL REFERENCES refresh_sessions (session_pub)"
@@ -130,7 +130,7 @@ TALER_MINT_init_withdraw_tables (PGconn *conn)
PQclear (result);
- result = PQexec (conn,
+ result = PQexec (conn,
"CREATE TABLE IF NOT EXISTS refresh_commit_link"
"("
" session_pub BYTEA NOT NULL REFERENCES refresh_sessions (session_pub)"
@@ -150,7 +150,7 @@ TALER_MINT_init_withdraw_tables (PGconn *conn)
}
PQclear (result);
- result = PQexec (conn,
+ result = PQexec (conn,
"CREATE TABLE IF NOT EXISTS refresh_commit_coin"
"("
" session_pub BYTEA NOT NULL REFERENCES refresh_sessions (session_pub) "
@@ -169,7 +169,7 @@ TALER_MINT_init_withdraw_tables (PGconn *conn)
}
PQclear (result);
- result = PQexec (conn,
+ result = PQexec (conn,
"CREATE TABLE IF NOT EXISTS refresh_melt"
"("
" session_pub BYTEA NOT NULL REFERENCES refresh_sessions (session_pub) "
@@ -185,7 +185,7 @@ TALER_MINT_init_withdraw_tables (PGconn *conn)
}
PQclear (result);
- result = PQexec (conn,
+ result = PQexec (conn,
"CREATE TABLE IF NOT EXISTS refresh_collectable"
"("
" session_pub BYTEA NOT NULL REFERENCES refresh_sessions (session_pub) "
@@ -245,7 +245,7 @@ main (int argc, char *const *argv)
GNUNET_GETOPT_OPTION_END
};
- if (GNUNET_GETOPT_run ("taler-mint-serve", options, argc, argv) < 0)
+ if (GNUNET_GETOPT_run ("taler-mint-serve", options, argc, argv) < 0)
return 1;
GNUNET_assert (GNUNET_OK == GNUNET_log_setup ("taler-mint-dbinit", "INFO", NULL));
@@ -256,7 +256,7 @@ main (int argc, char *const *argv)
return 1;
}
- cfg = TALER_MINT_config_load (mint_base_dir);
+ cfg = TALER_config_load (mint_base_dir);
if (NULL == cfg)
{
fprintf (stderr, "Can't load mint configuration.\n");
@@ -282,4 +282,3 @@ main (int argc, char *const *argv)
return 0;
}
-
diff --git a/src/mint/taler-mint-httpd.c b/src/mint/taler-mint-httpd.c
index ffd97a1ad..cde603168 100644
--- a/src/mint/taler-mint-httpd.c
+++ b/src/mint/taler-mint-httpd.c
@@ -233,7 +233,7 @@ mint_serve_process_config (const char *mint_directory)
char *master_pub_str;
char *db_cfg;
- cfg = TALER_MINT_config_load (mint_directory);
+ cfg = TALER_config_load (mint_directory);
if (NULL == cfg)
{
fprintf (stderr,
diff --git a/src/mint/taler-mint-httpd_db.c b/src/mint/taler-mint-httpd_db.c
index fcc6d915f..49c359a89 100644
--- a/src/mint/taler-mint-httpd_db.c
+++ b/src/mint/taler-mint-httpd_db.c
@@ -117,7 +117,7 @@ TALER_MINT_db_execute_deposit (struct MHD_Connection *connection,
/* coin valid but not known => insert into DB */
known_coin.is_refreshed = GNUNET_NO;
- known_coin.expended_balance = TALER_amount_ntoh (deposit->amount);
+ known_coin.expended_balance = deposit->amount;
known_coin.public_info = coin_info;
if (GNUNET_OK != TALER_MINT_DB_insert_known_coin (db_conn, &known_coin))
@@ -419,8 +419,7 @@ mint_amount_native_zero ()
struct TALER_Amount amount;
memset (&amount, 0, sizeof (amount));
- // FIXME: load from config
- memcpy (amount.currency, "EUR", 3);
+ memcpy (amount.currency, MINT_CURRENCY, strlen (MINT_CURRENCY) + 1);
return amount;
}
diff --git a/src/mint/taler-mint-httpd_deposit.c b/src/mint/taler-mint-httpd_deposit.c
index ed0eca8bb..ee9f76d5d 100644
--- a/src/mint/taler-mint-httpd_deposit.c
+++ b/src/mint/taler-mint-httpd_deposit.c
@@ -23,9 +23,8 @@
* @author Christian Grothoff
*
* TODO:
- * - actually verify coin signature
- * - revisit `struct Deposit` parsing once the struct
- * has been finalized
+ * - missing 'wire' format check (well-formed SEPA-details)
+ * - ugliy if-construction for deposit type
*/
#include "platform.h"
#include <gnunet/gnunet_util_lib.h>
@@ -59,19 +58,25 @@ verify_and_execute_deposit (struct MHD_Connection *connection,
const struct Deposit *deposit)
{
struct MintKeyState *key_state;
+ struct TALER_DepositRequest dr;
- /* FIXME: verify coin signature! */
- /*
- if (GNUNET_OK != GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_DEPOSIT,
- &deposit->purpose,
- &deposit->coin_sig,
- &deposit->coin_pub))
+ dr.purpose.purpose = htonl (TALER_SIGNATURE_DEPOSIT);
+ dr.purpose.size = htonl (sizeof (struct TALER_DepositRequest));
+ dr.h_contract = deposit->h_contract;
+ dr.h_wire = deposit->h_wire;
+ dr.transaction_id = GNUNET_htonll (deposit->transaction_id);
+ dr.amount = TALER_amount_hton (deposit->amount);
+ dr.coin_pub = deposit->coin.coin_pub;
+ if (GNUNET_OK !=
+ GNUNET_CRYPTO_ecdsa_verify (TALER_SIGNATURE_DEPOSIT,
+ &dr.purpose,
+ &deposit->csig,
+ &deposit->coin.coin_pub))
{
- resp = json_pack ("{s:s}", "error", "Signature verfication failed");
+ LOG_WARNING ("Invalid signature on /deposit request\n");
return TALER_MINT_reply_arg_invalid (connection,
"csig");
}
- */
key_state = TALER_MINT_key_state_acquire ();
if (GNUNET_YES !=
@@ -80,10 +85,7 @@ verify_and_execute_deposit (struct MHD_Connection *connection,
{
LOG_WARNING ("Invalid coin passed for /deposit\n");
TALER_MINT_key_state_release (key_state);
- return TALER_MINT_reply_json_pack (connection,
- MHD_HTTP_NOT_FOUND,
- "{s:s}",
- "error", "Coin is not valid");
+ return TALER_MINT_reply_coin_invalid (connection);
}
TALER_MINT_key_state_release (key_state);
@@ -101,6 +103,7 @@ verify_and_execute_deposit (struct MHD_Connection *connection,
* @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 amount how much should be deposited
* @param wire json describing the wire details (?)
* @return MHD result code
*/
@@ -108,6 +111,7 @@ static int
parse_and_handle_deposit_request (struct MHD_Connection *connection,
const json_t *root,
uint32_t purpose,
+ const struct TALER_Amount *amount,
const json_t *wire)
{
int res;
@@ -155,6 +159,7 @@ parse_and_handle_deposit_request (struct MHD_Connection *connection,
return TALER_MINT_reply_arg_invalid (connection,
"denom_pub");
}
+ /* FIXME: check that "wire" is formatted correctly */
if (NULL == (wire_enc = json_dumps (wire, JSON_COMPACT | JSON_SORT_KEYS)))
{
GNUNET_CRYPTO_rsa_public_key_free (deposit.coin.denom_pub);
@@ -172,9 +177,7 @@ parse_and_handle_deposit_request (struct MHD_Connection *connection,
deposit.wire = wire;
deposit.purpose = purpose;
-
- // FIXME: deposit.amount not initialized!
-
+ deposit.amount = *amount;
res = verify_and_execute_deposit (connection,
&deposit);
GNUNET_CRYPTO_rsa_public_key_free (deposit.coin.denom_pub);
@@ -212,6 +215,8 @@ TALER_MINT_handler_deposit (struct RequestHandler *rh,
const char *deposit_type;
int res;
uint32_t purpose;
+ struct TALER_Amount amount;
+ json_t *f;
res = TALER_MINT_parse_post_json (connection,
connection_cls,
@@ -223,16 +228,35 @@ TALER_MINT_handler_deposit (struct RequestHandler *rh,
if ( (GNUNET_NO == res) || (NULL == json) )
return MHD_YES;
if (-1 == json_unpack (json,
- "{s:s, s:o}",
+ "{s:s, s:o, f:o}",
"type", &deposit_type,
- "wire", &wire))
+ "wire", &wire,
+ "f", &f))
{
GNUNET_break_op (0);
+ json_decref (json);
return TALER_MINT_reply_json_pack (connection,
MHD_HTTP_BAD_REQUEST,
"{s:s}",
"error", "Bad format");
}
+ res = TALER_MINT_parse_amount_json (connection,
+ f,
+ &amount);
+ json_decref (f);
+ if (GNUNET_SYSERR == res)
+ {
+ json_decref (wire);
+ json_decref (json);
+ return MHD_NO;
+ }
+ if (GNUNET_NO == res)
+ {
+ json_decref (wire);
+ json_decref (json);
+ return MHD_YES;
+ }
+ /* FIXME: use array search and enum, this is ugly */
if (0 == strcmp ("DIRECT_DEPOSIT", deposit_type))
purpose = TALER_SIGNATURE_DEPOSIT;
else if (0 == strcmp ("INCREMENTAL_DEPOSIT", deposit_type))
@@ -241,6 +265,7 @@ TALER_MINT_handler_deposit (struct RequestHandler *rh,
{
GNUNET_break_op (0);
json_decref (wire);
+ json_decref (json);
return TALER_MINT_reply_json_pack (connection,
MHD_HTTP_BAD_REQUEST,
"{s:s}",
@@ -249,8 +274,10 @@ TALER_MINT_handler_deposit (struct RequestHandler *rh,
res = parse_and_handle_deposit_request (connection,
json,
purpose,
+ &amount,
wire);
json_decref (wire);
+ json_decref (json);
return res;
}
diff --git a/src/mint/taler-mint-httpd_parsing.c b/src/mint/taler-mint-httpd_parsing.c
index c4e28bba7..066f18913 100644
--- a/src/mint/taler-mint-httpd_parsing.c
+++ b/src/mint/taler-mint-httpd_parsing.c
@@ -110,8 +110,8 @@ buffer_deinit (struct Buffer *buf)
* @param data the data to append
* @param size the size of @a data
* @param max_size maximum size that the buffer can grow to
- * @return GNUNET_OK on success,
- * GNUNET_NO if the buffer can't accomodate for the new data
+ * @return #GNUNET_OK on success,
+ * #GNUNET_NO if the buffer can't accomodate for the new data
*/
static int
buffer_append (struct Buffer *buf,
@@ -153,14 +153,14 @@ buffer_append (struct Buffer *buf,
* @param upload_data the POST data
* @param upload_data_size number of bytes in @a upload_data
* @param json the JSON object for a completed request
- * @returns
- * GNUNET_YES if json object was parsed or at least
+ * @return
+ * #GNUNET_YES if json object was parsed or at least
* may be parsed in the future (call again);
* `*json` will be NULL if we need to be called again,
* and non-NULL if we are done.
- * GNUNET_NO is request incomplete or invalid
+ * #GNUNET_NO is request incomplete or invalid
* (error message was generated)
- * GNUNET_SYSERR on internal error
+ * #GNUNET_SYSERR on internal error
* (we could not even queue an error message,
* close HTTP session with MHD_NO)
*/
@@ -606,6 +606,78 @@ TALER_MINT_release_parsed_data (struct GNUNET_MINT_ParseFieldSpec *spec)
/**
+ * Parse amount specified in JSON format.
+ *
+ * @param connection the MHD connection (to report errors)
+ * @param f json specification of the amount
+ * @param amount[OUT] set to the amount specified in @a f
+ * @return
+ * #GNUNET_YES if parsing was successful
+ * #GNUNET_NO if json is malformed, error response was generated
+ * #GNUNET_SYSERR on internal error, error response was not generated
+ */
+int
+TALER_MINT_parse_amount_json (struct MHD_Connection *connection,
+ json_t *f,
+ struct TALER_Amount *amount)
+{
+ json_int_t value;
+ json_int_t fraction;
+ const char *currency;
+ struct TALER_Amount a;
+
+ if (-1 == json_unpack (f,
+ "{s:I, s:I, s:s}",
+ "value", &value,
+ "fraction", &fraction,
+ "currency", &currency))
+ {
+ LOG_WARNING ("Failed to parse JSON amount specification\n");
+ if (MHD_YES !=
+ TALER_MINT_reply_json_pack (connection,
+ MHD_HTTP_BAD_REQUEST,
+ "{s:s}",
+ "error", "Bad format"))
+ return GNUNET_SYSERR;
+ return GNUNET_NO;
+ }
+ if ( (value < 0) ||
+ (fraction < 0) ||
+ (value > UINT32_MAX) ||
+ (fraction > UINT32_MAX) )
+ {
+ LOG_WARNING ("Amount specified not in allowed range\n");
+ if (MHD_YES !=
+ TALER_MINT_reply_json_pack (connection,
+ MHD_HTTP_BAD_REQUEST,
+ "{s:s}",
+ "error", "Amount outside of allowed range"))
+ return GNUNET_SYSERR;
+ return GNUNET_NO;
+ }
+ if (0 != strcmp (currency,
+ MINT_CURRENCY))
+ {
+ LOG_WARNING ("Currency specified not supported by this mint\n");
+ if (MHD_YES !=
+ TALER_MINT_reply_json_pack (connection,
+ MHD_HTTP_BAD_REQUEST,
+ "{s:s, s:s}",
+ "error", "Currency not supported",
+ "currency", currency))
+ return GNUNET_SYSERR;
+ return GNUNET_NO;
+ }
+ a.value = (uint32_t) value;
+ a.fraction = (uint32_t) fraction;
+ GNUNET_assert (strlen (MINT_CURRENCY) < TALER_CURRENCY_LEN);
+ strcpy (a.currency, MINT_CURRENCY);
+ *amount = TALER_amount_normalize (a);
+ return GNUNET_OK;
+}
+
+
+/**
* Extract base32crockford encoded data from request.
*
* Queues an error response to the connection if the parameter is missing or
diff --git a/src/mint/taler-mint-httpd_parsing.h b/src/mint/taler-mint-httpd_parsing.h
index 9c4d8aafe..1c13c9469 100644
--- a/src/mint/taler-mint-httpd_parsing.h
+++ b/src/mint/taler-mint-httpd_parsing.h
@@ -25,6 +25,7 @@
#include <microhttpd.h>
#include <jansson.h>
+#include "taler_util.h"
/**
@@ -216,6 +217,23 @@ TALER_MINT_release_parsed_data (struct GNUNET_MINT_ParseFieldSpec *spec);
/**
+ * Parse amount specified in JSON format.
+ *
+ * @param connection the MHD connection (to report errors)
+ * @param f json specification of the amount
+ * @param amount[OUT] set to the amount specified in @a f
+ * @return
+ * #GNUNET_YES if parsing was successful
+ * #GNUNET_NO if json is malformed, error response was generated
+ * #GNUNET_SYSERR on internal error, error response was not generated
+ */
+int
+TALER_MINT_parse_amount_json (struct MHD_Connection *connection,
+ json_t *f,
+ struct TALER_Amount *amount);
+
+
+/**
* Extraxt fixed-size base32crockford encoded data from request.
*
* Queues an error response to the connection if the parameter is missing or
diff --git a/src/mint/taler-mint-httpd_responses.c b/src/mint/taler-mint-httpd_responses.c
index 12d4bced7..432772d79 100644
--- a/src/mint/taler-mint-httpd_responses.c
+++ b/src/mint/taler-mint-httpd_responses.c
@@ -125,6 +125,26 @@ TALER_MINT_reply_arg_invalid (struct MHD_Connection *connection,
/**
+ * Send a response indicating an invalid coin. (I.e. the signature
+ * over the public key of the coin does not match a valid signing key
+ * of this mint).
+ *
+ * @param connection the MHD connection to use
+ * @return MHD result code
+ */
+int
+TALER_MINT_reply_coin_invalid (struct MHD_Connection *connection)
+{
+ /* TODO: may want to be more precise in the future and
+ distinguish bogus signatures from bogus public keys. */
+ return TALER_MINT_reply_json_pack (connection,
+ MHD_HTTP_NOT_FOUND,
+ "{s:s}",
+ "error", "Coin is not valid");
+}
+
+
+/**
* Send a response indicating a missing argument.
*
* @param connection the MHD connection to use
diff --git a/src/mint/taler-mint-httpd_responses.h b/src/mint/taler-mint-httpd_responses.h
index 51abd9fb4..471d73bd1 100644
--- a/src/mint/taler-mint-httpd_responses.h
+++ b/src/mint/taler-mint-httpd_responses.h
@@ -78,6 +78,18 @@ TALER_MINT_reply_arg_invalid (struct MHD_Connection *connection,
/**
+ * Send a response indicating an invalid coin. (I.e. the signature
+ * over the public key of the coin does not match a valid signing key
+ * of this mint).
+ *
+ * @param connection the MHD connection to use
+ * @return MHD result code
+ */
+int
+TALER_MINT_reply_coin_invalid (struct MHD_Connection *connection);
+
+
+/**
* Send a response indicating a missing argument.
*
* @param connection the MHD connection to use
diff --git a/src/mint/taler-mint-keycheck.c b/src/mint/taler-mint-keycheck.c
index 419baf501..09f59ab2f 100644
--- a/src/mint/taler-mint-keycheck.c
+++ b/src/mint/taler-mint-keycheck.c
@@ -162,7 +162,7 @@ main (int argc, char *const *argv)
return 1;
}
- kcfg = TALER_MINT_config_load (mintdir);
+ kcfg = TALER_config_load (mintdir);
if (NULL == kcfg)
{
fprintf (stderr, "can't load mint configuration\n");
@@ -172,4 +172,3 @@ main (int argc, char *const *argv)
return 1;
return 0;
}
-
diff --git a/src/mint/taler-mint-keyup.c b/src/mint/taler-mint-keyup.c
index 7c35317ce..f8670eb97 100644
--- a/src/mint/taler-mint-keyup.c
+++ b/src/mint/taler-mint-keyup.c
@@ -621,7 +621,7 @@ main (int argc, char *const *argv)
}
ROUND_TO_SECS (now, abs_value_us);
- kcfg = TALER_MINT_config_load (mintdir);
+ kcfg = TALER_config_load (mintdir);
if (NULL == kcfg)
{
fprintf (stderr, "can't load mint configuration\n");
diff --git a/src/mint/taler-mint-reservemod.c b/src/mint/taler-mint-reservemod.c
index 3dd94f84b..48a9c88b4 100644
--- a/src/mint/taler-mint-reservemod.c
+++ b/src/mint/taler-mint-reservemod.c
@@ -38,7 +38,7 @@ static PGconn *db_conn;
/**
* Create a new or add to existing reserve.
* Fails if currencies do not match.
- *
+ *
* @param denom denomination to add
*
* @return ...
@@ -72,7 +72,7 @@ reservemod_add (struct TALER_Amount denom)
reserve_pub,
&value,
&fraction,
- denom.currency,
+ denom.currency,
&exnbo};
int param_lengths[] = {32, 4, 4, strlen(denom.currency), 8};
int param_formats[] = {1, 1, 1, 1, 1};
@@ -81,14 +81,14 @@ reservemod_add (struct TALER_Amount denom)
" expiration_date )"
"values ($1,$2,$3,$4,$5);",
5, NULL, (const char **) param_values, param_lengths, param_formats, 1);
-
+
if (PGRES_COMMAND_OK != PQresultStatus (result))
{
fprintf (stderr, "Insert failed: %s\n", PQresultErrorMessage (result));
return GNUNET_SYSERR;
}
- }
- else
+ }
+ else
{
struct TALER_Amount old_denom;
struct TALER_Amount new_denom;
@@ -125,8 +125,8 @@ reservemod_add (struct TALER_Amount denom)
return GNUNET_SYSERR;
}
- }
- return GNUNET_OK;
+ }
+ return GNUNET_OK;
}
@@ -159,18 +159,18 @@ main (int argc, char *const *argv)
GNUNET_assert (GNUNET_OK == GNUNET_log_setup ("taler-mint-keycheck", "WARNING", NULL));
- if (GNUNET_GETOPT_run ("taler-mint-keyup", options, argc, argv) < 0)
+ if (GNUNET_GETOPT_run ("taler-mint-keyup", options, argc, argv) < 0)
return 1;
if (NULL == mintdir)
{
- fprintf (stderr, "mint directory not given\n");
+ fprintf (stderr, "mint directory not given\n");
return 1;
}
reserve_pub = GNUNET_new (struct GNUNET_CRYPTO_EddsaPublicKey);
if ((NULL == reserve_pub_str) ||
(GNUNET_OK != GNUNET_STRINGS_string_to_data (reserve_pub_str,
- strlen (reserve_pub_str),
+ strlen (reserve_pub_str),
reserve_pub,
sizeof (struct GNUNET_CRYPTO_EddsaPublicKey))))
{
@@ -178,7 +178,7 @@ main (int argc, char *const *argv)
return 1;
}
- kcfg = TALER_MINT_config_load (mintdir);
+ kcfg = TALER_config_load (mintdir);
if (NULL == kcfg)
{
fprintf (stderr, "can't load mint configuration\n");
@@ -212,4 +212,3 @@ main (int argc, char *const *argv)
}
return 0;
}
-
diff --git a/src/mint/test_mint_deposits.c b/src/mint/test_mint_deposits.c
index 776bc15d2..00664cbbf 100644
--- a/src/mint/test_mint_deposits.c
+++ b/src/mint/test_mint_deposits.c
@@ -104,9 +104,12 @@ run (void *cls, char *const *args, const char *cfgfile,
htonl (GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, UINT32_MAX));
deposit->amount.fraction =
htonl (GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, UINT32_MAX));
- strcpy (deposit->amount.currency, "EUR");
+ GNUNET_assert (strlen (MINT_CURRENCY) < sizeof (deposit->amount.currency));
+ strcpy (deposit->amount.currency, MINT_CURRENCY);
/* Copy wireformat */
- (void) memcpy (deposit->wire, wire, sizeof (wire));
+ memcpy (deposit->wire,
+ wire,
+ sizeof (wire));
EXITIF (GNUNET_OK != TALER_MINT_DB_insert_deposit (conn,
deposit));
EXITIF (GNUNET_OK != TALER_MINT_DB_get_deposit (conn,
diff --git a/src/util/util.c b/src/util/util.c
index 440b49fab..de085d088 100644
--- a/src/util/util.c
+++ b/src/util/util.c
@@ -16,7 +16,7 @@
/**
* @file util.c
- * @brief Common utility functions
+ * @brief Common utility functions; we might choose to move those to GNUnet at some point
* @author Sree Harsha Totakura <sreeharsha@totakura.in>
* @author Florian Dold
* @author Benedikt Mueller
@@ -60,4 +60,33 @@ TALER_data_to_string_alloc (const void *buf, size_t size)
}
+/**
+ * Load configuration by parsing all configuration
+ * files in the given directory.
+ *
+ * @param base_dir directory with the configuration files
+ * @return NULL on error, otherwise configuration
+ */
+struct GNUNET_CONFIGURATION_Handle *
+TALER_config_load (const char *base_dir)
+{
+ struct GNUNET_CONFIGURATION_Handle *cfg;
+ char *cfg_dir;
+ int res;
+
+ res = GNUNET_asprintf (&cfg_dir,
+ "%s" DIR_SEPARATOR_STR "config",
+ base_dir);
+ GNUNET_assert (res > 0);
+ cfg = GNUNET_CONFIGURATION_create ();
+ res = GNUNET_CONFIGURATION_load_from (cfg, cfg_dir);
+ GNUNET_free (cfg_dir);
+ if (GNUNET_OK != res)
+ return NULL;
+ return cfg;
+}
+
+
+
+
/* end of util.c */