aboutsummaryrefslogtreecommitdiff
path: root/src/exchange-lib
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2016-08-05 16:08:19 +0200
committerChristian Grothoff <christian@grothoff.org>2016-08-05 16:08:19 +0200
commit745719dbc1482734ab3ca7a20541ee8a12ecb69c (patch)
tree68ca6a1f328f59351a69064c72dc87b92756b689 /src/exchange-lib
parente800772c85e1e1399c756162921c3f557794ffea (diff)
first half of changing refresh protocol to derive all key data from DH
Diffstat (limited to 'src/exchange-lib')
-rw-r--r--src/exchange-lib/exchange_api_refresh.c215
-rw-r--r--src/exchange-lib/exchange_api_refresh_link.c39
2 files changed, 58 insertions, 196 deletions
diff --git a/src/exchange-lib/exchange_api_refresh.c b/src/exchange-lib/exchange_api_refresh.c
index f259daa54..09e1a09bb 100644
--- a/src/exchange-lib/exchange_api_refresh.c
+++ b/src/exchange-lib/exchange_api_refresh.c
@@ -1,6 +1,6 @@
/*
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
terms of the GNU General Public License as published by the Free Software
@@ -93,26 +93,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
* persisting it on disk.
*/
@@ -125,12 +105,6 @@ struct MeltDataP
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
*/
uint16_t num_melted_coins GNUNET_PACKED;
@@ -144,7 +118,7 @@ struct MeltDataP
1) struct MeltedCoinP melted_coins[num_melted_coins];
2) struct TALER_EXCHANGE_DenomPublicKey fresh_pks[num_fresh_coins];
3) TALER_CNC_KAPPA times:
- 3a) struct FreshCoinP fresh_coins[num_fresh_coins];
+ 3a) struct TALER_FreshCoinP fresh_coins[num_fresh_coins];
*/
};
@@ -212,11 +186,6 @@ struct MeltData
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
*/
uint16_t num_fresh_coins;
@@ -236,7 +205,7 @@ struct MeltData
* Arrays of @e num_fresh_coins with information about the fresh
* 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
*/
static size_t
-serialize_fresh_coin (const struct FreshCoinP *fc,
+serialize_fresh_coin (const struct TALER_FreshCoinP *fc,
char *buf,
size_t off)
{
if (NULL != buf)
memcpy (&buf[off],
fc,
- sizeof (struct FreshCoinP));
- return sizeof (struct FreshCoinP);
+ sizeof (struct TALER_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
*/
static size_t
-deserialize_fresh_coin (struct FreshCoinP *fc,
+deserialize_fresh_coin (struct TALER_FreshCoinP *fc,
const char *buf,
size_t size,
int *ok)
{
- if (size < sizeof (struct FreshCoinP))
+ if (size < sizeof (struct TALER_FreshCoinP))
{
GNUNET_break (0);
*ok = GNUNET_NO;
@@ -557,8 +526,8 @@ deserialize_fresh_coin (struct FreshCoinP *fc,
}
memcpy (fc,
buf,
- sizeof (struct FreshCoinP));
- return sizeof (struct FreshCoinP);
+ sizeof (struct TALER_FreshCoinP));
+ return sizeof (struct TALER_FreshCoinP);
}
@@ -598,8 +567,6 @@ serialize_melt_data (const struct MeltData *md,
size = sizeof (struct MeltDataP);
mdp = (struct MeltDataP *) buf;
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);
}
size += serialize_melted_coin (&md->melted_coin,
@@ -646,14 +613,12 @@ deserialize_melt_data (const char *buf,
sizeof (struct MeltDataP));
md = GNUNET_new (struct MeltData);
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->fresh_pks = GNUNET_new_array (md->num_fresh_coins,
struct TALER_DenominationPublicKey);
for (i=0;i<TALER_CNC_KAPPA;i++)
md->fresh_coins[i] = GNUNET_new_array (md->num_fresh_coins,
- struct FreshCoinP);
+ struct TALER_FreshCoinP);
off = sizeof (struct MeltDataP);
ok = GNUNET_YES;
off += deserialize_melted_coin (&md->melted_coin,
@@ -688,27 +653,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
* unlinkable to the original coin(s). Note that melting more
* than one coin in a single request will make those coins linkable,
@@ -765,25 +709,37 @@ TALER_EXCHANGE_refresh_prepare (const struct TALER_CoinSpendPrivateKeyP *melt_pr
unsigned int j;
struct GNUNET_HashContext *hash_context;
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 */
for (i=0;i<TALER_CNC_KAPPA;i++)
- GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_STRONG,
- &md.link_secrets[i],
- sizeof (struct TALER_LinkSecretP));
- md.num_fresh_coins = fresh_pks_len;
- md.melted_coin.coin_priv = *melt_priv;
- md.melted_coin.melt_amount_with_fee = *melt_amount;
- md.melted_coin.fee_melt = melt_pk->fee_refresh;
- md.melted_coin.original_value = melt_pk->value;
- for (j=0;j<TALER_CNC_KAPPA;j++)
{
struct GNUNET_CRYPTO_EcdhePrivateKey *tpk;
+ struct TALER_TransferPublicKeyP tp;
tpk = GNUNET_CRYPTO_ecdhe_key_create ();
- md.melted_coin.transfer_priv[j].ecdhe_priv = *tpk;
+ 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.melted_coin.coin_priv = *melt_priv;
+ md.melted_coin.melt_amount_with_fee = *melt_amount;
+ md.melted_coin.fee_melt = melt_pk->fee_refresh;
+ md.melted_coin.original_value = melt_pk->value;
md.melted_coin.expire_deposit
= melt_pk->expire_deposit;
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++)
{
md.fresh_coins[i] = GNUNET_new_array (fresh_pks_len,
- struct FreshCoinP);
+ struct TALER_FreshCoinP);
for (j=0;j<fresh_pks_len;j++)
{
- setup_fresh_coin (&md.fresh_coins[i][j],
- &fresh_pks[j]);
+ TALER_setup_fresh_coin (&trans_sec[i],
+ j,
+ &md.fresh_coins[i][j]);
}
}
@@ -830,7 +787,7 @@ TALER_EXCHANGE_refresh_prepare (const struct TALER_CoinSpendPrivateKeyP *melt_pr
TALER_amount_cmp (&total,
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. */
GNUNET_break (0);
free_melt_data (&md);
@@ -839,7 +796,6 @@ TALER_EXCHANGE_refresh_prepare (const struct TALER_CoinSpendPrivateKeyP *melt_pr
/* now compute melt session hash */
- hash_context = GNUNET_CRYPTO_hash_context_start ();
for (i=0;i<fresh_pks_len;i++)
{
char *buf;
@@ -853,11 +809,8 @@ TALER_EXCHANGE_refresh_prepare (const struct TALER_CoinSpendPrivateKeyP *melt_pr
GNUNET_free (buf);
}
{
- struct TALER_CoinSpendPublicKeyP coin_pub;
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,
&coin_pub,
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++)
{
- const struct FreshCoinP *fc; /* coin this is about */
+ const struct TALER_FreshCoinP *fc; /* coin this is about */
struct TALER_CoinSpendPublicKeyP coin_pub;
struct GNUNET_HashCode coin_hash;
char *coin_ev; /* blinded message to be signed (in envelope) for each coin */
size_t coin_ev_size;
- struct TALER_RefreshLinkDecryptedP rld;
- struct TALER_RefreshLinkEncryptedP rle;
fc = &md.fresh_coins[i][j];
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_size);
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,
&md.melt_session_hash);
@@ -1315,8 +1239,6 @@ TALER_EXCHANGE_refresh_melt (struct TALER_EXCHANGE_Handle *exchange,
json_t *melt_coin;
json_t *coin_evs;
json_t *transfer_pubs;
- json_t *secret_encs;
- json_t *link_encs;
json_t *tmp;
struct TALER_EXCHANGE_RefreshMeltHandle *rmh;
CURL *eh;
@@ -1335,14 +1257,12 @@ TALER_EXCHANGE_refresh_melt (struct TALER_EXCHANGE_Handle *exchange,
return NULL;
}
- /* build JSON request, each of the 6 arrays first */
+ /* build JSON request, each of the 4 arrays first */
new_denoms = json_array ();
melt_coin = melted_coin_to_json (&md->melt_session_hash,
&md->melted_coin);
coin_evs = json_array ();
transfer_pubs = json_array ();
- secret_encs = json_array ();
- link_encs = json_array ();
/* now transfer_pubs */
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)));
}
- /* 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 */
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)));
}
- /* 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 */
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];
+ const struct TALER_FreshCoinP *fc = &md->fresh_coins[j][i];
struct TALER_CoinSpendPublicKeyP coin_pub;
struct GNUNET_HashCode coin_hash;
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 (melt_coin);
json_decref (transfer_pubs);
- json_decref (secret_encs);
- json_decref (link_encs);
return NULL;
}
GNUNET_assert (0 ==
@@ -1456,13 +1331,11 @@ TALER_EXCHANGE_refresh_melt (struct TALER_EXCHANGE_Handle *exchange,
}
/* 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,
"melt_coin", melt_coin,
"coin_evs", coin_evs,
- "transfer_pubs", transfer_pubs,
- "secret_encs", secret_encs,
- "link_encs", link_encs);
+ "transfer_pubs", transfer_pubs);
/* and now we can at last begin the actual request handling */
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++)
{
- const struct FreshCoinP *fc;
+ const struct TALER_FreshCoinP *fc;
struct TALER_DenominationPublicKey *pk;
json_t *jsonai;
struct GNUNET_CRYPTO_RsaSignature *blind_sig;
diff --git a/src/exchange-lib/exchange_api_refresh_link.c b/src/exchange-lib/exchange_api_refresh_link.c
index 2a1e3048b..31c27fe98 100644
--- a/src/exchange-lib/exchange_api_refresh_link.c
+++ b/src/exchange-lib/exchange_api_refresh_link.c
@@ -75,8 +75,8 @@ struct TALER_EXCHANGE_RefreshLinkHandle
*
* @param rlh refresh link handle
* @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 secret_enc encrypted key to decrypt link data
* @param[out] coin_priv where to return private coin key
* @param[out] sig where to return private coin signature
* @param[out] pub where to return the public key for the coin
@@ -85,24 +85,22 @@ struct TALER_EXCHANGE_RefreshLinkHandle
static int
parse_refresh_link_coin (const struct TALER_EXCHANGE_RefreshLinkHandle *rlh,
const json_t *json,
+ unsigned int coin_num,
const struct TALER_TransferPublicKeyP *trans_pub,
- const struct TALER_EncryptedLinkSecretP *secret_enc,
struct TALER_CoinSpendPrivateKeyP *coin_priv,
struct TALER_DenominationSignature *sig,
struct TALER_DenominationPublicKey *pub)
{
struct GNUNET_CRYPTO_RsaSignature *bsig;
struct GNUNET_CRYPTO_RsaPublicKey *rpub;
- struct TALER_RefreshLinkEncryptedP rle;
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_signature ("ev_sig", &bsig),
GNUNET_JSON_spec_end()
};
- struct TALER_RefreshLinkDecryptedP rld;
- struct TALER_LinkSecretP secret;
-
+ struct TALER_TransferSecretP secret;
+ struct TALER_FreshCoinP fc;
+
/* parse reply */
if (GNUNET_OK !=
GNUNET_JSON_parse (json,
@@ -113,25 +111,18 @@ parse_refresh_link_coin (const struct TALER_EXCHANGE_RefreshLinkHandle *rlh,
return GNUNET_SYSERR;
}
- if (GNUNET_OK !=
- TALER_link_decrypt_secret2 (secret_enc,
- trans_pub,
- &rlh->coin_priv,
- &secret))
- {
- GNUNET_break_op (0);
- GNUNET_JSON_parse_free (spec);
- return GNUNET_SYSERR;
- }
- TALER_refresh_decrypt (&rle,
- &secret,
- &rld);
+ TALER_link_recover_transfer_secret (trans_pub,
+ &rlh->coin_priv,
+ &secret);
+ TALER_setup_fresh_coin (&secret,
+ coin_num,
+ &fc);
/* extract coin and signature */
- *coin_priv = rld.coin_priv;
+ *coin_priv = fc.coin_priv;
sig->rsa_signature
= GNUNET_CRYPTO_rsa_unblind (bsig,
- &rld.blinding_key.bks,
+ &fc.blinding_key.bks,
rpub);
/* clean up */
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;
struct TALER_TransferPublicKeyP trans_pub;
- struct TALER_EncryptedLinkSecretP secret_enc;
struct GNUNET_JSON_Specification spec[] = {
GNUNET_JSON_spec_json ("new_coins", &jsona),
GNUNET_JSON_spec_fixed_auto ("transfer_pub", &trans_pub),
- GNUNET_JSON_spec_fixed_auto ("secret_enc", &secret_enc),
GNUNET_JSON_spec_end()
};
@@ -248,8 +237,8 @@ parse_refresh_link_ok (struct TALER_EXCHANGE_RefreshLinkHandle *rlh,
parse_refresh_link_coin (rlh,
json_array_get (jsona,
i),
+ i,
&trans_pub,
- &secret_enc,
&coin_privs[i+off_coin],
&sigs[i+off_coin],
&pubs[i+off_coin]))