aboutsummaryrefslogtreecommitdiff
path: root/src/mint/taler-mint-httpd_withdraw.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mint/taler-mint-httpd_withdraw.c')
-rw-r--r--src/mint/taler-mint-httpd_withdraw.c337
1 files changed, 36 insertions, 301 deletions
diff --git a/src/mint/taler-mint-httpd_withdraw.c b/src/mint/taler-mint-httpd_withdraw.c
index cc0de7f6f..5259c7fbf 100644
--- a/src/mint/taler-mint-httpd_withdraw.c
+++ b/src/mint/taler-mint-httpd_withdraw.c
@@ -19,6 +19,9 @@
* @author Florian Dold
* @author Benedikt Mueller
* @author Christian Grothoff
+ *
+ * TODO:
+ * - support variable-size RSA keys
*/
#include "platform.h"
#include <gnunet/gnunet_util_lib.h>
@@ -33,63 +36,13 @@
#include "taler_json_lib.h"
#include "taler-mint-httpd_parsing.h"
#include "taler-mint-httpd_keys.h"
+#include "taler-mint-httpd_db.h"
#include "taler-mint-httpd_mhd.h"
#include "taler-mint-httpd_withdraw.h"
#include "taler-mint-httpd_responses.h"
/**
- * Convert a signature (with purpose) to
- * a JSON object representation.
- *
- * @param purpose purpose of the signature
- * @param signature the signature
- * @return the JSON reporesentation of the signature with purpose
- */
-static json_t *
-sig_to_json (const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose,
- const struct GNUNET_CRYPTO_EddsaSignature *signature)
-{
- json_t *root;
- json_t *el;
-
- root = json_object ();
-
- el = json_integer ((json_int_t) ntohl (purpose->size));
- json_object_set_new (root, "size", el);
-
- 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));
- json_object_set_new (root, "sig", el);
-
- return root;
-}
-
-
-/**
- * Sign a reserve's status with the current signing key.
- *
- * @param reserve the reserve to sign
- * @param key_state the key state containing the current
- * signing private key
- */
-static void
-sign_reserve (struct Reserve *reserve,
- struct MintKeyState *key_state)
-{
- reserve->status_sign_pub = key_state->current_sign_key_issue.issue.signkey_pub;
- reserve->status_sig_purpose.purpose = htonl (TALER_SIGNATURE_RESERVE_STATUS);
- reserve->status_sig_purpose.size = htonl (sizeof (struct Reserve) -
- offsetof (struct Reserve, status_sig_purpose));
- GNUNET_CRYPTO_eddsa_sign (&key_state->current_sign_key_issue.signkey_priv,
- &reserve->status_sig_purpose,
- &reserve->status_sig);
-}
-
-
-/**
* Handle a "/withdraw/status" request
*
* @param rh context of the handler
@@ -107,100 +60,18 @@ TALER_MINT_handler_withdraw_status (struct RequestHandler *rh,
size_t *upload_data_size)
{
struct GNUNET_CRYPTO_EddsaPublicKey reserve_pub;
- PGconn *db_conn;
int res;
- struct Reserve reserve;
- struct MintKeyState *key_state;
- int must_update = GNUNET_NO;
- json_t *json;
res = TALER_MINT_mhd_request_arg_data (connection,
- "reserve_pub",
- &reserve_pub,
- sizeof (struct GNUNET_CRYPTO_EddsaPublicKey));
- if (GNUNET_SYSERR == res)
- {
- // FIXME: return 'internal error'
- GNUNET_break (0);
- return MHD_NO;
- }
- if (GNUNET_OK != res)
- return MHD_YES;
- if (NULL == (db_conn = TALER_MINT_DB_get_connection ()))
- {
- // FIXME: return 'internal error'?
- GNUNET_break (0);
- return MHD_NO;
- }
- res = TALER_MINT_DB_get_reserve (db_conn,
- &reserve_pub,
- &reserve);
+ "reserve_pub",
+ &reserve_pub,
+ sizeof (struct GNUNET_CRYPTO_EddsaPublicKey));
if (GNUNET_SYSERR == res)
- return TALER_MINT_reply_json_pack (connection,
- MHD_HTTP_NOT_FOUND,
- "{s:s}",
- "error",
- "Reserve not found");
- if (GNUNET_OK != res)
- {
- // FIXME: return 'internal error'?
- GNUNET_break (0);
- return MHD_NO;
- }
- key_state = TALER_MINT_key_state_acquire ();
- if (0 != memcmp (&key_state->current_sign_key_issue.issue.signkey_pub,
- &reserve.status_sign_pub,
- sizeof (struct GNUNET_CRYPTO_EddsaPublicKey)))
- {
- sign_reserve (&reserve, key_state);
- must_update = GNUNET_YES;
- }
- if ((GNUNET_YES == must_update) &&
- (GNUNET_OK != TALER_MINT_DB_update_reserve (db_conn, &reserve, !must_update)))
- {
- GNUNET_break (0);
- return MHD_YES;
- }
-
- /* Convert the public information of a reserve (i.e.
- excluding private key) to a JSON object. */
- json = json_object ();
- json_object_set_new (json,
- "balance",
- TALER_JSON_from_amount (TALER_amount_ntoh (reserve.balance)));
- json_object_set_new (json,
- "expiration",
- TALER_JSON_from_abs (GNUNET_TIME_absolute_ntoh (reserve.expiration)));
- json_object_set_new (json,
- "signature",
- sig_to_json (&reserve.status_sig_purpose,
- &reserve.status_sig));
-
- return TALER_MINT_reply_json (connection,
- json,
- MHD_HTTP_OK);
-}
-
-
-/**
- * Send positive, normal response for "/withdraw/sign".
- *
- * @param connection the connection to send the response to
- * @param collectable the collectable blindcoin (i.e. the blindly signed coin)
- * @return a MHD result code
- */
-static int
-helper_withdraw_sign_send_reply (struct MHD_Connection *connection,
- const struct CollectableBlindcoin *collectable)
-{
- json_t *root = json_object ();
-
- json_object_set_new (root, "ev_sig",
- TALER_JSON_from_data (&collectable->ev_sig,
- sizeof (struct TALER_RSA_Signature)));
- return TALER_MINT_reply_json (connection,
- root,
- MHD_HTTP_OK);
+ return MHD_NO; /* internal error */
+ if (GNUNET_NO == res)
+ return MHD_YES; /* parse error */
+ return TALER_MINT_db_execute_withdraw_status (connection,
+ &reserve_pub);
}
@@ -223,180 +94,44 @@ TALER_MINT_handler_withdraw_sign (struct RequestHandler *rh,
{
struct TALER_WithdrawRequest wsrd;
int res;
- PGconn *db_conn;
- struct Reserve reserve;
- struct MintKeyState *key_state;
- struct CollectableBlindcoin collectable;
- struct TALER_MINT_DenomKeyIssuePriv *dki;
- struct TALER_RSA_Signature ev_sig;
- struct TALER_Amount amount_required;
- memset (&wsrd,
- 0,
- sizeof (struct TALER_WithdrawRequest));
res = TALER_MINT_mhd_request_arg_data (connection,
- "reserve_pub",
- &wsrd.reserve_pub,
- sizeof (struct GNUNET_CRYPTO_EddsaPublicKey));
+ "reserve_pub",
+ &wsrd.reserve_pub,
+ sizeof (struct GNUNET_CRYPTO_EddsaPublicKey));
if (GNUNET_SYSERR == res)
- {
- // FIXME: return 'internal error'?
- GNUNET_break (0);
- return MHD_NO;
- }
- if (GNUNET_OK != res)
- return MHD_YES;
+ return MHD_NO; /* internal error */
+ if (GNUNET_NO == res)
+ return MHD_YES; /* invalid request */
+
+ /* FIXME: handle variable-size signing keys! */
res = TALER_MINT_mhd_request_arg_data (connection,
"denom_pub",
&wsrd.denomination_pub,
sizeof (struct TALER_RSA_PublicKeyBinaryEncoded));
if (GNUNET_SYSERR == res)
- {
- // FIXME: return 'internal error'?
- GNUNET_break (0);
- return MHD_NO;
- }
- if (GNUNET_OK != res)
- return MHD_YES;
+ return MHD_NO; /* internal error */
+ if (GNUNET_NO == res)
+ return MHD_YES; /* invalid request */
res = TALER_MINT_mhd_request_arg_data (connection,
- "coin_ev",
- &wsrd.coin_envelope,
- sizeof (struct TALER_RSA_Signature));
+ "coin_ev",
+ &wsrd.coin_envelope,
+ sizeof (struct TALER_RSA_Signature));
if (GNUNET_SYSERR == res)
- {
- // FIXME: return 'internal error'?
- GNUNET_break (0);
- return MHD_NO;
- }
- if (GNUNET_OK != res)
- return MHD_YES;
+ return MHD_NO; /* internal error */
+ if (GNUNET_NO == res)
+ return MHD_YES; /* invalid request */
res = TALER_MINT_mhd_request_arg_data (connection,
- "reserve_sig",
- &wsrd.sig,
- sizeof (struct GNUNET_CRYPTO_EddsaSignature));
+ "reserve_sig",
+ &wsrd.sig,
+ sizeof (struct GNUNET_CRYPTO_EddsaSignature));
if (GNUNET_SYSERR == res)
- {
- // FIXME: return 'internal error'?
- GNUNET_break (0);
- return MHD_NO;
- }
- if (GNUNET_OK != res)
- return MHD_YES;
-
- if (NULL == (db_conn = TALER_MINT_DB_get_connection ()))
- {
- // FIXME: return 'internal error'?
- GNUNET_break (0);
- return MHD_NO;
- }
-
- res = TALER_MINT_DB_get_collectable_blindcoin (db_conn,
- &wsrd.coin_envelope,
- &collectable);
- if (GNUNET_SYSERR == res)
- {
- // FIXME: return 'internal error'
- GNUNET_break (0);
- return MHD_NO;
- }
-
- /* Don't sign again if we have already signed the coin */
- if (GNUNET_YES == res)
- return helper_withdraw_sign_send_reply (connection,
- &collectable);
- GNUNET_assert (GNUNET_NO == res);
- res = TALER_MINT_DB_get_reserve (db_conn,
- &wsrd.reserve_pub,
- &reserve);
- if (GNUNET_SYSERR == res)
- {
- // FIXME: return 'internal error'
- GNUNET_break (0);
- return MHD_NO;
- }
+ return MHD_NO; /* internal error */
if (GNUNET_NO == res)
- return TALER_MINT_reply_json_pack (connection,
- MHD_HTTP_NOT_FOUND,
- "{s:s}",
- "error",
- "Reserve not found");
-
- // fill out all the missing info in the request before
- // we can check the signature on the request
-
- wsrd.purpose.purpose = htonl (TALER_SIGNATURE_WITHDRAW);
- wsrd.purpose.size = htonl (sizeof (struct TALER_WithdrawRequest) -
- offsetof (struct TALER_WithdrawRequest, purpose));
-
- if (GNUNET_OK !=
- GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WITHDRAW,
- &wsrd.purpose,
- &wsrd.sig,
- &wsrd.reserve_pub))
- return TALER_MINT_reply_json_pack (connection,
- MHD_HTTP_UNAUTHORIZED,
- "{s:s}",
- "error", "Invalid Signature");
-
- key_state = TALER_MINT_key_state_acquire ();
- dki = TALER_MINT_get_denom_key (key_state,
- &wsrd.denomination_pub);
- TALER_MINT_key_state_release (key_state);
- if (NULL == dki)
- return TALER_MINT_reply_json_pack (connection,
- MHD_HTTP_NOT_FOUND,
- "{s:s}",
- "error",
- "Denomination not found");
-
- amount_required = TALER_amount_ntoh (dki->issue.value);
- amount_required = TALER_amount_add (amount_required,
- TALER_amount_ntoh (dki->issue.fee_withdraw));
-
- if (0 < TALER_amount_cmp (amount_required,
- TALER_amount_ntoh (reserve.balance)))
- return TALER_MINT_reply_json_pack (connection,
- MHD_HTTP_PAYMENT_REQUIRED,
- "{s:s}",
- "error",
- "Insufficient funds");
- if (GNUNET_OK !=
- TALER_RSA_sign (dki->denom_priv,
- &wsrd.coin_envelope,
- sizeof (struct TALER_RSA_BlindedSignaturePurpose),
- &ev_sig))
- {
- // FIXME: return 'internal error'
- GNUNET_break (0);
- return MHD_NO;
- }
-
- reserve.balance = TALER_amount_hton (TALER_amount_subtract (TALER_amount_ntoh (reserve.balance),
- amount_required));
- if (GNUNET_OK !=
- TALER_MINT_DB_update_reserve (db_conn,
- &reserve,
- GNUNET_YES))
- {
- // FIXME: return 'internal error'
- GNUNET_break (0);
- return MHD_NO;
- }
+ return MHD_YES; /* invalid request */
- collectable.ev = wsrd.coin_envelope;
- collectable.ev_sig = ev_sig;
- collectable.reserve_pub = wsrd.reserve_pub;
- collectable.reserve_sig = wsrd.sig;
- if (GNUNET_OK !=
- TALER_MINT_DB_insert_collectable_blindcoin (db_conn,
- &collectable))
- {
- // FIXME: return 'internal error'
- GNUNET_break (0);
- return GNUNET_NO;;
- }
- return helper_withdraw_sign_send_reply (connection,
- &collectable);
+ return TALER_MINT_db_execute_withdraw_sign (connection,
+ &wsrd);
}
/* end of taler-mint-httpd_withdraw.c */