[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.
* FIXME[oec]: Make the [][] structure more explicit.
*/
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
{
@ -3726,7 +3728,7 @@ TALER_wallet_withdraw_verify (
/**
* 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 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.
@ -3762,7 +3764,6 @@ TALER_wallet_age_withdraw_verify (
const struct TALER_ReservePublicKeyP *reserve_pub,
const struct TALER_ReserveSignatureP *reserve_sig);
/**
* Verify exchange melt confirmation.
*
@ -4871,6 +4872,22 @@ TALER_exchange_online_age_withdraw_confirmation_sign (
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 ************************** */

View File

@ -18,6 +18,7 @@
* @brief C interface of libtalerexchange, a C library to use exchange's HTTP API
* @author Sree Harsha Totakura <sreeharsha@totakura.in>
* @author Christian Grothoff
* @author Özgür Kesim
*/
#ifndef _TALER_EXCHANGE_SERVICE_H
#define _TALER_EXCHANGE_SERVICE_H
@ -1618,7 +1619,8 @@ typedef void
/**
* 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 nonce client nonce for the request
* @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 *
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_CsNonce *nonce,
TALER_EXCHANGE_CsRWithdrawCallback res_cb,
@ -2448,7 +2451,9 @@ typedef void
* disk before calling, and be ready to repeat the request with the
* 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 wci inputs that determine the planchet
* @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 *
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_EXCHANGE_WithdrawCoinInput *wci,
TALER_EXCHANGE_WithdrawCallback res_cb,
@ -2575,7 +2582,9 @@ typedef void
* disk before calling, and be ready to repeat the request with the
* 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 wcis inputs that determine the planchets
* @param wci_length number of entries in @a wcis
@ -2587,7 +2596,9 @@ typedef void
*/
struct TALER_EXCHANGE_BatchWithdrawHandle *
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_EXCHANGE_WithdrawCoinInput *wcis,
unsigned int wci_length,
@ -2668,7 +2679,9 @@ struct TALER_EXCHANGE_Withdraw2Handle;
* disk before calling, and be ready to repeat the request with the
* 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 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
@ -2679,7 +2692,9 @@ struct TALER_EXCHANGE_Withdraw2Handle;
*/
struct TALER_EXCHANGE_Withdraw2Handle *
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_ReservePrivateKeyP *reserve_priv,
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
* 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_length number of entries in the @a pds array
* @param reserve_priv private key of the reserve to withdraw from
@ -2777,7 +2794,9 @@ struct TALER_EXCHANGE_BatchWithdraw2Handle;
*/
struct TALER_EXCHANGE_BatchWithdraw2Handle *
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_PlanchetDetail *pds,
unsigned int pds_length,
@ -2796,6 +2815,119 @@ TALER_EXCHANGE_batch_withdraw2_cancel (
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 ***************************** */
@ -3565,7 +3697,7 @@ TALER_EXCHANGE_verify_coin_history (
*/
enum GNUNET_GenericReturnValue
TALER_EXCHANGE_parse_reserve_history (
struct TALER_EXCHANGE_Keys *keys,
const struct TALER_EXCHANGE_Keys *keys,
const json_t *history,
const struct TALER_ReservePublicKeyP *reserve_pub,
const char *currency,

View File

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

View File

@ -22,6 +22,7 @@ libtalerexchange_la_LDFLAGS = \
-no-undefined
libtalerexchange_la_SOURCES = \
exchange_api_add_aml_decision.c \
exchange_api_age_withdraw.c \
exchange_api_auditor_add_denomination.c \
exchange_api_batch_deposit.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.
@ -255,7 +266,9 @@ phase_two (struct TALER_EXCHANGE_BatchWithdrawHandle *wh)
pds[i] = cd->pd;
}
wh->wh2 = TALER_EXCHANGE_batch_withdraw2 (
wh->exchange,
wh->curl_ctx,
wh->exchange_url,
wh->keys,
wh->reserve_priv,
pds,
wh->num_coins,
@ -322,7 +335,9 @@ withdraw_cs_stage_two_callback (
struct TALER_EXCHANGE_BatchWithdrawHandle *
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_EXCHANGE_WithdrawCoinInput *wcis,
unsigned int wci_length,
@ -332,7 +347,9 @@ TALER_EXCHANGE_batch_withdraw (
struct TALER_EXCHANGE_BatchWithdrawHandle *wh;
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_cls = res_cb_cls;
wh->reserve_priv = reserve_priv;
@ -386,7 +403,8 @@ TALER_EXCHANGE_batch_withdraw (
will be done after the /csr-withdraw request! */
cd->pd.blinded_planchet.cipher = TALER_DENOMINATION_CS;
cd->csrh = TALER_EXCHANGE_csr_withdraw (
exchange,
curl_ctx,
exchange_url,
&cd->pk,
&cd->pd.blinded_planchet.details.cs_blinded_planchet.nonce,
&withdraw_cs_stage_two_callback,

View File

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

View File

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

View File

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

View File

@ -25,7 +25,6 @@
#define _TALER_CURL_DEFAULTS_H
#include "platform.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 pull_all_keys = 0 != (flags & TALER_EXCHANGE_CKF_PULL_ALL_KEYS);
GNUNET_assert (NULL != exchange);
if ( (NULL != cb) &&
( (exchange->cert_cb != cb) ||
(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 *
TALER_EXCHANGE_melt (
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 *
TALER_EXCHANGE_refreshes_reveal (
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.
@ -232,7 +242,9 @@ withdraw_cs_stage_two_callback (
GNUNET_break (0);
break;
}
wh->wh2 = TALER_EXCHANGE_withdraw2 (wh->exchange,
wh->wh2 = TALER_EXCHANGE_withdraw2 (wh->curl_ctx,
wh->exchange_url,
wh->keys,
&wh->pd,
wh->reserve_priv,
&handle_reserve_withdraw_finished,
@ -249,7 +261,9 @@ withdraw_cs_stage_two_callback (
struct TALER_EXCHANGE_WithdrawHandle *
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_EXCHANGE_WithdrawCoinInput *wci,
TALER_EXCHANGE_WithdrawCallback res_cb,
@ -258,7 +272,9 @@ TALER_EXCHANGE_withdraw (
struct TALER_EXCHANGE_WithdrawHandle *wh;
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_cls = res_cb_cls;
wh->reserve_priv = reserve_priv;
@ -292,7 +308,9 @@ TALER_EXCHANGE_withdraw (
GNUNET_free (wh);
return NULL;
}
wh->wh2 = TALER_EXCHANGE_withdraw2 (exchange,
wh->wh2 = TALER_EXCHANGE_withdraw2 (curl_ctx,
exchange_url,
keys,
&wh->pd,
wh->reserve_priv,
&handle_reserve_withdraw_finished,
@ -309,7 +327,8 @@ TALER_EXCHANGE_withdraw (
will be done after the /csr-withdraw request! */
wh->pd.blinded_planchet.cipher = TALER_DENOMINATION_CS;
wh->csrh = TALER_EXCHANGE_csr_withdraw (
exchange,
curl_ctx,
exchange_url,
&wh->pk,
&wh->pd.blinded_planchet.details.cs_blinded_planchet.nonce,
&withdraw_cs_stage_two_callback,
@ -339,6 +358,7 @@ TALER_EXCHANGE_withdraw_cancel (struct TALER_EXCHANGE_WithdrawHandle *wh)
TALER_EXCHANGE_withdraw2_cancel (wh->wh2);
wh->wh2 = NULL;
}
TALER_EXCHANGE_keys_decref (wh->keys);
TALER_denom_pub_free (&wh->pk.key);
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.
@ -192,8 +192,7 @@ reserve_withdraw_payment_required (
}
if (GNUNET_OK !=
TALER_EXCHANGE_parse_reserve_history (TALER_EXCHANGE_get_keys (
wh->exchange),
TALER_EXCHANGE_parse_reserve_history (wh->keys,
history,
&wh->reserve_pub,
balance.currency,
@ -361,25 +360,21 @@ handle_reserve_withdraw_finished (void *cls,
struct TALER_EXCHANGE_Withdraw2Handle *
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_ReservePrivateKeyP *reserve_priv,
TALER_EXCHANGE_Withdraw2Callback res_cb,
void *res_cb_cls)
{
struct TALER_EXCHANGE_Withdraw2Handle *wh;
const struct TALER_EXCHANGE_Keys *keys;
const struct TALER_EXCHANGE_DenomPublicKey *dk;
struct TALER_ReserveSignatureP reserve_sig;
char arg_str[sizeof (struct TALER_ReservePublicKeyP) * 2 + 32];
struct TALER_BlindedCoinHashP bch;
keys = TALER_EXCHANGE_get_keys (exchange);
if (NULL == keys)
{
GNUNET_break (0);
return NULL;
}
GNUNET_assert (NULL != keys);
dk = TALER_EXCHANGE_get_denomination_key_by_hash (keys,
&pd->denom_pub_hash);
if (NULL == dk)
@ -388,7 +383,7 @@ TALER_EXCHANGE_withdraw2 (
return NULL;
}
wh = GNUNET_new (struct TALER_EXCHANGE_Withdraw2Handle);
wh->exchange = exchange;
wh->keys = TALER_EXCHANGE_keys_incref (keys);
wh->cb = res_cb;
wh->cb_cls = res_cb_cls;
/* Compute how much we expected to charge to the reserve */
@ -418,7 +413,7 @@ TALER_EXCHANGE_withdraw2 (
*end = '\0';
GNUNET_snprintf (arg_str,
sizeof (arg_str),
"/reserves/%s/withdraw",
"reserves/%s/withdraw",
pub_str);
}
@ -448,8 +443,9 @@ TALER_EXCHANGE_withdraw2 (
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Attempting to withdraw from reserve %s\n",
TALER_B2S (&wh->reserve_pub));
wh->url = TEAH_path_to_url (exchange,
arg_str);
wh->url = TALER_url_join (exchange_url,
arg_str,
NULL);
if (NULL == wh->url)
{
json_decref (withdraw_obj);
@ -458,9 +454,7 @@ TALER_EXCHANGE_withdraw2 (
}
{
CURL *eh;
struct GNUNET_CURL_Context *ctx;
ctx = TEAH_handle_to_context (exchange);
eh = TALER_EXCHANGE_curl_easy_get_ (wh->url);
if ( (NULL == eh) ||
(GNUNET_OK !=
@ -477,7 +471,7 @@ TALER_EXCHANGE_withdraw2 (
return NULL;
}
json_decref (withdraw_obj);
wh->job = GNUNET_CURL_job_add2 (ctx,
wh->job = GNUNET_CURL_job_add2 (curl_ctx,
eh,
wh->post_ctx.headers,
&handle_reserve_withdraw_finished,
@ -498,5 +492,6 @@ TALER_EXCHANGE_withdraw2_cancel (struct TALER_EXCHANGE_Withdraw2Handle *wh)
}
GNUNET_free (wh->url);
TALER_curl_easy_post_finished (&wh->post_ctx);
TALER_EXCHANGE_keys_decref (wh->keys);
GNUNET_free (wh);
}

View File

@ -321,12 +321,15 @@ batch_withdraw_run (void *cls,
wci->ps = &cs->ps;
wci->ach = cs->h_age_commitment;
}
ws->wsh = TALER_EXCHANGE_batch_withdraw (exchange,
rp,
wcis,
ws->num_coins,
&reserve_batch_withdraw_cb,
ws);
ws->wsh = TALER_EXCHANGE_batch_withdraw (
TALER_TESTING_interpreter_get_context (is),
TALER_TESTING_get_exchange_url (is),
TALER_TESTING_get_keys (is),
rp,
wcis,
ws->num_coins,
&reserve_batch_withdraw_cb,
ws);
if (NULL == ws->wsh)
{
GNUNET_break (0);

View File

@ -410,7 +410,7 @@ withdraw_run (void *cls,
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->age > 0);
if (NULL == dpk)
@ -443,11 +443,14 @@ withdraw_run (void *cls,
.ps = &ws->ps,
.ach = ws->h_age_commitment
};
ws->wsh = TALER_EXCHANGE_withdraw (exchange,
rp,
&wci,
&reserve_withdraw_cb,
ws);
ws->wsh = TALER_EXCHANGE_withdraw (
TALER_TESTING_interpreter_get_context (is),
TALER_TESTING_get_exchange_url (is),
TALER_TESTING_get_keys (is),
rp,
&wci,
&reserve_withdraw_cb,
ws);
}
if (NULL == ws->wsh)
{

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 */

View File

@ -22,6 +22,7 @@
#include "platform.h"
#include "taler_util.h"
#include "taler_signatures.h"
#include <gnunet/gnunet_common.h>
GNUNET_NETWORK_STRUCT_BEGIN
@ -621,9 +622,9 @@ struct TALER_AgeWithdrawRequestPS
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)
@ -635,7 +636,12 @@ struct TALER_AgeWithdrawRequestPS
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;
@ -665,6 +671,8 @@ TALER_wallet_age_withdraw_sign (
.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,
amount_with_fee);
GNUNET_CRYPTO_eddsa_sign (&reserve_priv->eddsa_priv,
@ -685,6 +693,7 @@ TALER_wallet_age_withdraw_verify (
struct TALER_AgeWithdrawRequestPS awsrd = {
.purpose.size = htonl (sizeof (awsrd)),
.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_AGE_WITHDRAW),
.reserve_pub = *reserve_pub,
.h_commitment = *h_commitment,
.mask = *mask,
.max_age_group = TALER_get_age_group (mask, max_age)