-clean up refresh reveal API
This commit is contained in:
parent
4d26042b5a
commit
7cedf3f0bf
@ -1637,6 +1637,72 @@ struct TALER_EXCHANGE_RefreshData
|
||||
struct TALER_EXCHANGE_MeltHandle;
|
||||
|
||||
|
||||
/**
|
||||
* Information we obtain per coin during melting.
|
||||
*/
|
||||
struct TALER_EXCHANGE_MeltBlindingDetail
|
||||
{
|
||||
/**
|
||||
* Exchange values contributed to the refresh operation
|
||||
*/
|
||||
struct TALER_ExchangeWithdrawValues alg_value;
|
||||
|
||||
/**
|
||||
* Blinding keys used to blind the fresh coins
|
||||
*/
|
||||
union TALER_DenominationBlindingKeyP bks;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Response returned to a /melt request.
|
||||
*/
|
||||
struct TALER_EXCHANGE_MeltResponse
|
||||
{
|
||||
/**
|
||||
* Full HTTP response details.
|
||||
*/
|
||||
struct TALER_EXCHANGE_HttpResponse hr;
|
||||
|
||||
/**
|
||||
* Parsed response details, variant depending on the
|
||||
* @e hr.http_status.
|
||||
*/
|
||||
union
|
||||
{
|
||||
/**
|
||||
* Results for status #MHD_HTTP_SUCCESS.
|
||||
*/
|
||||
struct
|
||||
{
|
||||
|
||||
/**
|
||||
* Length of the @a mbds array with the exchange values
|
||||
* and blinding keys we are using.
|
||||
*/
|
||||
unsigned int num_mbds;
|
||||
|
||||
/**
|
||||
* Information returned per coin.
|
||||
*/
|
||||
const struct TALER_EXCHANGE_MeltBlindingDetail *mbds;
|
||||
|
||||
/**
|
||||
* Key used by the exchange to sign the response.
|
||||
*/
|
||||
struct TALER_ExchangePublicKeyP sign_key;
|
||||
|
||||
/**
|
||||
* Gamma value chosen by the exchange.
|
||||
*/
|
||||
uint32_t noreveal_index;
|
||||
} success;
|
||||
|
||||
} details;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Callbacks of this type are used to notify the application about the result
|
||||
* of the /coins/$COIN_PUB/melt stage. If successful, the @a noreveal_index
|
||||
@ -1650,7 +1716,7 @@ struct TALER_EXCHANGE_MeltHandle;
|
||||
* @param bks array of @a num_coins blinding keys used to blind the fresh coins
|
||||
* @param noreveal_index choice by the exchange in the cut-and-choose protocol,
|
||||
* UINT32_MAX on error
|
||||
* @param sign_key exchange key used to sign @a full_response, or NULL
|
||||
* @param sign_key exchange key used to sign the response, or NULL
|
||||
*/
|
||||
typedef void
|
||||
(*TALER_EXCHANGE_MeltCallback) (
|
||||
@ -1734,13 +1800,22 @@ struct TALER_EXCHANGE_RevealResult
|
||||
*/
|
||||
struct TALER_EXCHANGE_HttpResponse hr;
|
||||
|
||||
/**
|
||||
* Parsed response details, variant depending on the
|
||||
* @e hr.http_status.
|
||||
*/
|
||||
union
|
||||
{
|
||||
/**
|
||||
* Results for status #MHD_HTTP_SUCCESS.
|
||||
*/
|
||||
struct
|
||||
{
|
||||
/**
|
||||
* Array of @e num_coins values about the
|
||||
* coins obtained via the refresh operation.
|
||||
* Array of @e num_coins values about the coins obtained via the refresh
|
||||
* operation. The array give the coins in the same order (and should
|
||||
* have the same length) in which the original melt request specified the
|
||||
* respective denomination keys.
|
||||
*/
|
||||
const struct TALER_EXCHANGE_RevealedCoinInfo *coins;
|
||||
|
||||
@ -1759,25 +1834,15 @@ struct TALER_EXCHANGE_RevealResult
|
||||
* Callbacks of this type are used to return the final result of
|
||||
* submitting a refresh request to a exchange. If the operation was
|
||||
* successful, this function returns the signatures over the coins
|
||||
* that were remelted. The @a coin_privs and @a sigs arrays give the
|
||||
* coins in the same order (and should have the same length) in which
|
||||
* the original request specified the respective denomination keys.
|
||||
* that were remelted.
|
||||
*
|
||||
* @param cls closure
|
||||
* @param hr HTTP response data
|
||||
* @param num_coins number of fresh coins created, length of the @a sigs, @a psa and @a coin_privs arrays, 0 if the operation failed
|
||||
* @param coin_privs array of @a num_coins private keys for the coins that were created, NULL on error
|
||||
* @param psa array of @a num_coins planchet secrets (derived from the transfer secret) for each of the coins
|
||||
* @param sigs array of signature over @a num_coins coins, NULL on error
|
||||
* @param rr result of the reveal operation
|
||||
*/
|
||||
typedef void
|
||||
(*TALER_EXCHANGE_RefreshesRevealCallback)(
|
||||
void *cls,
|
||||
const struct TALER_EXCHANGE_HttpResponse *hr,
|
||||
unsigned int num_coins,
|
||||
const struct TALER_CoinSpendPrivateKeyP *coin_privs,
|
||||
const struct TALER_PlanchetMasterSecretP *psa,
|
||||
const struct TALER_DenominationSignature *sigs);
|
||||
const struct TALER_EXCHANGE_RevealResult *rr);
|
||||
|
||||
|
||||
/**
|
||||
@ -1877,8 +1942,15 @@ struct TALER_EXCHANGE_LinkResult
|
||||
*/
|
||||
struct TALER_EXCHANGE_HttpResponse hr;
|
||||
|
||||
/**
|
||||
* Parsed response details, variant depending on the
|
||||
* @e hr.http_status.
|
||||
*/
|
||||
union
|
||||
{
|
||||
/**
|
||||
* Results for status #MHD_HTTP_SUCCESS.
|
||||
*/
|
||||
struct
|
||||
{
|
||||
/**
|
||||
|
@ -99,15 +99,13 @@ struct TALER_EXCHANGE_RefreshesRevealHandle
|
||||
*
|
||||
* @param rrh operation handle
|
||||
* @param json reply from the exchange
|
||||
* @param[out] coin_privs array of length `num_fresh_coins`, initialized to contain the coin private keys
|
||||
* @param[out] sigs array of length `num_fresh_coins`, initialized to contain signatures
|
||||
* @param[out] rcis array of length `num_fresh_coins`, initialized to contain the coin data
|
||||
* @return #GNUNET_OK on success, #GNUNET_SYSERR on errors
|
||||
*/
|
||||
static enum GNUNET_GenericReturnValue
|
||||
refresh_reveal_ok (struct TALER_EXCHANGE_RefreshesRevealHandle *rrh,
|
||||
const json_t *json,
|
||||
struct TALER_CoinSpendPrivateKeyP *coin_privs,
|
||||
struct TALER_DenominationSignature *sigs)
|
||||
struct TALER_EXCHANGE_RevealedCoinInfo *rcis)
|
||||
{
|
||||
json_t *jsona;
|
||||
struct GNUNET_JSON_Specification outer_spec[] = {
|
||||
@ -140,7 +138,8 @@ refresh_reveal_ok (struct TALER_EXCHANGE_RefreshesRevealHandle *rrh,
|
||||
}
|
||||
for (unsigned int i = 0; i<rrh->md.num_fresh_coins; i++)
|
||||
{
|
||||
const struct TALER_PlanchetMasterSecretP *fc;
|
||||
struct TALER_EXCHANGE_RevealedCoinInfo *rci =
|
||||
&rcis[i];
|
||||
struct TALER_DenominationPublicKey *pk;
|
||||
json_t *jsonai;
|
||||
struct TALER_BlindedDenominationSignature blind_sig;
|
||||
@ -154,7 +153,7 @@ refresh_reveal_ok (struct TALER_EXCHANGE_RefreshesRevealHandle *rrh,
|
||||
struct TALER_FreshCoin coin;
|
||||
union TALER_DenominationBlindingKeyP bks;
|
||||
|
||||
fc = &rrh->md.fresh_coins[rrh->noreveal_index][i];
|
||||
rci->ps = rrh->md.fresh_coins[rrh->noreveal_index][i];
|
||||
pk = &rrh->md.fresh_pks[i];
|
||||
jsonai = json_array_get (jsona, i);
|
||||
GNUNET_assert (NULL != jsonai);
|
||||
@ -169,15 +168,15 @@ refresh_reveal_ok (struct TALER_EXCHANGE_RefreshesRevealHandle *rrh,
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
|
||||
TALER_planchet_setup_coin_priv (fc,
|
||||
TALER_planchet_setup_coin_priv (&rci->ps,
|
||||
&rrh->alg_values[i],
|
||||
&coin_privs[i]);
|
||||
TALER_planchet_blinding_secret_create (fc,
|
||||
&rci->coin_priv);
|
||||
TALER_planchet_blinding_secret_create (&rci->ps,
|
||||
&rrh->alg_values[i],
|
||||
&bks);
|
||||
/* needed to verify the signature, and we didn't store it earlier,
|
||||
hence recomputing it here... */
|
||||
GNUNET_CRYPTO_eddsa_key_get_public (&coin_privs[i].eddsa_priv,
|
||||
GNUNET_CRYPTO_eddsa_key_get_public (&rci->coin_priv.eddsa_priv,
|
||||
&coin_pub.eddsa_pub);
|
||||
/* FIXME-Oec: Age commitment hash. */
|
||||
TALER_coin_pub_hash (&coin_pub,
|
||||
@ -187,7 +186,7 @@ refresh_reveal_ok (struct TALER_EXCHANGE_RefreshesRevealHandle *rrh,
|
||||
TALER_planchet_to_coin (pk,
|
||||
&blind_sig,
|
||||
&bks,
|
||||
&coin_privs[i],
|
||||
&rci->coin_priv,
|
||||
&coin_hash,
|
||||
&rrh->alg_values[i],
|
||||
&coin))
|
||||
@ -198,7 +197,7 @@ refresh_reveal_ok (struct TALER_EXCHANGE_RefreshesRevealHandle *rrh,
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
sigs[i] = coin.sig;
|
||||
rci->sig = coin.sig;
|
||||
}
|
||||
GNUNET_JSON_parse_free (outer_spec);
|
||||
return GNUNET_OK;
|
||||
@ -220,94 +219,86 @@ handle_refresh_reveal_finished (void *cls,
|
||||
{
|
||||
struct TALER_EXCHANGE_RefreshesRevealHandle *rrh = cls;
|
||||
const json_t *j = response;
|
||||
struct TALER_EXCHANGE_HttpResponse hr = {
|
||||
.reply = j,
|
||||
.http_status = (unsigned int) response_code
|
||||
struct TALER_EXCHANGE_RevealResult rr = {
|
||||
.hr.reply = j,
|
||||
.hr.http_status = (unsigned int) response_code
|
||||
};
|
||||
|
||||
rrh->job = NULL;
|
||||
switch (response_code)
|
||||
{
|
||||
case 0:
|
||||
hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
|
||||
rr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
|
||||
break;
|
||||
case MHD_HTTP_OK:
|
||||
{
|
||||
struct TALER_DenominationSignature sigs[rrh->md.num_fresh_coins];
|
||||
struct TALER_CoinSpendPrivateKeyP coin_privs[rrh->md.num_fresh_coins];
|
||||
struct TALER_EXCHANGE_RevealedCoinInfo rcis[rrh->md.num_fresh_coins];
|
||||
enum GNUNET_GenericReturnValue ret;
|
||||
|
||||
memset (sigs,
|
||||
memset (rcis,
|
||||
0,
|
||||
sizeof (sigs));
|
||||
sizeof (rcis));
|
||||
ret = refresh_reveal_ok (rrh,
|
||||
j,
|
||||
coin_privs,
|
||||
sigs);
|
||||
rcis);
|
||||
if (GNUNET_OK != ret)
|
||||
{
|
||||
hr.http_status = 0;
|
||||
hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
|
||||
rr.hr.http_status = 0;
|
||||
rr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
GNUNET_assert (rrh->noreveal_index < TALER_CNC_KAPPA);
|
||||
rr.details.success.num_coins = rrh->md.num_fresh_coins;
|
||||
rr.details.success.coins = rcis;
|
||||
rrh->reveal_cb (rrh->reveal_cb_cls,
|
||||
&hr,
|
||||
rrh->md.num_fresh_coins,
|
||||
coin_privs,
|
||||
rrh->md.fresh_coins[rrh->noreveal_index],
|
||||
sigs);
|
||||
&rr);
|
||||
rrh->reveal_cb = NULL;
|
||||
}
|
||||
for (unsigned int i = 0; i<rrh->md.num_fresh_coins; i++)
|
||||
TALER_denom_sig_free (&sigs[i]);
|
||||
TALER_denom_sig_free (&rcis[i].sig);
|
||||
TALER_EXCHANGE_refreshes_reveal_cancel (rrh);
|
||||
return;
|
||||
}
|
||||
case MHD_HTTP_BAD_REQUEST:
|
||||
/* This should never happen, either us or the exchange is buggy
|
||||
(or API version conflict); just pass JSON reply to the application */
|
||||
hr.ec = TALER_JSON_get_error_code (j);
|
||||
hr.hint = TALER_JSON_get_error_hint (j);
|
||||
rr.hr.ec = TALER_JSON_get_error_code (j);
|
||||
rr.hr.hint = TALER_JSON_get_error_hint (j);
|
||||
break;
|
||||
case MHD_HTTP_CONFLICT:
|
||||
/* Nothing really to verify, exchange says our reveal is inconsistent
|
||||
with our commitment, so either side is buggy; we
|
||||
should pass the JSON reply to the application */
|
||||
hr.ec = TALER_JSON_get_error_code (j);
|
||||
hr.hint = TALER_JSON_get_error_hint (j);
|
||||
rr.hr.ec = TALER_JSON_get_error_code (j);
|
||||
rr.hr.hint = TALER_JSON_get_error_hint (j);
|
||||
break;
|
||||
case MHD_HTTP_GONE:
|
||||
/* Server claims key expired or has been revoked */
|
||||
hr.ec = TALER_JSON_get_error_code (j);
|
||||
hr.hint = TALER_JSON_get_error_hint (j);
|
||||
rr.hr.ec = TALER_JSON_get_error_code (j);
|
||||
rr.hr.hint = TALER_JSON_get_error_hint (j);
|
||||
break;
|
||||
case MHD_HTTP_INTERNAL_SERVER_ERROR:
|
||||
/* Server had an internal issue; we should retry, but this API
|
||||
leaves this to the application */
|
||||
hr.ec = TALER_JSON_get_error_code (j);
|
||||
hr.hint = TALER_JSON_get_error_hint (j);
|
||||
rr.hr.ec = TALER_JSON_get_error_code (j);
|
||||
rr.hr.hint = TALER_JSON_get_error_hint (j);
|
||||
break;
|
||||
default:
|
||||
/* unexpected response code */
|
||||
GNUNET_break_op (0);
|
||||
hr.ec = TALER_JSON_get_error_code (j);
|
||||
hr.hint = TALER_JSON_get_error_hint (j);
|
||||
rr.hr.ec = TALER_JSON_get_error_code (j);
|
||||
rr.hr.hint = TALER_JSON_get_error_hint (j);
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Unexpected response code %u/%d for exchange refreshes reveal\n",
|
||||
(unsigned int) response_code,
|
||||
(int) hr.ec);
|
||||
(int) rr.hr.ec);
|
||||
break;
|
||||
}
|
||||
if (NULL != rrh->reveal_cb)
|
||||
rrh->reveal_cb (rrh->reveal_cb_cls,
|
||||
&hr,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
&rr);
|
||||
TALER_EXCHANGE_refreshes_reveal_cancel (rrh);
|
||||
}
|
||||
|
||||
|
@ -358,13 +358,10 @@ do_reveal_retry (void *cls)
|
||||
*/
|
||||
static void
|
||||
reveal_cb (void *cls,
|
||||
const struct TALER_EXCHANGE_HttpResponse *hr,
|
||||
unsigned int num_coins,
|
||||
const struct TALER_CoinSpendPrivateKeyP *coin_privs,
|
||||
const struct TALER_PlanchetMasterSecretP *psa,
|
||||
const struct TALER_DenominationSignature *sigs)
|
||||
const struct TALER_EXCHANGE_RevealResult *rr)
|
||||
{
|
||||
struct RefreshRevealState *rrs = cls;
|
||||
const struct TALER_EXCHANGE_HttpResponse *hr = &rr->hr;
|
||||
const struct TALER_TESTING_Command *melt_cmd;
|
||||
|
||||
rrs->rrh = NULL;
|
||||
@ -417,20 +414,22 @@ reveal_cb (void *cls,
|
||||
TALER_TESTING_interpreter_fail (rrs->is);
|
||||
return;
|
||||
}
|
||||
rrs->num_fresh_coins = num_coins;
|
||||
switch (hr->http_status)
|
||||
{
|
||||
case MHD_HTTP_OK:
|
||||
rrs->psa = GNUNET_memdup (psa,
|
||||
num_coins
|
||||
* sizeof (struct TALER_PlanchetMasterSecretP));
|
||||
rrs->fresh_coins = GNUNET_new_array (num_coins,
|
||||
rrs->num_fresh_coins = rr->details.success.num_coins;
|
||||
rrs->psa = GNUNET_new_array (rrs->num_fresh_coins,
|
||||
struct TALER_PlanchetMasterSecretP);
|
||||
rrs->fresh_coins = GNUNET_new_array (rrs->num_fresh_coins,
|
||||
struct TALER_TESTING_FreshCoinData);
|
||||
for (unsigned int i = 0; i<num_coins; i++)
|
||||
for (unsigned int i = 0; i<rrs->num_fresh_coins; i++)
|
||||
{
|
||||
const struct TALER_EXCHANGE_RevealedCoinInfo *coin
|
||||
= &rr->details.success.coins[i];
|
||||
struct TALER_TESTING_FreshCoinData *fc = &rrs->fresh_coins[i];
|
||||
const union TALER_DenominationBlindingKeyP *bks;
|
||||
|
||||
rrs->psa[i] = coin->ps;
|
||||
if (GNUNET_OK !=
|
||||
TALER_TESTING_get_trait_denom_pub (melt_cmd,
|
||||
i,
|
||||
@ -449,10 +448,10 @@ reveal_cb (void *cls,
|
||||
TALER_TESTING_interpreter_fail (rrs->is);
|
||||
return;
|
||||
}
|
||||
fc->coin_priv = coin_privs[i];
|
||||
fc->coin_priv = coin->coin_priv;
|
||||
fc->blinding_key = *bks;
|
||||
TALER_denom_sig_deep_copy (&fc->sig,
|
||||
&sigs[i]);
|
||||
&coin->sig);
|
||||
}
|
||||
if (0 != rrs->total_backoff.rel_value_us)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user