first half of changing refresh protocol to derive all key data from DH
This commit is contained in:
parent
e800772c85
commit
745719dbc1
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
This file is part of TALER
|
This file is part of TALER
|
||||||
Copyright (C) 2015 GNUnet e.V.
|
Copyright (C) 2015, 2016 GNUnet e.V.
|
||||||
|
|
||||||
TALER is free software; you can redistribute it and/or modify it under the
|
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
|
terms of the GNU General Public License as published by the Free Software
|
||||||
@ -92,26 +92,6 @@ struct MeltedCoinP
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Header for serializations of coin-specific information about the
|
|
||||||
* fresh coins we generate during a melt.
|
|
||||||
*/
|
|
||||||
struct FreshCoinP
|
|
||||||
{
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Private key of the coin.
|
|
||||||
*/
|
|
||||||
struct TALER_CoinSpendPrivateKeyP coin_priv;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The blinding key.
|
|
||||||
*/
|
|
||||||
struct TALER_DenominationBlindingKeyP blinding_key;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Header of serialized data about a melt operation, suitable for
|
* Header of serialized data about a melt operation, suitable for
|
||||||
* persisting it on disk.
|
* persisting it on disk.
|
||||||
@ -124,12 +104,6 @@ struct MeltDataP
|
|||||||
*/
|
*/
|
||||||
struct GNUNET_HashCode melt_session_hash;
|
struct GNUNET_HashCode melt_session_hash;
|
||||||
|
|
||||||
/**
|
|
||||||
* Link secret used to encrypt the @a coin_priv and the blinding
|
|
||||||
* key in the linkage data for the respective cut-and-choose dimension.
|
|
||||||
*/
|
|
||||||
struct TALER_LinkSecretP link_secrets[TALER_CNC_KAPPA];
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Number of coins we are melting, in NBO
|
* Number of coins we are melting, in NBO
|
||||||
*/
|
*/
|
||||||
@ -144,7 +118,7 @@ struct MeltDataP
|
|||||||
1) struct MeltedCoinP melted_coins[num_melted_coins];
|
1) struct MeltedCoinP melted_coins[num_melted_coins];
|
||||||
2) struct TALER_EXCHANGE_DenomPublicKey fresh_pks[num_fresh_coins];
|
2) struct TALER_EXCHANGE_DenomPublicKey fresh_pks[num_fresh_coins];
|
||||||
3) TALER_CNC_KAPPA times:
|
3) TALER_CNC_KAPPA times:
|
||||||
3a) struct FreshCoinP fresh_coins[num_fresh_coins];
|
3a) struct TALER_FreshCoinP fresh_coins[num_fresh_coins];
|
||||||
*/
|
*/
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -211,11 +185,6 @@ struct MeltData
|
|||||||
*/
|
*/
|
||||||
struct GNUNET_HashCode melt_session_hash;
|
struct GNUNET_HashCode melt_session_hash;
|
||||||
|
|
||||||
/**
|
|
||||||
* Link secrets for each cut-and-choose dimension.
|
|
||||||
*/
|
|
||||||
struct TALER_LinkSecretP link_secrets[TALER_CNC_KAPPA];
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Number of coins we are creating
|
* Number of coins we are creating
|
||||||
*/
|
*/
|
||||||
@ -236,7 +205,7 @@ struct MeltData
|
|||||||
* Arrays of @e num_fresh_coins with information about the fresh
|
* Arrays of @e num_fresh_coins with information about the fresh
|
||||||
* coins to be created, for each cut-and-choose dimension.
|
* coins to be created, for each cut-and-choose dimension.
|
||||||
*/
|
*/
|
||||||
struct FreshCoinP *fresh_coins[TALER_CNC_KAPPA];
|
struct TALER_FreshCoinP *fresh_coins[TALER_CNC_KAPPA];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -522,15 +491,15 @@ deserialize_denomination_key (struct TALER_DenominationPublicKey *dk,
|
|||||||
* @a buf is NULL, number of bytes required
|
* @a buf is NULL, number of bytes required
|
||||||
*/
|
*/
|
||||||
static size_t
|
static size_t
|
||||||
serialize_fresh_coin (const struct FreshCoinP *fc,
|
serialize_fresh_coin (const struct TALER_FreshCoinP *fc,
|
||||||
char *buf,
|
char *buf,
|
||||||
size_t off)
|
size_t off)
|
||||||
{
|
{
|
||||||
if (NULL != buf)
|
if (NULL != buf)
|
||||||
memcpy (&buf[off],
|
memcpy (&buf[off],
|
||||||
fc,
|
fc,
|
||||||
sizeof (struct FreshCoinP));
|
sizeof (struct TALER_FreshCoinP));
|
||||||
return sizeof (struct FreshCoinP);
|
return sizeof (struct TALER_FreshCoinP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -544,12 +513,12 @@ serialize_fresh_coin (const struct FreshCoinP *fc,
|
|||||||
* @return number of bytes read from @a buf, 0 on error
|
* @return number of bytes read from @a buf, 0 on error
|
||||||
*/
|
*/
|
||||||
static size_t
|
static size_t
|
||||||
deserialize_fresh_coin (struct FreshCoinP *fc,
|
deserialize_fresh_coin (struct TALER_FreshCoinP *fc,
|
||||||
const char *buf,
|
const char *buf,
|
||||||
size_t size,
|
size_t size,
|
||||||
int *ok)
|
int *ok)
|
||||||
{
|
{
|
||||||
if (size < sizeof (struct FreshCoinP))
|
if (size < sizeof (struct TALER_FreshCoinP))
|
||||||
{
|
{
|
||||||
GNUNET_break (0);
|
GNUNET_break (0);
|
||||||
*ok = GNUNET_NO;
|
*ok = GNUNET_NO;
|
||||||
@ -557,8 +526,8 @@ deserialize_fresh_coin (struct FreshCoinP *fc,
|
|||||||
}
|
}
|
||||||
memcpy (fc,
|
memcpy (fc,
|
||||||
buf,
|
buf,
|
||||||
sizeof (struct FreshCoinP));
|
sizeof (struct TALER_FreshCoinP));
|
||||||
return sizeof (struct FreshCoinP);
|
return sizeof (struct TALER_FreshCoinP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -598,8 +567,6 @@ serialize_melt_data (const struct MeltData *md,
|
|||||||
size = sizeof (struct MeltDataP);
|
size = sizeof (struct MeltDataP);
|
||||||
mdp = (struct MeltDataP *) buf;
|
mdp = (struct MeltDataP *) buf;
|
||||||
mdp->melt_session_hash = md->melt_session_hash;
|
mdp->melt_session_hash = md->melt_session_hash;
|
||||||
for (i=0;i<TALER_CNC_KAPPA;i++)
|
|
||||||
mdp->link_secrets[i] = md->link_secrets[i];
|
|
||||||
mdp->num_fresh_coins = htons (md->num_fresh_coins);
|
mdp->num_fresh_coins = htons (md->num_fresh_coins);
|
||||||
}
|
}
|
||||||
size += serialize_melted_coin (&md->melted_coin,
|
size += serialize_melted_coin (&md->melted_coin,
|
||||||
@ -646,14 +613,12 @@ deserialize_melt_data (const char *buf,
|
|||||||
sizeof (struct MeltDataP));
|
sizeof (struct MeltDataP));
|
||||||
md = GNUNET_new (struct MeltData);
|
md = GNUNET_new (struct MeltData);
|
||||||
md->melt_session_hash = mdp.melt_session_hash;
|
md->melt_session_hash = mdp.melt_session_hash;
|
||||||
for (i=0;i<TALER_CNC_KAPPA;i++)
|
|
||||||
md->link_secrets[i] = mdp.link_secrets[i];
|
|
||||||
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 (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 FreshCoinP);
|
struct TALER_FreshCoinP);
|
||||||
off = sizeof (struct MeltDataP);
|
off = sizeof (struct MeltDataP);
|
||||||
ok = GNUNET_YES;
|
ok = GNUNET_YES;
|
||||||
off += deserialize_melted_coin (&md->melted_coin,
|
off += deserialize_melted_coin (&md->melted_coin,
|
||||||
@ -687,27 +652,6 @@ deserialize_melt_data (const char *buf,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Setup information for a fresh coin.
|
|
||||||
*
|
|
||||||
* @param[out] fc value to initialize
|
|
||||||
* @param pk denomination information for the fresh coin
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
setup_fresh_coin (struct FreshCoinP *fc,
|
|
||||||
const struct TALER_EXCHANGE_DenomPublicKey *pk)
|
|
||||||
{
|
|
||||||
struct GNUNET_CRYPTO_EddsaPrivateKey *epk;
|
|
||||||
|
|
||||||
epk = GNUNET_CRYPTO_eddsa_key_create ();
|
|
||||||
fc->coin_priv.eddsa_priv = *epk;
|
|
||||||
GNUNET_free (epk);
|
|
||||||
GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_STRONG,
|
|
||||||
&fc->blinding_key,
|
|
||||||
sizeof (fc->blinding_key));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Melt (partially spent) coins to obtain fresh coins that are
|
* Melt (partially spent) coins to obtain fresh coins that are
|
||||||
* unlinkable to the original coin(s). Note that melting more
|
* unlinkable to the original coin(s). Note that melting more
|
||||||
@ -765,25 +709,37 @@ TALER_EXCHANGE_refresh_prepare (const struct TALER_CoinSpendPrivateKeyP *melt_pr
|
|||||||
unsigned int j;
|
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_TransferSecretP trans_sec[TALER_CNC_KAPPA];
|
||||||
|
|
||||||
|
GNUNET_CRYPTO_eddsa_key_get_public (&melt_priv->eddsa_priv,
|
||||||
|
&coin_pub.eddsa_pub);
|
||||||
|
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 (i=0;i<TALER_CNC_KAPPA;i++)
|
||||||
GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_STRONG,
|
{
|
||||||
&md.link_secrets[i],
|
struct GNUNET_CRYPTO_EcdhePrivateKey *tpk;
|
||||||
sizeof (struct TALER_LinkSecretP));
|
struct TALER_TransferPublicKeyP tp;
|
||||||
|
|
||||||
|
tpk = GNUNET_CRYPTO_ecdhe_key_create ();
|
||||||
|
md.melted_coin.transfer_priv[i].ecdhe_priv = *tpk;
|
||||||
|
GNUNET_free (tpk);
|
||||||
|
|
||||||
|
GNUNET_CRYPTO_ecdhe_key_get_public (&md.melted_coin.transfer_priv[i].ecdhe_priv,
|
||||||
|
&tp.ecdhe_pub);
|
||||||
|
GNUNET_CRYPTO_hash_context_read (hash_context,
|
||||||
|
&tp,
|
||||||
|
sizeof (struct TALER_TransferPublicKeyP));
|
||||||
|
/* DH */
|
||||||
|
TALER_link_derive_transfer_secret (melt_priv,
|
||||||
|
&md.melted_coin.transfer_priv[i],
|
||||||
|
&trans_sec[i]);
|
||||||
|
}
|
||||||
md.num_fresh_coins = fresh_pks_len;
|
md.num_fresh_coins = fresh_pks_len;
|
||||||
md.melted_coin.coin_priv = *melt_priv;
|
md.melted_coin.coin_priv = *melt_priv;
|
||||||
md.melted_coin.melt_amount_with_fee = *melt_amount;
|
md.melted_coin.melt_amount_with_fee = *melt_amount;
|
||||||
md.melted_coin.fee_melt = melt_pk->fee_refresh;
|
md.melted_coin.fee_melt = melt_pk->fee_refresh;
|
||||||
md.melted_coin.original_value = melt_pk->value;
|
md.melted_coin.original_value = melt_pk->value;
|
||||||
for (j=0;j<TALER_CNC_KAPPA;j++)
|
|
||||||
{
|
|
||||||
struct GNUNET_CRYPTO_EcdhePrivateKey *tpk;
|
|
||||||
|
|
||||||
tpk = GNUNET_CRYPTO_ecdhe_key_create ();
|
|
||||||
md.melted_coin.transfer_priv[j].ecdhe_priv = *tpk;
|
|
||||||
GNUNET_free (tpk);
|
|
||||||
}
|
|
||||||
md.melted_coin.expire_deposit
|
md.melted_coin.expire_deposit
|
||||||
= melt_pk->expire_deposit;
|
= melt_pk->expire_deposit;
|
||||||
md.melted_coin.pub_key.rsa_public_key
|
md.melted_coin.pub_key.rsa_public_key
|
||||||
@ -798,11 +754,12 @@ TALER_EXCHANGE_refresh_prepare (const struct TALER_CoinSpendPrivateKeyP *melt_pr
|
|||||||
for (i=0;i<TALER_CNC_KAPPA;i++)
|
for (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 FreshCoinP);
|
struct TALER_FreshCoinP);
|
||||||
for (j=0;j<fresh_pks_len;j++)
|
for (j=0;j<fresh_pks_len;j++)
|
||||||
{
|
{
|
||||||
setup_fresh_coin (&md.fresh_coins[i][j],
|
TALER_setup_fresh_coin (&trans_sec[i],
|
||||||
&fresh_pks[j]);
|
j,
|
||||||
|
&md.fresh_coins[i][j]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -830,7 +787,7 @@ TALER_EXCHANGE_refresh_prepare (const struct TALER_CoinSpendPrivateKeyP *melt_pr
|
|||||||
TALER_amount_cmp (&total,
|
TALER_amount_cmp (&total,
|
||||||
melt_amount) )
|
melt_amount) )
|
||||||
{
|
{
|
||||||
/* Eh, this operation is more expensive than the
|
/* Eh, this operation is more expensive than the
|
||||||
@a melt_amount. This is not OK. */
|
@a melt_amount. This is not OK. */
|
||||||
GNUNET_break (0);
|
GNUNET_break (0);
|
||||||
free_melt_data (&md);
|
free_melt_data (&md);
|
||||||
@ -839,7 +796,6 @@ TALER_EXCHANGE_refresh_prepare (const struct TALER_CoinSpendPrivateKeyP *melt_pr
|
|||||||
|
|
||||||
|
|
||||||
/* now compute melt session hash */
|
/* now compute melt session hash */
|
||||||
hash_context = GNUNET_CRYPTO_hash_context_start ();
|
|
||||||
for (i=0;i<fresh_pks_len;i++)
|
for (i=0;i<fresh_pks_len;i++)
|
||||||
{
|
{
|
||||||
char *buf;
|
char *buf;
|
||||||
@ -853,11 +809,8 @@ TALER_EXCHANGE_refresh_prepare (const struct TALER_CoinSpendPrivateKeyP *melt_pr
|
|||||||
GNUNET_free (buf);
|
GNUNET_free (buf);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
struct TALER_CoinSpendPublicKeyP coin_pub;
|
|
||||||
struct TALER_AmountNBO melt_amountn;
|
struct TALER_AmountNBO melt_amountn;
|
||||||
|
|
||||||
GNUNET_CRYPTO_eddsa_key_get_public (&melt_priv->eddsa_priv,
|
|
||||||
&coin_pub.eddsa_pub);
|
|
||||||
GNUNET_CRYPTO_hash_context_read (hash_context,
|
GNUNET_CRYPTO_hash_context_read (hash_context,
|
||||||
&coin_pub,
|
&coin_pub,
|
||||||
sizeof (struct TALER_CoinSpendPublicKeyP));
|
sizeof (struct TALER_CoinSpendPublicKeyP));
|
||||||
@ -872,13 +825,11 @@ TALER_EXCHANGE_refresh_prepare (const struct TALER_CoinSpendPrivateKeyP *melt_pr
|
|||||||
{
|
{
|
||||||
for (j = 0; j < fresh_pks_len; j++)
|
for (j = 0; j < fresh_pks_len; j++)
|
||||||
{
|
{
|
||||||
const struct FreshCoinP *fc; /* coin this is about */
|
const struct TALER_FreshCoinP *fc; /* coin this is about */
|
||||||
struct TALER_CoinSpendPublicKeyP coin_pub;
|
struct TALER_CoinSpendPublicKeyP coin_pub;
|
||||||
struct GNUNET_HashCode coin_hash;
|
struct GNUNET_HashCode coin_hash;
|
||||||
char *coin_ev; /* blinded message to be signed (in envelope) for each coin */
|
char *coin_ev; /* blinded message to be signed (in envelope) for each coin */
|
||||||
size_t coin_ev_size;
|
size_t coin_ev_size;
|
||||||
struct TALER_RefreshLinkDecryptedP rld;
|
|
||||||
struct TALER_RefreshLinkEncryptedP rle;
|
|
||||||
|
|
||||||
fc = &md.fresh_coins[i][j];
|
fc = &md.fresh_coins[i][j];
|
||||||
GNUNET_CRYPTO_eddsa_key_get_public (&fc->coin_priv.eddsa_priv,
|
GNUNET_CRYPTO_eddsa_key_get_public (&fc->coin_priv.eddsa_priv,
|
||||||
@ -902,35 +853,8 @@ TALER_EXCHANGE_refresh_prepare (const struct TALER_CoinSpendPrivateKeyP *melt_pr
|
|||||||
coin_ev,
|
coin_ev,
|
||||||
coin_ev_size);
|
coin_ev_size);
|
||||||
GNUNET_free (coin_ev);
|
GNUNET_free (coin_ev);
|
||||||
|
|
||||||
rld.coin_priv = fc->coin_priv;
|
|
||||||
rld.blinding_key = fc->blinding_key;
|
|
||||||
TALER_refresh_encrypt (&rld,
|
|
||||||
&md.link_secrets[i],
|
|
||||||
&rle);
|
|
||||||
GNUNET_CRYPTO_hash_context_read (hash_context,
|
|
||||||
&rle,
|
|
||||||
sizeof (rle));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (i = 0; i < TALER_CNC_KAPPA; i++)
|
|
||||||
{
|
|
||||||
struct TALER_RefreshCommitLinkP rcl;
|
|
||||||
struct TALER_TransferSecretP trans_sec;
|
|
||||||
|
|
||||||
GNUNET_CRYPTO_ecdhe_key_get_public (&md.melted_coin.transfer_priv[i].ecdhe_priv,
|
|
||||||
&rcl.transfer_pub.ecdhe_pub);
|
|
||||||
TALER_link_derive_transfer_secret (melt_priv,
|
|
||||||
&md.melted_coin.transfer_priv[i],
|
|
||||||
&trans_sec);
|
|
||||||
TALER_transfer_encrypt (&md.link_secrets[i],
|
|
||||||
&trans_sec,
|
|
||||||
&rcl.shared_secret_enc);
|
|
||||||
GNUNET_CRYPTO_hash_context_read (hash_context,
|
|
||||||
&rcl,
|
|
||||||
sizeof (struct TALER_RefreshCommitLinkP));
|
|
||||||
}
|
|
||||||
|
|
||||||
GNUNET_CRYPTO_hash_context_finish (hash_context,
|
GNUNET_CRYPTO_hash_context_finish (hash_context,
|
||||||
&md.melt_session_hash);
|
&md.melt_session_hash);
|
||||||
|
|
||||||
@ -1315,8 +1239,6 @@ TALER_EXCHANGE_refresh_melt (struct TALER_EXCHANGE_Handle *exchange,
|
|||||||
json_t *melt_coin;
|
json_t *melt_coin;
|
||||||
json_t *coin_evs;
|
json_t *coin_evs;
|
||||||
json_t *transfer_pubs;
|
json_t *transfer_pubs;
|
||||||
json_t *secret_encs;
|
|
||||||
json_t *link_encs;
|
|
||||||
json_t *tmp;
|
json_t *tmp;
|
||||||
struct TALER_EXCHANGE_RefreshMeltHandle *rmh;
|
struct TALER_EXCHANGE_RefreshMeltHandle *rmh;
|
||||||
CURL *eh;
|
CURL *eh;
|
||||||
@ -1335,14 +1257,12 @@ TALER_EXCHANGE_refresh_melt (struct TALER_EXCHANGE_Handle *exchange,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* build JSON request, each of the 6 arrays first */
|
/* build JSON request, each of the 4 arrays first */
|
||||||
new_denoms = json_array ();
|
new_denoms = json_array ();
|
||||||
melt_coin = melted_coin_to_json (&md->melt_session_hash,
|
melt_coin = melted_coin_to_json (&md->melt_session_hash,
|
||||||
&md->melted_coin);
|
&md->melted_coin);
|
||||||
coin_evs = json_array ();
|
coin_evs = json_array ();
|
||||||
transfer_pubs = json_array ();
|
transfer_pubs = json_array ();
|
||||||
secret_encs = json_array ();
|
|
||||||
link_encs = json_array ();
|
|
||||||
|
|
||||||
/* now transfer_pubs */
|
/* now transfer_pubs */
|
||||||
for (j=0;j<TALER_CNC_KAPPA;j++)
|
for (j=0;j<TALER_CNC_KAPPA;j++)
|
||||||
@ -1357,25 +1277,6 @@ TALER_EXCHANGE_refresh_melt (struct TALER_EXCHANGE_Handle *exchange,
|
|||||||
GNUNET_JSON_from_data_auto (&transfer_pub)));
|
GNUNET_JSON_from_data_auto (&transfer_pub)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* now secret_encs */
|
|
||||||
for (j=0;j<TALER_CNC_KAPPA;j++)
|
|
||||||
{
|
|
||||||
const struct MeltedCoin *mc = &md->melted_coin;
|
|
||||||
struct TALER_EncryptedLinkSecretP els;
|
|
||||||
struct TALER_TransferSecretP trans_sec;
|
|
||||||
|
|
||||||
TALER_link_derive_transfer_secret (&mc->coin_priv,
|
|
||||||
&mc->transfer_priv[j],
|
|
||||||
&trans_sec);
|
|
||||||
GNUNET_assert (GNUNET_OK ==
|
|
||||||
TALER_transfer_encrypt (&md->link_secrets[j],
|
|
||||||
&trans_sec,
|
|
||||||
&els));
|
|
||||||
GNUNET_assert (0 ==
|
|
||||||
json_array_append_new (secret_encs,
|
|
||||||
GNUNET_JSON_from_data_auto (&els)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* now new_denoms */
|
/* now new_denoms */
|
||||||
for (i=0;i<md->num_fresh_coins;i++)
|
for (i=0;i<md->num_fresh_coins;i++)
|
||||||
{
|
{
|
||||||
@ -1385,37 +1286,13 @@ TALER_EXCHANGE_refresh_melt (struct TALER_EXCHANGE_Handle *exchange,
|
|||||||
(md->fresh_pks[i].rsa_public_key)));
|
(md->fresh_pks[i].rsa_public_key)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* now link_encs */
|
|
||||||
for (j=0;j<TALER_CNC_KAPPA;j++)
|
|
||||||
{
|
|
||||||
tmp = json_array ();
|
|
||||||
for (i=0;i<md->num_fresh_coins;i++)
|
|
||||||
{
|
|
||||||
const struct FreshCoinP *fc = &md->fresh_coins[j][i];
|
|
||||||
struct TALER_RefreshLinkDecryptedP rld;
|
|
||||||
struct TALER_RefreshLinkEncryptedP rle;
|
|
||||||
|
|
||||||
rld.coin_priv = fc->coin_priv;
|
|
||||||
rld.blinding_key = fc->blinding_key;
|
|
||||||
TALER_refresh_encrypt (&rld,
|
|
||||||
&md->link_secrets[j],
|
|
||||||
&rle);
|
|
||||||
GNUNET_assert (0 ==
|
|
||||||
json_array_append_new (tmp,
|
|
||||||
GNUNET_JSON_from_data_auto (&rle)));
|
|
||||||
}
|
|
||||||
GNUNET_assert (0 ==
|
|
||||||
json_array_append_new (link_encs,
|
|
||||||
tmp));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* now coin_evs */
|
/* now coin_evs */
|
||||||
for (j=0;j<TALER_CNC_KAPPA;j++)
|
for (j=0;j<TALER_CNC_KAPPA;j++)
|
||||||
{
|
{
|
||||||
tmp = json_array ();
|
tmp = json_array ();
|
||||||
for (i=0;i<md->num_fresh_coins;i++)
|
for (i=0;i<md->num_fresh_coins;i++)
|
||||||
{
|
{
|
||||||
const struct FreshCoinP *fc = &md->fresh_coins[j][i];
|
const struct TALER_FreshCoinP *fc = &md->fresh_coins[j][i];
|
||||||
struct TALER_CoinSpendPublicKeyP coin_pub;
|
struct TALER_CoinSpendPublicKeyP coin_pub;
|
||||||
struct GNUNET_HashCode coin_hash;
|
struct GNUNET_HashCode coin_hash;
|
||||||
char *coin_ev; /* blinded message to be signed (in envelope) for each coin */
|
char *coin_ev; /* blinded message to be signed (in envelope) for each coin */
|
||||||
@ -1440,8 +1317,6 @@ TALER_EXCHANGE_refresh_melt (struct TALER_EXCHANGE_Handle *exchange,
|
|||||||
json_decref (coin_evs);
|
json_decref (coin_evs);
|
||||||
json_decref (melt_coin);
|
json_decref (melt_coin);
|
||||||
json_decref (transfer_pubs);
|
json_decref (transfer_pubs);
|
||||||
json_decref (secret_encs);
|
|
||||||
json_decref (link_encs);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
GNUNET_assert (0 ==
|
GNUNET_assert (0 ==
|
||||||
@ -1456,13 +1331,11 @@ TALER_EXCHANGE_refresh_melt (struct TALER_EXCHANGE_Handle *exchange,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* finally, assemble main JSON request from constitutent arrays */
|
/* finally, assemble main JSON request from constitutent arrays */
|
||||||
melt_obj = json_pack ("{s:o, s:o, s:o, s:o, s:o, s:o}",
|
melt_obj = json_pack ("{s:o, s:o, s:o, s:o}",
|
||||||
"new_denoms", new_denoms,
|
"new_denoms", new_denoms,
|
||||||
"melt_coin", melt_coin,
|
"melt_coin", melt_coin,
|
||||||
"coin_evs", coin_evs,
|
"coin_evs", coin_evs,
|
||||||
"transfer_pubs", transfer_pubs,
|
"transfer_pubs", transfer_pubs);
|
||||||
"secret_encs", secret_encs,
|
|
||||||
"link_encs", link_encs);
|
|
||||||
|
|
||||||
/* and now we can at last begin the actual request handling */
|
/* and now we can at last begin the actual request handling */
|
||||||
rmh = GNUNET_new (struct TALER_EXCHANGE_RefreshMeltHandle);
|
rmh = GNUNET_new (struct TALER_EXCHANGE_RefreshMeltHandle);
|
||||||
@ -1627,7 +1500,7 @@ refresh_reveal_ok (struct TALER_EXCHANGE_RefreshRevealHandle *rrh,
|
|||||||
}
|
}
|
||||||
for (i=0;i<rrh->md->num_fresh_coins;i++)
|
for (i=0;i<rrh->md->num_fresh_coins;i++)
|
||||||
{
|
{
|
||||||
const struct FreshCoinP *fc;
|
const struct TALER_FreshCoinP *fc;
|
||||||
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;
|
||||||
|
@ -75,8 +75,8 @@ struct TALER_EXCHANGE_RefreshLinkHandle
|
|||||||
*
|
*
|
||||||
* @param rlh refresh link handle
|
* @param rlh refresh link handle
|
||||||
* @param json json reply with the data for one coin
|
* @param json json reply with the data for one coin
|
||||||
|
* @param coin_num number of the coin to decode
|
||||||
* @param trans_pub our transfer public key
|
* @param trans_pub our transfer public key
|
||||||
* @param secret_enc encrypted key to decrypt link data
|
|
||||||
* @param[out] coin_priv where to return private coin key
|
* @param[out] coin_priv where to return private coin key
|
||||||
* @param[out] sig where to return private coin signature
|
* @param[out] sig where to return private coin signature
|
||||||
* @param[out] pub where to return the public key for the coin
|
* @param[out] pub where to return the public key for the coin
|
||||||
@ -85,24 +85,22 @@ struct TALER_EXCHANGE_RefreshLinkHandle
|
|||||||
static int
|
static int
|
||||||
parse_refresh_link_coin (const struct TALER_EXCHANGE_RefreshLinkHandle *rlh,
|
parse_refresh_link_coin (const struct TALER_EXCHANGE_RefreshLinkHandle *rlh,
|
||||||
const json_t *json,
|
const json_t *json,
|
||||||
|
unsigned int coin_num,
|
||||||
const struct TALER_TransferPublicKeyP *trans_pub,
|
const struct TALER_TransferPublicKeyP *trans_pub,
|
||||||
const struct TALER_EncryptedLinkSecretP *secret_enc,
|
|
||||||
struct TALER_CoinSpendPrivateKeyP *coin_priv,
|
struct TALER_CoinSpendPrivateKeyP *coin_priv,
|
||||||
struct TALER_DenominationSignature *sig,
|
struct TALER_DenominationSignature *sig,
|
||||||
struct TALER_DenominationPublicKey *pub)
|
struct TALER_DenominationPublicKey *pub)
|
||||||
{
|
{
|
||||||
struct GNUNET_CRYPTO_RsaSignature *bsig;
|
struct GNUNET_CRYPTO_RsaSignature *bsig;
|
||||||
struct GNUNET_CRYPTO_RsaPublicKey *rpub;
|
struct GNUNET_CRYPTO_RsaPublicKey *rpub;
|
||||||
struct TALER_RefreshLinkEncryptedP rle;
|
|
||||||
struct GNUNET_JSON_Specification spec[] = {
|
struct GNUNET_JSON_Specification spec[] = {
|
||||||
GNUNET_JSON_spec_fixed_auto ("link_enc", &rle),
|
|
||||||
GNUNET_JSON_spec_rsa_public_key ("denom_pub", &rpub),
|
GNUNET_JSON_spec_rsa_public_key ("denom_pub", &rpub),
|
||||||
GNUNET_JSON_spec_rsa_signature ("ev_sig", &bsig),
|
GNUNET_JSON_spec_rsa_signature ("ev_sig", &bsig),
|
||||||
GNUNET_JSON_spec_end()
|
GNUNET_JSON_spec_end()
|
||||||
};
|
};
|
||||||
struct TALER_RefreshLinkDecryptedP rld;
|
struct TALER_TransferSecretP secret;
|
||||||
struct TALER_LinkSecretP secret;
|
struct TALER_FreshCoinP fc;
|
||||||
|
|
||||||
/* parse reply */
|
/* parse reply */
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
GNUNET_JSON_parse (json,
|
GNUNET_JSON_parse (json,
|
||||||
@ -113,25 +111,18 @@ parse_refresh_link_coin (const struct TALER_EXCHANGE_RefreshLinkHandle *rlh,
|
|||||||
return GNUNET_SYSERR;
|
return GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GNUNET_OK !=
|
TALER_link_recover_transfer_secret (trans_pub,
|
||||||
TALER_link_decrypt_secret2 (secret_enc,
|
&rlh->coin_priv,
|
||||||
trans_pub,
|
&secret);
|
||||||
&rlh->coin_priv,
|
TALER_setup_fresh_coin (&secret,
|
||||||
&secret))
|
coin_num,
|
||||||
{
|
&fc);
|
||||||
GNUNET_break_op (0);
|
|
||||||
GNUNET_JSON_parse_free (spec);
|
|
||||||
return GNUNET_SYSERR;
|
|
||||||
}
|
|
||||||
TALER_refresh_decrypt (&rle,
|
|
||||||
&secret,
|
|
||||||
&rld);
|
|
||||||
|
|
||||||
/* extract coin and signature */
|
/* extract coin and signature */
|
||||||
*coin_priv = rld.coin_priv;
|
*coin_priv = fc.coin_priv;
|
||||||
sig->rsa_signature
|
sig->rsa_signature
|
||||||
= GNUNET_CRYPTO_rsa_unblind (bsig,
|
= GNUNET_CRYPTO_rsa_unblind (bsig,
|
||||||
&rld.blinding_key.bks,
|
&fc.blinding_key.bks,
|
||||||
rpub);
|
rpub);
|
||||||
/* clean up */
|
/* clean up */
|
||||||
pub->rsa_public_key = GNUNET_CRYPTO_rsa_public_key_dup (rpub);
|
pub->rsa_public_key = GNUNET_CRYPTO_rsa_public_key_dup (rpub);
|
||||||
@ -217,11 +208,9 @@ parse_refresh_link_ok (struct TALER_EXCHANGE_RefreshLinkHandle *rlh,
|
|||||||
{
|
{
|
||||||
json_t *jsona;
|
json_t *jsona;
|
||||||
struct TALER_TransferPublicKeyP trans_pub;
|
struct TALER_TransferPublicKeyP trans_pub;
|
||||||
struct TALER_EncryptedLinkSecretP secret_enc;
|
|
||||||
struct GNUNET_JSON_Specification spec[] = {
|
struct GNUNET_JSON_Specification spec[] = {
|
||||||
GNUNET_JSON_spec_json ("new_coins", &jsona),
|
GNUNET_JSON_spec_json ("new_coins", &jsona),
|
||||||
GNUNET_JSON_spec_fixed_auto ("transfer_pub", &trans_pub),
|
GNUNET_JSON_spec_fixed_auto ("transfer_pub", &trans_pub),
|
||||||
GNUNET_JSON_spec_fixed_auto ("secret_enc", &secret_enc),
|
|
||||||
GNUNET_JSON_spec_end()
|
GNUNET_JSON_spec_end()
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -248,8 +237,8 @@ parse_refresh_link_ok (struct TALER_EXCHANGE_RefreshLinkHandle *rlh,
|
|||||||
parse_refresh_link_coin (rlh,
|
parse_refresh_link_coin (rlh,
|
||||||
json_array_get (jsona,
|
json_array_get (jsona,
|
||||||
i),
|
i),
|
||||||
|
i,
|
||||||
&trans_pub,
|
&trans_pub,
|
||||||
&secret_enc,
|
|
||||||
&coin_privs[i+off_coin],
|
&coin_privs[i+off_coin],
|
||||||
&sigs[i+off_coin],
|
&sigs[i+off_coin],
|
||||||
&pubs[i+off_coin]))
|
&pubs[i+off_coin]))
|
||||||
|
@ -973,7 +973,7 @@ refresh_check_melt (struct MHD_Connection *connection,
|
|||||||
* @param commit_coin 2d array of coin commitments (what the exchange is to sign
|
* @param commit_coin 2d array of coin commitments (what the exchange is to sign
|
||||||
* once the "/refres/reveal" of cut and choose is done),
|
* once the "/refres/reveal" of cut and choose is done),
|
||||||
* x-dimension must be #TALER_CNC_KAPPA
|
* x-dimension must be #TALER_CNC_KAPPA
|
||||||
* @param commit_link array of coin link commitments (what the exchange is
|
* @param transfer_pubs array of transfer public keys (what the exchange is
|
||||||
* to return via "/refresh/link" to enable linkage in the
|
* to return via "/refresh/link" to enable linkage in the
|
||||||
* future) of length #TALER_CNC_KAPPA
|
* future) of length #TALER_CNC_KAPPA
|
||||||
* @return MHD result code
|
* @return MHD result code
|
||||||
@ -985,7 +985,7 @@ TMH_DB_execute_refresh_melt (struct MHD_Connection *connection,
|
|||||||
const struct TALER_DenominationPublicKey *denom_pubs,
|
const struct TALER_DenominationPublicKey *denom_pubs,
|
||||||
const struct TMH_DB_MeltDetails *coin_melt_detail,
|
const struct TMH_DB_MeltDetails *coin_melt_detail,
|
||||||
struct TALER_EXCHANGEDB_RefreshCommitCoin *const* commit_coin,
|
struct TALER_EXCHANGEDB_RefreshCommitCoin *const* commit_coin,
|
||||||
const struct TALER_RefreshCommitLinkP *commit_link)
|
const struct TALER_TransferPublicKeyP *transfer_pubs)
|
||||||
{
|
{
|
||||||
struct TMH_KS_StateHandle *key_state;
|
struct TMH_KS_StateHandle *key_state;
|
||||||
struct TALER_EXCHANGEDB_RefreshSession refresh_session;
|
struct TALER_EXCHANGEDB_RefreshSession refresh_session;
|
||||||
@ -1082,11 +1082,11 @@ TMH_DB_execute_refresh_melt (struct MHD_Connection *connection,
|
|||||||
for (i = 0; i < TALER_CNC_KAPPA; i++)
|
for (i = 0; i < TALER_CNC_KAPPA; i++)
|
||||||
{
|
{
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
TMH_plugin->insert_refresh_commit_link (TMH_plugin->cls,
|
TMH_plugin->insert_refresh_transfer_public_key (TMH_plugin->cls,
|
||||||
session,
|
session,
|
||||||
session_hash,
|
session_hash,
|
||||||
i,
|
i,
|
||||||
&commit_link[i]))
|
&transfer_pubs[i]))
|
||||||
{
|
{
|
||||||
TMH_plugin->rollback (TMH_plugin->cls,
|
TMH_plugin->rollback (TMH_plugin->cls,
|
||||||
session);
|
session);
|
||||||
@ -1180,19 +1180,19 @@ check_commitment (struct MHD_Connection *connection,
|
|||||||
unsigned int num_newcoins,
|
unsigned int num_newcoins,
|
||||||
const struct TALER_DenominationPublicKey *denom_pubs)
|
const struct TALER_DenominationPublicKey *denom_pubs)
|
||||||
{
|
{
|
||||||
struct TALER_RefreshCommitLinkP commit_link;
|
struct TALER_TransferPublicKeyP transfer_pub;
|
||||||
struct TALER_LinkSecretP shared_secret;
|
struct TALER_TransferSecretP transfer_secret;
|
||||||
struct TALER_TransferPublicKeyP transfer_pub_check;
|
struct TALER_TransferPublicKeyP transfer_pub_check;
|
||||||
struct TALER_EXCHANGEDB_RefreshCommitCoin *commit_coins;
|
struct TALER_EXCHANGEDB_RefreshCommitCoin *commit_coins;
|
||||||
unsigned int j;
|
unsigned int j;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
TMH_plugin->get_refresh_commit_link (TMH_plugin->cls,
|
TMH_plugin->get_refresh_transfer_public_key (TMH_plugin->cls,
|
||||||
session,
|
session,
|
||||||
session_hash,
|
session_hash,
|
||||||
off,
|
off,
|
||||||
&commit_link))
|
&transfer_pub))
|
||||||
{
|
{
|
||||||
GNUNET_break (0);
|
GNUNET_break (0);
|
||||||
return (MHD_YES == TMH_RESPONSE_reply_internal_db_error (connection))
|
return (MHD_YES == TMH_RESPONSE_reply_internal_db_error (connection))
|
||||||
@ -1203,7 +1203,7 @@ check_commitment (struct MHD_Connection *connection,
|
|||||||
&transfer_pub_check.ecdhe_pub);
|
&transfer_pub_check.ecdhe_pub);
|
||||||
if (0 !=
|
if (0 !=
|
||||||
memcmp (&transfer_pub_check,
|
memcmp (&transfer_pub_check,
|
||||||
&commit_link.transfer_pub,
|
&transfer_pub,
|
||||||
sizeof (struct TALER_TransferPublicKeyP)))
|
sizeof (struct TALER_TransferPublicKeyP)))
|
||||||
{
|
{
|
||||||
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
|
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
|
||||||
@ -1217,17 +1217,9 @@ check_commitment (struct MHD_Connection *connection,
|
|||||||
"transfer key");
|
"transfer key");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GNUNET_OK !=
|
TALER_link_reveal_transfer_secret (transfer_priv,
|
||||||
TALER_link_decrypt_secret (&commit_link.shared_secret_enc,
|
&melt->coin.coin_pub,
|
||||||
transfer_priv,
|
&transfer_secret);
|
||||||
&melt->coin.coin_pub,
|
|
||||||
&shared_secret))
|
|
||||||
{
|
|
||||||
return (MHD_YES ==
|
|
||||||
TMH_RESPONSE_reply_internal_error (connection,
|
|
||||||
"Transfer secret decryption error"))
|
|
||||||
? GNUNET_NO : GNUNET_SYSERR;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check that the commitments for all new coins were correct */
|
/* Check that the commitments for all new coins were correct */
|
||||||
commit_coins = GNUNET_new_array (num_newcoins,
|
commit_coins = GNUNET_new_array (num_newcoins,
|
||||||
@ -1249,23 +1241,23 @@ check_commitment (struct MHD_Connection *connection,
|
|||||||
|
|
||||||
for (j = 0; j < num_newcoins; j++)
|
for (j = 0; j < num_newcoins; j++)
|
||||||
{
|
{
|
||||||
struct TALER_RefreshLinkDecryptedP link_data;
|
struct TALER_FreshCoinP fc;
|
||||||
struct TALER_CoinSpendPublicKeyP coin_pub;
|
struct TALER_CoinSpendPublicKeyP coin_pub;
|
||||||
struct GNUNET_HashCode h_msg;
|
struct GNUNET_HashCode h_msg;
|
||||||
char *buf;
|
char *buf;
|
||||||
size_t buf_len;
|
size_t buf_len;
|
||||||
|
|
||||||
TALER_refresh_decrypt (&commit_coins[j].refresh_link,
|
TALER_setup_fresh_coin (&transfer_secret,
|
||||||
&shared_secret,
|
j,
|
||||||
&link_data);
|
&fc);
|
||||||
GNUNET_CRYPTO_eddsa_key_get_public (&link_data.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,
|
GNUNET_CRYPTO_hash (&coin_pub,
|
||||||
sizeof (struct TALER_CoinSpendPublicKeyP),
|
sizeof (struct TALER_CoinSpendPublicKeyP),
|
||||||
&h_msg);
|
&h_msg);
|
||||||
if (GNUNET_YES !=
|
if (GNUNET_YES !=
|
||||||
GNUNET_CRYPTO_rsa_blind (&h_msg,
|
GNUNET_CRYPTO_rsa_blind (&h_msg,
|
||||||
&link_data.blinding_key.bks,
|
&fc.blinding_key.bks,
|
||||||
denom_pubs[j].rsa_public_key,
|
denom_pubs[j].rsa_public_key,
|
||||||
&buf,
|
&buf,
|
||||||
&buf_len))
|
&buf_len))
|
||||||
@ -1598,13 +1590,11 @@ struct HTD_Context
|
|||||||
* @param cls closure, a `struct HTD_Context`
|
* @param cls closure, a `struct HTD_Context`
|
||||||
* @param session_hash a session the coin was melted in
|
* @param session_hash a session the coin was melted in
|
||||||
* @param transfer_pub public transfer key for the session
|
* @param transfer_pub public transfer key for the session
|
||||||
* @param shared_secret_enc set to shared secret for the session
|
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
handle_transfer_data (void *cls,
|
handle_transfer_data (void *cls,
|
||||||
const struct GNUNET_HashCode *session_hash,
|
const struct GNUNET_HashCode *session_hash,
|
||||||
const struct TALER_TransferPublicKeyP *transfer_pub,
|
const struct TALER_TransferPublicKeyP *transfer_pub)
|
||||||
const struct TALER_EncryptedLinkSecretP *shared_secret_enc)
|
|
||||||
{
|
{
|
||||||
struct HTD_Context *ctx = cls;
|
struct HTD_Context *ctx = cls;
|
||||||
struct TALER_EXCHANGEDB_LinkDataList *ldl;
|
struct TALER_EXCHANGEDB_LinkDataList *ldl;
|
||||||
@ -1632,7 +1622,6 @@ handle_transfer_data (void *cls,
|
|||||||
ctx->num_sessions + 1);
|
ctx->num_sessions + 1);
|
||||||
lsi = &ctx->sessions[ctx->num_sessions - 1];
|
lsi = &ctx->sessions[ctx->num_sessions - 1];
|
||||||
lsi->transfer_pub = *transfer_pub;
|
lsi->transfer_pub = *transfer_pub;
|
||||||
lsi->shared_secret_enc = *shared_secret_enc;
|
|
||||||
lsi->ldl = ldl;
|
lsi->ldl = ldl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,7 +136,7 @@ struct TMH_DB_MeltDetails
|
|||||||
* @param coin_melt_details signatures and (residual) value of and information about the respective coin to be melted
|
* @param coin_melt_details signatures and (residual) value of and information about the respective coin to be melted
|
||||||
* @param commit_coin 2d array of coin commitments (what the exchange is to sign
|
* @param commit_coin 2d array of coin commitments (what the exchange is to sign
|
||||||
* once the "/refres/reveal" of cut and choose is done)
|
* once the "/refres/reveal" of cut and choose is done)
|
||||||
* @param commit_link array of coin link commitments (what the exchange is
|
* @param transfer_pubs array of transfer public keys (what the exchange is
|
||||||
* to return via "/refresh/link" to enable linkage in the
|
* to return via "/refresh/link" to enable linkage in the
|
||||||
* future) of length #TALER_CNC_KAPPA
|
* future) of length #TALER_CNC_KAPPA
|
||||||
* @return MHD result code
|
* @return MHD result code
|
||||||
@ -148,7 +148,7 @@ TMH_DB_execute_refresh_melt (struct MHD_Connection *connection,
|
|||||||
const struct TALER_DenominationPublicKey *denom_pubs,
|
const struct TALER_DenominationPublicKey *denom_pubs,
|
||||||
const struct TMH_DB_MeltDetails *coin_melt_details,
|
const struct TMH_DB_MeltDetails *coin_melt_details,
|
||||||
struct TALER_EXCHANGEDB_RefreshCommitCoin *const* commit_coin,
|
struct TALER_EXCHANGEDB_RefreshCommitCoin *const* commit_coin,
|
||||||
const struct TALER_RefreshCommitLinkP *commit_link);
|
const struct TALER_TransferPublicKeyP *transfer_pubs);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -43,7 +43,7 @@
|
|||||||
* @param session_hash hash over the data that the client commits to
|
* @param session_hash hash over the data that the client commits to
|
||||||
* @param commit_coin 2d array of coin commitments (what the exchange is to sign
|
* @param commit_coin 2d array of coin commitments (what the exchange is to sign
|
||||||
* once the "/refres/reveal" of cut and choose is done)
|
* once the "/refres/reveal" of cut and choose is done)
|
||||||
* @param commit_link array of coin link commitments (what the exchange is
|
* @param transfer_pubs array of transfer public keys (which the exchange is
|
||||||
* to return via "/refresh/link" to enable linkage in the
|
* to return via "/refresh/link" to enable linkage in the
|
||||||
* future) of length #TALER_CNC_KAPPA
|
* future) of length #TALER_CNC_KAPPA
|
||||||
* @return MHD result code
|
* @return MHD result code
|
||||||
@ -55,7 +55,7 @@ handle_refresh_melt_binary (struct MHD_Connection *connection,
|
|||||||
const struct TMH_DB_MeltDetails *coin_melt_details,
|
const struct TMH_DB_MeltDetails *coin_melt_details,
|
||||||
const struct GNUNET_HashCode *session_hash,
|
const struct GNUNET_HashCode *session_hash,
|
||||||
struct TALER_EXCHANGEDB_RefreshCommitCoin *const* commit_coin,
|
struct TALER_EXCHANGEDB_RefreshCommitCoin *const* commit_coin,
|
||||||
const struct TALER_RefreshCommitLinkP * commit_link)
|
const struct TALER_TransferPublicKeyP *transfer_pubs)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
struct TMH_KS_StateHandle *key_state;
|
struct TMH_KS_StateHandle *key_state;
|
||||||
@ -146,7 +146,7 @@ handle_refresh_melt_binary (struct MHD_Connection *connection,
|
|||||||
denom_pubs,
|
denom_pubs,
|
||||||
coin_melt_details,
|
coin_melt_details,
|
||||||
commit_coin,
|
commit_coin,
|
||||||
commit_link);
|
transfer_pubs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -321,9 +321,7 @@ free_commit_coins (struct TALER_EXCHANGEDB_RefreshCommitCoin **commit_coin,
|
|||||||
* @param new_denoms array of denomination keys
|
* @param new_denoms array of denomination keys
|
||||||
* @param melt_coin coin to melt
|
* @param melt_coin coin to melt
|
||||||
* @param transfer_pubs #TALER_CNC_KAPPA-dimensional array of transfer keys
|
* @param transfer_pubs #TALER_CNC_KAPPA-dimensional array of transfer keys
|
||||||
* @param secret_encs #TALER_CNC_KAPPA-dimensional array of old coin secrets
|
|
||||||
* @param coin_evs #TALER_CNC_KAPPA-dimensional array of envelopes to sign
|
* @param coin_evs #TALER_CNC_KAPPA-dimensional array of envelopes to sign
|
||||||
* @param link_encs #TALER_CNC_KAPPA-dimensional array of `length(@a new_denoms)` encrypted links (2D array)
|
|
||||||
* @return MHD result code
|
* @return MHD result code
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
@ -331,9 +329,7 @@ handle_refresh_melt_json (struct MHD_Connection *connection,
|
|||||||
const json_t *new_denoms,
|
const json_t *new_denoms,
|
||||||
const json_t *melt_coin,
|
const json_t *melt_coin,
|
||||||
const json_t *transfer_pubs,
|
const json_t *transfer_pubs,
|
||||||
const json_t *secret_encs,
|
const json_t *coin_evs)
|
||||||
const json_t *coin_evs,
|
|
||||||
const json_t *link_encs)
|
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
@ -344,11 +340,36 @@ handle_refresh_melt_json (struct MHD_Connection *connection,
|
|||||||
struct GNUNET_HashCode session_hash;
|
struct GNUNET_HashCode session_hash;
|
||||||
struct GNUNET_HashContext *hash_context;
|
struct GNUNET_HashContext *hash_context;
|
||||||
struct TALER_EXCHANGEDB_RefreshCommitCoin *commit_coin[TALER_CNC_KAPPA];
|
struct TALER_EXCHANGEDB_RefreshCommitCoin *commit_coin[TALER_CNC_KAPPA];
|
||||||
struct TALER_RefreshCommitLinkP commit_link[TALER_CNC_KAPPA];
|
struct TALER_TransferPublicKeyP transfer_pub[TALER_CNC_KAPPA];
|
||||||
|
|
||||||
|
|
||||||
/* For the signature check, we hash most of the inputs together
|
/* For the signature check, we hash most of the inputs together
|
||||||
(except for the signatures on the coins). */
|
(except for the signatures on the coins). */
|
||||||
hash_context = GNUNET_CRYPTO_hash_context_start ();
|
hash_context = GNUNET_CRYPTO_hash_context_start ();
|
||||||
|
|
||||||
|
for (i = 0; i < TALER_CNC_KAPPA; i++)
|
||||||
|
{
|
||||||
|
struct GNUNET_JSON_Specification trans_spec[] = {
|
||||||
|
GNUNET_JSON_spec_fixed_auto (NULL, &transfer_pub[i]),
|
||||||
|
GNUNET_JSON_spec_end ()
|
||||||
|
};
|
||||||
|
|
||||||
|
res = TMH_PARSE_json_array (connection,
|
||||||
|
transfer_pubs,
|
||||||
|
trans_spec,
|
||||||
|
i, -1);
|
||||||
|
if (GNUNET_OK != res)
|
||||||
|
{
|
||||||
|
GNUNET_break_op (0);
|
||||||
|
res = (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
GNUNET_CRYPTO_hash_context_read (hash_context,
|
||||||
|
&transfer_pub[i],
|
||||||
|
sizeof (struct TALER_TransferPublicKeyP));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
num_newcoins = json_array_size (new_denoms);
|
num_newcoins = json_array_size (new_denoms);
|
||||||
denom_pubs = GNUNET_new_array (num_newcoins,
|
denom_pubs = GNUNET_new_array (num_newcoins,
|
||||||
struct TALER_DenominationPublicKey);
|
struct TALER_DenominationPublicKey);
|
||||||
@ -405,7 +426,6 @@ handle_refresh_melt_json (struct MHD_Connection *connection,
|
|||||||
/* parse JSON arrays into binary arrays and hash everything
|
/* parse JSON arrays into binary arrays and hash everything
|
||||||
together for the signature check */
|
together for the signature check */
|
||||||
memset (commit_coin, 0, sizeof (commit_coin));
|
memset (commit_coin, 0, sizeof (commit_coin));
|
||||||
memset (commit_link, 0, sizeof (commit_link));
|
|
||||||
for (i = 0; i < TALER_CNC_KAPPA; i++)
|
for (i = 0; i < TALER_CNC_KAPPA; i++)
|
||||||
{
|
{
|
||||||
commit_coin[i] = GNUNET_new_array (num_newcoins,
|
commit_coin[i] = GNUNET_new_array (num_newcoins,
|
||||||
@ -419,11 +439,6 @@ handle_refresh_melt_json (struct MHD_Connection *connection,
|
|||||||
&rcc->coin_ev_size),
|
&rcc->coin_ev_size),
|
||||||
GNUNET_JSON_spec_end ()
|
GNUNET_JSON_spec_end ()
|
||||||
};
|
};
|
||||||
struct GNUNET_JSON_Specification link_spec[] = {
|
|
||||||
GNUNET_JSON_spec_fixed_auto (NULL,
|
|
||||||
&rcc->refresh_link),
|
|
||||||
GNUNET_JSON_spec_end ()
|
|
||||||
};
|
|
||||||
|
|
||||||
res = TMH_PARSE_json_array (connection,
|
res = TMH_PARSE_json_array (connection,
|
||||||
coin_evs,
|
coin_evs,
|
||||||
@ -439,59 +454,10 @@ handle_refresh_melt_json (struct MHD_Connection *connection,
|
|||||||
GNUNET_CRYPTO_hash_context_read (hash_context,
|
GNUNET_CRYPTO_hash_context_read (hash_context,
|
||||||
rcc->coin_ev,
|
rcc->coin_ev,
|
||||||
rcc->coin_ev_size);
|
rcc->coin_ev_size);
|
||||||
res = TMH_PARSE_json_array (connection,
|
GNUNET_JSON_parse_free (coin_spec);
|
||||||
link_encs,
|
|
||||||
link_spec,
|
|
||||||
i, j, -1);
|
|
||||||
if (GNUNET_OK != res)
|
|
||||||
{
|
|
||||||
GNUNET_break_op (0);
|
|
||||||
res = (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES;
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
GNUNET_CRYPTO_hash_context_read (hash_context,
|
|
||||||
&rcc->refresh_link,
|
|
||||||
sizeof (rcc->refresh_link));
|
|
||||||
GNUNET_JSON_parse_free (link_spec);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < TALER_CNC_KAPPA; i++)
|
|
||||||
{
|
|
||||||
struct TALER_RefreshCommitLinkP *rcl = &commit_link[i];
|
|
||||||
struct GNUNET_JSON_Specification trans_spec[] = {
|
|
||||||
GNUNET_JSON_spec_fixed_auto (NULL, &rcl->transfer_pub),
|
|
||||||
GNUNET_JSON_spec_end ()
|
|
||||||
};
|
|
||||||
struct GNUNET_JSON_Specification sec_spec[] = {
|
|
||||||
GNUNET_JSON_spec_fixed_auto (NULL, &rcl->shared_secret_enc),
|
|
||||||
GNUNET_JSON_spec_end ()
|
|
||||||
};
|
|
||||||
|
|
||||||
res = TMH_PARSE_json_array (connection,
|
|
||||||
transfer_pubs,
|
|
||||||
trans_spec,
|
|
||||||
i, -1);
|
|
||||||
if (GNUNET_OK != res)
|
|
||||||
{
|
|
||||||
GNUNET_break_op (0);
|
|
||||||
res = (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES;
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
res = TMH_PARSE_json_array (connection,
|
|
||||||
secret_encs,
|
|
||||||
sec_spec,
|
|
||||||
i, -1);
|
|
||||||
if (GNUNET_OK != res)
|
|
||||||
{
|
|
||||||
GNUNET_break_op (0);
|
|
||||||
res = (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES;
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
GNUNET_CRYPTO_hash_context_read (hash_context,
|
|
||||||
rcl,
|
|
||||||
sizeof (struct TALER_RefreshCommitLinkP));
|
|
||||||
}
|
|
||||||
GNUNET_CRYPTO_hash_context_finish (hash_context,
|
GNUNET_CRYPTO_hash_context_finish (hash_context,
|
||||||
&session_hash);
|
&session_hash);
|
||||||
hash_context = NULL;
|
hash_context = NULL;
|
||||||
@ -513,7 +479,7 @@ handle_refresh_melt_json (struct MHD_Connection *connection,
|
|||||||
&coin_melt_details,
|
&coin_melt_details,
|
||||||
&session_hash,
|
&session_hash,
|
||||||
commit_coin,
|
commit_coin,
|
||||||
commit_link);
|
transfer_pub);
|
||||||
cleanup:
|
cleanup:
|
||||||
free_commit_coins (commit_coin,
|
free_commit_coins (commit_coin,
|
||||||
TALER_CNC_KAPPA,
|
TALER_CNC_KAPPA,
|
||||||
@ -558,17 +524,13 @@ TMH_REFRESH_handler_refresh_melt (struct TMH_RequestHandler *rh,
|
|||||||
json_t *new_denoms;
|
json_t *new_denoms;
|
||||||
json_t *melt_coin;
|
json_t *melt_coin;
|
||||||
json_t *coin_evs;
|
json_t *coin_evs;
|
||||||
json_t *link_encs;
|
|
||||||
json_t *transfer_pubs;
|
json_t *transfer_pubs;
|
||||||
json_t *secret_encs;
|
|
||||||
int res;
|
int res;
|
||||||
struct GNUNET_JSON_Specification spec[] = {
|
struct GNUNET_JSON_Specification spec[] = {
|
||||||
GNUNET_JSON_spec_json ("new_denoms", &new_denoms),
|
GNUNET_JSON_spec_json ("new_denoms", &new_denoms),
|
||||||
GNUNET_JSON_spec_json ("melt_coin", &melt_coin),
|
GNUNET_JSON_spec_json ("melt_coin", &melt_coin),
|
||||||
GNUNET_JSON_spec_json ("coin_evs", &coin_evs),
|
GNUNET_JSON_spec_json ("coin_evs", &coin_evs),
|
||||||
GNUNET_JSON_spec_json ("link_encs", &link_encs),
|
|
||||||
GNUNET_JSON_spec_json ("transfer_pubs", &transfer_pubs),
|
GNUNET_JSON_spec_json ("transfer_pubs", &transfer_pubs),
|
||||||
GNUNET_JSON_spec_json ("secret_encs", &secret_encs),
|
|
||||||
GNUNET_JSON_spec_end ()
|
GNUNET_JSON_spec_end ()
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -608,9 +570,7 @@ TMH_REFRESH_handler_refresh_melt (struct TMH_RequestHandler *rh,
|
|||||||
new_denoms,
|
new_denoms,
|
||||||
melt_coin,
|
melt_coin,
|
||||||
transfer_pubs,
|
transfer_pubs,
|
||||||
secret_encs,
|
coin_evs);
|
||||||
coin_evs,
|
|
||||||
link_encs);
|
|
||||||
GNUNET_JSON_parse_free (spec);
|
GNUNET_JSON_parse_free (spec);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -1028,7 +1028,7 @@ TMH_RESPONSE_reply_refresh_reveal_missmatch (struct MHD_Connection *connection,
|
|||||||
{
|
{
|
||||||
json_t *info_commit_k;
|
json_t *info_commit_k;
|
||||||
json_t *info_link_k;
|
json_t *info_link_k;
|
||||||
const struct TALER_RefreshCommitLinkP *cl;
|
const struct TALER_TransferPublicKeyP *transfer_pub;
|
||||||
|
|
||||||
info_commit_k = json_array ();
|
info_commit_k = json_array ();
|
||||||
for (i=0;i<mc->num_newcoins;i++)
|
for (i=0;i<mc->num_newcoins;i++)
|
||||||
@ -1042,13 +1042,6 @@ TMH_RESPONSE_reply_refresh_reveal_missmatch (struct MHD_Connection *connection,
|
|||||||
"coin_ev",
|
"coin_ev",
|
||||||
GNUNET_JSON_from_data (cc->coin_ev,
|
GNUNET_JSON_from_data (cc->coin_ev,
|
||||||
cc->coin_ev_size));
|
cc->coin_ev_size));
|
||||||
json_object_set_new (cc_json,
|
|
||||||
"coin_priv_enc",
|
|
||||||
GNUNET_JSON_from_data_auto (cc->refresh_link.coin_priv_enc));
|
|
||||||
json_object_set_new (cc_json,
|
|
||||||
"blinding_key_enc",
|
|
||||||
GNUNET_JSON_from_data_auto (&cc->refresh_link.blinding_key_enc));
|
|
||||||
|
|
||||||
GNUNET_assert (0 ==
|
GNUNET_assert (0 ==
|
||||||
json_array_append_new (info_commit_k,
|
json_array_append_new (info_commit_k,
|
||||||
cc_json));
|
cc_json));
|
||||||
@ -1058,13 +1051,10 @@ TMH_RESPONSE_reply_refresh_reveal_missmatch (struct MHD_Connection *connection,
|
|||||||
info_commit_k));
|
info_commit_k));
|
||||||
|
|
||||||
info_link_k = json_object ();
|
info_link_k = json_object ();
|
||||||
cl = &mc->commit_links[k];
|
transfer_pub = &mc->transfer_pubs[k];
|
||||||
json_object_set_new (info_link_k,
|
json_object_set_new (info_link_k,
|
||||||
"transfer_pub",
|
"transfer_pub",
|
||||||
GNUNET_JSON_from_data_auto (&cl->transfer_pub));
|
GNUNET_JSON_from_data_auto (transfer_pub));
|
||||||
json_object_set_new (info_link_k,
|
|
||||||
"shared_secret_enc",
|
|
||||||
GNUNET_JSON_from_data_auto (&cl->shared_secret_enc));
|
|
||||||
GNUNET_assert (0 ==
|
GNUNET_assert (0 ==
|
||||||
json_array_append_new (info_links,
|
json_array_append_new (info_links,
|
||||||
info_link_k));
|
info_link_k));
|
||||||
@ -1113,9 +1103,6 @@ TMH_RESPONSE_reply_refresh_link_success (struct MHD_Connection *connection,
|
|||||||
json_t *obj;
|
json_t *obj;
|
||||||
|
|
||||||
obj = json_object ();
|
obj = json_object ();
|
||||||
json_object_set_new (obj,
|
|
||||||
"link_enc",
|
|
||||||
GNUNET_JSON_from_data_auto (&pos->link_data_enc));
|
|
||||||
json_object_set_new (obj,
|
json_object_set_new (obj,
|
||||||
"denom_pub",
|
"denom_pub",
|
||||||
GNUNET_JSON_from_rsa_public_key (pos->denom_pub.rsa_public_key));
|
GNUNET_JSON_from_rsa_public_key (pos->denom_pub.rsa_public_key));
|
||||||
@ -1133,9 +1120,6 @@ TMH_RESPONSE_reply_refresh_link_success (struct MHD_Connection *connection,
|
|||||||
json_object_set_new (root,
|
json_object_set_new (root,
|
||||||
"transfer_pub",
|
"transfer_pub",
|
||||||
GNUNET_JSON_from_data_auto (&sessions[i].transfer_pub));
|
GNUNET_JSON_from_data_auto (&sessions[i].transfer_pub));
|
||||||
json_object_set_new (root,
|
|
||||||
"secret_enc",
|
|
||||||
GNUNET_JSON_from_data_auto (&sessions[i].shared_secret_enc));
|
|
||||||
GNUNET_assert (0 ==
|
GNUNET_assert (0 ==
|
||||||
json_array_append_new (mlist,
|
json_array_append_new (mlist,
|
||||||
root));
|
root));
|
||||||
|
@ -521,11 +521,6 @@ struct TMH_RESPONSE_LinkSessionInfo
|
|||||||
*/
|
*/
|
||||||
struct TALER_TransferPublicKeyP transfer_pub;
|
struct TALER_TransferPublicKeyP transfer_pub;
|
||||||
|
|
||||||
/**
|
|
||||||
* Encrypted shared secret for decrypting the transfer secrets.
|
|
||||||
*/
|
|
||||||
struct TALER_EncryptedLinkSecretP shared_secret_enc;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Linked data of coins being created in the session.
|
* Linked data of coins being created in the session.
|
||||||
*/
|
*/
|
||||||
|
@ -535,16 +535,14 @@ TMH_TEST_handler_test_transfer (struct TMH_RequestHandler *rh,
|
|||||||
{
|
{
|
||||||
json_t *json;
|
json_t *json;
|
||||||
int res;
|
int res;
|
||||||
struct TALER_EncryptedLinkSecretP secret_enc;
|
|
||||||
struct TALER_TransferPrivateKeyP trans_priv;
|
struct TALER_TransferPrivateKeyP trans_priv;
|
||||||
struct TALER_CoinSpendPublicKeyP coin_pub;
|
struct TALER_CoinSpendPublicKeyP coin_pub;
|
||||||
struct GNUNET_JSON_Specification spec[] = {
|
struct GNUNET_JSON_Specification spec[] = {
|
||||||
GNUNET_JSON_spec_fixed_auto ("secret_enc", &secret_enc),
|
|
||||||
GNUNET_JSON_spec_fixed_auto ("trans_priv", &trans_priv),
|
GNUNET_JSON_spec_fixed_auto ("trans_priv", &trans_priv),
|
||||||
GNUNET_JSON_spec_fixed_auto ("coin_pub", &coin_pub),
|
GNUNET_JSON_spec_fixed_auto ("coin_pub", &coin_pub),
|
||||||
GNUNET_JSON_spec_end ()
|
GNUNET_JSON_spec_end ()
|
||||||
};
|
};
|
||||||
struct TALER_LinkSecretP secret;
|
struct TALER_TransferSecretP secret;
|
||||||
|
|
||||||
res = TMH_PARSE_post_json (connection,
|
res = TMH_PARSE_post_json (connection,
|
||||||
connection_cls,
|
connection_cls,
|
||||||
@ -561,16 +559,9 @@ TMH_TEST_handler_test_transfer (struct TMH_RequestHandler *rh,
|
|||||||
json_decref (json);
|
json_decref (json);
|
||||||
if (GNUNET_YES != res)
|
if (GNUNET_YES != res)
|
||||||
return (GNUNET_NO == res) ? MHD_YES : MHD_NO;
|
return (GNUNET_NO == res) ? MHD_YES : MHD_NO;
|
||||||
if (GNUNET_OK !=
|
TALER_link_reveal_transfer_secret (&trans_priv,
|
||||||
TALER_link_decrypt_secret (&secret_enc,
|
&coin_pub,
|
||||||
&trans_priv,
|
&secret);
|
||||||
&coin_pub,
|
|
||||||
&secret))
|
|
||||||
{
|
|
||||||
GNUNET_JSON_parse_free (spec);
|
|
||||||
return TMH_RESPONSE_reply_internal_error (connection,
|
|
||||||
"Failed to decrypt secret");
|
|
||||||
}
|
|
||||||
return TMH_RESPONSE_reply_json_pack (connection,
|
return TMH_RESPONSE_reply_json_pack (connection,
|
||||||
MHD_HTTP_OK,
|
MHD_HTTP_OK,
|
||||||
"{s:o}",
|
"{s:o}",
|
||||||
|
@ -221,7 +221,7 @@ postgres_drop_tables (void *cls)
|
|||||||
SQLEXEC_ (conn,
|
SQLEXEC_ (conn,
|
||||||
"DROP TABLE IF EXISTS refresh_commit_coin;");
|
"DROP TABLE IF EXISTS refresh_commit_coin;");
|
||||||
SQLEXEC_ (conn,
|
SQLEXEC_ (conn,
|
||||||
"DROP TABLE IF EXISTS refresh_commit_link;");
|
"DROP TABLE IF EXISTS refresh_transfer_public_key;");
|
||||||
SQLEXEC_ (conn,
|
SQLEXEC_ (conn,
|
||||||
"DROP TABLE IF EXISTS refunds;");
|
"DROP TABLE IF EXISTS refunds;");
|
||||||
SQLEXEC_ (conn,
|
SQLEXEC_ (conn,
|
||||||
@ -385,15 +385,14 @@ postgres_create_tables (void *cls)
|
|||||||
oldcoin index and the cut-and-choose index (from 0 to #TALER_CNC_KAPPA-1),
|
oldcoin index and the cut-and-choose index (from 0 to #TALER_CNC_KAPPA-1),
|
||||||
as well as the actual link data (the transfer public key and the encrypted
|
as well as the actual link data (the transfer public key and the encrypted
|
||||||
link secret) */
|
link secret) */
|
||||||
SQLEXEC("CREATE TABLE IF NOT EXISTS refresh_commit_link "
|
SQLEXEC("CREATE TABLE IF NOT EXISTS refresh_transfer_public_key "
|
||||||
"(session_hash BYTEA NOT NULL REFERENCES refresh_sessions (session_hash) ON DELETE CASCADE"
|
"(session_hash BYTEA NOT NULL REFERENCES refresh_sessions (session_hash) ON DELETE CASCADE"
|
||||||
",transfer_pub BYTEA NOT NULL CHECK(LENGTH(transfer_pub)=32)"
|
",transfer_pub BYTEA NOT NULL CHECK(LENGTH(transfer_pub)=32)"
|
||||||
",link_secret_enc BYTEA NOT NULL CHECK(LENGTH(link_secret_enc)=64)"
|
|
||||||
",cnc_index INT2 NOT NULL"
|
",cnc_index INT2 NOT NULL"
|
||||||
",UNIQUE (session_hash, cnc_index)"
|
",UNIQUE (session_hash, cnc_index)"
|
||||||
")");
|
")");
|
||||||
SQLEXEC_INDEX("CREATE INDEX refresh_commit_link_session_hash_index "
|
SQLEXEC_INDEX("CREATE INDEX refresh_transfer_public_key_index "
|
||||||
"ON refresh_commit_link(session_hash, cnc_index)");
|
"ON refresh_transfer_public_key(session_hash, cnc_index)");
|
||||||
|
|
||||||
/* Table with the commitments for the new coins that are to be created
|
/* Table with the commitments for the new coins that are to be created
|
||||||
during a melting session. Includes the session, the cut-and-choose
|
during a melting session. Includes the session, the cut-and-choose
|
||||||
@ -405,7 +404,6 @@ postgres_create_tables (void *cls)
|
|||||||
"(session_hash BYTEA NOT NULL REFERENCES refresh_sessions (session_hash) ON DELETE CASCADE"
|
"(session_hash BYTEA NOT NULL REFERENCES refresh_sessions (session_hash) ON DELETE CASCADE"
|
||||||
",cnc_index INT2 NOT NULL"
|
",cnc_index INT2 NOT NULL"
|
||||||
",newcoin_index INT2 NOT NULL"
|
",newcoin_index INT2 NOT NULL"
|
||||||
",link_vector_enc BYTEA NOT NULL CHECK(LENGTH(link_vector_enc)=64)"
|
|
||||||
",coin_ev BYTEA NOT NULL"
|
",coin_ev BYTEA NOT NULL"
|
||||||
",UNIQUE (session_hash, cnc_index, newcoin_index)"
|
",UNIQUE (session_hash, cnc_index, newcoin_index)"
|
||||||
")");
|
")");
|
||||||
@ -827,25 +825,23 @@ postgres_prepare (PGconn *db_conn)
|
|||||||
1, NULL);
|
1, NULL);
|
||||||
|
|
||||||
|
|
||||||
/* Used in #postgres_insert_refresh_commit_link() to
|
/* Used in #postgres_insert_transfer_public_key() to
|
||||||
store commitments */
|
store commitments */
|
||||||
PREPARE ("insert_refresh_commit_link",
|
PREPARE ("insert_transfer_public_key",
|
||||||
"INSERT INTO refresh_commit_link "
|
"INSERT INTO refresh_transfer_public_key "
|
||||||
"(session_hash"
|
"(session_hash"
|
||||||
",transfer_pub"
|
",transfer_pub"
|
||||||
",cnc_index"
|
",cnc_index"
|
||||||
",link_secret_enc"
|
|
||||||
") VALUES "
|
") VALUES "
|
||||||
"($1, $2, $3, $4);",
|
"($1, $2, $3);",
|
||||||
4, NULL);
|
3, NULL);
|
||||||
|
|
||||||
/* Used in #postgres_get_refresh_commit_link() to
|
/* Used in #postgres_get_refresh_transfer_public_key() to
|
||||||
retrieve original commitments during /refresh/reveal */
|
retrieve original commitments during /refresh/reveal */
|
||||||
PREPARE ("get_refresh_commit_link",
|
PREPARE ("get_refresh_transfer_public_key",
|
||||||
"SELECT"
|
"SELECT"
|
||||||
" transfer_pub"
|
" transfer_pub"
|
||||||
",link_secret_enc"
|
" FROM refresh_transfer_public_key"
|
||||||
" FROM refresh_commit_link"
|
|
||||||
" WHERE session_hash=$1 AND cnc_index=$2",
|
" WHERE session_hash=$1 AND cnc_index=$2",
|
||||||
2, NULL);
|
2, NULL);
|
||||||
|
|
||||||
@ -856,19 +852,17 @@ postgres_prepare (PGconn *db_conn)
|
|||||||
"(session_hash"
|
"(session_hash"
|
||||||
",cnc_index"
|
",cnc_index"
|
||||||
",newcoin_index"
|
",newcoin_index"
|
||||||
",link_vector_enc"
|
|
||||||
",coin_ev"
|
",coin_ev"
|
||||||
") VALUES "
|
") VALUES "
|
||||||
"($1, $2, $3, $4, $5);",
|
"($1, $2, $3, $4);",
|
||||||
5, NULL);
|
4, NULL);
|
||||||
|
|
||||||
/* Used in #postgres_get_refresh_commit_coins() to
|
/* Used in #postgres_get_refresh_commit_coins() to
|
||||||
retrieve the original coin envelopes, to either be
|
retrieve the original coin envelopes, to either be
|
||||||
verified or signed. */
|
verified or signed. */
|
||||||
PREPARE ("get_refresh_commit_coin",
|
PREPARE ("get_refresh_commit_coin",
|
||||||
"SELECT"
|
"SELECT"
|
||||||
" link_vector_enc"
|
" coin_ev"
|
||||||
",coin_ev"
|
|
||||||
" FROM refresh_commit_coin"
|
" FROM refresh_commit_coin"
|
||||||
" WHERE session_hash=$1 AND cnc_index=$2 AND newcoin_index=$3",
|
" WHERE session_hash=$1 AND cnc_index=$2 AND newcoin_index=$3",
|
||||||
3, NULL);
|
3, NULL);
|
||||||
@ -1068,8 +1062,7 @@ postgres_prepare (PGconn *db_conn)
|
|||||||
3, NULL);
|
3, NULL);
|
||||||
|
|
||||||
/* Used in #postgres_get_link_data_list(). We use the session_hash
|
/* Used in #postgres_get_link_data_list(). We use the session_hash
|
||||||
to obtain the "noreveal_index" for that session, and then select
|
to obtain the "noreveal_index" for that session, and then select the
|
||||||
the encrypted link vectors (link_vector_enc) and the
|
|
||||||
corresponding signatures (ev_sig) and the denomination keys from
|
corresponding signatures (ev_sig) and the denomination keys from
|
||||||
the respective tables (namely refresh_melts and refresh_order)
|
the respective tables (namely refresh_melts and refresh_order)
|
||||||
using the session_hash as the primary filter (on join) and the
|
using the session_hash as the primary filter (on join) and the
|
||||||
@ -1081,7 +1074,7 @@ postgres_prepare (PGconn *db_conn)
|
|||||||
being exchangeed in the refresh ops. NOTE: There may be more
|
being exchangeed in the refresh ops. NOTE: There may be more
|
||||||
efficient ways to express the same query. */
|
efficient ways to express the same query. */
|
||||||
PREPARE ("get_link",
|
PREPARE ("get_link",
|
||||||
"SELECT link_vector_enc,ev_sig,ro.denom_pub"
|
"SELECT ev_sig,ro.denom_pub"
|
||||||
" FROM refresh_sessions rs "
|
" FROM refresh_sessions rs "
|
||||||
" JOIN refresh_order ro USING (session_hash)"
|
" JOIN refresh_order ro USING (session_hash)"
|
||||||
" JOIN refresh_commit_coin rcc USING (session_hash)"
|
" JOIN refresh_commit_coin rcc USING (session_hash)"
|
||||||
@ -1100,9 +1093,9 @@ postgres_prepare (PGconn *db_conn)
|
|||||||
NOTE: This may (in theory) return multiple results, one per session
|
NOTE: This may (in theory) return multiple results, one per session
|
||||||
that the old coin was melted into. */
|
that the old coin was melted into. */
|
||||||
PREPARE ("get_transfer",
|
PREPARE ("get_transfer",
|
||||||
"SELECT transfer_pub,link_secret_enc,session_hash"
|
"SELECT transfer_pub,session_hash"
|
||||||
" FROM refresh_sessions rs"
|
" FROM refresh_sessions rs"
|
||||||
" JOIN refresh_commit_link rcl USING (session_hash)"
|
" JOIN refresh_transfer_public_key rcl USING (session_hash)"
|
||||||
" WHERE rs.old_coin_pub=$1"
|
" WHERE rs.old_coin_pub=$1"
|
||||||
" AND rcl.cnc_index=rs.noreveal_index",
|
" AND rcl.cnc_index=rs.noreveal_index",
|
||||||
1, NULL);
|
1, NULL);
|
||||||
@ -3078,7 +3071,6 @@ postgres_insert_refresh_commit_coins (void *cls,
|
|||||||
GNUNET_PQ_query_param_auto_from_type (session_hash),
|
GNUNET_PQ_query_param_auto_from_type (session_hash),
|
||||||
GNUNET_PQ_query_param_uint16 (&cnc_index),
|
GNUNET_PQ_query_param_uint16 (&cnc_index),
|
||||||
GNUNET_PQ_query_param_uint16 (&coin_off),
|
GNUNET_PQ_query_param_uint16 (&coin_off),
|
||||||
GNUNET_PQ_query_param_auto_from_type (&commit_coins[i].refresh_link),
|
|
||||||
GNUNET_PQ_query_param_fixed_size (commit_coins[i].coin_ev,
|
GNUNET_PQ_query_param_fixed_size (commit_coins[i].coin_ev,
|
||||||
commit_coins[i].coin_ev_size),
|
commit_coins[i].coin_ev_size),
|
||||||
GNUNET_PQ_query_param_end
|
GNUNET_PQ_query_param_end
|
||||||
@ -3184,8 +3176,6 @@ postgres_get_refresh_commit_coins (void *cls,
|
|||||||
}
|
}
|
||||||
{
|
{
|
||||||
struct GNUNET_PQ_ResultSpec rs[] = {
|
struct GNUNET_PQ_ResultSpec rs[] = {
|
||||||
GNUNET_PQ_result_spec_auto_from_type ("link_vector_enc",
|
|
||||||
&commit_coins[i].refresh_link),
|
|
||||||
GNUNET_PQ_result_spec_variable_size ("coin_ev",
|
GNUNET_PQ_result_spec_variable_size ("coin_ev",
|
||||||
&c_buf,
|
&c_buf,
|
||||||
&c_buf_size),
|
&c_buf_size),
|
||||||
@ -3216,28 +3206,27 @@ postgres_get_refresh_commit_coins (void *cls,
|
|||||||
* @param session database connection to use
|
* @param session database connection to use
|
||||||
* @param session_hash hash to identify refresh session
|
* @param session_hash hash to identify refresh session
|
||||||
* @param cnc_index cut and choose index (1st dimension)
|
* @param cnc_index cut and choose index (1st dimension)
|
||||||
* @param[out] link link information to store return
|
* @param tp transfer public key to store
|
||||||
* @return #GNUNET_SYSERR on internal error, #GNUNET_OK on success
|
* @return #GNUNET_SYSERR on internal error, #GNUNET_OK on success
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
postgres_insert_refresh_commit_link (void *cls,
|
postgres_insert_refresh_transfer_public_key (void *cls,
|
||||||
struct TALER_EXCHANGEDB_Session *session,
|
struct TALER_EXCHANGEDB_Session *session,
|
||||||
const struct GNUNET_HashCode *session_hash,
|
const struct GNUNET_HashCode *session_hash,
|
||||||
uint16_t cnc_index,
|
uint16_t cnc_index,
|
||||||
const struct TALER_RefreshCommitLinkP *link)
|
const struct TALER_TransferPublicKeyP *tp)
|
||||||
{
|
{
|
||||||
struct GNUNET_PQ_QueryParam params[] = {
|
struct GNUNET_PQ_QueryParam params[] = {
|
||||||
GNUNET_PQ_query_param_auto_from_type (session_hash),
|
GNUNET_PQ_query_param_auto_from_type (session_hash),
|
||||||
GNUNET_PQ_query_param_auto_from_type (&link->transfer_pub),
|
GNUNET_PQ_query_param_auto_from_type (tp),
|
||||||
GNUNET_PQ_query_param_uint16 (&cnc_index),
|
GNUNET_PQ_query_param_uint16 (&cnc_index),
|
||||||
GNUNET_PQ_query_param_auto_from_type (&link->shared_secret_enc),
|
|
||||||
GNUNET_PQ_query_param_end
|
GNUNET_PQ_query_param_end
|
||||||
};
|
};
|
||||||
|
|
||||||
PGresult *result;
|
PGresult *result;
|
||||||
|
|
||||||
result = GNUNET_PQ_exec_prepared (session->conn,
|
result = GNUNET_PQ_exec_prepared (session->conn,
|
||||||
"insert_refresh_commit_link",
|
"insert_transfer_public_key",
|
||||||
params);
|
params);
|
||||||
if (PGRES_COMMAND_OK != PQresultStatus (result))
|
if (PGRES_COMMAND_OK != PQresultStatus (result))
|
||||||
{
|
{
|
||||||
@ -3264,17 +3253,17 @@ postgres_insert_refresh_commit_link (void *cls,
|
|||||||
* @param session database connection to use
|
* @param session database connection to use
|
||||||
* @param session_hash hash to identify refresh session
|
* @param session_hash hash to identify refresh session
|
||||||
* @param cnc_index cut and choose index (1st dimension)
|
* @param cnc_index cut and choose index (1st dimension)
|
||||||
* @param[out] link information to return
|
* @param[out] tp information to return
|
||||||
* @return #GNUNET_SYSERR on internal error,
|
* @return #GNUNET_SYSERR on internal error,
|
||||||
* #GNUNET_NO if commitment was not found
|
* #GNUNET_NO if commitment was not found
|
||||||
* #GNUNET_OK on success
|
* #GNUNET_OK on success
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
postgres_get_refresh_commit_link (void *cls,
|
postgres_get_refresh_transfer_public_key (void *cls,
|
||||||
struct TALER_EXCHANGEDB_Session *session,
|
struct TALER_EXCHANGEDB_Session *session,
|
||||||
const struct GNUNET_HashCode *session_hash,
|
const struct GNUNET_HashCode *session_hash,
|
||||||
uint16_t cnc_index,
|
uint16_t cnc_index,
|
||||||
struct TALER_RefreshCommitLinkP *link)
|
struct TALER_TransferPublicKeyP *tp)
|
||||||
{
|
{
|
||||||
struct GNUNET_PQ_QueryParam params[] = {
|
struct GNUNET_PQ_QueryParam params[] = {
|
||||||
GNUNET_PQ_query_param_auto_from_type (session_hash),
|
GNUNET_PQ_query_param_auto_from_type (session_hash),
|
||||||
@ -3284,7 +3273,7 @@ postgres_get_refresh_commit_link (void *cls,
|
|||||||
PGresult *result;
|
PGresult *result;
|
||||||
|
|
||||||
result = GNUNET_PQ_exec_prepared (session->conn,
|
result = GNUNET_PQ_exec_prepared (session->conn,
|
||||||
"get_refresh_commit_link",
|
"get_refresh_transfer_public_key",
|
||||||
params);
|
params);
|
||||||
if (PGRES_TUPLES_OK != PQresultStatus (result))
|
if (PGRES_TUPLES_OK != PQresultStatus (result))
|
||||||
{
|
{
|
||||||
@ -3300,9 +3289,7 @@ postgres_get_refresh_commit_link (void *cls,
|
|||||||
{
|
{
|
||||||
struct GNUNET_PQ_ResultSpec rs[] = {
|
struct GNUNET_PQ_ResultSpec rs[] = {
|
||||||
GNUNET_PQ_result_spec_auto_from_type ("transfer_pub",
|
GNUNET_PQ_result_spec_auto_from_type ("transfer_pub",
|
||||||
&link->transfer_pub),
|
tp),
|
||||||
GNUNET_PQ_result_spec_auto_from_type ("link_secret_enc",
|
|
||||||
&link->shared_secret_enc),
|
|
||||||
GNUNET_PQ_result_spec_end
|
GNUNET_PQ_result_spec_end
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -3376,11 +3363,11 @@ postgres_get_melt_commitment (void *cls,
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
postgres_get_refresh_commit_link (cls,
|
postgres_get_refresh_transfer_public_key (cls,
|
||||||
session,
|
session,
|
||||||
session_hash,
|
session_hash,
|
||||||
cnc_index,
|
cnc_index,
|
||||||
&mc->commit_links[cnc_index]))
|
&mc->transfer_pubs[cnc_index]))
|
||||||
{
|
{
|
||||||
GNUNET_break (0);
|
GNUNET_break (0);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
@ -3486,8 +3473,6 @@ postgres_get_link_data_list (void *cls,
|
|||||||
pos = GNUNET_new (struct TALER_EXCHANGEDB_LinkDataList);
|
pos = GNUNET_new (struct TALER_EXCHANGEDB_LinkDataList);
|
||||||
{
|
{
|
||||||
struct GNUNET_PQ_ResultSpec rs[] = {
|
struct GNUNET_PQ_ResultSpec rs[] = {
|
||||||
GNUNET_PQ_result_spec_auto_from_type ("link_vector_enc",
|
|
||||||
&pos->link_data_enc),
|
|
||||||
GNUNET_PQ_result_spec_rsa_signature ("ev_sig",
|
GNUNET_PQ_result_spec_rsa_signature ("ev_sig",
|
||||||
&sig),
|
&sig),
|
||||||
GNUNET_PQ_result_spec_rsa_public_key ("denom_pub",
|
GNUNET_PQ_result_spec_rsa_public_key ("denom_pub",
|
||||||
@ -3567,10 +3552,8 @@ postgres_get_transfer (void *cls,
|
|||||||
{
|
{
|
||||||
struct GNUNET_HashCode session_hash;
|
struct GNUNET_HashCode session_hash;
|
||||||
struct TALER_TransferPublicKeyP transfer_pub;
|
struct TALER_TransferPublicKeyP transfer_pub;
|
||||||
struct TALER_EncryptedLinkSecretP shared_secret_enc;
|
|
||||||
struct GNUNET_PQ_ResultSpec rs[] = {
|
struct GNUNET_PQ_ResultSpec rs[] = {
|
||||||
GNUNET_PQ_result_spec_auto_from_type ("transfer_pub", &transfer_pub),
|
GNUNET_PQ_result_spec_auto_from_type ("transfer_pub", &transfer_pub),
|
||||||
GNUNET_PQ_result_spec_auto_from_type ("link_secret_enc", &shared_secret_enc),
|
|
||||||
GNUNET_PQ_result_spec_auto_from_type ("session_hash", &session_hash),
|
GNUNET_PQ_result_spec_auto_from_type ("session_hash", &session_hash),
|
||||||
GNUNET_PQ_result_spec_end
|
GNUNET_PQ_result_spec_end
|
||||||
};
|
};
|
||||||
@ -3584,8 +3567,7 @@ postgres_get_transfer (void *cls,
|
|||||||
}
|
}
|
||||||
tdc (tdc_cls,
|
tdc (tdc_cls,
|
||||||
&session_hash,
|
&session_hash,
|
||||||
&transfer_pub,
|
&transfer_pub);
|
||||||
&shared_secret_enc);
|
|
||||||
}
|
}
|
||||||
PQclear (result);
|
PQclear (result);
|
||||||
return GNUNET_OK;
|
return GNUNET_OK;
|
||||||
@ -4424,8 +4406,8 @@ libtaler_plugin_exchangedb_postgres_init (void *cls)
|
|||||||
plugin->insert_refresh_commit_coins = &postgres_insert_refresh_commit_coins;
|
plugin->insert_refresh_commit_coins = &postgres_insert_refresh_commit_coins;
|
||||||
plugin->get_refresh_commit_coins = &postgres_get_refresh_commit_coins;
|
plugin->get_refresh_commit_coins = &postgres_get_refresh_commit_coins;
|
||||||
plugin->free_refresh_commit_coins = &postgres_free_refresh_commit_coins;
|
plugin->free_refresh_commit_coins = &postgres_free_refresh_commit_coins;
|
||||||
plugin->insert_refresh_commit_link = &postgres_insert_refresh_commit_link;
|
plugin->insert_refresh_transfer_public_key = &postgres_insert_refresh_transfer_public_key;
|
||||||
plugin->get_refresh_commit_link = &postgres_get_refresh_commit_link;
|
plugin->get_refresh_transfer_public_key = &postgres_get_refresh_transfer_public_key;
|
||||||
plugin->get_melt_commitment = &postgres_get_melt_commitment;
|
plugin->get_melt_commitment = &postgres_get_melt_commitment;
|
||||||
plugin->free_melt_commitment = &common_free_melt_commitment;
|
plugin->free_melt_commitment = &common_free_melt_commitment;
|
||||||
plugin->insert_refresh_out = &postgres_insert_refresh_out;
|
plugin->insert_refresh_out = &postgres_insert_refresh_out;
|
||||||
|
@ -412,7 +412,7 @@ GNUNET_NETWORK_STRUCT_BEGIN
|
|||||||
struct TALER_TransferSecretP
|
struct TALER_TransferSecretP
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Secret used to encrypt/decrypt the `struct TALER_LinkSecretP`.
|
* Secret used to derive private inputs for refreshed coins.
|
||||||
* Must be (currently) a hash as this is what
|
* Must be (currently) a hash as this is what
|
||||||
* #GNUNET_CRYPTO_ecc_ecdh() returns to us.
|
* #GNUNET_CRYPTO_ecc_ecdh() returns to us.
|
||||||
*/
|
*/
|
||||||
@ -420,49 +420,6 @@ struct TALER_TransferSecretP
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Secret used to decrypt refresh links.
|
|
||||||
*/
|
|
||||||
struct TALER_LinkSecretP
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Secret used to decrypt the refresh link data.
|
|
||||||
*/
|
|
||||||
char key[sizeof (struct GNUNET_HashCode)];
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Encrypted secret used to decrypt refresh links.
|
|
||||||
*/
|
|
||||||
struct TALER_EncryptedLinkSecretP
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Encrypted secret, must be the given size!
|
|
||||||
*/
|
|
||||||
char enc[sizeof (struct TALER_LinkSecretP)];
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Representation of an refresh link in cleartext.
|
|
||||||
*/
|
|
||||||
struct TALER_RefreshLinkDecryptedP
|
|
||||||
{
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Private key of the coin.
|
|
||||||
*/
|
|
||||||
struct TALER_CoinSpendPrivateKeyP coin_priv;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Blinding key.
|
|
||||||
*/
|
|
||||||
struct TALER_DenominationBlindingKeyP blinding_key;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Length of the raw value in the Taler wire transfer identifier
|
* Length of the raw value in the Taler wire transfer identifier
|
||||||
* (in binary representation).
|
* (in binary representation).
|
||||||
@ -540,44 +497,6 @@ struct TALER_RefreshLinkEncryptedP
|
|||||||
|
|
||||||
GNUNET_NETWORK_STRUCT_END
|
GNUNET_NETWORK_STRUCT_END
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Decrypt the shared @a secret from the information in the
|
|
||||||
* encrypted link secret @e secret_enc using the transfer
|
|
||||||
* private key and the coin's public key.
|
|
||||||
*
|
|
||||||
* @param secret_enc encrypted link secret
|
|
||||||
* @param trans_priv transfer private key
|
|
||||||
* @param coin_pub coin public key
|
|
||||||
* @param[out] secret set to the shared secret
|
|
||||||
* @return #GNUNET_OK on success, #GNUNET_SYSERR on error
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
TALER_link_decrypt_secret (const struct TALER_EncryptedLinkSecretP *secret_enc,
|
|
||||||
const struct TALER_TransferPrivateKeyP *trans_priv,
|
|
||||||
const struct TALER_CoinSpendPublicKeyP *coin_pub,
|
|
||||||
struct TALER_LinkSecretP *secret);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Decrypt the shared @a secret from the information in the
|
|
||||||
* encrypted link secret @e secret_enc using the transfer
|
|
||||||
* public key and the coin's private key.
|
|
||||||
*
|
|
||||||
* @param secret_enc encrypted link secret
|
|
||||||
* @param trans_pub transfer public key
|
|
||||||
* @param coin_priv coin private key
|
|
||||||
* @param[out] secret set to the shared secret
|
|
||||||
* @return #GNUNET_OK on success, #GNUNET_SYSERR on error
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
TALER_link_decrypt_secret2 (const struct TALER_EncryptedLinkSecretP *secret_enc,
|
|
||||||
const struct TALER_TransferPublicKeyP *trans_pub,
|
|
||||||
const struct TALER_CoinSpendPrivateKeyP *coin_priv,
|
|
||||||
struct TALER_LinkSecretP *secret);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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
|
||||||
@ -596,78 +515,68 @@ TALER_link_derive_transfer_secret (const struct TALER_CoinSpendPrivateKeyP *coin
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encrypt the shared @a secret to generate the encrypted link secret.
|
* Decrypt the shared @a secret from the information in the
|
||||||
* Also creates the transfer key.
|
* @a trans_priv and @a coin_pub.
|
||||||
*
|
*
|
||||||
* @param secret link secret to encrypt
|
* @param trans_priv transfer private key
|
||||||
* @param coin_pub coin public key
|
* @param coin_pub coin public key
|
||||||
* @param[out] trans_priv set to transfer private key
|
* @param[out] secret set to the shared secret
|
||||||
* @param[out] trans_pub set to transfer public key
|
|
||||||
* @param[out] secret_enc set to the encryptd @a secret
|
|
||||||
* @return #GNUNET_OK on success, #GNUNET_SYSERR on error
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
TALER_link_encrypt_secret (const struct TALER_LinkSecretP *secret,
|
|
||||||
const struct TALER_CoinSpendPublicKeyP *coin_pub,
|
|
||||||
struct TALER_TransferPrivateKeyP *trans_priv,
|
|
||||||
struct TALER_TransferPublicKeyP *trans_pub,
|
|
||||||
struct TALER_EncryptedLinkSecretP *secret_enc);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Use the @a trans_sec (from ECDHE) to decrypt the @a secret_enc
|
|
||||||
* to obtain the @a secret to decrypt the linkage data.
|
|
||||||
*
|
|
||||||
* @param secret_enc encrypted secret
|
|
||||||
* @param trans_sec transfer secret
|
|
||||||
* @param secret shared secret for refresh link decryption
|
|
||||||
* @return #GNUNET_OK on success
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
TALER_transfer_decrypt (const struct TALER_EncryptedLinkSecretP *secret_enc,
|
|
||||||
const struct TALER_TransferSecretP *trans_sec,
|
|
||||||
struct TALER_LinkSecretP *secret);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Use the @a trans_sec (from ECDHE) to encrypt the @a secret
|
|
||||||
* to obtain the @a secret_enc.
|
|
||||||
*
|
|
||||||
* @param secret shared secret for refresh link decryption
|
|
||||||
* @param trans_sec transfer secret
|
|
||||||
* @param[out] secret_enc encrypted secret
|
|
||||||
* @return #GNUNET_OK on success
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
TALER_transfer_encrypt (const struct TALER_LinkSecretP *secret,
|
|
||||||
const struct TALER_TransferSecretP *trans_sec,
|
|
||||||
struct TALER_EncryptedLinkSecretP *secret_enc);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Decrypt refresh link information.
|
|
||||||
*
|
|
||||||
* @param input encrypted refresh link data
|
|
||||||
* @param secret shared secret to use for decryption
|
|
||||||
* @param[out] output where to write decrypted refresh link
|
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
TALER_refresh_decrypt (const struct TALER_RefreshLinkEncryptedP *input,
|
TALER_link_reveal_transfer_secret (const struct TALER_TransferPrivateKeyP *trans_priv,
|
||||||
const struct TALER_LinkSecretP *secret,
|
const struct TALER_CoinSpendPublicKeyP *coin_pub,
|
||||||
struct TALER_RefreshLinkDecryptedP *output);
|
struct TALER_TransferSecretP *transfer_secret);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encrypt refresh link information.
|
* Decrypt the shared @a secret from the information in the
|
||||||
|
* @a trans_priv and @a coin_pub.
|
||||||
*
|
*
|
||||||
* @param input plaintext refresh link data
|
* @param trans_pub transfer private key
|
||||||
* @param secret shared secret to use for encryption
|
* @param coin_priv coin public key
|
||||||
* @param[out] output where to write encrypted refresh link
|
* @param[out] secret set to the shared secret
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
TALER_refresh_encrypt (const struct TALER_RefreshLinkDecryptedP *input,
|
TALER_link_recover_transfer_secret (const struct TALER_TransferPublicKeyP *trans_pub,
|
||||||
const struct TALER_LinkSecretP *secret,
|
const struct TALER_CoinSpendPrivateKeyP *coin_priv,
|
||||||
struct TALER_RefreshLinkEncryptedP *output);
|
struct TALER_TransferSecretP *transfer_secret);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Header for serializations of coin-specific information about the
|
||||||
|
* fresh coins we generate during a melt.
|
||||||
|
*/
|
||||||
|
struct TALER_FreshCoinP
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Private key of the coin.
|
||||||
|
*/
|
||||||
|
struct TALER_CoinSpendPrivateKeyP coin_priv;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The blinding key.
|
||||||
|
*/
|
||||||
|
struct TALER_DenominationBlindingKeyP blinding_key;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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_setup_fresh_coin (const struct TALER_TransferSecretP *secret_seed,
|
||||||
|
unsigned int coin_num_salt,
|
||||||
|
struct TALER_FreshCoinP *fc);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -444,12 +444,6 @@ struct TALER_EXCHANGEDB_RefreshSession
|
|||||||
struct TALER_EXCHANGEDB_RefreshCommitCoin
|
struct TALER_EXCHANGEDB_RefreshCommitCoin
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
|
||||||
* Encrypted data allowing those able to decrypt it to derive
|
|
||||||
* the private keys of the new coins created by the refresh.
|
|
||||||
*/
|
|
||||||
struct TALER_RefreshLinkEncryptedP refresh_link;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Blinded message to be signed (in envelope), with @e coin_env_size bytes.
|
* Blinded message to be signed (in envelope), with @e coin_env_size bytes.
|
||||||
*/
|
*/
|
||||||
@ -473,12 +467,6 @@ struct TALER_EXCHANGEDB_LinkDataList
|
|||||||
*/
|
*/
|
||||||
struct TALER_EXCHANGEDB_LinkDataList *next;
|
struct TALER_EXCHANGEDB_LinkDataList *next;
|
||||||
|
|
||||||
/**
|
|
||||||
* Link data, used to recover the private key of the coin
|
|
||||||
* by the owner of the old coin.
|
|
||||||
*/
|
|
||||||
struct TALER_RefreshLinkEncryptedP link_data_enc;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Denomination public key, determines the value of the coin.
|
* Denomination public key, determines the value of the coin.
|
||||||
*/
|
*/
|
||||||
@ -579,9 +567,9 @@ struct TALER_EXCHANGEDB_MeltCommitment
|
|||||||
struct TALER_EXCHANGEDB_RefreshCommitCoin *commit_coins[TALER_CNC_KAPPA];
|
struct TALER_EXCHANGEDB_RefreshCommitCoin *commit_coins[TALER_CNC_KAPPA];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Array of #TALER_CNC_KAPPA links.
|
* Array of #TALER_CNC_KAPPA transfer public keys.
|
||||||
*/
|
*/
|
||||||
struct TALER_RefreshCommitLinkP commit_links[TALER_CNC_KAPPA];
|
struct TALER_TransferPublicKeyP transfer_pubs[TALER_CNC_KAPPA];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -635,8 +623,7 @@ typedef int
|
|||||||
typedef void
|
typedef void
|
||||||
(*TALER_EXCHANGEDB_TransferDataCallback)(void *cls,
|
(*TALER_EXCHANGEDB_TransferDataCallback)(void *cls,
|
||||||
const struct GNUNET_HashCode *session_hash,
|
const struct GNUNET_HashCode *session_hash,
|
||||||
const struct TALER_TransferPublicKeyP *transfer_pub,
|
const struct TALER_TransferPublicKeyP *transfer_pub);
|
||||||
const struct TALER_EncryptedLinkSecretP *shared_secret_enc);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1217,15 +1204,15 @@ struct TALER_EXCHANGEDB_Plugin
|
|||||||
* @param session database connection to use
|
* @param session database connection to use
|
||||||
* @param session_hash hash to identify refresh session
|
* @param session_hash hash to identify refresh session
|
||||||
* @param cnc_index cut and choose index, relating to #TALER_CNC_KAPPA
|
* @param cnc_index cut and choose index, relating to #TALER_CNC_KAPPA
|
||||||
* @param link link information to store
|
* @param tp public key to store
|
||||||
* @return #GNUNET_SYSERR on internal error, #GNUNET_OK on success
|
* @return #GNUNET_SYSERR on internal error, #GNUNET_OK on success
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
(*insert_refresh_commit_link) (void *cls,
|
(*insert_refresh_transfer_public_key) (void *cls,
|
||||||
struct TALER_EXCHANGEDB_Session *session,
|
struct TALER_EXCHANGEDB_Session *session,
|
||||||
const struct GNUNET_HashCode *session_hash,
|
const struct GNUNET_HashCode *session_hash,
|
||||||
uint16_t cnc_index,
|
uint16_t cnc_index,
|
||||||
const struct TALER_RefreshCommitLinkP *link);
|
const struct TALER_TransferPublicKeyP *tp);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Obtain the commited (encrypted) refresh link data
|
* Obtain the commited (encrypted) refresh link data
|
||||||
@ -1235,17 +1222,17 @@ struct TALER_EXCHANGEDB_Plugin
|
|||||||
* @param session database connection to use
|
* @param session database connection to use
|
||||||
* @param session_hash hash to identify refresh session
|
* @param session_hash hash to identify refresh session
|
||||||
* @param cnc_index cut and choose index (1st dimension)
|
* @param cnc_index cut and choose index (1st dimension)
|
||||||
* @param[out] link information to return
|
* @param[out] tp information to return
|
||||||
* @return #GNUNET_SYSERR on internal error,
|
* @return #GNUNET_SYSERR on internal error,
|
||||||
* #GNUNET_NO if commitment was not found
|
* #GNUNET_NO if commitment was not found
|
||||||
* #GNUNET_OK on success
|
* #GNUNET_OK on success
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
(*get_refresh_commit_link) (void *cls,
|
(*get_refresh_transfer_public_key) (void *cls,
|
||||||
struct TALER_EXCHANGEDB_Session *session,
|
struct TALER_EXCHANGEDB_Session *session,
|
||||||
const struct GNUNET_HashCode *session_hash,
|
const struct GNUNET_HashCode *session_hash,
|
||||||
uint16_t cnc_index,
|
uint16_t cnc_index,
|
||||||
struct TALER_RefreshCommitLinkP *link);
|
struct TALER_TransferPublicKeyP *tp);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -877,31 +877,6 @@ struct TALER_ExchangeKeyValidityPS
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief For each (old) coin being melted, we have a `struct
|
|
||||||
* RefreshCommitLinkP` that allows the user to find the shared secret
|
|
||||||
* to decrypt the respective refresh links for the new coins in the
|
|
||||||
* `struct TALER_EXCHANGEDB_RefreshCommitCoin`.
|
|
||||||
*
|
|
||||||
* Part of the construction of the refresh session's hash and
|
|
||||||
* thus of what is signed there.
|
|
||||||
*/
|
|
||||||
struct TALER_RefreshCommitLinkP
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Transfer public key, used to decrypt the @e shared_secret_enc
|
|
||||||
* in combintation with the corresponding private key of the
|
|
||||||
* coin.
|
|
||||||
*/
|
|
||||||
struct TALER_TransferPublicKeyP transfer_pub;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Encrypted shared secret to decrypt the link.
|
|
||||||
*/
|
|
||||||
struct TALER_EncryptedLinkSecretP shared_secret_enc;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Information signed by the exchange's master
|
* @brief Information signed by the exchange's master
|
||||||
* key affirming the SEPA details for the exchange.
|
* key affirming the SEPA details for the exchange.
|
||||||
|
@ -73,92 +73,32 @@ TALER_gcrypt_init ()
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Derive symmetric key material for refresh operations from
|
* Check if a coin is valid; that is, whether the denomination key exists,
|
||||||
* a given shared secret for link decryption.
|
* is not expired, and the signature is correct.
|
||||||
*
|
*
|
||||||
* @param secret the shared secret
|
* @param coin_public_info the coin public info to check for validity
|
||||||
* @param[out] iv set to initialization vector
|
* @return #GNUNET_YES if the coin is valid,
|
||||||
* @param[out] skey set to session key
|
* #GNUNET_NO if it is invalid
|
||||||
*/
|
* #GNUNET_SYSERROR if an internal error occured
|
||||||
static void
|
|
||||||
derive_refresh_key (const struct TALER_LinkSecretP *secret,
|
|
||||||
struct GNUNET_CRYPTO_SymmetricInitializationVector *iv,
|
|
||||||
struct GNUNET_CRYPTO_SymmetricSessionKey *skey)
|
|
||||||
{
|
|
||||||
static const char ctx_key[] = "taler-link-skey";
|
|
||||||
static const char ctx_iv[] = "taler-link-iv";
|
|
||||||
|
|
||||||
GNUNET_assert (GNUNET_YES ==
|
|
||||||
GNUNET_CRYPTO_kdf (skey, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
|
|
||||||
ctx_key, strlen (ctx_key),
|
|
||||||
secret, sizeof (struct TALER_LinkSecretP),
|
|
||||||
NULL, 0));
|
|
||||||
GNUNET_assert (GNUNET_YES ==
|
|
||||||
GNUNET_CRYPTO_kdf (iv, sizeof (struct GNUNET_CRYPTO_SymmetricInitializationVector),
|
|
||||||
ctx_iv, strlen (ctx_iv),
|
|
||||||
secret, sizeof (struct TALER_LinkSecretP),
|
|
||||||
NULL, 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Derive symmetric key material for refresh operations from
|
|
||||||
* a given shared secret for key decryption.
|
|
||||||
*
|
|
||||||
* @param secret the shared secret
|
|
||||||
* @param[out] iv set to initialization vector
|
|
||||||
* @param[out] skey set to session key
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
derive_transfer_key (const struct TALER_TransferSecretP *secret,
|
|
||||||
struct GNUNET_CRYPTO_SymmetricInitializationVector *iv,
|
|
||||||
struct GNUNET_CRYPTO_SymmetricSessionKey *skey)
|
|
||||||
{
|
|
||||||
static const char ctx_key[] = "taler-transfer-skey";
|
|
||||||
static const char ctx_iv[] = "taler-transfer-iv";
|
|
||||||
|
|
||||||
GNUNET_assert (GNUNET_YES ==
|
|
||||||
GNUNET_CRYPTO_kdf (skey, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
|
|
||||||
ctx_key, strlen (ctx_key),
|
|
||||||
secret, sizeof (struct TALER_TransferSecretP),
|
|
||||||
NULL, 0));
|
|
||||||
GNUNET_assert (GNUNET_YES ==
|
|
||||||
GNUNET_CRYPTO_kdf (iv, sizeof (struct GNUNET_CRYPTO_SymmetricInitializationVector),
|
|
||||||
ctx_iv, strlen (ctx_iv),
|
|
||||||
secret, sizeof (struct TALER_TransferSecretP),
|
|
||||||
NULL, 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Use the @a trans_sec (from ECDHE) to decrypt the @a secret_enc
|
|
||||||
* to obtain the @a secret to decrypt the linkage data.
|
|
||||||
*
|
|
||||||
* @param secret_enc encrypted secret
|
|
||||||
* @param trans_sec transfer secret
|
|
||||||
* @param secret shared secret for refresh link decryption
|
|
||||||
* @return #GNUNET_OK on success
|
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
TALER_transfer_decrypt (const struct TALER_EncryptedLinkSecretP *secret_enc,
|
TALER_test_coin_valid (const struct TALER_CoinPublicInfo *coin_public_info)
|
||||||
const struct TALER_TransferSecretP *trans_sec,
|
|
||||||
struct TALER_LinkSecretP *secret)
|
|
||||||
{
|
{
|
||||||
struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
|
struct GNUNET_HashCode c_hash;
|
||||||
struct GNUNET_CRYPTO_SymmetricSessionKey skey;
|
|
||||||
ssize_t s;
|
|
||||||
|
|
||||||
GNUNET_assert (sizeof (struct TALER_EncryptedLinkSecretP) ==
|
GNUNET_CRYPTO_hash (&coin_public_info->coin_pub,
|
||||||
sizeof (struct TALER_LinkSecretP));
|
sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey),
|
||||||
derive_transfer_key (trans_sec, &iv, &skey);
|
&c_hash);
|
||||||
s = GNUNET_CRYPTO_symmetric_decrypt (secret_enc,
|
if (GNUNET_OK !=
|
||||||
sizeof (struct TALER_LinkSecretP),
|
GNUNET_CRYPTO_rsa_verify (&c_hash,
|
||||||
&skey,
|
coin_public_info->denom_sig.rsa_signature,
|
||||||
&iv,
|
coin_public_info->denom_pub.rsa_public_key))
|
||||||
secret);
|
{
|
||||||
if (sizeof (struct TALER_LinkSecretP) != s)
|
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
|
||||||
return GNUNET_SYSERR;
|
"coin signature is invalid\n");
|
||||||
return GNUNET_OK;
|
return GNUNET_NO;
|
||||||
|
}
|
||||||
|
return GNUNET_YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -190,245 +130,74 @@ TALER_link_derive_transfer_secret (const struct TALER_CoinSpendPrivateKeyP *coin
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Use the @a trans_sec (from ECDHE) to encrypt the @a secret
|
|
||||||
* to obtain the @a secret_enc.
|
|
||||||
*
|
|
||||||
* @param secret shared secret for refresh link decryption
|
|
||||||
* @param trans_sec transfer secret
|
|
||||||
* @param[out] secret_enc encrypted secret
|
|
||||||
* @return #GNUNET_OK on success
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
TALER_transfer_encrypt (const struct TALER_LinkSecretP *secret,
|
|
||||||
const struct TALER_TransferSecretP *trans_sec,
|
|
||||||
struct TALER_EncryptedLinkSecretP *secret_enc)
|
|
||||||
{
|
|
||||||
struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
|
|
||||||
struct GNUNET_CRYPTO_SymmetricSessionKey skey;
|
|
||||||
ssize_t s;
|
|
||||||
|
|
||||||
GNUNET_assert (sizeof (struct TALER_EncryptedLinkSecretP) ==
|
|
||||||
sizeof (struct TALER_LinkSecretP));
|
|
||||||
derive_transfer_key (trans_sec, &iv, &skey);
|
|
||||||
s = GNUNET_CRYPTO_symmetric_encrypt (secret,
|
|
||||||
sizeof (struct TALER_LinkSecretP),
|
|
||||||
&skey,
|
|
||||||
&iv,
|
|
||||||
secret_enc);
|
|
||||||
if (sizeof (struct TALER_LinkSecretP) != s)
|
|
||||||
return GNUNET_SYSERR;
|
|
||||||
return GNUNET_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Decrypt refresh link information.
|
|
||||||
*
|
|
||||||
* @param input encrypted refresh link data
|
|
||||||
* @param secret shared secret to use for decryption
|
|
||||||
* @param[out] output where to write decrypted data
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
TALER_refresh_decrypt (const struct TALER_RefreshLinkEncryptedP *input,
|
|
||||||
const struct TALER_LinkSecretP *secret,
|
|
||||||
struct TALER_RefreshLinkDecryptedP *output)
|
|
||||||
{
|
|
||||||
struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
|
|
||||||
struct GNUNET_CRYPTO_SymmetricSessionKey skey;
|
|
||||||
|
|
||||||
derive_refresh_key (secret, &iv, &skey);
|
|
||||||
GNUNET_assert (sizeof (struct TALER_RefreshLinkEncryptedP) ==
|
|
||||||
sizeof (struct TALER_RefreshLinkDecryptedP));
|
|
||||||
GNUNET_assert (sizeof (struct TALER_RefreshLinkEncryptedP) ==
|
|
||||||
GNUNET_CRYPTO_symmetric_decrypt (input,
|
|
||||||
sizeof (struct TALER_RefreshLinkEncryptedP),
|
|
||||||
&skey,
|
|
||||||
&iv,
|
|
||||||
output));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Encrypt refresh link information.
|
|
||||||
*
|
|
||||||
* @param input plaintext refresh link data
|
|
||||||
* @param secret shared secret to use for encryption
|
|
||||||
* @param[out] output where to write encrypted link data
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
TALER_refresh_encrypt (const struct TALER_RefreshLinkDecryptedP *input,
|
|
||||||
const struct TALER_LinkSecretP *secret,
|
|
||||||
struct TALER_RefreshLinkEncryptedP *output)
|
|
||||||
{
|
|
||||||
struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
|
|
||||||
struct GNUNET_CRYPTO_SymmetricSessionKey skey;
|
|
||||||
|
|
||||||
derive_refresh_key (secret, &iv, &skey);
|
|
||||||
GNUNET_assert (sizeof (struct TALER_RefreshLinkEncryptedP) ==
|
|
||||||
sizeof (struct TALER_RefreshLinkDecryptedP));
|
|
||||||
GNUNET_assert (sizeof (struct TALER_RefreshLinkEncryptedP) ==
|
|
||||||
GNUNET_CRYPTO_symmetric_encrypt (input,
|
|
||||||
sizeof (struct TALER_RefreshLinkDecryptedP),
|
|
||||||
&skey,
|
|
||||||
&iv,
|
|
||||||
output));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if a coin is valid; that is, whether the denomination key exists,
|
|
||||||
* is not expired, and the signature is correct.
|
|
||||||
*
|
|
||||||
* @param coin_public_info the coin public info to check for validity
|
|
||||||
* @return #GNUNET_YES if the coin is valid,
|
|
||||||
* #GNUNET_NO if it is invalid
|
|
||||||
* #GNUNET_SYSERROR if an internal error occured
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
TALER_test_coin_valid (const struct TALER_CoinPublicInfo *coin_public_info)
|
|
||||||
{
|
|
||||||
struct GNUNET_HashCode c_hash;
|
|
||||||
|
|
||||||
GNUNET_CRYPTO_hash (&coin_public_info->coin_pub,
|
|
||||||
sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey),
|
|
||||||
&c_hash);
|
|
||||||
if (GNUNET_OK !=
|
|
||||||
GNUNET_CRYPTO_rsa_verify (&c_hash,
|
|
||||||
coin_public_info->denom_sig.rsa_signature,
|
|
||||||
coin_public_info->denom_pub.rsa_public_key))
|
|
||||||
{
|
|
||||||
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
|
|
||||||
"coin signature is invalid\n");
|
|
||||||
return GNUNET_NO;
|
|
||||||
}
|
|
||||||
return GNUNET_YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decrypt the shared @a secret from the information in the
|
* Decrypt the shared @a secret from the information in the
|
||||||
* encrypted link secret @e secret_enc using the transfer
|
* @a trans_priv and @a coin_pub.
|
||||||
* private key and the coin's public key.
|
|
||||||
*
|
*
|
||||||
* @param secret_enc encrypted link secret
|
|
||||||
* @param trans_priv transfer private key
|
* @param trans_priv transfer private key
|
||||||
* @param coin_pub coin public key
|
* @param coin_pub coin public key
|
||||||
* @param[out] secret set to the shared secret
|
* @param[out] secret set to the shared secret
|
||||||
* @return #GNUNET_OK on success, #GNUNET_SYSERR on error
|
|
||||||
*/
|
*/
|
||||||
int
|
void
|
||||||
TALER_link_decrypt_secret (const struct TALER_EncryptedLinkSecretP *secret_enc,
|
TALER_link_reveal_transfer_secret (const struct TALER_TransferPrivateKeyP *trans_priv,
|
||||||
const struct TALER_TransferPrivateKeyP *trans_priv,
|
const struct TALER_CoinSpendPublicKeyP *coin_pub,
|
||||||
const struct TALER_CoinSpendPublicKeyP *coin_pub,
|
struct TALER_TransferSecretP *transfer_secret)
|
||||||
struct TALER_LinkSecretP *secret)
|
|
||||||
{
|
{
|
||||||
struct TALER_TransferSecretP transfer_secret;
|
GNUNET_assert (GNUNET_OK ==
|
||||||
|
GNUNET_CRYPTO_ecdh_eddsa (&trans_priv->ecdhe_priv,
|
||||||
if (GNUNET_OK !=
|
&coin_pub->eddsa_pub,
|
||||||
GNUNET_CRYPTO_ecdh_eddsa (&trans_priv->ecdhe_priv,
|
&transfer_secret->key));
|
||||||
&coin_pub->eddsa_pub,
|
|
||||||
&transfer_secret.key))
|
|
||||||
{
|
|
||||||
GNUNET_break (0);
|
|
||||||
return GNUNET_SYSERR;
|
|
||||||
}
|
|
||||||
if (GNUNET_OK !=
|
|
||||||
TALER_transfer_decrypt (secret_enc,
|
|
||||||
&transfer_secret,
|
|
||||||
secret))
|
|
||||||
{
|
|
||||||
GNUNET_break (0);
|
|
||||||
return GNUNET_SYSERR;
|
|
||||||
}
|
|
||||||
return GNUNET_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decrypt the shared @a secret from the information in the
|
* Decrypt the shared @a secret from the information in the
|
||||||
* encrypted link secret @e secret_enc using the transfer
|
* @a trans_priv and @a coin_pub.
|
||||||
* public key and the coin's private key.
|
|
||||||
*
|
*
|
||||||
* @param secret_enc encrypted link secret
|
* @param trans_pub transfer private key
|
||||||
* @param trans_pub transfer public key
|
* @param coin_priv coin public key
|
||||||
* @param coin_priv coin private key
|
|
||||||
* @param[out] secret set to the shared secret
|
* @param[out] secret set to the shared secret
|
||||||
* @return #GNUNET_OK on success, #GNUNET_SYSERR on error
|
|
||||||
*/
|
*/
|
||||||
int
|
void
|
||||||
TALER_link_decrypt_secret2 (const struct TALER_EncryptedLinkSecretP *secret_enc,
|
TALER_link_recover_transfer_secret (const struct TALER_TransferPublicKeyP *trans_pub,
|
||||||
const struct TALER_TransferPublicKeyP *trans_pub,
|
const struct TALER_CoinSpendPrivateKeyP *coin_priv,
|
||||||
const struct TALER_CoinSpendPrivateKeyP *coin_priv,
|
struct TALER_TransferSecretP *transfer_secret)
|
||||||
struct TALER_LinkSecretP *secret)
|
|
||||||
{
|
{
|
||||||
struct TALER_TransferSecretP transfer_secret;
|
GNUNET_assert (GNUNET_OK ==
|
||||||
|
GNUNET_CRYPTO_eddsa_ecdh (&coin_priv->eddsa_priv,
|
||||||
if (GNUNET_OK !=
|
&trans_pub->ecdhe_pub,
|
||||||
GNUNET_CRYPTO_eddsa_ecdh (&coin_priv->eddsa_priv,
|
&transfer_secret->key));
|
||||||
&trans_pub->ecdhe_pub,
|
|
||||||
&transfer_secret.key))
|
|
||||||
{
|
|
||||||
GNUNET_break (0);
|
|
||||||
return GNUNET_SYSERR;
|
|
||||||
}
|
|
||||||
if (GNUNET_OK !=
|
|
||||||
TALER_transfer_decrypt (secret_enc,
|
|
||||||
&transfer_secret,
|
|
||||||
secret))
|
|
||||||
{
|
|
||||||
GNUNET_break (0);
|
|
||||||
return GNUNET_SYSERR;
|
|
||||||
}
|
|
||||||
return GNUNET_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encrypt the shared @a secret to generate the encrypted link secret.
|
* Setup information for a fresh coin.
|
||||||
* Also creates the transfer key.
|
|
||||||
*
|
*
|
||||||
* @param secret link secret to encrypt
|
* @param secret_seed seed to use for KDF to derive coin keys
|
||||||
* @param coin_pub coin public key
|
* @param coin_num_salt number of the coin to include in KDF
|
||||||
* @param[out] trans_priv set to transfer private key
|
* @param[out] fc value to initialize
|
||||||
* @param[out] trans_pub set to transfer public key
|
|
||||||
* @param[out] secret_enc set to the encryptd @a secret
|
|
||||||
* @return #GNUNET_OK on success, #GNUNET_SYSERR on error
|
|
||||||
*/
|
*/
|
||||||
int
|
void
|
||||||
TALER_link_encrypt_secret (const struct TALER_LinkSecretP *secret,
|
TALER_setup_fresh_coin (const struct TALER_TransferSecretP *secret_seed,
|
||||||
const struct TALER_CoinSpendPublicKeyP *coin_pub,
|
unsigned int coin_num_salt,
|
||||||
struct TALER_TransferPrivateKeyP *trans_priv,
|
struct TALER_FreshCoinP *fc)
|
||||||
struct TALER_TransferPublicKeyP *trans_pub,
|
|
||||||
struct TALER_EncryptedLinkSecretP *secret_enc)
|
|
||||||
{
|
{
|
||||||
struct TALER_TransferSecretP transfer_secret;
|
uint32_t be_salt = htonl (coin_num_salt);
|
||||||
struct GNUNET_CRYPTO_EcdhePrivateKey *pk;
|
|
||||||
|
|
||||||
pk = GNUNET_CRYPTO_ecdhe_key_create ();
|
GNUNET_assert (GNUNET_OK ==
|
||||||
if (GNUNET_OK !=
|
GNUNET_CRYPTO_kdf (fc,
|
||||||
GNUNET_CRYPTO_ecdh_eddsa (pk,
|
sizeof (*fc),
|
||||||
&coin_pub->eddsa_pub,
|
secret_seed,
|
||||||
&transfer_secret.key))
|
sizeof (*secret_seed),
|
||||||
{
|
&be_salt,
|
||||||
GNUNET_break (0);
|
sizeof (be_salt),
|
||||||
GNUNET_free (pk);
|
"taler-coin-derivation",
|
||||||
return GNUNET_SYSERR;
|
strlen ("taler-coin-derivation"),
|
||||||
}
|
NULL, 0));
|
||||||
if (GNUNET_OK !=
|
/* FIXME: twiddle the bits of the private key */
|
||||||
TALER_transfer_encrypt (secret,
|
|
||||||
&transfer_secret,
|
|
||||||
secret_enc))
|
|
||||||
{
|
|
||||||
GNUNET_break (0);
|
|
||||||
return GNUNET_SYSERR;
|
|
||||||
}
|
|
||||||
trans_priv->ecdhe_priv = *pk;
|
|
||||||
GNUNET_CRYPTO_ecdhe_key_get_public (pk,
|
|
||||||
&trans_pub->ecdhe_pub);
|
|
||||||
GNUNET_free (pk);
|
|
||||||
return GNUNET_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* end of crypto.c */
|
/* end of crypto.c */
|
||||||
|
@ -24,58 +24,6 @@
|
|||||||
#include "taler_crypto_lib.h"
|
#include "taler_crypto_lib.h"
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test low-level link encryption/decryption APIs.
|
|
||||||
*
|
|
||||||
* @return 0 on success
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
test_basics ()
|
|
||||||
{
|
|
||||||
struct TALER_EncryptedLinkSecretP secret_enc;
|
|
||||||
struct TALER_TransferSecretP trans_sec;
|
|
||||||
struct TALER_LinkSecretP secret;
|
|
||||||
struct TALER_LinkSecretP secret2;
|
|
||||||
struct TALER_RefreshLinkEncryptedP rl_enc;
|
|
||||||
struct TALER_RefreshLinkDecryptedP rl;
|
|
||||||
struct TALER_RefreshLinkDecryptedP rld;
|
|
||||||
|
|
||||||
GNUNET_log_setup ("test-crypto",
|
|
||||||
"WARNING",
|
|
||||||
NULL);
|
|
||||||
GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
|
|
||||||
&secret,
|
|
||||||
sizeof (secret));
|
|
||||||
GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
|
|
||||||
&rl,
|
|
||||||
sizeof (rl));
|
|
||||||
TALER_refresh_encrypt (&rl,
|
|
||||||
&secret,
|
|
||||||
&rl_enc);
|
|
||||||
GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
|
|
||||||
&trans_sec,
|
|
||||||
sizeof (trans_sec));
|
|
||||||
GNUNET_assert (GNUNET_OK ==
|
|
||||||
TALER_transfer_encrypt (&secret,
|
|
||||||
&trans_sec,
|
|
||||||
&secret_enc));
|
|
||||||
GNUNET_assert (GNUNET_OK ==
|
|
||||||
TALER_transfer_decrypt (&secret_enc,
|
|
||||||
&trans_sec,
|
|
||||||
&secret2));
|
|
||||||
GNUNET_assert (0 == memcmp (&secret,
|
|
||||||
&secret2,
|
|
||||||
sizeof (secret)));
|
|
||||||
TALER_refresh_decrypt (&rl_enc,
|
|
||||||
&secret2,
|
|
||||||
&rld);
|
|
||||||
GNUNET_assert (0 == memcmp (&rld,
|
|
||||||
&rl,
|
|
||||||
sizeof (struct TALER_RefreshLinkDecryptedP)));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test high-level link encryption/decryption API.
|
* Test high-level link encryption/decryption API.
|
||||||
*
|
*
|
||||||
@ -85,46 +33,53 @@ static int
|
|||||||
test_high_level ()
|
test_high_level ()
|
||||||
{
|
{
|
||||||
struct GNUNET_CRYPTO_EddsaPrivateKey *pk;
|
struct GNUNET_CRYPTO_EddsaPrivateKey *pk;
|
||||||
struct TALER_LinkSecretP secret;
|
|
||||||
struct TALER_LinkSecretP secret2;
|
|
||||||
struct TALER_CoinSpendPublicKeyP coin_pub;
|
|
||||||
struct TALER_CoinSpendPrivateKeyP coin_priv;
|
struct TALER_CoinSpendPrivateKeyP coin_priv;
|
||||||
|
struct TALER_CoinSpendPublicKeyP coin_pub;
|
||||||
|
struct GNUNET_CRYPTO_EcdhePrivateKey *pk2;
|
||||||
struct TALER_TransferPrivateKeyP trans_priv;
|
struct TALER_TransferPrivateKeyP trans_priv;
|
||||||
struct TALER_TransferPublicKeyP trans_pub;
|
struct TALER_TransferPublicKeyP trans_pub;
|
||||||
struct TALER_EncryptedLinkSecretP secret_enc;
|
struct TALER_TransferSecretP secret;
|
||||||
|
struct TALER_TransferSecretP secret2;
|
||||||
|
struct TALER_FreshCoinP fc1;
|
||||||
|
struct TALER_FreshCoinP fc2;
|
||||||
|
|
||||||
pk = GNUNET_CRYPTO_eddsa_key_create ();
|
pk = GNUNET_CRYPTO_eddsa_key_create ();
|
||||||
GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
|
|
||||||
&secret,
|
|
||||||
sizeof (secret));
|
|
||||||
GNUNET_CRYPTO_eddsa_key_get_public (pk,
|
|
||||||
&coin_pub.eddsa_pub);
|
|
||||||
GNUNET_assert (GNUNET_OK ==
|
|
||||||
TALER_link_encrypt_secret (&secret,
|
|
||||||
&coin_pub,
|
|
||||||
&trans_priv,
|
|
||||||
&trans_pub,
|
|
||||||
&secret_enc));
|
|
||||||
GNUNET_assert (GNUNET_OK ==
|
|
||||||
TALER_link_decrypt_secret (&secret_enc,
|
|
||||||
&trans_priv,
|
|
||||||
&coin_pub,
|
|
||||||
&secret2));
|
|
||||||
GNUNET_assert (0 ==
|
|
||||||
memcmp (&secret,
|
|
||||||
&secret2,
|
|
||||||
sizeof (secret)));
|
|
||||||
coin_priv.eddsa_priv = *pk;
|
coin_priv.eddsa_priv = *pk;
|
||||||
GNUNET_assert (GNUNET_OK ==
|
GNUNET_free (pk);
|
||||||
TALER_link_decrypt_secret2 (&secret_enc,
|
GNUNET_CRYPTO_eddsa_key_get_public (&coin_priv.eddsa_priv,
|
||||||
&trans_pub,
|
&coin_pub.eddsa_pub);
|
||||||
&coin_priv,
|
pk2 = GNUNET_CRYPTO_ecdhe_key_create ();
|
||||||
&secret2));
|
trans_priv.ecdhe_priv = *pk2;
|
||||||
|
GNUNET_free (pk2);
|
||||||
|
GNUNET_CRYPTO_ecdhe_key_get_public (&trans_priv.ecdhe_priv,
|
||||||
|
&trans_pub.ecdhe_pub);
|
||||||
|
TALER_link_derive_transfer_secret (&coin_priv,
|
||||||
|
&trans_priv,
|
||||||
|
&secret);
|
||||||
|
TALER_link_reveal_transfer_secret (&trans_priv,
|
||||||
|
&coin_pub,
|
||||||
|
&secret2);
|
||||||
GNUNET_assert (0 ==
|
GNUNET_assert (0 ==
|
||||||
memcmp (&secret,
|
memcmp (&secret,
|
||||||
&secret2,
|
&secret2,
|
||||||
sizeof (secret)));
|
sizeof (secret)));
|
||||||
GNUNET_free (pk);
|
TALER_link_recover_transfer_secret (&trans_pub,
|
||||||
|
&coin_priv,
|
||||||
|
&secret2);
|
||||||
|
GNUNET_assert (0 ==
|
||||||
|
memcmp (&secret,
|
||||||
|
&secret2,
|
||||||
|
sizeof (secret)));
|
||||||
|
TALER_setup_fresh_coin (&secret,
|
||||||
|
0,
|
||||||
|
&fc1);
|
||||||
|
TALER_setup_fresh_coin (&secret,
|
||||||
|
1,
|
||||||
|
&fc2);
|
||||||
|
GNUNET_assert (0 !=
|
||||||
|
memcmp (&fc1,
|
||||||
|
&fc2,
|
||||||
|
sizeof (struct TALER_FreshCoinP)));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,11 +88,9 @@ int
|
|||||||
main(int argc,
|
main(int argc,
|
||||||
const char *const argv[])
|
const char *const argv[])
|
||||||
{
|
{
|
||||||
if (0 != test_basics ())
|
|
||||||
return 1;
|
|
||||||
if (0 != test_high_level ())
|
if (0 != test_high_level ())
|
||||||
return 1;
|
return 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* end of test_crypto.c */
|
/* end of test_crypto.c */
|
||||||
|
Loading…
Reference in New Issue
Block a user