[age-withdraw] added library function for age-withdraw

- Added TALER_EXCHANGE_age_withdraw
- Also: Change TALER_EXCHANGE_batch_withdraw and related functions to
  use GNUNET_CURL_ctx, TALER_EXCHANGE_keys and const char *echange_url
This commit is contained in:
Özgür Kesim 2023-07-03 16:18:40 +02:00
parent 9c3ddcbc18
commit 40629e8992
Signed by: oec
GPG Key ID: 3D76A56D79EDD9D7
20 changed files with 1355 additions and 103 deletions

View File

@ -69,6 +69,7 @@ struct AgeWithdrawContext
/** /**
* kappa * #num_coins hashes of blinded coin planchets. * kappa * #num_coins hashes of blinded coin planchets.
* FIXME[oec]: Make the [][] structure more explicit.
*/ */
struct TALER_BlindedPlanchet *coin_evs; struct TALER_BlindedPlanchet *coin_evs;

View File

@ -439,7 +439,9 @@ struct TALER_AgeCommitmentPublicKeyP
/* /*
* @brief Hash to represent the commitment to n*kappa blinded keys during a age-withdrawal. * @brief Hash to represent the commitment to n*kappa blinded keys during a
* age-withdrawal. It is the running SHA512 hash over the hashes of the blinded
* envelopes of n*kappa coins.
*/ */
struct TALER_AgeWithdrawCommitmentHashP struct TALER_AgeWithdrawCommitmentHashP
{ {
@ -3726,7 +3728,7 @@ TALER_wallet_withdraw_verify (
/** /**
* Sign age-withdraw request. * Sign age-withdraw request.
* *
* @param h_commitment hash all n*kappa blinded coins in the commitment for the age-withdraw * @param h_commitment hash over all n*kappa blinded coins in the commitment for the age-withdraw
* @param amount_with_fee amount to debit the reserve for * @param amount_with_fee amount to debit the reserve for
* @param mask the mask that defines the age groups * @param mask the mask that defines the age groups
* @param max_age maximum age from which the age group is derived, that the withdrawn coins must be restricted to. * @param max_age maximum age from which the age group is derived, that the withdrawn coins must be restricted to.
@ -3762,7 +3764,6 @@ TALER_wallet_age_withdraw_verify (
const struct TALER_ReservePublicKeyP *reserve_pub, const struct TALER_ReservePublicKeyP *reserve_pub,
const struct TALER_ReserveSignatureP *reserve_sig); const struct TALER_ReserveSignatureP *reserve_sig);
/** /**
* Verify exchange melt confirmation. * Verify exchange melt confirmation.
* *
@ -4871,6 +4872,22 @@ TALER_exchange_online_age_withdraw_confirmation_sign (
struct TALER_ExchangeSignatureP *sig); struct TALER_ExchangeSignatureP *sig);
/**
* Verfiy an exchange age-withdraw confirmation
*
* @param h_commitment Commitment over all n*kappa coin candidates from the original request to age-withdraw
* @param noreveal_index The index returned by the exchange
* @param exchange_pub The public key used for signing
* @param exchange_sig The signature from the exchange
*/
enum GNUNET_GenericReturnValue
TALER_exchange_online_age_withdraw_confirmation_verify (
const struct TALER_AgeWithdrawCommitmentHashP *h_commitment,
uint32_t noreveal_index,
const struct TALER_ExchangePublicKeyP *exchange_pub,
const struct TALER_ExchangeSignatureP *exchange_sig);
/* ********************* offline signing ************************** */ /* ********************* offline signing ************************** */

View File

@ -18,6 +18,7 @@
* @brief C interface of libtalerexchange, a C library to use exchange's HTTP API * @brief C interface of libtalerexchange, a C library to use exchange's HTTP API
* @author Sree Harsha Totakura <sreeharsha@totakura.in> * @author Sree Harsha Totakura <sreeharsha@totakura.in>
* @author Christian Grothoff * @author Christian Grothoff
* @author Özgür Kesim
*/ */
#ifndef _TALER_EXCHANGE_SERVICE_H #ifndef _TALER_EXCHANGE_SERVICE_H
#define _TALER_EXCHANGE_SERVICE_H #define _TALER_EXCHANGE_SERVICE_H
@ -1618,7 +1619,8 @@ typedef void
/** /**
* Get a CS R using a /csr-withdraw request. * Get a CS R using a /csr-withdraw request.
* *
* @param exchange the exchange handle; the exchange must be ready to operate * @param curl_ctx The curl context to use for the requests
* @param exchange_url Base-URL to the excnange
* @param pk Which denomination key is the /csr request for * @param pk Which denomination key is the /csr request for
* @param nonce client nonce for the request * @param nonce client nonce for the request
* @param res_cb the callback to call when the final result for this request is available * @param res_cb the callback to call when the final result for this request is available
@ -1629,7 +1631,8 @@ typedef void
*/ */
struct TALER_EXCHANGE_CsRWithdrawHandle * struct TALER_EXCHANGE_CsRWithdrawHandle *
TALER_EXCHANGE_csr_withdraw ( TALER_EXCHANGE_csr_withdraw (
struct TALER_EXCHANGE_Handle *exchange, struct GNUNET_CURL_Context *curl_ctx,
const char *exchange_url,
const struct TALER_EXCHANGE_DenomPublicKey *pk, const struct TALER_EXCHANGE_DenomPublicKey *pk,
const struct TALER_CsNonce *nonce, const struct TALER_CsNonce *nonce,
TALER_EXCHANGE_CsRWithdrawCallback res_cb, TALER_EXCHANGE_CsRWithdrawCallback res_cb,
@ -2448,7 +2451,9 @@ typedef void
* disk before calling, and be ready to repeat the request with the * disk before calling, and be ready to repeat the request with the
* same arguments in case of failures. * same arguments in case of failures.
* *
* @param exchange the exchange handle; the exchange must be ready to operate * @param curl_ctx The curl context to use
* @param exchange_url The base-URL of the exchange
* @param keys The /keys material from the exchange
* @param reserve_priv private key of the reserve to withdraw from * @param reserve_priv private key of the reserve to withdraw from
* @param wci inputs that determine the planchet * @param wci inputs that determine the planchet
* @param res_cb the callback to call when the final result for this request is available * @param res_cb the callback to call when the final result for this request is available
@ -2459,7 +2464,9 @@ typedef void
*/ */
struct TALER_EXCHANGE_WithdrawHandle * struct TALER_EXCHANGE_WithdrawHandle *
TALER_EXCHANGE_withdraw ( TALER_EXCHANGE_withdraw (
struct TALER_EXCHANGE_Handle *exchange, struct GNUNET_CURL_Context *curl_ctx,
const char *exchange_url,
struct TALER_EXCHANGE_Keys *keys,
const struct TALER_ReservePrivateKeyP *reserve_priv, const struct TALER_ReservePrivateKeyP *reserve_priv,
const struct TALER_EXCHANGE_WithdrawCoinInput *wci, const struct TALER_EXCHANGE_WithdrawCoinInput *wci,
TALER_EXCHANGE_WithdrawCallback res_cb, TALER_EXCHANGE_WithdrawCallback res_cb,
@ -2575,7 +2582,9 @@ typedef void
* disk before calling, and be ready to repeat the request with the * disk before calling, and be ready to repeat the request with the
* same arguments in case of failures. * same arguments in case of failures.
* *
* @param exchange the exchange handle; the exchange must be ready to operate * @param curl_ctx The curl context to use
* @param exchange_url The base-URL of the exchange
* @param keys The /keys material from the exchange
* @param reserve_priv private key of the reserve to withdraw from * @param reserve_priv private key of the reserve to withdraw from
* @param wcis inputs that determine the planchets * @param wcis inputs that determine the planchets
* @param wci_length number of entries in @a wcis * @param wci_length number of entries in @a wcis
@ -2587,7 +2596,9 @@ typedef void
*/ */
struct TALER_EXCHANGE_BatchWithdrawHandle * struct TALER_EXCHANGE_BatchWithdrawHandle *
TALER_EXCHANGE_batch_withdraw ( TALER_EXCHANGE_batch_withdraw (
struct TALER_EXCHANGE_Handle *exchange, struct GNUNET_CURL_Context *curl_ctx,
const char *exchange_url,
const struct TALER_EXCHANGE_Keys *keys,
const struct TALER_ReservePrivateKeyP *reserve_priv, const struct TALER_ReservePrivateKeyP *reserve_priv,
const struct TALER_EXCHANGE_WithdrawCoinInput *wcis, const struct TALER_EXCHANGE_WithdrawCoinInput *wcis,
unsigned int wci_length, unsigned int wci_length,
@ -2668,7 +2679,9 @@ struct TALER_EXCHANGE_Withdraw2Handle;
* disk before calling, and be ready to repeat the request with the * disk before calling, and be ready to repeat the request with the
* same arguments in case of failures. * same arguments in case of failures.
* *
* @param exchange the exchange handle; the exchange must be ready to operate * @param curl_ctx The curl-context to use
* @param exchange_url The base-URL of the exchange
* @param keys The /keys material from the exchange
* @param pd planchet details of the planchet to withdraw * @param pd planchet details of the planchet to withdraw
* @param reserve_priv private key of the reserve to withdraw from * @param reserve_priv private key of the reserve to withdraw from
* @param res_cb the callback to call when the final result for this request is available * @param res_cb the callback to call when the final result for this request is available
@ -2679,7 +2692,9 @@ struct TALER_EXCHANGE_Withdraw2Handle;
*/ */
struct TALER_EXCHANGE_Withdraw2Handle * struct TALER_EXCHANGE_Withdraw2Handle *
TALER_EXCHANGE_withdraw2 ( TALER_EXCHANGE_withdraw2 (
struct TALER_EXCHANGE_Handle *exchange, struct GNUNET_CURL_Context *curl_ctx,
const char *exchange_url,
struct TALER_EXCHANGE_Keys *keys,
const struct TALER_PlanchetDetail *pd, const struct TALER_PlanchetDetail *pd,
const struct TALER_ReservePrivateKeyP *reserve_priv, const struct TALER_ReservePrivateKeyP *reserve_priv,
TALER_EXCHANGE_Withdraw2Callback res_cb, TALER_EXCHANGE_Withdraw2Callback res_cb,
@ -2765,7 +2780,9 @@ struct TALER_EXCHANGE_BatchWithdraw2Handle;
* disk before calling, and be ready to repeat the request with the * disk before calling, and be ready to repeat the request with the
* same arguments in case of failures. * same arguments in case of failures.
* *
* @param exchange the exchange handle; the exchange must be ready to operate * @param curl_ctx The curl context to use
* @param exchange_url The base-URL of the exchange
* @param keys The /keys material from the exchange
* @param pds array of planchet details of the planchet to withdraw * @param pds array of planchet details of the planchet to withdraw
* @param pds_length number of entries in the @a pds array * @param pds_length number of entries in the @a pds array
* @param reserve_priv private key of the reserve to withdraw from * @param reserve_priv private key of the reserve to withdraw from
@ -2777,7 +2794,9 @@ struct TALER_EXCHANGE_BatchWithdraw2Handle;
*/ */
struct TALER_EXCHANGE_BatchWithdraw2Handle * struct TALER_EXCHANGE_BatchWithdraw2Handle *
TALER_EXCHANGE_batch_withdraw2 ( TALER_EXCHANGE_batch_withdraw2 (
struct TALER_EXCHANGE_Handle *exchange, struct GNUNET_CURL_Context *curl_ctx,
const char *exchange_url,
const struct TALER_EXCHANGE_Keys *keys,
const struct TALER_ReservePrivateKeyP *reserve_priv, const struct TALER_ReservePrivateKeyP *reserve_priv,
const struct TALER_PlanchetDetail *pds, const struct TALER_PlanchetDetail *pds,
unsigned int pds_length, unsigned int pds_length,
@ -2796,6 +2815,119 @@ TALER_EXCHANGE_batch_withdraw2_cancel (
struct TALER_EXCHANGE_BatchWithdraw2Handle *wh); struct TALER_EXCHANGE_BatchWithdraw2Handle *wh);
/* ********************* /reserve/$RESERVE_PUB/age-withdraw *************** */
/**
* @brief Information needed to withdraw age restricted coins.
*/
struct TALER_EXCHANGE_AgeWithdrawCoinInput
{
/* The master secret from which we derive all other relevant values for
* the coin: private key, nonces (if applicable) and age restriction
*/
const struct TALER_PlanchetMasterSecretP secret[TALER_CNC_KAPPA];
/* The denomination of the coin. Must support age restriction, i.e
* its .keys.age_mask MUST not be 0 */
const struct TALER_EXCHANGE_DenomPublicKey *denom_pub;
};
/**
* @brief A handle to a /reserves/$RESERVE_PUB/age-withdraw request
*/
struct TALER_EXCHANGE_AgeWithdrawHandle;
/**
* @brief Details about the response for a age withdraw request.
*/
struct TALER_EXCHANGE_AgeWithdrawResponse
{
/**
* HTTP response data.
*/
struct TALER_EXCHANGE_HttpResponse hr;
/**
* Details about the response
*/
union
{
/**
* Details if the status is #MHD_HTTP_OK.
*/
struct
{
/**
* Index that should not be revealed during the age-withdraw reveal phase.
* The struct TALER_PlanchetMasterSecretP * from the request
* with this index are the ones to keep.
*/
uint8_t noreveal_index;
/**
* Signature of the exchange over the origina TALER_AgeWithdrawRequestPS
*/
struct TALER_ExchangeSignatureP exchange_sig;
/**
* Key used by the exchange for @e exchange_sig
*/
struct TALER_ExchangePublicKeyP exchange_pub;
} ok;
/* FIXME[oec]: error cases */
} details;
};
typedef void
(*TALER_EXCHANGE_AgeWithdrawCallback)(
void *cls,
const struct TALER_EXCHANGE_AgeWithdrawResponse *awr);
/**
* Submit an age-withdraw request to the exchange and get the exchange's
* response.
*
* This API is typically used by a wallet. Note that to ensure that
* no money is lost in case of hardware failures, the provided
* argument @a rd should be committed to persistent storage
* prior to calling this function.
*
* @param curl_ctx The curl context
* @param exchange_url The base url of the exchange
* @parm keys The denomination keys from the exchange
* @param reserve_priv The pivate key to the reserve
* @param coin_inputs The input for the coins to withdraw
* @param num_coins The number of elements in @e coin_inputs
* @param max_age The maximum age we commit to.
* @param res_cb A callback for the result, maybe NULL
* @param res_cb_cls A closure for @e res_cb, maybe NULL
* @return a handle for this request; NULL if the argument was invalid.
* In this case, the callback will not be called.
*/
struct TALER_EXCHANGE_AgeWithdrawHandle *
TALER_EXCHANGE_age_withdraw (
struct GNUNET_CURL_Context *curl_ctx,
const char *exchange_url,
struct TALER_EXCHANGE_Keys *keys,
const struct TALER_ReservePrivateKeyP *reserve_priv,
const struct TALER_EXCHANGE_AgeWithdrawCoinInput *coin_inputs,
size_t num_coins,
uint8_t max_age,
TALER_EXCHANGE_AgeWithdrawCallback res_cb,
void *res_cb_cls);
/**
* Cancel a age-withdraw request. This function cannot be used
* on a request handle if a response is already served for it.
*
* @param awh the age-withdraw handle
*/
void
TALER_EXCHANGE_age_withdraw_cancel (
struct TALER_EXCHANGE_AgeWithdrawHandle *awh);
/* ********************* /refresh/melt+reveal ***************************** */ /* ********************* /refresh/melt+reveal ***************************** */
@ -3565,7 +3697,7 @@ TALER_EXCHANGE_verify_coin_history (
*/ */
enum GNUNET_GenericReturnValue enum GNUNET_GenericReturnValue
TALER_EXCHANGE_parse_reserve_history ( TALER_EXCHANGE_parse_reserve_history (
struct TALER_EXCHANGE_Keys *keys, const struct TALER_EXCHANGE_Keys *keys,
const json_t *history, const json_t *history,
const struct TALER_ReservePublicKeyP *reserve_pub, const struct TALER_ReservePublicKeyP *reserve_pub,
const char *currency, const char *currency,

View File

@ -1215,8 +1215,7 @@ struct TALER_EXCHANGEDB_AgeWithdraw
/** /**
* Signature confirming the age withdrawal commitment, matching @e * Signature confirming the age withdrawal commitment, matching @e
* reserve_pub, @e maximum_age_group and @e h_commitment and @e * reserve_pub, @e max_age and @e h_commitment and @e amount_with_fee.
* total_amount_with_fee.
*/ */
struct TALER_ReserveSignatureP reserve_sig; struct TALER_ReserveSignatureP reserve_sig;

View File

@ -22,6 +22,7 @@ libtalerexchange_la_LDFLAGS = \
-no-undefined -no-undefined
libtalerexchange_la_SOURCES = \ libtalerexchange_la_SOURCES = \
exchange_api_add_aml_decision.c \ exchange_api_add_aml_decision.c \
exchange_api_age_withdraw.c \
exchange_api_auditor_add_denomination.c \ exchange_api_auditor_add_denomination.c \
exchange_api_batch_deposit.c \ exchange_api_batch_deposit.c \
exchange_api_batch_withdraw.c \ exchange_api_batch_withdraw.c \

File diff suppressed because it is too large Load Diff

View File

@ -97,9 +97,20 @@ struct TALER_EXCHANGE_BatchWithdrawHandle
{ {
/** /**
* The connection to exchange this request handle will use * The curl context to use
*/ */
struct TALER_EXCHANGE_Handle *exchange; struct GNUNET_CURL_Context *curl_ctx;
/**
* The base URL to the exchange
*/
const char *exchange_url;
/**
* The /keys information from the exchange
*/
const struct TALER_EXCHANGE_Keys *keys;
/** /**
* Handle for the actual (internal) batch withdraw operation. * Handle for the actual (internal) batch withdraw operation.
@ -255,7 +266,9 @@ phase_two (struct TALER_EXCHANGE_BatchWithdrawHandle *wh)
pds[i] = cd->pd; pds[i] = cd->pd;
} }
wh->wh2 = TALER_EXCHANGE_batch_withdraw2 ( wh->wh2 = TALER_EXCHANGE_batch_withdraw2 (
wh->exchange, wh->curl_ctx,
wh->exchange_url,
wh->keys,
wh->reserve_priv, wh->reserve_priv,
pds, pds,
wh->num_coins, wh->num_coins,
@ -322,7 +335,9 @@ withdraw_cs_stage_two_callback (
struct TALER_EXCHANGE_BatchWithdrawHandle * struct TALER_EXCHANGE_BatchWithdrawHandle *
TALER_EXCHANGE_batch_withdraw ( TALER_EXCHANGE_batch_withdraw (
struct TALER_EXCHANGE_Handle *exchange, struct GNUNET_CURL_Context *curl_ctx,
const char *exchange_url,
const struct TALER_EXCHANGE_Keys *keys,
const struct TALER_ReservePrivateKeyP *reserve_priv, const struct TALER_ReservePrivateKeyP *reserve_priv,
const struct TALER_EXCHANGE_WithdrawCoinInput *wcis, const struct TALER_EXCHANGE_WithdrawCoinInput *wcis,
unsigned int wci_length, unsigned int wci_length,
@ -332,7 +347,9 @@ TALER_EXCHANGE_batch_withdraw (
struct TALER_EXCHANGE_BatchWithdrawHandle *wh; struct TALER_EXCHANGE_BatchWithdrawHandle *wh;
wh = GNUNET_new (struct TALER_EXCHANGE_BatchWithdrawHandle); wh = GNUNET_new (struct TALER_EXCHANGE_BatchWithdrawHandle);
wh->exchange = exchange; wh->curl_ctx = curl_ctx;
wh->exchange_url = exchange_url;
wh->keys = keys;
wh->cb = res_cb; wh->cb = res_cb;
wh->cb_cls = res_cb_cls; wh->cb_cls = res_cb_cls;
wh->reserve_priv = reserve_priv; wh->reserve_priv = reserve_priv;
@ -386,7 +403,8 @@ TALER_EXCHANGE_batch_withdraw (
will be done after the /csr-withdraw request! */ will be done after the /csr-withdraw request! */
cd->pd.blinded_planchet.cipher = TALER_DENOMINATION_CS; cd->pd.blinded_planchet.cipher = TALER_DENOMINATION_CS;
cd->csrh = TALER_EXCHANGE_csr_withdraw ( cd->csrh = TALER_EXCHANGE_csr_withdraw (
exchange, curl_ctx,
exchange_url,
&cd->pk, &cd->pk,
&cd->pd.blinded_planchet.details.cs_blinded_planchet.nonce, &cd->pd.blinded_planchet.details.cs_blinded_planchet.nonce,
&withdraw_cs_stage_two_callback, &withdraw_cs_stage_two_callback,

View File

@ -38,16 +38,16 @@
struct TALER_EXCHANGE_BatchWithdraw2Handle struct TALER_EXCHANGE_BatchWithdraw2Handle
{ {
/**
* The connection to exchange this request handle will use
*/
struct TALER_EXCHANGE_Handle *exchange;
/** /**
* The url for this request. * The url for this request.
*/ */
char *url; char *url;
/**
* The /keys material from the exchange
*/
const struct TALER_EXCHANGE_Keys *keys;
/** /**
* Handle for the request. * Handle for the request.
*/ */
@ -219,7 +219,7 @@ reserve_batch_withdraw_payment_required (
if (GNUNET_OK != if (GNUNET_OK !=
TALER_EXCHANGE_parse_reserve_history ( TALER_EXCHANGE_parse_reserve_history (
TALER_EXCHANGE_get_keys (wh->exchange), wh->keys,
history, history,
&wh->reserve_pub, &wh->reserve_pub,
balance.currency, balance.currency,
@ -387,7 +387,9 @@ handle_reserve_batch_withdraw_finished (void *cls,
struct TALER_EXCHANGE_BatchWithdraw2Handle * struct TALER_EXCHANGE_BatchWithdraw2Handle *
TALER_EXCHANGE_batch_withdraw2 ( TALER_EXCHANGE_batch_withdraw2 (
struct TALER_EXCHANGE_Handle *exchange, struct GNUNET_CURL_Context *curl_ctx,
const char *exchange_url,
const struct TALER_EXCHANGE_Keys *keys,
const struct TALER_ReservePrivateKeyP *reserve_priv, const struct TALER_ReservePrivateKeyP *reserve_priv,
const struct TALER_PlanchetDetail *pds, const struct TALER_PlanchetDetail *pds,
unsigned int pds_length, unsigned int pds_length,
@ -395,21 +397,15 @@ TALER_EXCHANGE_batch_withdraw2 (
void *res_cb_cls) void *res_cb_cls)
{ {
struct TALER_EXCHANGE_BatchWithdraw2Handle *wh; struct TALER_EXCHANGE_BatchWithdraw2Handle *wh;
const struct TALER_EXCHANGE_Keys *keys;
const struct TALER_EXCHANGE_DenomPublicKey *dk; const struct TALER_EXCHANGE_DenomPublicKey *dk;
struct TALER_ReserveSignatureP reserve_sig; struct TALER_ReserveSignatureP reserve_sig;
char arg_str[sizeof (struct TALER_ReservePublicKeyP) * 2 + 32]; char arg_str[sizeof (struct TALER_ReservePublicKeyP) * 2 + 32];
struct TALER_BlindedCoinHashP bch; struct TALER_BlindedCoinHashP bch;
json_t *jc; json_t *jc;
keys = TALER_EXCHANGE_get_keys (exchange); GNUNET_assert (NULL != keys);
if (NULL == keys)
{
GNUNET_break (0);
return NULL;
}
wh = GNUNET_new (struct TALER_EXCHANGE_BatchWithdraw2Handle); wh = GNUNET_new (struct TALER_EXCHANGE_BatchWithdraw2Handle);
wh->exchange = exchange; wh->keys = keys;
wh->cb = res_cb; wh->cb = res_cb;
wh->cb_cls = res_cb_cls; wh->cb_cls = res_cb_cls;
wh->num_coins = pds_length; wh->num_coins = pds_length;
@ -430,14 +426,15 @@ TALER_EXCHANGE_batch_withdraw2 (
*end = '\0'; *end = '\0';
GNUNET_snprintf (arg_str, GNUNET_snprintf (arg_str,
sizeof (arg_str), sizeof (arg_str),
"/reserves/%s/batch-withdraw", "reserves/%s/batch-withdraw",
pub_str); pub_str);
} }
GNUNET_log (GNUNET_ERROR_TYPE_INFO, GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Attempting to batch-withdraw from reserve %s\n", "Attempting to batch-withdraw from reserve %s\n",
TALER_B2S (&wh->reserve_pub)); TALER_B2S (&wh->reserve_pub));
wh->url = TEAH_path_to_url (exchange, wh->url = TALER_url_join (exchange_url,
arg_str); arg_str,
NULL);
if (NULL == wh->url) if (NULL == wh->url)
{ {
GNUNET_break (0); GNUNET_break (0);
@ -513,13 +510,11 @@ TALER_EXCHANGE_batch_withdraw2 (
} }
{ {
CURL *eh; CURL *eh;
struct GNUNET_CURL_Context *ctx;
json_t *req; json_t *req;
req = GNUNET_JSON_PACK ( req = GNUNET_JSON_PACK (
GNUNET_JSON_pack_array_steal ("planchets", GNUNET_JSON_pack_array_steal ("planchets",
jc)); jc));
ctx = TEAH_handle_to_context (exchange);
eh = TALER_EXCHANGE_curl_easy_get_ (wh->url); eh = TALER_EXCHANGE_curl_easy_get_ (wh->url);
if ( (NULL == eh) || if ( (NULL == eh) ||
(GNUNET_OK != (GNUNET_OK !=
@ -535,7 +530,7 @@ TALER_EXCHANGE_batch_withdraw2 (
return NULL; return NULL;
} }
json_decref (req); json_decref (req);
wh->job = GNUNET_CURL_job_add2 (ctx, wh->job = GNUNET_CURL_job_add2 (curl_ctx,
eh, eh,
wh->post_ctx.headers, wh->post_ctx.headers,
&handle_reserve_batch_withdraw_finished, &handle_reserve_batch_withdraw_finished,

View File

@ -36,7 +36,7 @@ struct HistoryParseContext
/** /**
* Keys of the exchange we use. * Keys of the exchange we use.
*/ */
struct TALER_EXCHANGE_Keys *keys; const struct TALER_EXCHANGE_Keys *keys;
/** /**
* Our reserve public key. * Our reserve public key.
@ -647,7 +647,7 @@ parse_close (struct TALER_EXCHANGE_ReserveHistoryEntry *rh,
enum GNUNET_GenericReturnValue enum GNUNET_GenericReturnValue
TALER_EXCHANGE_parse_reserve_history ( TALER_EXCHANGE_parse_reserve_history (
struct TALER_EXCHANGE_Keys *keys, const struct TALER_EXCHANGE_Keys *keys,
const json_t *history, const json_t *history,
const struct TALER_ReservePublicKeyP *reserve_pub, const struct TALER_ReservePublicKeyP *reserve_pub,
const char *currency, const char *currency,

View File

@ -38,11 +38,6 @@
*/ */
struct TALER_EXCHANGE_CsRWithdrawHandle struct TALER_EXCHANGE_CsRWithdrawHandle
{ {
/**
* The connection to exchange this request handle will use
*/
struct TALER_EXCHANGE_Handle *exchange;
/** /**
* Function to call with the result. * Function to call with the result.
*/ */
@ -204,7 +199,9 @@ handle_csr_finished (void *cls,
struct TALER_EXCHANGE_CsRWithdrawHandle * struct TALER_EXCHANGE_CsRWithdrawHandle *
TALER_EXCHANGE_csr_withdraw (struct TALER_EXCHANGE_Handle *exchange, TALER_EXCHANGE_csr_withdraw (
struct GNUNET_CURL_Context *curl_ctx,
const char *exchange_url,
const struct TALER_EXCHANGE_DenomPublicKey *pk, const struct TALER_EXCHANGE_DenomPublicKey *pk,
const struct TALER_CsNonce *nonce, const struct TALER_CsNonce *nonce,
TALER_EXCHANGE_CsRWithdrawCallback res_cb, TALER_EXCHANGE_CsRWithdrawCallback res_cb,
@ -218,11 +215,11 @@ TALER_EXCHANGE_csr_withdraw (struct TALER_EXCHANGE_Handle *exchange,
return NULL; return NULL;
} }
csrh = GNUNET_new (struct TALER_EXCHANGE_CsRWithdrawHandle); csrh = GNUNET_new (struct TALER_EXCHANGE_CsRWithdrawHandle);
csrh->exchange = exchange;
csrh->cb = res_cb; csrh->cb = res_cb;
csrh->cb_cls = res_cb_cls; csrh->cb_cls = res_cb_cls;
csrh->url = TEAH_path_to_url (exchange, csrh->url = TALER_url_join (exchange_url,
"/csr-withdraw"); "csr-withdraw",
NULL);
if (NULL == csrh->url) if (NULL == csrh->url)
{ {
GNUNET_free (csrh); GNUNET_free (csrh);
@ -231,7 +228,6 @@ TALER_EXCHANGE_csr_withdraw (struct TALER_EXCHANGE_Handle *exchange,
{ {
CURL *eh; CURL *eh;
struct GNUNET_CURL_Context *ctx;
json_t *req; json_t *req;
req = GNUNET_JSON_PACK ( req = GNUNET_JSON_PACK (
@ -242,7 +238,6 @@ TALER_EXCHANGE_csr_withdraw (struct TALER_EXCHANGE_Handle *exchange,
&pk->h_key, &pk->h_key,
sizeof(struct TALER_DenominationHashP))); sizeof(struct TALER_DenominationHashP)));
GNUNET_assert (NULL != req); GNUNET_assert (NULL != req);
ctx = TEAH_handle_to_context (exchange);
eh = TALER_EXCHANGE_curl_easy_get_ (csrh->url); eh = TALER_EXCHANGE_curl_easy_get_ (csrh->url);
if ( (NULL == eh) || if ( (NULL == eh) ||
(GNUNET_OK != (GNUNET_OK !=
@ -259,7 +254,7 @@ TALER_EXCHANGE_csr_withdraw (struct TALER_EXCHANGE_Handle *exchange,
return NULL; return NULL;
} }
json_decref (req); json_decref (req);
csrh->job = GNUNET_CURL_job_add2 (ctx, csrh->job = GNUNET_CURL_job_add2 (curl_ctx,
eh, eh,
csrh->post_ctx.headers, csrh->post_ctx.headers,
&handle_csr_finished, &handle_csr_finished,

View File

@ -25,7 +25,6 @@
#define _TALER_CURL_DEFAULTS_H #define _TALER_CURL_DEFAULTS_H
#include "platform.h"
#include <gnunet/gnunet_curl_lib.h> #include <gnunet/gnunet_curl_lib.h>

View File

@ -1229,6 +1229,8 @@ TALER_EXCHANGE_check_keys_current (struct TALER_EXCHANGE_Handle *exchange,
bool force_download = 0 != (flags & TALER_EXCHANGE_CKF_FORCE_DOWNLOAD); bool force_download = 0 != (flags & TALER_EXCHANGE_CKF_FORCE_DOWNLOAD);
bool pull_all_keys = 0 != (flags & TALER_EXCHANGE_CKF_PULL_ALL_KEYS); bool pull_all_keys = 0 != (flags & TALER_EXCHANGE_CKF_PULL_ALL_KEYS);
GNUNET_assert (NULL != exchange);
if ( (NULL != cb) && if ( (NULL != cb) &&
( (exchange->cert_cb != cb) || ( (exchange->cert_cb != cb) ||
(exchange->cert_cb_cls != cb_cls) ) ) (exchange->cert_cb_cls != cb_cls) ) )

View File

@ -504,6 +504,7 @@ csr_cb (void *cls,
} }
/* FIXME: refactor this to use struct TALER_EXCHANGE_Handle */
struct TALER_EXCHANGE_MeltHandle * struct TALER_EXCHANGE_MeltHandle *
TALER_EXCHANGE_melt ( TALER_EXCHANGE_melt (
struct GNUNET_CURL_Context *ctx, struct GNUNET_CURL_Context *ctx,

View File

@ -303,6 +303,7 @@ handle_refresh_reveal_finished (void *cls,
} }
/* FIXME: refactor this to use struct TALER_EXCHANGE_Handle */
struct TALER_EXCHANGE_RefreshesRevealHandle * struct TALER_EXCHANGE_RefreshesRevealHandle *
TALER_EXCHANGE_refreshes_reveal ( TALER_EXCHANGE_refreshes_reveal (
struct GNUNET_CURL_Context *ctx, struct GNUNET_CURL_Context *ctx,

View File

@ -39,9 +39,19 @@ struct TALER_EXCHANGE_WithdrawHandle
{ {
/** /**
* The connection to exchange this request handle will use * The curl context to use
*/ */
struct TALER_EXCHANGE_Handle *exchange; struct GNUNET_CURL_Context *curl_ctx;
/**
* The base-URL to the exchange
*/
const char *exchange_url;
/**
* The /keys material from the exchange
*/
struct TALER_EXCHANGE_Keys *keys;
/** /**
* Handle for the actual (internal) withdraw operation. * Handle for the actual (internal) withdraw operation.
@ -232,7 +242,9 @@ withdraw_cs_stage_two_callback (
GNUNET_break (0); GNUNET_break (0);
break; break;
} }
wh->wh2 = TALER_EXCHANGE_withdraw2 (wh->exchange, wh->wh2 = TALER_EXCHANGE_withdraw2 (wh->curl_ctx,
wh->exchange_url,
wh->keys,
&wh->pd, &wh->pd,
wh->reserve_priv, wh->reserve_priv,
&handle_reserve_withdraw_finished, &handle_reserve_withdraw_finished,
@ -249,7 +261,9 @@ withdraw_cs_stage_two_callback (
struct TALER_EXCHANGE_WithdrawHandle * struct TALER_EXCHANGE_WithdrawHandle *
TALER_EXCHANGE_withdraw ( TALER_EXCHANGE_withdraw (
struct TALER_EXCHANGE_Handle *exchange, struct GNUNET_CURL_Context *curl_ctx,
const char *exchange_url,
struct TALER_EXCHANGE_Keys *keys,
const struct TALER_ReservePrivateKeyP *reserve_priv, const struct TALER_ReservePrivateKeyP *reserve_priv,
const struct TALER_EXCHANGE_WithdrawCoinInput *wci, const struct TALER_EXCHANGE_WithdrawCoinInput *wci,
TALER_EXCHANGE_WithdrawCallback res_cb, TALER_EXCHANGE_WithdrawCallback res_cb,
@ -258,7 +272,9 @@ TALER_EXCHANGE_withdraw (
struct TALER_EXCHANGE_WithdrawHandle *wh; struct TALER_EXCHANGE_WithdrawHandle *wh;
wh = GNUNET_new (struct TALER_EXCHANGE_WithdrawHandle); wh = GNUNET_new (struct TALER_EXCHANGE_WithdrawHandle);
wh->exchange = exchange; wh->keys = TALER_EXCHANGE_keys_incref (keys);
wh->exchange_url = exchange_url;
wh->curl_ctx = curl_ctx;
wh->cb = res_cb; wh->cb = res_cb;
wh->cb_cls = res_cb_cls; wh->cb_cls = res_cb_cls;
wh->reserve_priv = reserve_priv; wh->reserve_priv = reserve_priv;
@ -292,7 +308,9 @@ TALER_EXCHANGE_withdraw (
GNUNET_free (wh); GNUNET_free (wh);
return NULL; return NULL;
} }
wh->wh2 = TALER_EXCHANGE_withdraw2 (exchange, wh->wh2 = TALER_EXCHANGE_withdraw2 (curl_ctx,
exchange_url,
keys,
&wh->pd, &wh->pd,
wh->reserve_priv, wh->reserve_priv,
&handle_reserve_withdraw_finished, &handle_reserve_withdraw_finished,
@ -309,7 +327,8 @@ TALER_EXCHANGE_withdraw (
will be done after the /csr-withdraw request! */ will be done after the /csr-withdraw request! */
wh->pd.blinded_planchet.cipher = TALER_DENOMINATION_CS; wh->pd.blinded_planchet.cipher = TALER_DENOMINATION_CS;
wh->csrh = TALER_EXCHANGE_csr_withdraw ( wh->csrh = TALER_EXCHANGE_csr_withdraw (
exchange, curl_ctx,
exchange_url,
&wh->pk, &wh->pk,
&wh->pd.blinded_planchet.details.cs_blinded_planchet.nonce, &wh->pd.blinded_planchet.details.cs_blinded_planchet.nonce,
&withdraw_cs_stage_two_callback, &withdraw_cs_stage_two_callback,
@ -339,6 +358,7 @@ TALER_EXCHANGE_withdraw_cancel (struct TALER_EXCHANGE_WithdrawHandle *wh)
TALER_EXCHANGE_withdraw2_cancel (wh->wh2); TALER_EXCHANGE_withdraw2_cancel (wh->wh2);
wh->wh2 = NULL; wh->wh2 = NULL;
} }
TALER_EXCHANGE_keys_decref (wh->keys);
TALER_denom_pub_free (&wh->pk.key); TALER_denom_pub_free (&wh->pk.key);
GNUNET_free (wh); GNUNET_free (wh);
} }

View File

@ -39,9 +39,9 @@ struct TALER_EXCHANGE_Withdraw2Handle
{ {
/** /**
* The connection to exchange this request handle will use * The /keys material from the exchange
*/ */
struct TALER_EXCHANGE_Handle *exchange; struct TALER_EXCHANGE_Keys *keys;
/** /**
* The url for this request. * The url for this request.
@ -192,8 +192,7 @@ reserve_withdraw_payment_required (
} }
if (GNUNET_OK != if (GNUNET_OK !=
TALER_EXCHANGE_parse_reserve_history (TALER_EXCHANGE_get_keys ( TALER_EXCHANGE_parse_reserve_history (wh->keys,
wh->exchange),
history, history,
&wh->reserve_pub, &wh->reserve_pub,
balance.currency, balance.currency,
@ -361,25 +360,21 @@ handle_reserve_withdraw_finished (void *cls,
struct TALER_EXCHANGE_Withdraw2Handle * struct TALER_EXCHANGE_Withdraw2Handle *
TALER_EXCHANGE_withdraw2 ( TALER_EXCHANGE_withdraw2 (
struct TALER_EXCHANGE_Handle *exchange, struct GNUNET_CURL_Context *curl_ctx,
const char *exchange_url,
struct TALER_EXCHANGE_Keys *keys,
const struct TALER_PlanchetDetail *pd, const struct TALER_PlanchetDetail *pd,
const struct TALER_ReservePrivateKeyP *reserve_priv, const struct TALER_ReservePrivateKeyP *reserve_priv,
TALER_EXCHANGE_Withdraw2Callback res_cb, TALER_EXCHANGE_Withdraw2Callback res_cb,
void *res_cb_cls) void *res_cb_cls)
{ {
struct TALER_EXCHANGE_Withdraw2Handle *wh; struct TALER_EXCHANGE_Withdraw2Handle *wh;
const struct TALER_EXCHANGE_Keys *keys;
const struct TALER_EXCHANGE_DenomPublicKey *dk; const struct TALER_EXCHANGE_DenomPublicKey *dk;
struct TALER_ReserveSignatureP reserve_sig; struct TALER_ReserveSignatureP reserve_sig;
char arg_str[sizeof (struct TALER_ReservePublicKeyP) * 2 + 32]; char arg_str[sizeof (struct TALER_ReservePublicKeyP) * 2 + 32];
struct TALER_BlindedCoinHashP bch; struct TALER_BlindedCoinHashP bch;
keys = TALER_EXCHANGE_get_keys (exchange); GNUNET_assert (NULL != keys);
if (NULL == keys)
{
GNUNET_break (0);
return NULL;
}
dk = TALER_EXCHANGE_get_denomination_key_by_hash (keys, dk = TALER_EXCHANGE_get_denomination_key_by_hash (keys,
&pd->denom_pub_hash); &pd->denom_pub_hash);
if (NULL == dk) if (NULL == dk)
@ -388,7 +383,7 @@ TALER_EXCHANGE_withdraw2 (
return NULL; return NULL;
} }
wh = GNUNET_new (struct TALER_EXCHANGE_Withdraw2Handle); wh = GNUNET_new (struct TALER_EXCHANGE_Withdraw2Handle);
wh->exchange = exchange; wh->keys = TALER_EXCHANGE_keys_incref (keys);
wh->cb = res_cb; wh->cb = res_cb;
wh->cb_cls = res_cb_cls; wh->cb_cls = res_cb_cls;
/* Compute how much we expected to charge to the reserve */ /* Compute how much we expected to charge to the reserve */
@ -418,7 +413,7 @@ TALER_EXCHANGE_withdraw2 (
*end = '\0'; *end = '\0';
GNUNET_snprintf (arg_str, GNUNET_snprintf (arg_str,
sizeof (arg_str), sizeof (arg_str),
"/reserves/%s/withdraw", "reserves/%s/withdraw",
pub_str); pub_str);
} }
@ -448,8 +443,9 @@ TALER_EXCHANGE_withdraw2 (
GNUNET_log (GNUNET_ERROR_TYPE_INFO, GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Attempting to withdraw from reserve %s\n", "Attempting to withdraw from reserve %s\n",
TALER_B2S (&wh->reserve_pub)); TALER_B2S (&wh->reserve_pub));
wh->url = TEAH_path_to_url (exchange, wh->url = TALER_url_join (exchange_url,
arg_str); arg_str,
NULL);
if (NULL == wh->url) if (NULL == wh->url)
{ {
json_decref (withdraw_obj); json_decref (withdraw_obj);
@ -458,9 +454,7 @@ TALER_EXCHANGE_withdraw2 (
} }
{ {
CURL *eh; CURL *eh;
struct GNUNET_CURL_Context *ctx;
ctx = TEAH_handle_to_context (exchange);
eh = TALER_EXCHANGE_curl_easy_get_ (wh->url); eh = TALER_EXCHANGE_curl_easy_get_ (wh->url);
if ( (NULL == eh) || if ( (NULL == eh) ||
(GNUNET_OK != (GNUNET_OK !=
@ -477,7 +471,7 @@ TALER_EXCHANGE_withdraw2 (
return NULL; return NULL;
} }
json_decref (withdraw_obj); json_decref (withdraw_obj);
wh->job = GNUNET_CURL_job_add2 (ctx, wh->job = GNUNET_CURL_job_add2 (curl_ctx,
eh, eh,
wh->post_ctx.headers, wh->post_ctx.headers,
&handle_reserve_withdraw_finished, &handle_reserve_withdraw_finished,
@ -498,5 +492,6 @@ TALER_EXCHANGE_withdraw2_cancel (struct TALER_EXCHANGE_Withdraw2Handle *wh)
} }
GNUNET_free (wh->url); GNUNET_free (wh->url);
TALER_curl_easy_post_finished (&wh->post_ctx); TALER_curl_easy_post_finished (&wh->post_ctx);
TALER_EXCHANGE_keys_decref (wh->keys);
GNUNET_free (wh); GNUNET_free (wh);
} }

View File

@ -321,7 +321,10 @@ batch_withdraw_run (void *cls,
wci->ps = &cs->ps; wci->ps = &cs->ps;
wci->ach = cs->h_age_commitment; wci->ach = cs->h_age_commitment;
} }
ws->wsh = TALER_EXCHANGE_batch_withdraw (exchange, ws->wsh = TALER_EXCHANGE_batch_withdraw (
TALER_TESTING_interpreter_get_context (is),
TALER_TESTING_get_exchange_url (is),
TALER_TESTING_get_keys (is),
rp, rp,
wcis, wcis,
ws->num_coins, ws->num_coins,

View File

@ -410,7 +410,7 @@ withdraw_run (void *cls,
if (NULL == ws->pk) if (NULL == ws->pk)
{ {
dpk = TALER_TESTING_find_pk (TALER_EXCHANGE_get_keys (exchange), dpk = TALER_TESTING_find_pk (TALER_TESTING_get_keys (is),
&ws->amount, &ws->amount,
ws->age > 0); ws->age > 0);
if (NULL == dpk) if (NULL == dpk)
@ -443,7 +443,10 @@ withdraw_run (void *cls,
.ps = &ws->ps, .ps = &ws->ps,
.ach = ws->h_age_commitment .ach = ws->h_age_commitment
}; };
ws->wsh = TALER_EXCHANGE_withdraw (exchange, ws->wsh = TALER_EXCHANGE_withdraw (
TALER_TESTING_interpreter_get_context (is),
TALER_TESTING_get_exchange_url (is),
TALER_TESTING_get_keys (is),
rp, rp,
&wci, &wci,
&reserve_withdraw_cb, &reserve_withdraw_cb,

View File

@ -413,6 +413,34 @@ TALER_exchange_online_age_withdraw_confirmation_sign (
} }
enum GNUNET_GenericReturnValue
TALER_exchange_online_age_withdraw_confirmation_verify (
const struct TALER_AgeWithdrawCommitmentHashP *h_commitment,
uint32_t noreveal_index,
const struct TALER_ExchangePublicKeyP *exchange_pub,
const struct TALER_ExchangeSignatureP *exchange_sig)
{
struct TALER_AgeWithdrawConfirmationPS confirm = {
.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_AGE_WITHDRAW),
.purpose.size = htonl (sizeof (confirm)),
.h_commitment = *h_commitment,
.noreveal_index = htonl (noreveal_index)
};
if (GNUNET_OK !=
GNUNET_CRYPTO_eddsa_verify (
TALER_SIGNATURE_EXCHANGE_CONFIRM_AGE_WITHDRAW,
&confirm,
&exchange_sig->eddsa_signature,
&exchange_pub->eddsa_pub))
{
GNUNET_break_op (0);
return GNUNET_SYSERR;
}
return GNUNET_OK;
}
/* TODO:oec: add signature for age-withdraw, age-reveal */ /* TODO:oec: add signature for age-withdraw, age-reveal */

View File

@ -22,6 +22,7 @@
#include "platform.h" #include "platform.h"
#include "taler_util.h" #include "taler_util.h"
#include "taler_signatures.h" #include "taler_signatures.h"
#include <gnunet/gnunet_common.h>
GNUNET_NETWORK_STRUCT_BEGIN GNUNET_NETWORK_STRUCT_BEGIN
@ -621,9 +622,9 @@ struct TALER_AgeWithdrawRequestPS
struct GNUNET_CRYPTO_EccSignaturePurpose purpose; struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
/** /**
* Hash of the commitment of n*kappa coins * The reserve's public key
*/ */
struct TALER_AgeWithdrawCommitmentHashP h_commitment GNUNET_PACKED; struct TALER_ReservePublicKeyP reserve_pub;
/** /**
* Value of the coin being exchanged (matching the denomination key) * Value of the coin being exchanged (matching the denomination key)
@ -635,7 +636,12 @@ struct TALER_AgeWithdrawRequestPS
struct TALER_AmountNBO amount_with_fee; struct TALER_AmountNBO amount_with_fee;
/** /**
* The mask that defines the age groups * Running SHA512 hash of the commitment of n*kappa coins
*/
struct TALER_AgeWithdrawCommitmentHashP h_commitment;
/**
* The mask that defines the age groups. MUST be the same for all denominations.
*/ */
struct TALER_AgeMask mask; struct TALER_AgeMask mask;
@ -665,6 +671,8 @@ TALER_wallet_age_withdraw_sign (
.max_age_group = TALER_get_age_group (mask, max_age) .max_age_group = TALER_get_age_group (mask, max_age)
}; };
GNUNET_CRYPTO_eddsa_key_get_public (&reserve_priv->eddsa_priv,
&req.reserve_pub.eddsa_pub);
TALER_amount_hton (&req.amount_with_fee, TALER_amount_hton (&req.amount_with_fee,
amount_with_fee); amount_with_fee);
GNUNET_CRYPTO_eddsa_sign (&reserve_priv->eddsa_priv, GNUNET_CRYPTO_eddsa_sign (&reserve_priv->eddsa_priv,
@ -685,6 +693,7 @@ TALER_wallet_age_withdraw_verify (
struct TALER_AgeWithdrawRequestPS awsrd = { struct TALER_AgeWithdrawRequestPS awsrd = {
.purpose.size = htonl (sizeof (awsrd)), .purpose.size = htonl (sizeof (awsrd)),
.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_AGE_WITHDRAW), .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_AGE_WITHDRAW),
.reserve_pub = *reserve_pub,
.h_commitment = *h_commitment, .h_commitment = *h_commitment,
.mask = *mask, .mask = *mask,
.max_age_group = TALER_get_age_group (mask, max_age) .max_age_group = TALER_get_age_group (mask, max_age)