summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorChristian Grothoff <grothoff@gnunet.org>2022-02-04 23:58:41 +0100
committerChristian Grothoff <grothoff@gnunet.org>2022-02-04 23:58:41 +0100
commitb30765c7d07240a48e66a551e6f82dc0a5670bec (patch)
treeb3a05d51662e3cfb6146dc15f5a11e07d1e48480 /src/lib
parentcfc6c3fcd04e9bed639816828d05e8645d80860f (diff)
downloadexchange-b30765c7d07240a48e66a551e6f82dc0a5670bec.tar.gz
exchange-b30765c7d07240a48e66a551e6f82dc0a5670bec.tar.bz2
exchange-b30765c7d07240a48e66a551e6f82dc0a5670bec.zip
make API actually workable, sketch out melt
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/exchange_api_melt.c230
-rw-r--r--src/lib/exchange_api_refresh_common.c1
-rw-r--r--src/lib/exchange_api_refresh_common.h10
3 files changed, 197 insertions, 44 deletions
diff --git a/src/lib/exchange_api_melt.c b/src/lib/exchange_api_melt.c
index b93d255ec..dc9a400d6 100644
--- a/src/lib/exchange_api_melt.c
+++ b/src/lib/exchange_api_melt.c
@@ -73,7 +73,23 @@ struct TALER_EXCHANGE_MeltHandle
/**
* Actual information about the melt operation.
*/
- struct MeltData *md;
+ struct MeltData md;
+
+ /**
+ * The secret the entire melt operation is seeded from.
+ */
+ const struct TALER_PlanchetSecretsP *ps;
+
+ /**
+ * Details about the characteristics of the requested melt operation.
+ */
+ const struct TALER_EXCHANGE_RefreshData *rd;
+
+ /**
+ * Array of `num_fresh_coins` contributory values of
+ * the exchange to the melt operation.
+ */
+ struct TALER_ExchangeWithdrawValues *alg_values;
/**
* Public key of the coin being melted.
@@ -106,9 +122,12 @@ verify_melt_signature_ok (struct TALER_EXCHANGE_MeltHandle *mh,
struct TALER_ExchangeSignatureP exchange_sig;
const struct TALER_EXCHANGE_Keys *key_state;
struct GNUNET_JSON_Specification spec[] = {
- GNUNET_JSON_spec_fixed_auto ("exchange_sig", &exchange_sig),
- GNUNET_JSON_spec_fixed_auto ("exchange_pub", exchange_pub),
- GNUNET_JSON_spec_uint32 ("noreveal_index", noreveal_index),
+ GNUNET_JSON_spec_fixed_auto ("exchange_sig",
+ &exchange_sig),
+ GNUNET_JSON_spec_fixed_auto ("exchange_pub",
+ exchange_pub),
+ GNUNET_JSON_spec_uint32 ("noreveal_index",
+ noreveal_index),
GNUNET_JSON_spec_end ()
};
struct TALER_RefreshMeltConfirmationPS confirm;
@@ -338,6 +357,12 @@ handle_melt_finished (void *cls,
{
mh->melt_cb (mh->melt_cb_cls,
&hr,
+ (0 == hr.http_status)
+ ? 0
+ : mh->rd->fresh_pks_len,
+ (0 == hr.http_status)
+ ? NULL
+ : mh->alg_values,
noreveal_index,
(0 == hr.http_status)
? NULL
@@ -419,42 +444,37 @@ handle_melt_finished (void *cls,
if (NULL != mh->melt_cb)
mh->melt_cb (mh->melt_cb_cls,
&hr,
+ 0,
+ NULL,
UINT32_MAX,
NULL);
TALER_EXCHANGE_melt_cancel (mh);
}
-struct TALER_EXCHANGE_MeltHandle *
-TALER_EXCHANGE_melt (struct TALER_EXCHANGE_Handle *exchange,
- const struct TALER_PlanchetSecretsP *ps,
- const struct TALER_EXCHANGE_RefreshData *rd,
- TALER_EXCHANGE_MeltCallback melt_cb,
- void *melt_cb_cls)
+static enum GNUNET_GenericReturnValue
+start_melt (struct TALER_EXCHANGE_MeltHandle *mh)
{
const struct TALER_EXCHANGE_Keys *key_state;
const struct TALER_EXCHANGE_DenomPublicKey *dki;
json_t *melt_obj;
- struct TALER_EXCHANGE_MeltHandle *mh;
CURL *eh;
struct GNUNET_CURL_Context *ctx;
- struct MeltData *md;
struct TALER_CoinSpendSignatureP confirm_sig;
char arg_str[sizeof (struct TALER_CoinSpendPublicKeyP) * 2 + 32];
struct TALER_DenominationHash h_denom_pub;
struct TALER_CoinSpendPublicKeyP coin_pub;
- GNUNET_assert (GNUNET_YES ==
- TEAH_handle_is_ready (exchange));
if (GNUNET_OK !=
- TALER_EXCHANGE_get_melt_data (ps,
- rd,
- &md))
+ TALER_EXCHANGE_get_melt_data_ (mh->ps,
+ mh->rd,
+ mh->alg_values,
+ &mh->md))
{
GNUNET_break (0);
- return NULL;
+ return GNUNET_SYSERR;
}
- TALER_denom_pub_hash (&md->melted_coin.pub_key,
+ TALER_denom_pub_hash (&mh->md.melted_coin.pub_key,
&h_denom_pub);
TALER_wallet_melt_sign (&md->melted_coin.melt_amount_with_fee,
&md->melted_coin.fee_melt,
@@ -491,30 +511,19 @@ TALER_EXCHANGE_melt (struct TALER_EXCHANGE_Handle *exchange,
pub_str);
}
- key_state = TALER_EXCHANGE_get_keys (exchange);
+ ctx = TEAH_handle_to_context (mh->exchange);
+ key_state = TALER_EXCHANGE_get_keys (mh->exchange);
dki = TALER_EXCHANGE_get_denomination_key (key_state,
- &md->melted_coin.pub_key);
+ &mh->md.melted_coin.pub_key);
/* and now we can at last begin the actual request handling */
- mh = GNUNET_new (struct TALER_EXCHANGE_MeltHandle);
- mh->exchange = exchange;
- mh->coin_pub = coin_pub;
- mh->dki = *dki;
- memset (&mh->dki.key,
- 0,
- sizeof (mh->dki.key)); /* lifetime not warranted, so better
- not copy the pointers */
- mh->melt_cb = melt_cb;
- mh->melt_cb_cls = melt_cb_cls;
- mh->md = md;
- mh->url = TEAH_path_to_url (exchange,
+
+ mh->url = TEAH_path_to_url (mh->exchange,
arg_str);
if (NULL == mh->url)
{
json_decref (melt_obj);
- TALER_EXCHANGE_free_melt_data_ (&md);
- GNUNET_free (mh);
- return NULL;
+ return GNUNET_SYSERR;
}
eh = TALER_EXCHANGE_curl_easy_get_ (mh->url);
if ( (NULL == eh) ||
@@ -526,19 +535,155 @@ TALER_EXCHANGE_melt (struct TALER_EXCHANGE_Handle *exchange,
GNUNET_break (0);
if (NULL != eh)
curl_easy_cleanup (eh);
- TALER_EXCHANGE_free_melt_data_ (&md);
json_decref (melt_obj);
- GNUNET_free (mh->url);
- GNUNET_free (mh);
- return NULL;
+ return GNUNET_SYSERR;
}
json_decref (melt_obj);
- ctx = TEAH_handle_to_context (exchange);
mh->job = GNUNET_CURL_job_add2 (ctx,
eh,
mh->ctx.headers,
&handle_melt_finished,
mh);
+ return GNUNET_OK;
+}
+
+
+static void
+fail_mh (struct TALER_EXCHANGE_MeltHandle *mh)
+{
+ // FIXME: do return more than NULLs if
+ // the /csr failed!
+ mh->melt_cb (mh->melt_cb_cls,
+ NULL,
+ 0,
+ NULL,
+ UINT32_MAX,
+ NULL);
+ TALER_EXCHANGE_melt_cancel (mh);
+}
+
+
+/**
+ * Callbacks of this type are used to serve the result of submitting a
+ * CS R request to a exchange.
+ *
+ * @param cls closure with our `struct TALER_EXCHANGE_MeltHandle *`
+ * @param csrr response details
+ */
+static void
+csr_cb (void *cls,
+ const struct TALER_EXCHANGE_CsRResponse *csrr)
+{
+ struct TALER_EXCHANGE_MeltHandle *mh = cls;
+ unsigned int nks_off = 0;
+
+ for (unsigned int i = 0; i<rd->fresh_pks_len; i++)
+ {
+ const struct TALER_EXCHANGE_DenomPublicKey *fresh_pk = &rd->fresh_pks[i];
+ struct TALER_ExchangeWithdrawValues *wv = &mh->alg_values[i];
+
+ switch (fresh_pk->cipher)
+ {
+ case TALER_DENOMINATION_INVALID:
+ GNUNET_break (0);
+ fail_mh (mh).
+ return;
+ case TALER_DENOMINATION_RSA:
+ GNUNET_assert (TALER_DENOMINATION_RSA == wv->cipher);
+ break;
+ case TALER_DENOMINATION_CS:
+ GNUNET_assert (TALER_DENOMINATION_CS == wv->cipher);
+ *wv = csrr->details.success.alg_values[nks_off];
+ nks_off++;
+ break;
+ }
+ }
+ if (GNUNET_OK !=
+ start_melt (mh))
+ {
+ GNUNET_break (0);
+ fail_mh (mh);
+ return;
+ }
+}
+
+
+struct TALER_EXCHANGE_MeltHandle *
+TALER_EXCHANGE_melt (struct TALER_EXCHANGE_Handle *exchange,
+ const struct TALER_PlanchetSecretsP *ps,
+ const struct TALER_EXCHANGE_RefreshData *rd,
+ TALER_EXCHANGE_MeltCallback melt_cb,
+ void *melt_cb_cls)
+s
+{
+ const struct TALER_EXCHANGE_NonceKey *nks[GNUNET_NZL (rd->refresh_pks_len)];
+ unsigned int nks_off = 0;
+
+ if (0 == rd->refresh_pks_len)
+ {
+ GNUNET_break (0);
+ return NULL;
+ }
+ GNUNET_assert (GNUNET_YES ==
+ TEAH_handle_is_ready (exchange));
+ mh = GNUNET_new (struct TALER_EXCHANGE_MeltHandle);
+ mh->exchange = exchange;
+ mh->rd = rd;
+ mh->ps = ps;
+ mh->melt_cb = melt_cb;
+ mh->melt_cb_cls = melt_cb_cls;
+ mh->alg_values = GNUNET_new_array (struct TALER_ExchangeWithdrawValues,
+ rd->fresh_pks_len);
+ for (unsigned int i = 0; i<rd->fresh_pks_len; i++)
+ {
+ const struct TALER_EXCHANGE_DenomPublicKey *fresh_pk = &rd->fresh_pks[i];
+ struct TALER_ExchangeWithdrawValues *wv = &mh->alg_values[i];
+
+ switch (fresh_pk->cipher)
+ {
+ case TALER_DENOMINATION_INVALID:
+ GNUNET_break (0);
+ GNUNET_free (mh->alg_values);
+ GNUNET_free (mh);
+ return NULL;
+ case TALER_DENOMINATION_RSA:
+ wv->cipher = TALER_DENOMINATION_RSA;
+ break;
+ case TALER_DENOMINATION_CS:
+ wv->cipher = TALER_DENOMINATION_CS;
+ nks[nks_off].pk = fresh_pk;
+ // derive nonce for refresh by index and ps;
+ // FIXME: include fresh_pk or not?
+ TALER_CRYPTO_XXX (ps,
+ fresh_pk,
+ i,
+ &nks[nks_off].nonce);
+ nks_off++;
+ break;
+ }
+ }
+ if (0 != nks_off)
+ {
+ mh->csr = TALER_EXCHANGE_csr (exchange,
+ nks_off,
+ nks,
+ &csr_cb,
+ mh);
+ if (NULL == mh->csr)
+ {
+ GNUNET_break (0);
+ TALER_EXCHANGE_melt_cancel (mh->csr);
+ return NULL;
+ }
+ return mh;
+ }
+ if (GNUNET_OK !=
+ start_melt (mh))
+ {
+ GNUNET_break (0);
+ TALER_EXCHANGE_melt_cancel (mh->csr);
+ return NULL;
+ }
return mh;
}
@@ -551,8 +696,7 @@ TALER_EXCHANGE_melt_cancel (struct TALER_EXCHANGE_MeltHandle *mh)
GNUNET_CURL_job_cancel (mh->job);
mh->job = NULL;
}
- TALER_EXCHANGE_free_melt_data_ (mh->md); /* does not free 'md' itself */
- GNUNET_free (mh->md);
+ TALER_EXCHANGE_free_melt_data_ (&mh->md); /* does not free 'md' itself */
GNUNET_free (mh->url);
TALER_curl_easy_post_finished (&mh->ctx);
GNUNET_free (mh);
diff --git a/src/lib/exchange_api_refresh_common.c b/src/lib/exchange_api_refresh_common.c
index 9fcc26877..cf04bca58 100644
--- a/src/lib/exchange_api_refresh_common.c
+++ b/src/lib/exchange_api_refresh_common.c
@@ -46,6 +46,7 @@ enum GNUNET_GenericReturnValue
TALER_EXCHANGE_get_melt_data_ (
const struct TALER_PlanchetSecretsP *ps,
const struct struct TALER_EXCHANGE_RefreshData *rd,
+ const struct TALER_ExchangeWithdrawValues *alg_values,
struct MeltData *md)
{
struct MeltData md;
diff --git a/src/lib/exchange_api_refresh_common.h b/src/lib/exchange_api_refresh_common.h
index 1ce513efb..653d48866 100644
--- a/src/lib/exchange_api_refresh_common.h
+++ b/src/lib/exchange_api_refresh_common.h
@@ -1,6 +1,6 @@
/*
This file is part of TALER
- Copyright (C) 2015-2020 Taler Systems SA
+ Copyright (C) 2015-2022 Taler Systems SA
TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
@@ -103,6 +103,12 @@ struct MeltData
struct TALER_DenominationPublicKey *fresh_pks;
/**
+ * Array of @e num_fresh_coins with exchange contributions
+ * made during the refresh.
+ */
+ struct TALER_ExchangeWithdrawValues *exchange_vals;
+
+ /**
* Arrays of @e num_fresh_coins with information about the fresh
* coins to be created, for each cut-and-choose dimension.
*/
@@ -115,12 +121,14 @@ struct MeltData
*
* @param ps secret internals of the refresh-reveal operation
* @param rd refresh data with the characteristics of the operation
+ * @param alg_values contributions from the exchange into the melt
* @param[out] rd where to write the derived melt data
*/
enum GNUNET_GenericReturnValue
TALER_EXCHANGE_get_melt_data_ (
const struct TALER_PlanchetSecretsP *ps,
const struct struct TALER_EXCHANGE_RefreshData *rd,
+ const struct TALER_ExchangeWithdrawValues *alg_values,
struct MeltData *md);