major API refactoring, adding planchet generation and coin extraction APIs to the Taler crypto library, thereby simplifying code in withdraw, refresh, tipping, payback and testcases; slight API incompatibilities to previous versions are introduced
This commit is contained in:
parent
ec8146de92
commit
2f2930f1ba
@ -1,3 +1,9 @@
|
|||||||
|
Tue Oct 31 13:43:55 CET 2017
|
||||||
|
Extended crypto API to provide planchet generation functions
|
||||||
|
explicitly (to be used on withdraw, refresh and tipping).
|
||||||
|
Renamed a few API calls to better reflect their functions.
|
||||||
|
Changed a few function signatures to use new structs. -CG
|
||||||
|
|
||||||
Wed Oct 18 15:20:29 CEST 2017
|
Wed Oct 18 15:20:29 CEST 2017
|
||||||
Releasing Taler v0.4.0. -CG
|
Releasing Taler v0.4.0. -CG
|
||||||
|
|
||||||
|
@ -981,6 +981,7 @@ withdraw_coin (struct Coin *coin)
|
|||||||
struct TALER_Amount left;
|
struct TALER_Amount left;
|
||||||
const struct TALER_EXCHANGE_Keys *keys;
|
const struct TALER_EXCHANGE_Keys *keys;
|
||||||
struct Reserve *r;
|
struct Reserve *r;
|
||||||
|
struct TALER_PlanchetSecretsP ps;
|
||||||
|
|
||||||
keys = TALER_EXCHANGE_get_keys (exchange);
|
keys = TALER_EXCHANGE_get_keys (exchange);
|
||||||
r = &reserves[coin->reserve_index];
|
r = &reserves[coin->reserve_index];
|
||||||
@ -996,12 +997,13 @@ withdraw_coin (struct Coin *coin)
|
|||||||
GNUNET_assert (NULL != (coin->pk = find_pk (keys, &amount)));
|
GNUNET_assert (NULL != (coin->pk = find_pk (keys, &amount)));
|
||||||
if (warm >= WARM_THRESHOLD)
|
if (warm >= WARM_THRESHOLD)
|
||||||
num_withdraw++;
|
num_withdraw++;
|
||||||
|
ps.coin_priv = coin->coin_priv;
|
||||||
|
ps.blinding_key = blinding_key;
|
||||||
coin->wsh =
|
coin->wsh =
|
||||||
TALER_EXCHANGE_reserve_withdraw (exchange,
|
TALER_EXCHANGE_reserve_withdraw (exchange,
|
||||||
coin->pk,
|
coin->pk,
|
||||||
&r->reserve_priv,
|
&r->reserve_priv,
|
||||||
&coin->coin_priv,
|
&ps,
|
||||||
&blinding_key,
|
|
||||||
&reserve_withdraw_cb,
|
&reserve_withdraw_cb,
|
||||||
coin);
|
coin);
|
||||||
GNUNET_assert (GNUNET_SYSERR !=
|
GNUNET_assert (GNUNET_SYSERR !=
|
||||||
|
@ -260,8 +260,7 @@ handle_payback_finished (void *cls,
|
|||||||
* @param exchange the exchange handle; the exchange must be ready to operate
|
* @param exchange the exchange handle; the exchange must be ready to operate
|
||||||
* @param pk kind of coin to pay back
|
* @param pk kind of coin to pay back
|
||||||
* @param denom_sig signature over the coin by the exchange using @a pk
|
* @param denom_sig signature over the coin by the exchange using @a pk
|
||||||
* @param coin_priv the coin's private key,
|
* @param ps secret internals of the original planchet
|
||||||
* @param blinding_key where to fetch the coin's blinding key
|
|
||||||
* @param payback_cb the callback to call when the final result for this request is available
|
* @param payback_cb the callback to call when the final result for this request is available
|
||||||
* @param payback_cb_cls closure for @a payback_cb
|
* @param payback_cb_cls closure for @a payback_cb
|
||||||
* @return NULL
|
* @return NULL
|
||||||
@ -272,8 +271,7 @@ struct TALER_EXCHANGE_PaybackHandle *
|
|||||||
TALER_EXCHANGE_payback (struct TALER_EXCHANGE_Handle *exchange,
|
TALER_EXCHANGE_payback (struct TALER_EXCHANGE_Handle *exchange,
|
||||||
const struct TALER_EXCHANGE_DenomPublicKey *pk,
|
const struct TALER_EXCHANGE_DenomPublicKey *pk,
|
||||||
const struct TALER_DenominationSignature *denom_sig,
|
const struct TALER_DenominationSignature *denom_sig,
|
||||||
const struct TALER_CoinSpendPrivateKeyP *coin_priv,
|
const struct TALER_PlanchetSecretsP *ps,
|
||||||
const struct TALER_DenominationBlindingKeyP *blinding_key,
|
|
||||||
TALER_EXCHANGE_PaybackResultCallback payback_cb,
|
TALER_EXCHANGE_PaybackResultCallback payback_cb,
|
||||||
void *payback_cb_cls)
|
void *payback_cb_cls)
|
||||||
{
|
{
|
||||||
@ -288,12 +286,12 @@ TALER_EXCHANGE_payback (struct TALER_EXCHANGE_Handle *exchange,
|
|||||||
MAH_handle_is_ready (exchange));
|
MAH_handle_is_ready (exchange));
|
||||||
pr.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_PAYBACK);
|
pr.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_PAYBACK);
|
||||||
pr.purpose.size = htonl (sizeof (struct TALER_PaybackRequestPS));
|
pr.purpose.size = htonl (sizeof (struct TALER_PaybackRequestPS));
|
||||||
GNUNET_CRYPTO_eddsa_key_get_public (&coin_priv->eddsa_priv,
|
GNUNET_CRYPTO_eddsa_key_get_public (&ps->coin_priv.eddsa_priv,
|
||||||
&pr.coin_pub.eddsa_pub);
|
&pr.coin_pub.eddsa_pub);
|
||||||
pr.h_denom_pub = pk->h_key;
|
pr.h_denom_pub = pk->h_key;
|
||||||
pr.coin_blind = *blinding_key;
|
pr.coin_blind = ps->blinding_key;
|
||||||
GNUNET_assert (GNUNET_OK ==
|
GNUNET_assert (GNUNET_OK ==
|
||||||
GNUNET_CRYPTO_eddsa_sign (&coin_priv->eddsa_priv,
|
GNUNET_CRYPTO_eddsa_sign (&ps->coin_priv.eddsa_priv,
|
||||||
&pr.purpose,
|
&pr.purpose,
|
||||||
&coin_sig.eddsa_signature));
|
&coin_sig.eddsa_signature));
|
||||||
|
|
||||||
@ -304,7 +302,7 @@ TALER_EXCHANGE_payback (struct TALER_EXCHANGE_Handle *exchange,
|
|||||||
"denom_sig", GNUNET_JSON_from_rsa_signature (denom_sig->rsa_signature),
|
"denom_sig", GNUNET_JSON_from_rsa_signature (denom_sig->rsa_signature),
|
||||||
"coin_pub", GNUNET_JSON_from_data_auto (&pr.coin_pub),
|
"coin_pub", GNUNET_JSON_from_data_auto (&pr.coin_pub),
|
||||||
"coin_sig", GNUNET_JSON_from_data_auto (&coin_sig),
|
"coin_sig", GNUNET_JSON_from_data_auto (&coin_sig),
|
||||||
"coin_blind_key_secret", GNUNET_JSON_from_data_auto (blinding_key)
|
"coin_blind_key_secret", GNUNET_JSON_from_data_auto (&ps->blinding_key)
|
||||||
);
|
);
|
||||||
if (NULL == payback_obj)
|
if (NULL == payback_obj)
|
||||||
{
|
{
|
||||||
|
@ -236,18 +236,16 @@ free_melted_coin (struct MeltedCoin *mc)
|
|||||||
static void
|
static void
|
||||||
free_melt_data (struct MeltData *md)
|
free_melt_data (struct MeltData *md)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
free_melted_coin (&md->melted_coin);
|
free_melted_coin (&md->melted_coin);
|
||||||
if (NULL != md->fresh_pks)
|
if (NULL != md->fresh_pks)
|
||||||
{
|
{
|
||||||
for (i=0;i<md->num_fresh_coins;i++)
|
for (unsigned int i=0;i<md->num_fresh_coins;i++)
|
||||||
if (NULL != md->fresh_pks[i].rsa_public_key)
|
if (NULL != md->fresh_pks[i].rsa_public_key)
|
||||||
GNUNET_CRYPTO_rsa_public_key_free (md->fresh_pks[i].rsa_public_key);
|
GNUNET_CRYPTO_rsa_public_key_free (md->fresh_pks[i].rsa_public_key);
|
||||||
GNUNET_free (md->fresh_pks);
|
GNUNET_free (md->fresh_pks);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i=0;i<TALER_CNC_KAPPA;i++)
|
for (unsigned int i=0;i<TALER_CNC_KAPPA;i++)
|
||||||
GNUNET_free (md->fresh_coins[i]);
|
GNUNET_free (md->fresh_coins[i]);
|
||||||
/* Finally, clean up a bit...
|
/* Finally, clean up a bit...
|
||||||
(NOTE: compilers might optimize this away, so this is
|
(NOTE: compilers might optimize this away, so this is
|
||||||
@ -600,8 +598,6 @@ deserialize_melt_data (const char *buf,
|
|||||||
{
|
{
|
||||||
struct MeltData *md;
|
struct MeltData *md;
|
||||||
struct MeltDataP mdp;
|
struct MeltDataP mdp;
|
||||||
unsigned int i;
|
|
||||||
unsigned int j;
|
|
||||||
size_t off;
|
size_t off;
|
||||||
int ok;
|
int ok;
|
||||||
|
|
||||||
@ -615,7 +611,7 @@ deserialize_melt_data (const char *buf,
|
|||||||
md->num_fresh_coins = ntohs (mdp.num_fresh_coins);
|
md->num_fresh_coins = ntohs (mdp.num_fresh_coins);
|
||||||
md->fresh_pks = GNUNET_new_array (md->num_fresh_coins,
|
md->fresh_pks = GNUNET_new_array (md->num_fresh_coins,
|
||||||
struct TALER_DenominationPublicKey);
|
struct TALER_DenominationPublicKey);
|
||||||
for (i=0;i<TALER_CNC_KAPPA;i++)
|
for (unsigned int i=0;i<TALER_CNC_KAPPA;i++)
|
||||||
md->fresh_coins[i] = GNUNET_new_array (md->num_fresh_coins,
|
md->fresh_coins[i] = GNUNET_new_array (md->num_fresh_coins,
|
||||||
struct TALER_PlanchetSecretsP);
|
struct TALER_PlanchetSecretsP);
|
||||||
off = sizeof (struct MeltDataP);
|
off = sizeof (struct MeltDataP);
|
||||||
@ -624,14 +620,14 @@ deserialize_melt_data (const char *buf,
|
|||||||
&buf[off],
|
&buf[off],
|
||||||
buf_size - off,
|
buf_size - off,
|
||||||
&ok);
|
&ok);
|
||||||
for (i=0;(i<md->num_fresh_coins)&&(GNUNET_YES == ok);i++)
|
for (unsigned int i=0;(i<md->num_fresh_coins)&&(GNUNET_YES == ok);i++)
|
||||||
off += deserialize_denomination_key (&md->fresh_pks[i],
|
off += deserialize_denomination_key (&md->fresh_pks[i],
|
||||||
&buf[off],
|
&buf[off],
|
||||||
buf_size - off,
|
buf_size - off,
|
||||||
&ok);
|
&ok);
|
||||||
|
|
||||||
for (i=0;i<TALER_CNC_KAPPA;i++)
|
for (unsigned int i=0;i<TALER_CNC_KAPPA;i++)
|
||||||
for(j=0;(j<md->num_fresh_coins)&&(GNUNET_YES == ok);j++)
|
for (unsigned int j=0;(j<md->num_fresh_coins)&&(GNUNET_YES == ok);j++)
|
||||||
off += deserialize_fresh_coin (&md->fresh_coins[i][j],
|
off += deserialize_fresh_coin (&md->fresh_coins[i][j],
|
||||||
&buf[off],
|
&buf[off],
|
||||||
buf_size - off,
|
buf_size - off,
|
||||||
@ -704,8 +700,6 @@ TALER_EXCHANGE_refresh_prepare (const struct TALER_CoinSpendPrivateKeyP *melt_pr
|
|||||||
{
|
{
|
||||||
struct MeltData md;
|
struct MeltData md;
|
||||||
char *buf;
|
char *buf;
|
||||||
unsigned int i;
|
|
||||||
unsigned int j;
|
|
||||||
struct GNUNET_HashContext *hash_context;
|
struct GNUNET_HashContext *hash_context;
|
||||||
struct TALER_Amount total;
|
struct TALER_Amount total;
|
||||||
struct TALER_CoinSpendPublicKeyP coin_pub;
|
struct TALER_CoinSpendPublicKeyP coin_pub;
|
||||||
@ -715,7 +709,7 @@ TALER_EXCHANGE_refresh_prepare (const struct TALER_CoinSpendPrivateKeyP *melt_pr
|
|||||||
&coin_pub.eddsa_pub);
|
&coin_pub.eddsa_pub);
|
||||||
hash_context = GNUNET_CRYPTO_hash_context_start ();
|
hash_context = GNUNET_CRYPTO_hash_context_start ();
|
||||||
/* build up melt data structure */
|
/* build up melt data structure */
|
||||||
for (i=0;i<TALER_CNC_KAPPA;i++)
|
for (unsigned int i=0;i<TALER_CNC_KAPPA;i++)
|
||||||
{
|
{
|
||||||
struct GNUNET_CRYPTO_EcdhePrivateKey *tpk;
|
struct GNUNET_CRYPTO_EcdhePrivateKey *tpk;
|
||||||
struct TALER_TransferPublicKeyP tp;
|
struct TALER_TransferPublicKeyP tp;
|
||||||
@ -747,18 +741,18 @@ TALER_EXCHANGE_refresh_prepare (const struct TALER_CoinSpendPrivateKeyP *melt_pr
|
|||||||
= GNUNET_CRYPTO_rsa_signature_dup (melt_sig->rsa_signature);
|
= GNUNET_CRYPTO_rsa_signature_dup (melt_sig->rsa_signature);
|
||||||
md.fresh_pks = GNUNET_new_array (fresh_pks_len,
|
md.fresh_pks = GNUNET_new_array (fresh_pks_len,
|
||||||
struct TALER_DenominationPublicKey);
|
struct TALER_DenominationPublicKey);
|
||||||
for (i=0;i<fresh_pks_len;i++)
|
for (unsigned int i=0;i<fresh_pks_len;i++)
|
||||||
md.fresh_pks[i].rsa_public_key
|
md.fresh_pks[i].rsa_public_key
|
||||||
= GNUNET_CRYPTO_rsa_public_key_dup (fresh_pks[i].key.rsa_public_key);
|
= GNUNET_CRYPTO_rsa_public_key_dup (fresh_pks[i].key.rsa_public_key);
|
||||||
for (i=0;i<TALER_CNC_KAPPA;i++)
|
for (unsigned int i=0;i<TALER_CNC_KAPPA;i++)
|
||||||
{
|
{
|
||||||
md.fresh_coins[i] = GNUNET_new_array (fresh_pks_len,
|
md.fresh_coins[i] = GNUNET_new_array (fresh_pks_len,
|
||||||
struct TALER_PlanchetSecretsP);
|
struct TALER_PlanchetSecretsP);
|
||||||
for (j=0;j<fresh_pks_len;j++)
|
for (unsigned int j=0;j<fresh_pks_len;j++)
|
||||||
{
|
{
|
||||||
TALER_planchet_setup_refresh (&trans_sec[i],
|
TALER_planchet_setup_refresh (&trans_sec[i],
|
||||||
j,
|
j,
|
||||||
&md.fresh_coins[i][j]);
|
&md.fresh_coins[i][j]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -766,7 +760,7 @@ TALER_EXCHANGE_refresh_prepare (const struct TALER_CoinSpendPrivateKeyP *melt_pr
|
|||||||
GNUNET_assert (GNUNET_OK ==
|
GNUNET_assert (GNUNET_OK ==
|
||||||
TALER_amount_get_zero (melt_amount->currency,
|
TALER_amount_get_zero (melt_amount->currency,
|
||||||
&total));
|
&total));
|
||||||
for (j=0;j<fresh_pks_len;j++)
|
for (unsigned int j=0;j<fresh_pks_len;j++)
|
||||||
{
|
{
|
||||||
if ( (GNUNET_OK !=
|
if ( (GNUNET_OK !=
|
||||||
TALER_amount_add (&total,
|
TALER_amount_add (&total,
|
||||||
@ -795,7 +789,7 @@ TALER_EXCHANGE_refresh_prepare (const struct TALER_CoinSpendPrivateKeyP *melt_pr
|
|||||||
|
|
||||||
/* next, add all of the hashes from the denomination keys to the
|
/* next, add all of the hashes from the denomination keys to the
|
||||||
hash_context */
|
hash_context */
|
||||||
for (i=0;i<fresh_pks_len;i++)
|
for (unsigned int i=0;i<fresh_pks_len;i++)
|
||||||
{
|
{
|
||||||
char *buf;
|
char *buf;
|
||||||
size_t buf_size;
|
size_t buf_size;
|
||||||
@ -820,28 +814,18 @@ TALER_EXCHANGE_refresh_prepare (const struct TALER_CoinSpendPrivateKeyP *melt_pr
|
|||||||
sizeof (struct TALER_AmountNBO));
|
sizeof (struct TALER_AmountNBO));
|
||||||
|
|
||||||
}
|
}
|
||||||
for (i = 0; i < TALER_CNC_KAPPA; i++)
|
for (unsigned int i = 0; i < TALER_CNC_KAPPA; i++)
|
||||||
{
|
{
|
||||||
for (j = 0; j < fresh_pks_len; j++)
|
for (unsigned int j = 0; j < fresh_pks_len; j++)
|
||||||
{
|
{
|
||||||
const struct TALER_PlanchetSecretsP *fc; /* coin this is about */
|
const struct TALER_PlanchetSecretsP *fc; /* coin this is about */
|
||||||
struct TALER_CoinSpendPublicKeyP coin_pub;
|
struct TALER_PlanchetDetail pd;
|
||||||
struct GNUNET_HashCode coin_hash;
|
|
||||||
char *coin_ev; /* blinded message to be signed (in envelope) for each coin */
|
|
||||||
size_t coin_ev_size;
|
|
||||||
|
|
||||||
fc = &md.fresh_coins[i][j];
|
fc = &md.fresh_coins[i][j];
|
||||||
GNUNET_CRYPTO_eddsa_key_get_public (&fc->coin_priv.eddsa_priv,
|
if (GNUNET_OK !=
|
||||||
&coin_pub.eddsa_pub);
|
TALER_planchet_prepare (&md.fresh_pks[j],
|
||||||
GNUNET_CRYPTO_hash (&coin_pub.eddsa_pub,
|
fc,
|
||||||
sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey),
|
&pd))
|
||||||
&coin_hash);
|
|
||||||
if (GNUNET_YES !=
|
|
||||||
GNUNET_CRYPTO_rsa_blind (&coin_hash,
|
|
||||||
&fc->blinding_key.bks,
|
|
||||||
md.fresh_pks[j].rsa_public_key,
|
|
||||||
&coin_ev,
|
|
||||||
&coin_ev_size))
|
|
||||||
{
|
{
|
||||||
GNUNET_break_op (0);
|
GNUNET_break_op (0);
|
||||||
GNUNET_CRYPTO_hash_context_abort (hash_context);
|
GNUNET_CRYPTO_hash_context_abort (hash_context);
|
||||||
@ -849,9 +833,9 @@ TALER_EXCHANGE_refresh_prepare (const struct TALER_CoinSpendPrivateKeyP *melt_pr
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
GNUNET_CRYPTO_hash_context_read (hash_context,
|
GNUNET_CRYPTO_hash_context_read (hash_context,
|
||||||
coin_ev,
|
pd.coin_ev,
|
||||||
coin_ev_size);
|
pd.coin_ev_size);
|
||||||
GNUNET_free (coin_ev);
|
GNUNET_free (pd.coin_ev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
GNUNET_CRYPTO_hash_context_finish (hash_context,
|
GNUNET_CRYPTO_hash_context_finish (hash_context,
|
||||||
@ -1294,22 +1278,12 @@ TALER_EXCHANGE_refresh_melt (struct TALER_EXCHANGE_Handle *exchange,
|
|||||||
for (i=0;i<md->num_fresh_coins;i++)
|
for (i=0;i<md->num_fresh_coins;i++)
|
||||||
{
|
{
|
||||||
const struct TALER_PlanchetSecretsP *fc = &md->fresh_coins[j][i];
|
const struct TALER_PlanchetSecretsP *fc = &md->fresh_coins[j][i];
|
||||||
struct TALER_CoinSpendPublicKeyP coin_pub;
|
struct TALER_PlanchetDetail pd;
|
||||||
struct GNUNET_HashCode coin_hash;
|
|
||||||
char *coin_ev; /* blinded message to be signed (in envelope) for each coin */
|
|
||||||
size_t coin_ev_size;
|
|
||||||
|
|
||||||
GNUNET_CRYPTO_eddsa_key_get_public (&fc->coin_priv.eddsa_priv,
|
if (GNUNET_OK !=
|
||||||
&coin_pub.eddsa_pub);
|
TALER_planchet_prepare (&md->fresh_pks[i],
|
||||||
GNUNET_CRYPTO_hash (&coin_pub.eddsa_pub,
|
fc,
|
||||||
sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey),
|
&pd))
|
||||||
&coin_hash);
|
|
||||||
if (GNUNET_YES !=
|
|
||||||
GNUNET_CRYPTO_rsa_blind (&coin_hash,
|
|
||||||
&fc->blinding_key.bks,
|
|
||||||
md->fresh_pks[i].rsa_public_key,
|
|
||||||
&coin_ev,
|
|
||||||
&coin_ev_size))
|
|
||||||
{
|
{
|
||||||
/* This should have been noticed during the preparation stage. */
|
/* This should have been noticed during the preparation stage. */
|
||||||
GNUNET_break (0);
|
GNUNET_break (0);
|
||||||
@ -1322,9 +1296,9 @@ TALER_EXCHANGE_refresh_melt (struct TALER_EXCHANGE_Handle *exchange,
|
|||||||
}
|
}
|
||||||
GNUNET_assert (0 ==
|
GNUNET_assert (0 ==
|
||||||
json_array_append_new (tmp,
|
json_array_append_new (tmp,
|
||||||
GNUNET_JSON_from_data (coin_ev,
|
GNUNET_JSON_from_data (pd.coin_ev,
|
||||||
coin_ev_size)));
|
pd.coin_ev_size)));
|
||||||
GNUNET_free (coin_ev);
|
GNUNET_free (pd.coin_ev);
|
||||||
}
|
}
|
||||||
GNUNET_assert (0 ==
|
GNUNET_assert (0 ==
|
||||||
json_array_append_new (coin_evs,
|
json_array_append_new (coin_evs,
|
||||||
@ -1510,13 +1484,13 @@ refresh_reveal_ok (struct TALER_EXCHANGE_RefreshRevealHandle *rrh,
|
|||||||
struct TALER_DenominationPublicKey *pk;
|
struct TALER_DenominationPublicKey *pk;
|
||||||
json_t *jsonai;
|
json_t *jsonai;
|
||||||
struct GNUNET_CRYPTO_RsaSignature *blind_sig;
|
struct GNUNET_CRYPTO_RsaSignature *blind_sig;
|
||||||
struct GNUNET_CRYPTO_RsaSignature *sig;
|
|
||||||
struct TALER_CoinSpendPublicKeyP coin_pub;
|
struct TALER_CoinSpendPublicKeyP coin_pub;
|
||||||
struct GNUNET_HashCode coin_hash;
|
struct GNUNET_HashCode coin_hash;
|
||||||
struct GNUNET_JSON_Specification spec[] = {
|
struct GNUNET_JSON_Specification spec[] = {
|
||||||
GNUNET_JSON_spec_rsa_signature ("ev_sig", &blind_sig),
|
GNUNET_JSON_spec_rsa_signature ("ev_sig", &blind_sig),
|
||||||
GNUNET_JSON_spec_end()
|
GNUNET_JSON_spec_end()
|
||||||
};
|
};
|
||||||
|
struct TALER_FreshCoin coin;
|
||||||
|
|
||||||
fc = &rrh->md->fresh_coins[rrh->noreveal_index][i];
|
fc = &rrh->md->fresh_coins[rrh->noreveal_index][i];
|
||||||
pk = &rrh->md->fresh_pks[i];
|
pk = &rrh->md->fresh_pks[i];
|
||||||
@ -1533,31 +1507,28 @@ refresh_reveal_ok (struct TALER_EXCHANGE_RefreshRevealHandle *rrh,
|
|||||||
return GNUNET_SYSERR;
|
return GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* unblind the signature */
|
/* needed to verify the signature, and we didn't store it earlier,
|
||||||
sig = GNUNET_CRYPTO_rsa_unblind (blind_sig,
|
hence recomputing it here... */
|
||||||
&fc->blinding_key.bks,
|
|
||||||
pk->rsa_public_key);
|
|
||||||
GNUNET_CRYPTO_rsa_signature_free (blind_sig);
|
|
||||||
|
|
||||||
/* verify the signature */
|
|
||||||
GNUNET_CRYPTO_eddsa_key_get_public (&fc->coin_priv.eddsa_priv,
|
GNUNET_CRYPTO_eddsa_key_get_public (&fc->coin_priv.eddsa_priv,
|
||||||
&coin_pub.eddsa_pub);
|
&coin_pub.eddsa_pub);
|
||||||
GNUNET_CRYPTO_hash (&coin_pub.eddsa_pub,
|
GNUNET_CRYPTO_hash (&coin_pub.eddsa_pub,
|
||||||
sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey),
|
sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey),
|
||||||
&coin_hash);
|
&coin_hash);
|
||||||
|
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
GNUNET_CRYPTO_rsa_verify (&coin_hash,
|
TALER_planchet_to_coin (pk,
|
||||||
sig,
|
blind_sig,
|
||||||
pk->rsa_public_key))
|
fc,
|
||||||
|
&coin_hash,
|
||||||
|
&coin))
|
||||||
{
|
{
|
||||||
GNUNET_break_op (0);
|
GNUNET_break_op (0);
|
||||||
GNUNET_CRYPTO_rsa_signature_free (sig);
|
GNUNET_CRYPTO_rsa_signature_free (blind_sig);
|
||||||
GNUNET_JSON_parse_free (outer_spec);
|
GNUNET_JSON_parse_free (outer_spec);
|
||||||
return GNUNET_SYSERR;
|
return GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
coin_privs[i] = fc->coin_priv;
|
GNUNET_CRYPTO_rsa_signature_free (blind_sig);
|
||||||
sigs[i].rsa_signature = sig;
|
coin_privs[i] = coin.coin_priv;
|
||||||
|
sigs[i] = coin.sig;
|
||||||
}
|
}
|
||||||
GNUNET_JSON_parse_free (outer_spec);
|
GNUNET_JSON_parse_free (outer_spec);
|
||||||
return GNUNET_OK;
|
return GNUNET_OK;
|
||||||
|
@ -693,9 +693,9 @@ struct TALER_EXCHANGE_ReserveWithdrawHandle
|
|||||||
TALER_EXCHANGE_ReserveWithdrawResultCallback cb;
|
TALER_EXCHANGE_ReserveWithdrawResultCallback cb;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Key used to blind the value.
|
* Secrets of the planchet.
|
||||||
*/
|
*/
|
||||||
struct TALER_DenominationBlindingKeyP blinding_key;
|
struct TALER_PlanchetSecretsP ps;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Denomination key we are withdrawing.
|
* Denomination key we are withdrawing.
|
||||||
@ -739,8 +739,7 @@ reserve_withdraw_ok (struct TALER_EXCHANGE_ReserveWithdrawHandle *wsh,
|
|||||||
const json_t *json)
|
const json_t *json)
|
||||||
{
|
{
|
||||||
struct GNUNET_CRYPTO_RsaSignature *blind_sig;
|
struct GNUNET_CRYPTO_RsaSignature *blind_sig;
|
||||||
struct GNUNET_CRYPTO_RsaSignature *sig;
|
struct TALER_FreshCoin fc;
|
||||||
struct TALER_DenominationSignature dsig;
|
|
||||||
struct GNUNET_JSON_Specification spec[] = {
|
struct GNUNET_JSON_Specification spec[] = {
|
||||||
GNUNET_JSON_spec_rsa_signature ("ev_sig", &blind_sig),
|
GNUNET_JSON_spec_rsa_signature ("ev_sig", &blind_sig),
|
||||||
GNUNET_JSON_spec_end()
|
GNUNET_JSON_spec_end()
|
||||||
@ -754,29 +753,28 @@ reserve_withdraw_ok (struct TALER_EXCHANGE_ReserveWithdrawHandle *wsh,
|
|||||||
GNUNET_break_op (0);
|
GNUNET_break_op (0);
|
||||||
return GNUNET_SYSERR;
|
return GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
sig = GNUNET_CRYPTO_rsa_unblind (blind_sig,
|
|
||||||
&wsh->blinding_key.bks,
|
|
||||||
wsh->pk->key.rsa_public_key);
|
|
||||||
GNUNET_CRYPTO_rsa_signature_free (blind_sig);
|
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
GNUNET_CRYPTO_rsa_verify (&wsh->c_hash,
|
TALER_planchet_to_coin (&wsh->pk->key,
|
||||||
sig,
|
blind_sig,
|
||||||
wsh->pk->key.rsa_public_key))
|
&wsh->ps,
|
||||||
|
&wsh->c_hash,
|
||||||
|
&fc))
|
||||||
{
|
{
|
||||||
GNUNET_break_op (0);
|
GNUNET_break_op (0);
|
||||||
GNUNET_CRYPTO_rsa_signature_free (sig);
|
GNUNET_JSON_parse_free (spec);
|
||||||
return GNUNET_SYSERR;
|
return GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
|
GNUNET_JSON_parse_free (spec);
|
||||||
|
|
||||||
/* signature is valid, return it to the application */
|
/* signature is valid, return it to the application */
|
||||||
dsig.rsa_signature = sig;
|
|
||||||
wsh->cb (wsh->cb_cls,
|
wsh->cb (wsh->cb_cls,
|
||||||
MHD_HTTP_OK,
|
MHD_HTTP_OK,
|
||||||
TALER_EC_NONE,
|
TALER_EC_NONE,
|
||||||
&dsig,
|
&fc.sig,
|
||||||
json);
|
json);
|
||||||
/* make sure callback isn't called again after return */
|
/* make sure callback isn't called again after return */
|
||||||
wsh->cb = NULL;
|
wsh->cb = NULL;
|
||||||
GNUNET_CRYPTO_rsa_signature_free (sig);
|
GNUNET_CRYPTO_rsa_signature_free (fc.sig.rsa_signature);
|
||||||
return GNUNET_OK;
|
return GNUNET_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -978,9 +976,7 @@ handle_reserve_withdraw_finished (void *cls,
|
|||||||
* @param exchange the exchange handle; the exchange must be ready to operate
|
* @param exchange the exchange handle; the exchange must be ready to operate
|
||||||
* @param pk kind of coin to create
|
* @param pk kind of coin to create
|
||||||
* @param reserve_priv private key of the reserve to withdraw from
|
* @param reserve_priv private key of the reserve to withdraw from
|
||||||
* @param coin_priv where to fetch the coin's private key,
|
* @param ps secrets of the planchet
|
||||||
* caller must have committed this value to disk before the call (with @a pk)
|
|
||||||
* @param blinding_key where to fetch the coin's blinding key
|
|
||||||
* caller must have committed this value to disk before the call (with @a pk)
|
* caller must have committed this value to disk before the call (with @a pk)
|
||||||
* @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
|
||||||
* @param res_cb_cls closure for the above callback
|
* @param res_cb_cls closure for the above callback
|
||||||
@ -992,44 +988,33 @@ struct TALER_EXCHANGE_ReserveWithdrawHandle *
|
|||||||
TALER_EXCHANGE_reserve_withdraw (struct TALER_EXCHANGE_Handle *exchange,
|
TALER_EXCHANGE_reserve_withdraw (struct TALER_EXCHANGE_Handle *exchange,
|
||||||
const struct TALER_EXCHANGE_DenomPublicKey *pk,
|
const struct TALER_EXCHANGE_DenomPublicKey *pk,
|
||||||
const struct TALER_ReservePrivateKeyP *reserve_priv,
|
const struct TALER_ReservePrivateKeyP *reserve_priv,
|
||||||
const struct TALER_CoinSpendPrivateKeyP *coin_priv,
|
const struct TALER_PlanchetSecretsP *ps,
|
||||||
const struct TALER_DenominationBlindingKeyP *blinding_key,
|
|
||||||
TALER_EXCHANGE_ReserveWithdrawResultCallback res_cb,
|
TALER_EXCHANGE_ReserveWithdrawResultCallback res_cb,
|
||||||
void *res_cb_cls)
|
void *res_cb_cls)
|
||||||
{
|
{
|
||||||
struct TALER_EXCHANGE_ReserveWithdrawHandle *wsh;
|
struct TALER_EXCHANGE_ReserveWithdrawHandle *wsh;
|
||||||
struct TALER_WithdrawRequestPS req;
|
struct TALER_WithdrawRequestPS req;
|
||||||
struct TALER_ReserveSignatureP reserve_sig;
|
struct TALER_ReserveSignatureP reserve_sig;
|
||||||
struct TALER_CoinSpendPublicKeyP coin_pub;
|
|
||||||
struct GNUNET_CURL_Context *ctx;
|
struct GNUNET_CURL_Context *ctx;
|
||||||
struct TALER_Amount amount_with_fee;
|
struct TALER_Amount amount_with_fee;
|
||||||
char *coin_ev;
|
|
||||||
size_t coin_ev_size;
|
|
||||||
json_t *withdraw_obj;
|
json_t *withdraw_obj;
|
||||||
CURL *eh;
|
CURL *eh;
|
||||||
|
struct TALER_PlanchetDetail pd;
|
||||||
|
|
||||||
|
if (GNUNET_OK !=
|
||||||
|
TALER_planchet_prepare (&pk->key,
|
||||||
|
ps,
|
||||||
|
&pd))
|
||||||
|
{
|
||||||
|
GNUNET_break_op (0);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
wsh = GNUNET_new (struct TALER_EXCHANGE_ReserveWithdrawHandle);
|
wsh = GNUNET_new (struct TALER_EXCHANGE_ReserveWithdrawHandle);
|
||||||
wsh->exchange = exchange;
|
wsh->exchange = exchange;
|
||||||
wsh->cb = res_cb;
|
wsh->cb = res_cb;
|
||||||
wsh->cb_cls = res_cb_cls;
|
wsh->cb_cls = res_cb_cls;
|
||||||
wsh->pk = pk;
|
wsh->pk = pk;
|
||||||
|
wsh->c_hash = pd.c_hash;
|
||||||
GNUNET_CRYPTO_eddsa_key_get_public (&coin_priv->eddsa_priv,
|
|
||||||
&coin_pub.eddsa_pub);
|
|
||||||
GNUNET_CRYPTO_hash (&coin_pub.eddsa_pub,
|
|
||||||
sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey),
|
|
||||||
&wsh->c_hash);
|
|
||||||
if (GNUNET_YES !=
|
|
||||||
GNUNET_CRYPTO_rsa_blind (&wsh->c_hash,
|
|
||||||
&blinding_key->bks,
|
|
||||||
pk->key.rsa_public_key,
|
|
||||||
&coin_ev,
|
|
||||||
&coin_ev_size))
|
|
||||||
{
|
|
||||||
GNUNET_break_op (0);
|
|
||||||
GNUNET_free (wsh);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
GNUNET_CRYPTO_eddsa_key_get_public (&reserve_priv->eddsa_priv,
|
GNUNET_CRYPTO_eddsa_key_get_public (&reserve_priv->eddsa_priv,
|
||||||
&wsh->reserve_pub.eddsa_pub);
|
&wsh->reserve_pub.eddsa_pub);
|
||||||
req.purpose.size = htonl (sizeof (struct TALER_WithdrawRequestPS));
|
req.purpose.size = htonl (sizeof (struct TALER_WithdrawRequestPS));
|
||||||
@ -1042,7 +1027,7 @@ TALER_EXCHANGE_reserve_withdraw (struct TALER_EXCHANGE_Handle *exchange,
|
|||||||
{
|
{
|
||||||
/* exchange gave us denomination keys that overflow like this!? */
|
/* exchange gave us denomination keys that overflow like this!? */
|
||||||
GNUNET_break_op (0);
|
GNUNET_break_op (0);
|
||||||
GNUNET_free (coin_ev);
|
GNUNET_free (pd.coin_ev);
|
||||||
GNUNET_free (wsh);
|
GNUNET_free (wsh);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -1050,10 +1035,9 @@ TALER_EXCHANGE_reserve_withdraw (struct TALER_EXCHANGE_Handle *exchange,
|
|||||||
&amount_with_fee);
|
&amount_with_fee);
|
||||||
TALER_amount_hton (&req.withdraw_fee,
|
TALER_amount_hton (&req.withdraw_fee,
|
||||||
&pk->fee_withdraw);
|
&pk->fee_withdraw);
|
||||||
GNUNET_CRYPTO_rsa_public_key_hash (pk->key.rsa_public_key,
|
req.h_denomination_pub = pd.denom_pub_hash;
|
||||||
&req.h_denomination_pub);
|
GNUNET_CRYPTO_hash (pd.coin_ev,
|
||||||
GNUNET_CRYPTO_hash (coin_ev,
|
pd.coin_ev_size,
|
||||||
coin_ev_size,
|
|
||||||
&req.h_coin_envelope);
|
&req.h_coin_envelope);
|
||||||
GNUNET_assert (GNUNET_OK ==
|
GNUNET_assert (GNUNET_OK ==
|
||||||
GNUNET_CRYPTO_eddsa_sign (&reserve_priv->eddsa_priv,
|
GNUNET_CRYPTO_eddsa_sign (&reserve_priv->eddsa_priv,
|
||||||
@ -1062,11 +1046,11 @@ TALER_EXCHANGE_reserve_withdraw (struct TALER_EXCHANGE_Handle *exchange,
|
|||||||
withdraw_obj = json_pack ("{s:o, s:o," /* denom_pub and coin_ev */
|
withdraw_obj = json_pack ("{s:o, s:o," /* denom_pub and coin_ev */
|
||||||
" s:o, s:o}",/* reserve_pub and reserve_sig */
|
" s:o, s:o}",/* reserve_pub and reserve_sig */
|
||||||
"denom_pub", GNUNET_JSON_from_rsa_public_key (pk->key.rsa_public_key),
|
"denom_pub", GNUNET_JSON_from_rsa_public_key (pk->key.rsa_public_key),
|
||||||
"coin_ev", GNUNET_JSON_from_data (coin_ev,
|
"coin_ev", GNUNET_JSON_from_data (pd.coin_ev,
|
||||||
coin_ev_size),
|
pd.coin_ev_size),
|
||||||
"reserve_pub", GNUNET_JSON_from_data_auto (&wsh->reserve_pub),
|
"reserve_pub", GNUNET_JSON_from_data_auto (&wsh->reserve_pub),
|
||||||
"reserve_sig", GNUNET_JSON_from_data_auto (&reserve_sig));
|
"reserve_sig", GNUNET_JSON_from_data_auto (&reserve_sig));
|
||||||
GNUNET_free (coin_ev);
|
GNUNET_free (pd.coin_ev);
|
||||||
if (NULL == withdraw_obj)
|
if (NULL == withdraw_obj)
|
||||||
{
|
{
|
||||||
GNUNET_break (0);
|
GNUNET_break (0);
|
||||||
@ -1074,7 +1058,7 @@ TALER_EXCHANGE_reserve_withdraw (struct TALER_EXCHANGE_Handle *exchange,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
wsh->blinding_key = *blinding_key;
|
wsh->ps = *ps;
|
||||||
wsh->url = MAH_path_to_url (exchange, "/reserve/withdraw");
|
wsh->url = MAH_path_to_url (exchange, "/reserve/withdraw");
|
||||||
|
|
||||||
eh = curl_easy_init ();
|
eh = curl_easy_init ();
|
||||||
|
@ -341,14 +341,9 @@ struct Command
|
|||||||
struct TALER_DenominationSignature sig;
|
struct TALER_DenominationSignature sig;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set (by the interpreter) to the coin's private key.
|
* Private key material of the coin, set by the interpreter.
|
||||||
*/
|
*/
|
||||||
struct TALER_CoinSpendPrivateKeyP coin_priv;
|
struct TALER_PlanchetSecretsP ps;
|
||||||
|
|
||||||
/**
|
|
||||||
* Blinding key used for the operation.
|
|
||||||
*/
|
|
||||||
struct TALER_DenominationBlindingKeyP blinding_key;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Withdraw handle (while operation is running).
|
* Withdraw handle (while operation is running).
|
||||||
@ -1984,7 +1979,7 @@ get_public_key_from_coin_command (const struct Command *coin,
|
|||||||
switch (coin->oc)
|
switch (coin->oc)
|
||||||
{
|
{
|
||||||
case OC_WITHDRAW_SIGN:
|
case OC_WITHDRAW_SIGN:
|
||||||
GNUNET_CRYPTO_eddsa_key_get_public (&coin->details.reserve_withdraw.coin_priv.eddsa_priv,
|
GNUNET_CRYPTO_eddsa_key_get_public (&coin->details.reserve_withdraw.ps.coin_priv.eddsa_priv,
|
||||||
&coin_pub->eddsa_pub);
|
&coin_pub->eddsa_pub);
|
||||||
break;
|
break;
|
||||||
case OC_REFRESH_REVEAL:
|
case OC_REFRESH_REVEAL:
|
||||||
@ -2016,7 +2011,6 @@ interpreter_run (void *cls)
|
|||||||
struct Command *cmd = &is->commands[is->ip];
|
struct Command *cmd = &is->commands[is->ip];
|
||||||
const struct Command *ref;
|
const struct Command *ref;
|
||||||
struct TALER_ReservePublicKeyP reserve_pub;
|
struct TALER_ReservePublicKeyP reserve_pub;
|
||||||
struct TALER_CoinSpendPublicKeyP coin_pub;
|
|
||||||
struct TALER_Amount amount;
|
struct TALER_Amount amount;
|
||||||
struct GNUNET_TIME_Absolute execution_date;
|
struct GNUNET_TIME_Absolute execution_date;
|
||||||
json_t *sender_details;
|
json_t *sender_details;
|
||||||
@ -2165,27 +2159,14 @@ interpreter_run (void *cls)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* create coin's private key */
|
TALER_planchet_setup_random (&cmd->details.reserve_withdraw.ps);
|
||||||
{
|
|
||||||
struct GNUNET_CRYPTO_EddsaPrivateKey *priv;
|
|
||||||
|
|
||||||
priv = GNUNET_CRYPTO_eddsa_key_create ();
|
|
||||||
cmd->details.reserve_withdraw.coin_priv.eddsa_priv = *priv;
|
|
||||||
GNUNET_free (priv);
|
|
||||||
}
|
|
||||||
GNUNET_CRYPTO_eddsa_key_get_public (&cmd->details.reserve_withdraw.coin_priv.eddsa_priv,
|
|
||||||
&coin_pub.eddsa_pub);
|
|
||||||
GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
|
|
||||||
&cmd->details.reserve_withdraw.blinding_key,
|
|
||||||
sizeof (cmd->details.reserve_withdraw.blinding_key));
|
|
||||||
cmd->details.reserve_withdraw.wsh
|
cmd->details.reserve_withdraw.wsh
|
||||||
= TALER_EXCHANGE_reserve_withdraw (exchange,
|
= TALER_EXCHANGE_reserve_withdraw (exchange,
|
||||||
cmd->details.reserve_withdraw.pk,
|
cmd->details.reserve_withdraw.pk,
|
||||||
&ref->details.admin_add_incoming.reserve_priv,
|
&ref->details.admin_add_incoming.reserve_priv,
|
||||||
&cmd->details.reserve_withdraw.coin_priv,
|
&cmd->details.reserve_withdraw.ps,
|
||||||
&cmd->details.reserve_withdraw.blinding_key,
|
&reserve_withdraw_cb,
|
||||||
&reserve_withdraw_cb,
|
is);
|
||||||
is);
|
|
||||||
if (NULL == cmd->details.reserve_withdraw.wsh)
|
if (NULL == cmd->details.reserve_withdraw.wsh)
|
||||||
{
|
{
|
||||||
GNUNET_break (0);
|
GNUNET_break (0);
|
||||||
@ -2217,7 +2198,7 @@ interpreter_run (void *cls)
|
|||||||
switch (ref->oc)
|
switch (ref->oc)
|
||||||
{
|
{
|
||||||
case OC_WITHDRAW_SIGN:
|
case OC_WITHDRAW_SIGN:
|
||||||
coin_priv = &ref->details.reserve_withdraw.coin_priv;
|
coin_priv = &ref->details.reserve_withdraw.ps.coin_priv;
|
||||||
coin_pk = ref->details.reserve_withdraw.pk;
|
coin_pk = ref->details.reserve_withdraw.pk;
|
||||||
coin_pk_sig = &ref->details.reserve_withdraw.sig;
|
coin_pk_sig = &ref->details.reserve_withdraw.sig;
|
||||||
break;
|
break;
|
||||||
@ -2376,7 +2357,7 @@ interpreter_run (void *cls)
|
|||||||
GNUNET_assert (NULL != ref);
|
GNUNET_assert (NULL != ref);
|
||||||
GNUNET_assert (OC_WITHDRAW_SIGN == ref->oc);
|
GNUNET_assert (OC_WITHDRAW_SIGN == ref->oc);
|
||||||
|
|
||||||
melt_priv = ref->details.reserve_withdraw.coin_priv;
|
melt_priv = ref->details.reserve_withdraw.ps.coin_priv;
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
TALER_string_to_amount (md->amount,
|
TALER_string_to_amount (md->amount,
|
||||||
&melt_amount))
|
&melt_amount))
|
||||||
@ -2478,7 +2459,7 @@ interpreter_run (void *cls)
|
|||||||
/* finally, use private key from withdraw sign command */
|
/* finally, use private key from withdraw sign command */
|
||||||
cmd->details.refresh_link.rlh
|
cmd->details.refresh_link.rlh
|
||||||
= TALER_EXCHANGE_refresh_link (exchange,
|
= TALER_EXCHANGE_refresh_link (exchange,
|
||||||
&ref->details.reserve_withdraw.coin_priv,
|
&ref->details.reserve_withdraw.ps.coin_priv,
|
||||||
&link_cb,
|
&link_cb,
|
||||||
is);
|
is);
|
||||||
if (NULL == cmd->details.refresh_link.rlh)
|
if (NULL == cmd->details.refresh_link.rlh)
|
||||||
@ -2745,8 +2726,7 @@ interpreter_run (void *cls)
|
|||||||
= TALER_EXCHANGE_payback (exchange,
|
= TALER_EXCHANGE_payback (exchange,
|
||||||
ref->details.reserve_withdraw.pk,
|
ref->details.reserve_withdraw.pk,
|
||||||
&ref->details.reserve_withdraw.sig,
|
&ref->details.reserve_withdraw.sig,
|
||||||
&ref->details.reserve_withdraw.coin_priv,
|
&ref->details.reserve_withdraw.ps,
|
||||||
&ref->details.reserve_withdraw.blinding_key,
|
|
||||||
&payback_cb,
|
&payback_cb,
|
||||||
is);
|
is);
|
||||||
return;
|
return;
|
||||||
|
@ -396,7 +396,83 @@ int
|
|||||||
TALER_test_coin_valid (const struct TALER_CoinPublicInfo *coin_public_info);
|
TALER_test_coin_valid (const struct TALER_CoinPublicInfo *coin_public_info);
|
||||||
|
|
||||||
|
|
||||||
/* ****************** Refresh crypto primitives ************* */
|
GNUNET_NETWORK_STRUCT_BEGIN
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Header for serializations of coin-specific information about the
|
||||||
|
* fresh coins we generate. These are the secrets that arise during
|
||||||
|
* planchet generation, which is the first stage of creating a new
|
||||||
|
* coin.
|
||||||
|
*/
|
||||||
|
struct TALER_PlanchetSecretsP
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Private key of the coin.
|
||||||
|
*/
|
||||||
|
struct TALER_CoinSpendPrivateKeyP coin_priv;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The blinding key.
|
||||||
|
*/
|
||||||
|
struct TALER_DenominationBlindingKeyP blinding_key;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
GNUNET_NETWORK_STRUCT_END
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Details about a planchet that the customer wants to obtain
|
||||||
|
* a withdrawal authorization. This is the information that
|
||||||
|
* will need to be sent to the exchange to obtain the blind
|
||||||
|
* signature required to turn a planchet into a coin.
|
||||||
|
*/
|
||||||
|
struct TALER_PlanchetDetail
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Hash of the denomination public key.
|
||||||
|
*/
|
||||||
|
struct GNUNET_HashCode denom_pub_hash;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hash of the coin's public key. Kept around so we do not need to
|
||||||
|
* compute it again. Can be recomputed by hashing the public key
|
||||||
|
* of @a coin_priv if storage is at a premium.
|
||||||
|
*/
|
||||||
|
struct GNUNET_HashCode c_hash;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Blinded coin (see GNUNET_CRYPTO_rsa_blind()). Note: is malloc()'ed!
|
||||||
|
*/
|
||||||
|
char *coin_ev;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Number of bytes in @a coin_ev.
|
||||||
|
*/
|
||||||
|
size_t coin_ev_size;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Information about a (fresh) coin, returned from the API when we
|
||||||
|
* finished creating a coin. Note that @e sig needs to be freed
|
||||||
|
* using the appropriate code.
|
||||||
|
*/
|
||||||
|
struct TALER_FreshCoin
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The exchange's signature over the coin's public key.
|
||||||
|
*/
|
||||||
|
struct TALER_DenominationSignature sig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The coin's private key.
|
||||||
|
*/
|
||||||
|
struct TALER_CoinSpendPrivateKeyP coin_priv;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
GNUNET_NETWORK_STRUCT_BEGIN
|
GNUNET_NETWORK_STRUCT_BEGIN
|
||||||
@ -426,6 +502,7 @@ struct TALER_TransferSecretP
|
|||||||
*/
|
*/
|
||||||
#define TALER_WIRE_TRANSFER_IDENTIFIER_LEN_STR "32"
|
#define TALER_WIRE_TRANSFER_IDENTIFIER_LEN_STR "32"
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Raw value of a wire transfer subjects, without the checksum.
|
* Raw value of a wire transfer subjects, without the checksum.
|
||||||
*/
|
*/
|
||||||
@ -472,6 +549,68 @@ struct TALER_WireTransferIdentifierP
|
|||||||
|
|
||||||
GNUNET_NETWORK_STRUCT_END
|
GNUNET_NETWORK_STRUCT_END
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setup information for a fresh coin, deriving the coin private key
|
||||||
|
* and the blinding factor from the @a secret_seed with a KDF salted
|
||||||
|
* by the @a coin_num_salt.
|
||||||
|
*
|
||||||
|
* @param secret_seed seed to use for KDF to derive coin keys
|
||||||
|
* @param coin_num_salt number of the coin to include in KDF
|
||||||
|
* @param[out] fc value to initialize
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
TALER_planchet_setup_refresh (const struct TALER_TransferSecretP *secret_seed,
|
||||||
|
unsigned int coin_num_salt,
|
||||||
|
struct TALER_PlanchetSecretsP *fc);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setup information for a fresh coin.
|
||||||
|
*
|
||||||
|
* @param[out] ps value to initialize
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
TALER_planchet_setup_random (struct TALER_PlanchetSecretsP *ps);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare a planchet for tipping. Creates and blinds a coin.
|
||||||
|
*
|
||||||
|
* @param dk denomination key for the coin to be created
|
||||||
|
* @param ps secret planchet internals (for #TALER_planchet_to_coin)
|
||||||
|
* @param[out] pd set to the planchet detail for TALER_MERCHANT_tip_pickup() and
|
||||||
|
* other withdraw operations
|
||||||
|
* @return #GNUNET_OK on success
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
TALER_planchet_prepare (const struct TALER_DenominationPublicKey *dk,
|
||||||
|
const struct TALER_PlanchetSecretsP *ps,
|
||||||
|
struct TALER_PlanchetDetail *pd);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtain a coin from the planchet's secrets and the blind signature
|
||||||
|
* of the exchange.
|
||||||
|
*
|
||||||
|
* @param dk denomination key, must match what was given to #TALER_planchet_prepare()
|
||||||
|
* @param blind_sig blind signature from the exchange
|
||||||
|
* @param ps secrets from #TALER_planchet_prepare()
|
||||||
|
* @param c_hash hash of the coin's public key for verification of the signature
|
||||||
|
* @param[out] coin set to the details of the fresh coin
|
||||||
|
* @return #GNUNET_OK on success
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
TALER_planchet_to_coin (const struct TALER_DenominationPublicKey *dk,
|
||||||
|
const struct GNUNET_CRYPTO_RsaSignature *blind_sig,
|
||||||
|
const struct TALER_PlanchetSecretsP *ps,
|
||||||
|
const struct GNUNET_HashCode *c_hash,
|
||||||
|
struct TALER_FreshCoin *coin);
|
||||||
|
|
||||||
|
|
||||||
|
/* ****************** Refresh crypto primitives ************* */
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given the coin and the transfer private keys, compute the
|
* Given the coin and the transfer private keys, compute the
|
||||||
* transfer secret. (Technically, we only need one of the two
|
* transfer secret. (Technically, we only need one of the two
|
||||||
@ -516,44 +655,5 @@ TALER_link_recover_transfer_secret (const struct TALER_TransferPublicKeyP *trans
|
|||||||
const struct TALER_CoinSpendPrivateKeyP *coin_priv,
|
const struct TALER_CoinSpendPrivateKeyP *coin_priv,
|
||||||
struct TALER_TransferSecretP *transfer_secret);
|
struct TALER_TransferSecretP *transfer_secret);
|
||||||
|
|
||||||
GNUNET_NETWORK_STRUCT_BEGIN
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Header for serializations of coin-specific information about the
|
|
||||||
* fresh coins we generate during a melt.
|
|
||||||
*/
|
|
||||||
struct TALER_PlanchetSecretsP
|
|
||||||
{
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Private key of the coin.
|
|
||||||
*/
|
|
||||||
struct TALER_CoinSpendPrivateKeyP coin_priv;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The blinding key.
|
|
||||||
*/
|
|
||||||
struct TALER_DenominationBlindingKeyP blinding_key;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
GNUNET_NETWORK_STRUCT_END
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Setup information for a fresh coin, deriving the coin private key
|
|
||||||
* and the blinding factor from the @a secret_seed with a KDF salted
|
|
||||||
* by the @a coin_num_salt.
|
|
||||||
*
|
|
||||||
* @param secret_seed seed to use for KDF to derive coin keys
|
|
||||||
* @param coin_num_salt number of the coin to include in KDF
|
|
||||||
* @param[out] fc value to initialize
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
TALER_planchet_setup_refresh (const struct TALER_TransferSecretP *secret_seed,
|
|
||||||
unsigned int coin_num_salt,
|
|
||||||
struct TALER_PlanchetSecretsP *fc);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -976,9 +976,7 @@ typedef void
|
|||||||
* @param exchange the exchange handle; the exchange must be ready to operate
|
* @param exchange the exchange handle; the exchange must be ready to operate
|
||||||
* @param pk kind of coin to create
|
* @param pk kind of coin to create
|
||||||
* @param reserve_priv private key of the reserve to withdraw from
|
* @param reserve_priv private key of the reserve to withdraw from
|
||||||
* @param coin_priv where to fetch the coin's private key,
|
* @param ps secrets of the planchet
|
||||||
* caller must have committed this value to disk before the call (with @a pk)
|
|
||||||
* @param blinding_key where to fetch the coin's blinding key
|
|
||||||
* caller must have committed this value to disk before the call (with @a pk)
|
* caller must have committed this value to disk before the call (with @a pk)
|
||||||
* @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
|
||||||
* @param res_cb_cls closure for @a res_cb
|
* @param res_cb_cls closure for @a res_cb
|
||||||
@ -990,8 +988,7 @@ struct TALER_EXCHANGE_ReserveWithdrawHandle *
|
|||||||
TALER_EXCHANGE_reserve_withdraw (struct TALER_EXCHANGE_Handle *exchange,
|
TALER_EXCHANGE_reserve_withdraw (struct TALER_EXCHANGE_Handle *exchange,
|
||||||
const struct TALER_EXCHANGE_DenomPublicKey *pk,
|
const struct TALER_EXCHANGE_DenomPublicKey *pk,
|
||||||
const struct TALER_ReservePrivateKeyP *reserve_priv,
|
const struct TALER_ReservePrivateKeyP *reserve_priv,
|
||||||
const struct TALER_CoinSpendPrivateKeyP *coin_priv,
|
const struct TALER_PlanchetSecretsP *ps,
|
||||||
const struct TALER_DenominationBlindingKeyP *blinding_key,
|
|
||||||
TALER_EXCHANGE_ReserveWithdrawResultCallback res_cb,
|
TALER_EXCHANGE_ReserveWithdrawResultCallback res_cb,
|
||||||
void *res_cb_cls);
|
void *res_cb_cls);
|
||||||
|
|
||||||
@ -1540,8 +1537,7 @@ typedef void
|
|||||||
* @param exchange the exchange handle; the exchange must be ready to operate
|
* @param exchange the exchange handle; the exchange must be ready to operate
|
||||||
* @param pk kind of coin to pay back
|
* @param pk kind of coin to pay back
|
||||||
* @param denom_sig signature over the coin by the exchange using @a pk
|
* @param denom_sig signature over the coin by the exchange using @a pk
|
||||||
* @param coin_priv the coin's private key,
|
* @param ps secret internals of the original planchet
|
||||||
* @param blinding_key where to fetch the coin's blinding key
|
|
||||||
* @param payback_cb the callback to call when the final result for this request is available
|
* @param payback_cb the callback to call when the final result for this request is available
|
||||||
* @param payback_cb_cls closure for @a payback_cb
|
* @param payback_cb_cls closure for @a payback_cb
|
||||||
* @return NULL
|
* @return NULL
|
||||||
@ -1552,8 +1548,7 @@ struct TALER_EXCHANGE_PaybackHandle *
|
|||||||
TALER_EXCHANGE_payback (struct TALER_EXCHANGE_Handle *exchange,
|
TALER_EXCHANGE_payback (struct TALER_EXCHANGE_Handle *exchange,
|
||||||
const struct TALER_EXCHANGE_DenomPublicKey *pk,
|
const struct TALER_EXCHANGE_DenomPublicKey *pk,
|
||||||
const struct TALER_DenominationSignature *denom_sig,
|
const struct TALER_DenominationSignature *denom_sig,
|
||||||
const struct TALER_CoinSpendPrivateKeyP *coin_priv,
|
const struct TALER_PlanchetSecretsP *ps,
|
||||||
const struct TALER_DenominationBlindingKeyP *blinding_key,
|
|
||||||
TALER_EXCHANGE_PaybackResultCallback payback_cb,
|
TALER_EXCHANGE_PaybackResultCallback payback_cb,
|
||||||
void *payback_cb_cls);
|
void *payback_cb_cls);
|
||||||
|
|
||||||
|
@ -134,6 +134,4 @@ const struct GNUNET_OS_ProjectData *
|
|||||||
TALER_project_data_default (void);
|
TALER_project_data_default (void);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -171,35 +171,19 @@ TALER_link_recover_transfer_secret (const struct TALER_TransferPublicKeyP *trans
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Setup information for a fresh coin.
|
* Set the bits in the private EdDSA key so that they match
|
||||||
|
* the specification.
|
||||||
*
|
*
|
||||||
* @param secret_seed seed to use for KDF to derive coin keys
|
* @param[in,out] pk private key to patch
|
||||||
* @param coin_num_salt number of the coin to include in KDF
|
|
||||||
* @param[out] fc value to initialize
|
|
||||||
*/
|
*/
|
||||||
void
|
static void
|
||||||
TALER_planchet_setup_refresh (const struct TALER_TransferSecretP *secret_seed,
|
patch_private_key (struct GNUNET_CRYPTO_EddsaPrivateKey *pk)
|
||||||
unsigned int coin_num_salt,
|
|
||||||
struct TALER_PlanchetSecretsP *fc)
|
|
||||||
{
|
{
|
||||||
uint32_t be_salt = htonl (coin_num_salt);
|
uint8_t *p = (uint8_t *) pk;
|
||||||
uint8_t *p;
|
|
||||||
|
|
||||||
GNUNET_assert (GNUNET_OK ==
|
|
||||||
GNUNET_CRYPTO_kdf (fc,
|
|
||||||
sizeof (*fc),
|
|
||||||
&be_salt,
|
|
||||||
sizeof (be_salt),
|
|
||||||
secret_seed,
|
|
||||||
sizeof (*secret_seed),
|
|
||||||
"taler-coin-derivation",
|
|
||||||
strlen ("taler-coin-derivation"),
|
|
||||||
NULL, 0));
|
|
||||||
|
|
||||||
/* Taken from like 170-172 of libgcrypt/cipher/ecc.c
|
/* Taken from like 170-172 of libgcrypt/cipher/ecc.c
|
||||||
* We note that libgcrypt stores the private key in the reverse order
|
* We note that libgcrypt stores the private key in the reverse order
|
||||||
* from many Ed25519 implementatons. */
|
* from many Ed25519 implementatons. */
|
||||||
p = (uint8_t *) &(fc->coin_priv);
|
|
||||||
p[0] &= 0x7f; /* Clear bit 255. */
|
p[0] &= 0x7f; /* Clear bit 255. */
|
||||||
p[0] |= 0x40; /* Set bit 254. */
|
p[0] |= 0x40; /* Set bit 254. */
|
||||||
p[31] &= 0xf8; /* Clear bits 2..0 so that d mod 8 == 0 */
|
p[31] &= 0xf8; /* Clear bits 2..0 so that d mod 8 == 0 */
|
||||||
@ -213,6 +197,121 @@ TALER_planchet_setup_refresh (const struct TALER_TransferSecretP *secret_seed,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setup information for a fresh coin.
|
||||||
|
*
|
||||||
|
* @param secret_seed seed to use for KDF to derive coin keys
|
||||||
|
* @param coin_num_salt number of the coin to include in KDF
|
||||||
|
* @param[out] ps value to initialize
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
TALER_planchet_setup_refresh (const struct TALER_TransferSecretP *secret_seed,
|
||||||
|
unsigned int coin_num_salt,
|
||||||
|
struct TALER_PlanchetSecretsP *ps)
|
||||||
|
{
|
||||||
|
uint32_t be_salt = htonl (coin_num_salt);
|
||||||
|
|
||||||
|
GNUNET_assert (GNUNET_OK ==
|
||||||
|
GNUNET_CRYPTO_kdf (ps,
|
||||||
|
sizeof (*ps),
|
||||||
|
&be_salt,
|
||||||
|
sizeof (be_salt),
|
||||||
|
secret_seed,
|
||||||
|
sizeof (*secret_seed),
|
||||||
|
"taler-coin-derivation",
|
||||||
|
strlen ("taler-coin-derivation"),
|
||||||
|
NULL, 0));
|
||||||
|
patch_private_key (&ps->coin_priv.eddsa_priv);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setup information for a fresh coin.
|
||||||
|
*
|
||||||
|
* @param[out] ps value to initialize
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
TALER_planchet_setup_random (struct TALER_PlanchetSecretsP *ps)
|
||||||
|
{
|
||||||
|
GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_STRONG,
|
||||||
|
ps,
|
||||||
|
sizeof (*ps));
|
||||||
|
patch_private_key (&ps->coin_priv.eddsa_priv);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare a planchet for tipping. Creates and blinds a coin.
|
||||||
|
*
|
||||||
|
* @param dk denomination key for the coin to be created
|
||||||
|
* @param ps secret planchet internals (for #TALER_planchet_to_coin)
|
||||||
|
* @param[out] pd set to the planchet detail for TALER_MERCHANT_tip_pickup() and
|
||||||
|
* other withdraw operations
|
||||||
|
* @return #GNUNET_OK on success
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
TALER_planchet_prepare (const struct TALER_DenominationPublicKey *dk,
|
||||||
|
const struct TALER_PlanchetSecretsP *ps,
|
||||||
|
struct TALER_PlanchetDetail *pd)
|
||||||
|
{
|
||||||
|
struct TALER_CoinSpendPublicKeyP coin_pub;
|
||||||
|
|
||||||
|
GNUNET_CRYPTO_eddsa_key_get_public (&ps->coin_priv.eddsa_priv,
|
||||||
|
&coin_pub.eddsa_pub);
|
||||||
|
GNUNET_CRYPTO_hash (&coin_pub.eddsa_pub,
|
||||||
|
sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey),
|
||||||
|
&pd->c_hash);
|
||||||
|
if (GNUNET_YES !=
|
||||||
|
GNUNET_CRYPTO_rsa_blind (&pd->c_hash,
|
||||||
|
&ps->blinding_key.bks,
|
||||||
|
dk->rsa_public_key,
|
||||||
|
&pd->coin_ev,
|
||||||
|
&pd->coin_ev_size))
|
||||||
|
{
|
||||||
|
GNUNET_break_op (0);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
GNUNET_CRYPTO_rsa_public_key_hash (dk->rsa_public_key,
|
||||||
|
&pd->denom_pub_hash);
|
||||||
|
return GNUNET_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtain a coin from the planchet's secrets and the blind signature
|
||||||
|
* of the exchange.
|
||||||
|
*
|
||||||
|
* @param dk denomination key, must match what was given to #TALER_planchet_prepare()
|
||||||
|
* @param blind_sig blind signature from the exchange
|
||||||
|
* @param ps secrets from #TALER_planchet_prepare()
|
||||||
|
* @param c_hash hash of the coin's public key for verification of the signature
|
||||||
|
* @param[out] coin set to the details of the fresh coin
|
||||||
|
* @return #GNUNET_OK on success
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
TALER_planchet_to_coin (const struct TALER_DenominationPublicKey *dk,
|
||||||
|
const struct GNUNET_CRYPTO_RsaSignature *blind_sig,
|
||||||
|
const struct TALER_PlanchetSecretsP *ps,
|
||||||
|
const struct GNUNET_HashCode *c_hash,
|
||||||
|
struct TALER_FreshCoin *coin)
|
||||||
|
{
|
||||||
|
struct GNUNET_CRYPTO_RsaSignature *sig;
|
||||||
|
|
||||||
|
sig = GNUNET_CRYPTO_rsa_unblind (blind_sig,
|
||||||
|
&ps->blinding_key.bks,
|
||||||
|
dk->rsa_public_key);
|
||||||
|
if (GNUNET_OK !=
|
||||||
|
GNUNET_CRYPTO_rsa_verify (c_hash,
|
||||||
|
sig,
|
||||||
|
dk->rsa_public_key))
|
||||||
|
{
|
||||||
|
GNUNET_break_op (0);
|
||||||
|
GNUNET_CRYPTO_rsa_signature_free (sig);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
coin->sig.rsa_signature = sig;
|
||||||
|
coin->coin_priv = ps->coin_priv;
|
||||||
|
return GNUNET_OK;
|
||||||
|
}
|
||||||
|
|
||||||
/* end of crypto.c */
|
/* end of crypto.c */
|
||||||
|
@ -71,11 +71,11 @@ test_high_level ()
|
|||||||
&secret2,
|
&secret2,
|
||||||
sizeof (secret)));
|
sizeof (secret)));
|
||||||
TALER_planchet_setup_refresh (&secret,
|
TALER_planchet_setup_refresh (&secret,
|
||||||
0,
|
0,
|
||||||
&fc1);
|
&fc1);
|
||||||
TALER_planchet_setup_refresh (&secret,
|
TALER_planchet_setup_refresh (&secret,
|
||||||
1,
|
1,
|
||||||
&fc2);
|
&fc2);
|
||||||
GNUNET_assert (0 !=
|
GNUNET_assert (0 !=
|
||||||
memcmp (&fc1,
|
memcmp (&fc1,
|
||||||
&fc2,
|
&fc2,
|
||||||
@ -84,12 +84,55 @@ test_high_level ()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test the basic planchet functionality of creating a fresh planchet
|
||||||
|
* and extracting the respective signature.
|
||||||
|
*
|
||||||
|
* @return 0 on success
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
test_planchets ()
|
||||||
|
{
|
||||||
|
struct TALER_PlanchetSecretsP ps;
|
||||||
|
struct TALER_DenominationPrivateKey dk_priv;
|
||||||
|
struct TALER_DenominationPublicKey dk_pub;
|
||||||
|
struct TALER_PlanchetDetail pd;
|
||||||
|
struct GNUNET_CRYPTO_RsaSignature *blind_sig;
|
||||||
|
struct TALER_FreshCoin coin;
|
||||||
|
|
||||||
|
dk_priv.rsa_private_key = GNUNET_CRYPTO_rsa_private_key_create (1024);
|
||||||
|
dk_pub.rsa_public_key = GNUNET_CRYPTO_rsa_private_key_get_public (dk_priv.rsa_private_key);
|
||||||
|
TALER_planchet_setup_random (&ps);
|
||||||
|
GNUNET_assert (GNUNET_OK ==
|
||||||
|
TALER_planchet_prepare (&dk_pub,
|
||||||
|
&ps,
|
||||||
|
&pd));
|
||||||
|
blind_sig = GNUNET_CRYPTO_rsa_sign_blinded (dk_priv.rsa_private_key,
|
||||||
|
pd.coin_ev,
|
||||||
|
pd.coin_ev_size);
|
||||||
|
GNUNET_assert (NULL != blind_sig);
|
||||||
|
GNUNET_assert (GNUNET_OK ==
|
||||||
|
TALER_planchet_to_coin (&dk_pub,
|
||||||
|
blind_sig,
|
||||||
|
&ps,
|
||||||
|
&pd.c_hash,
|
||||||
|
&coin));
|
||||||
|
GNUNET_CRYPTO_rsa_signature_free (blind_sig);
|
||||||
|
GNUNET_CRYPTO_rsa_signature_free (coin.sig.rsa_signature);
|
||||||
|
GNUNET_CRYPTO_rsa_private_key_free (dk_priv.rsa_private_key);
|
||||||
|
GNUNET_CRYPTO_rsa_public_key_free (dk_pub.rsa_public_key);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc,
|
main(int argc,
|
||||||
const char *const argv[])
|
const char *const argv[])
|
||||||
{
|
{
|
||||||
if (0 != test_high_level ())
|
if (0 != test_high_level ())
|
||||||
return 1;
|
return 1;
|
||||||
|
if (0 != test_planchets ())
|
||||||
|
return 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user