aboutsummaryrefslogtreecommitdiff
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
parente800772c85e1e1399c756162921c3f557794ffea (diff)
first half of changing refresh protocol to derive all key data from DH
-rw-r--r--src/exchange-lib/exchange_api_refresh.c215
-rw-r--r--src/exchange-lib/exchange_api_refresh_link.c39
-rw-r--r--src/exchange/taler-exchange-httpd_db.c61
-rw-r--r--src/exchange/taler-exchange-httpd_db.h4
-rw-r--r--src/exchange/taler-exchange-httpd_refresh.c106
-rw-r--r--src/exchange/taler-exchange-httpd_responses.c22
-rw-r--r--src/exchange/taler-exchange-httpd_responses.h5
-rw-r--r--src/exchange/taler-exchange-httpd_test.c17
-rw-r--r--src/exchangedb/plugin_exchangedb_postgres.c104
-rw-r--r--src/include/taler_crypto_lib.h177
-rw-r--r--src/include/taler_exchangedb_plugin.h43
-rw-r--r--src/include/taler_signatures.h25
-rw-r--r--src/util/crypto.c357
-rw-r--r--src/util/test_crypto.c115
14 files changed, 323 insertions, 967 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]))
diff --git a/src/exchange/taler-exchange-httpd_db.c b/src/exchange/taler-exchange-httpd_db.c
index 99805653e..9847a7ba3 100644
--- a/src/exchange/taler-exchange-httpd_db.c
+++ b/src/exchange/taler-exchange-httpd_db.c
@@ -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
* once the "/refres/reveal" of cut and choose is done),
* 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
* future) of length #TALER_CNC_KAPPA
* @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 TMH_DB_MeltDetails *coin_melt_detail,
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 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++)
{
if (GNUNET_OK !=
- TMH_plugin->insert_refresh_commit_link (TMH_plugin->cls,
- session,
- session_hash,
- i,
- &commit_link[i]))
+ TMH_plugin->insert_refresh_transfer_public_key (TMH_plugin->cls,
+ session,
+ session_hash,
+ i,
+ &transfer_pubs[i]))
{
TMH_plugin->rollback (TMH_plugin->cls,
session);
@@ -1180,19 +1180,19 @@ check_commitment (struct MHD_Connection *connection,
unsigned int num_newcoins,
const struct TALER_DenominationPublicKey *denom_pubs)
{
- struct TALER_RefreshCommitLinkP commit_link;
- struct TALER_LinkSecretP shared_secret;
+ struct TALER_TransferPublicKeyP transfer_pub;
+ struct TALER_TransferSecretP transfer_secret;
struct TALER_TransferPublicKeyP transfer_pub_check;
struct TALER_EXCHANGEDB_RefreshCommitCoin *commit_coins;
unsigned int j;
int ret;
if (GNUNET_OK !=
- TMH_plugin->get_refresh_commit_link (TMH_plugin->cls,
- session,
- session_hash,
- off,
- &commit_link))
+ TMH_plugin->get_refresh_transfer_public_key (TMH_plugin->cls,
+ session,
+ session_hash,
+ off,
+ &transfer_pub))
{
GNUNET_break (0);
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);
if (0 !=
memcmp (&transfer_pub_check,
- &commit_link.transfer_pub,
+ &transfer_pub,
sizeof (struct TALER_TransferPublicKeyP)))
{
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
@@ -1217,17 +1217,9 @@ check_commitment (struct MHD_Connection *connection,
"transfer key");
}
- if (GNUNET_OK !=
- TALER_link_decrypt_secret (&commit_link.shared_secret_enc,
- transfer_priv,
- &melt->coin.coin_pub,
- &shared_secret))
- {
- return (MHD_YES ==
- TMH_RESPONSE_reply_internal_error (connection,
- "Transfer secret decryption error"))
- ? GNUNET_NO : GNUNET_SYSERR;
- }
+ TALER_link_reveal_transfer_secret (transfer_priv,
+ &melt->coin.coin_pub,
+ &transfer_secret);
/* Check that the commitments for all new coins were correct */
commit_coins = GNUNET_new_array (num_newcoins,
@@ -1249,23 +1241,23 @@ check_commitment (struct MHD_Connection *connection,
for (j = 0; j < num_newcoins; j++)
{
- struct TALER_RefreshLinkDecryptedP link_data;
+ struct TALER_FreshCoinP fc;
struct TALER_CoinSpendPublicKeyP coin_pub;
struct GNUNET_HashCode h_msg;
char *buf;
size_t buf_len;
- TALER_refresh_decrypt (&commit_coins[j].refresh_link,
- &shared_secret,
- &link_data);
- GNUNET_CRYPTO_eddsa_key_get_public (&link_data.coin_priv.eddsa_priv,
+ TALER_setup_fresh_coin (&transfer_secret,
+ j,
+ &fc);
+ GNUNET_CRYPTO_eddsa_key_get_public (&fc.coin_priv.eddsa_priv,
&coin_pub.eddsa_pub);
GNUNET_CRYPTO_hash (&coin_pub,
sizeof (struct TALER_CoinSpendPublicKeyP),
&h_msg);
if (GNUNET_YES !=
GNUNET_CRYPTO_rsa_blind (&h_msg,
- &link_data.blinding_key.bks,
+ &fc.blinding_key.bks,
denom_pubs[j].rsa_public_key,
&buf,
&buf_len))
@@ -1598,13 +1590,11 @@ struct HTD_Context
* @param cls closure, a `struct HTD_Context`
* @param session_hash a session the coin was melted in
* @param transfer_pub public transfer key for the session
- * @param shared_secret_enc set to shared secret for the session
*/
static void
handle_transfer_data (void *cls,
const struct GNUNET_HashCode *session_hash,
- const struct TALER_TransferPublicKeyP *transfer_pub,
- const struct TALER_EncryptedLinkSecretP *shared_secret_enc)
+ const struct TALER_TransferPublicKeyP *transfer_pub)
{
struct HTD_Context *ctx = cls;
struct TALER_EXCHANGEDB_LinkDataList *ldl;
@@ -1632,7 +1622,6 @@ handle_transfer_data (void *cls,
ctx->num_sessions + 1);
lsi = &ctx->sessions[ctx->num_sessions - 1];
lsi->transfer_pub = *transfer_pub;
- lsi->shared_secret_enc = *shared_secret_enc;
lsi->ldl = ldl;
}
diff --git a/src/exchange/taler-exchange-httpd_db.h b/src/exchange/taler-exchange-httpd_db.h
index 8685cd5ae..67fe8d5b4 100644
--- a/src/exchange/taler-exchange-httpd_db.h
+++ b/src/exchange/taler-exchange-httpd_db.h
@@ -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 commit_coin 2d array of coin commitments (what the exchange is to sign
* 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
* future) of length #TALER_CNC_KAPPA
* @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 TMH_DB_MeltDetails *coin_melt_details,
struct TALER_EXCHANGEDB_RefreshCommitCoin *const* commit_coin,
- const struct TALER_RefreshCommitLinkP *commit_link);
+ const struct TALER_TransferPublicKeyP *transfer_pubs);
/**
diff --git a/src/exchange/taler-exchange-httpd_refresh.c b/src/exchange/taler-exchange-httpd_refresh.c
index 40a00e163..3dbffe511 100644
--- a/src/exchange/taler-exchange-httpd_refresh.c
+++ b/src/exchange/taler-exchange-httpd_refresh.c
@@ -43,7 +43,7 @@
* @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
* 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
* future) of length #TALER_CNC_KAPPA
* @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 GNUNET_HashCode *session_hash,
struct TALER_EXCHANGEDB_RefreshCommitCoin *const* commit_coin,
- const struct TALER_RefreshCommitLinkP * commit_link)
+ const struct TALER_TransferPublicKeyP *transfer_pubs)
{
unsigned int i;
struct TMH_KS_StateHandle *key_state;
@@ -146,7 +146,7 @@ handle_refresh_melt_binary (struct MHD_Connection *connection,
denom_pubs,
coin_melt_details,
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 melt_coin coin to melt
* @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 link_encs #TALER_CNC_KAPPA-dimensional array of `length(@a new_denoms)` encrypted links (2D array)
* @return MHD result code
*/
static int
@@ -331,9 +329,7 @@ handle_refresh_melt_json (struct MHD_Connection *connection,
const json_t *new_denoms,
const json_t *melt_coin,
const json_t *transfer_pubs,
- const json_t *secret_encs,
- const json_t *coin_evs,
- const json_t *link_encs)
+ const json_t *coin_evs)
{
int res;
unsigned int i;
@@ -344,11 +340,36 @@ handle_refresh_melt_json (struct MHD_Connection *connection,
struct GNUNET_HashCode session_hash;
struct GNUNET_HashContext *hash_context;
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
(except for the signatures on the coins). */
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);
denom_pubs = GNUNET_new_array (num_newcoins,
struct TALER_DenominationPublicKey);
@@ -405,7 +426,6 @@ handle_refresh_melt_json (struct MHD_Connection *connection,
/* parse JSON arrays into binary arrays and hash everything
together for the signature check */
memset (commit_coin, 0, sizeof (commit_coin));
- memset (commit_link, 0, sizeof (commit_link));
for (i = 0; i < TALER_CNC_KAPPA; i++)
{
commit_coin[i] = GNUNET_new_array (num_newcoins,
@@ -419,11 +439,6 @@ handle_refresh_melt_json (struct MHD_Connection *connection,
&rcc->coin_ev_size),
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,
coin_evs,
@@ -439,59 +454,10 @@ handle_refresh_melt_json (struct MHD_Connection *connection,
GNUNET_CRYPTO_hash_context_read (hash_context,
rcc->coin_ev,
rcc->coin_ev_size);
- res = TMH_PARSE_json_array (connection,
- 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);
+ GNUNET_JSON_parse_free (coin_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,
&session_hash);
hash_context = NULL;
@@ -513,7 +479,7 @@ handle_refresh_melt_json (struct MHD_Connection *connection,
&coin_melt_details,
&session_hash,
commit_coin,
- commit_link);
+ transfer_pub);
cleanup:
free_commit_coins (commit_coin,
TALER_CNC_KAPPA,
@@ -558,17 +524,13 @@ TMH_REFRESH_handler_refresh_melt (struct TMH_RequestHandler *rh,
json_t *new_denoms;
json_t *melt_coin;
json_t *coin_evs;
- json_t *link_encs;
json_t *transfer_pubs;
- json_t *secret_encs;
int res;
struct GNUNET_JSON_Specification spec[] = {
GNUNET_JSON_spec_json ("new_denoms", &new_denoms),
GNUNET_JSON_spec_json ("melt_coin", &melt_coin),
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 ("secret_encs", &secret_encs),
GNUNET_JSON_spec_end ()
};
@@ -608,9 +570,7 @@ TMH_REFRESH_handler_refresh_melt (struct TMH_RequestHandler *rh,
new_denoms,
melt_coin,
transfer_pubs,
- secret_encs,
- coin_evs,
- link_encs);
+ coin_evs);
GNUNET_JSON_parse_free (spec);
return res;
}
diff --git a/src/exchange/taler-exchange-httpd_responses.c b/src/exchange/taler-exchange-httpd_responses.c
index bbcdbe35f..b39b68a44 100644
--- a/src/exchange/taler-exchange-httpd_responses.c
+++ b/src/exchange/taler-exchange-httpd_responses.c
@@ -1028,7 +1028,7 @@ TMH_RESPONSE_reply_refresh_reveal_missmatch (struct MHD_Connection *connection,
{
json_t *info_commit_k;
json_t *info_link_k;
- const struct TALER_RefreshCommitLinkP *cl;
+ const struct TALER_TransferPublicKeyP *transfer_pub;
info_commit_k = json_array ();
for (i=0;i<mc->num_newcoins;i++)
@@ -1042,13 +1042,6 @@ TMH_RESPONSE_reply_refresh_reveal_missmatch (struct MHD_Connection *connection,
"coin_ev",
GNUNET_JSON_from_data (cc->coin_ev,
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 ==
json_array_append_new (info_commit_k,
cc_json));
@@ -1058,13 +1051,10 @@ TMH_RESPONSE_reply_refresh_reveal_missmatch (struct MHD_Connection *connection,
info_commit_k));
info_link_k = json_object ();
- cl = &mc->commit_links[k];
+ transfer_pub = &mc->transfer_pubs[k];
json_object_set_new (info_link_k,
"transfer_pub",
- GNUNET_JSON_from_data_auto (&cl->transfer_pub));
- json_object_set_new (info_link_k,
- "shared_secret_enc",
- GNUNET_JSON_from_data_auto (&cl->shared_secret_enc));
+ GNUNET_JSON_from_data_auto (transfer_pub));
GNUNET_assert (0 ==
json_array_append_new (info_links,
info_link_k));
@@ -1114,9 +1104,6 @@ TMH_RESPONSE_reply_refresh_link_success (struct MHD_Connection *connection,
obj = json_object ();
json_object_set_new (obj,
- "link_enc",
- GNUNET_JSON_from_data_auto (&pos->link_data_enc));
- json_object_set_new (obj,
"denom_pub",
GNUNET_JSON_from_rsa_public_key (pos->denom_pub.rsa_public_key));
json_object_set_new (obj,
@@ -1133,9 +1120,6 @@ TMH_RESPONSE_reply_refresh_link_success (struct MHD_Connection *connection,
json_object_set_new (root,
"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 ==
json_array_append_new (mlist,
root));
diff --git a/src/exchange/taler-exchange-httpd_responses.h b/src/exchange/taler-exchange-httpd_responses.h
index ce6710080..4079bd12b 100644
--- a/src/exchange/taler-exchange-httpd_responses.h
+++ b/src/exchange/taler-exchange-httpd_responses.h
@@ -522,11 +522,6 @@ struct TMH_RESPONSE_LinkSessionInfo
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.
*/
struct TALER_EXCHANGEDB_LinkDataList *ldl;
diff --git a/src/exchange/taler-exchange-httpd_test.c b/src/exchange/taler-exchange-httpd_test.c
index d8849d310..b371bd215 100644
--- a/src/exchange/taler-exchange-httpd_test.c
+++ b/src/exchange/taler-exchange-httpd_test.c
@@ -535,16 +535,14 @@ TMH_TEST_handler_test_transfer (struct TMH_RequestHandler *rh,
{
json_t *json;
int res;
- struct TALER_EncryptedLinkSecretP secret_enc;
struct TALER_TransferPrivateKeyP trans_priv;
struct TALER_CoinSpendPublicKeyP coin_pub;
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 ("coin_pub", &coin_pub),
GNUNET_JSON_spec_end ()
};
- struct TALER_LinkSecretP secret;
+ struct TALER_TransferSecretP secret;
res = TMH_PARSE_post_json (connection,
connection_cls,
@@ -561,16 +559,9 @@ TMH_TEST_handler_test_transfer (struct TMH_RequestHandler *rh,
json_decref (json);
if (GNUNET_YES != res)
return (GNUNET_NO == res) ? MHD_YES : MHD_NO;
- if (GNUNET_OK !=
- TALER_link_decrypt_secret (&secret_enc,
- &trans_priv,
- &coin_pub,
- &secret))
- {
- GNUNET_JSON_parse_free (spec);
- return TMH_RESPONSE_reply_internal_error (connection,
- "Failed to decrypt secret");
- }
+ TALER_link_reveal_transfer_secret (&trans_priv,
+ &coin_pub,
+ &secret);
return TMH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_OK,
"{s:o}",
diff --git a/src/exchangedb/plugin_exchangedb_postgres.c b/src/exchangedb/plugin_exchangedb_postgres.c
index 508a242b4..47d59c862 100644
--- a/src/exchangedb/plugin_exchangedb_postgres.c
+++ b/src/exchangedb/plugin_exchangedb_postgres.c
@@ -221,7 +221,7 @@ postgres_drop_tables (void *cls)
SQLEXEC_ (conn,
"DROP TABLE IF EXISTS refresh_commit_coin;");
SQLEXEC_ (conn,
- "DROP TABLE IF EXISTS refresh_commit_link;");
+ "DROP TABLE IF EXISTS refresh_transfer_public_key;");
SQLEXEC_ (conn,
"DROP TABLE IF EXISTS refunds;");
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),
as well as the actual link data (the transfer public key and the encrypted
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"
",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"
",UNIQUE (session_hash, cnc_index)"
")");
- SQLEXEC_INDEX("CREATE INDEX refresh_commit_link_session_hash_index "
- "ON refresh_commit_link(session_hash, cnc_index)");
+ SQLEXEC_INDEX("CREATE INDEX refresh_transfer_public_key_index "
+ "ON refresh_transfer_public_key(session_hash, cnc_index)");
/* Table with the commitments for the new coins that are to be created
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"
",cnc_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"
",UNIQUE (session_hash, cnc_index, newcoin_index)"
")");
@@ -827,25 +825,23 @@ postgres_prepare (PGconn *db_conn)
1, NULL);
- /* Used in #postgres_insert_refresh_commit_link() to
+ /* Used in #postgres_insert_transfer_public_key() to
store commitments */
- PREPARE ("insert_refresh_commit_link",
- "INSERT INTO refresh_commit_link "
+ PREPARE ("insert_transfer_public_key",
+ "INSERT INTO refresh_transfer_public_key "
"(session_hash"
",transfer_pub"
",cnc_index"
- ",link_secret_enc"
") VALUES "
- "($1, $2, $3, $4);",
- 4, NULL);
+ "($1, $2, $3);",
+ 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 */
- PREPARE ("get_refresh_commit_link",
+ PREPARE ("get_refresh_transfer_public_key",
"SELECT"
" transfer_pub"
- ",link_secret_enc"
- " FROM refresh_commit_link"
+ " FROM refresh_transfer_public_key"
" WHERE session_hash=$1 AND cnc_index=$2",
2, NULL);
@@ -856,19 +852,17 @@ postgres_prepare (PGconn *db_conn)
"(session_hash"
",cnc_index"
",newcoin_index"
- ",link_vector_enc"
",coin_ev"
") VALUES "
- "($1, $2, $3, $4, $5);",
- 5, NULL);
+ "($1, $2, $3, $4);",
+ 4, NULL);
/* Used in #postgres_get_refresh_commit_coins() to
retrieve the original coin envelopes, to either be
verified or signed. */
PREPARE ("get_refresh_commit_coin",
"SELECT"
- " link_vector_enc"
- ",coin_ev"
+ " coin_ev"
" FROM refresh_commit_coin"
" WHERE session_hash=$1 AND cnc_index=$2 AND newcoin_index=$3",
3, NULL);
@@ -1068,8 +1062,7 @@ postgres_prepare (PGconn *db_conn)
3, NULL);
/* Used in #postgres_get_link_data_list(). We use the session_hash
- to obtain the "noreveal_index" for that session, and then select
- the encrypted link vectors (link_vector_enc) and the
+ to obtain the "noreveal_index" for that session, and then select the
corresponding signatures (ev_sig) and the denomination keys from
the respective tables (namely refresh_melts and refresh_order)
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
efficient ways to express the same query. */
PREPARE ("get_link",
- "SELECT link_vector_enc,ev_sig,ro.denom_pub"
+ "SELECT ev_sig,ro.denom_pub"
" FROM refresh_sessions rs "
" JOIN refresh_order ro 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
that the old coin was melted into. */
PREPARE ("get_transfer",
- "SELECT transfer_pub,link_secret_enc,session_hash"
+ "SELECT transfer_pub,session_hash"
" 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"
" AND rcl.cnc_index=rs.noreveal_index",
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_uint16 (&cnc_index),
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,
commit_coins[i].coin_ev_size),
GNUNET_PQ_query_param_end
@@ -3184,8 +3176,6 @@ postgres_get_refresh_commit_coins (void *cls,
}
{
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",
&c_buf,
&c_buf_size),
@@ -3216,28 +3206,27 @@ postgres_get_refresh_commit_coins (void *cls,
* @param session database connection to use
* @param session_hash hash to identify refresh session
* @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
*/
static int
-postgres_insert_refresh_commit_link (void *cls,
- struct TALER_EXCHANGEDB_Session *session,
- const struct GNUNET_HashCode *session_hash,
- uint16_t cnc_index,
- const struct TALER_RefreshCommitLinkP *link)
+postgres_insert_refresh_transfer_public_key (void *cls,
+ struct TALER_EXCHANGEDB_Session *session,
+ const struct GNUNET_HashCode *session_hash,
+ uint16_t cnc_index,
+ const struct TALER_TransferPublicKeyP *tp)
{
struct GNUNET_PQ_QueryParam params[] = {
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_auto_from_type (&link->shared_secret_enc),
GNUNET_PQ_query_param_end
};
PGresult *result;
result = GNUNET_PQ_exec_prepared (session->conn,
- "insert_refresh_commit_link",
+ "insert_transfer_public_key",
params);
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_hash hash to identify refresh session
* @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,
* #GNUNET_NO if commitment was not found
* #GNUNET_OK on success
*/
static int
-postgres_get_refresh_commit_link (void *cls,
- struct TALER_EXCHANGEDB_Session *session,
- const struct GNUNET_HashCode *session_hash,
- uint16_t cnc_index,
- struct TALER_RefreshCommitLinkP *link)
+postgres_get_refresh_transfer_public_key (void *cls,
+ struct TALER_EXCHANGEDB_Session *session,
+ const struct GNUNET_HashCode *session_hash,
+ uint16_t cnc_index,
+ struct TALER_TransferPublicKeyP *tp)
{
struct GNUNET_PQ_QueryParam params[] = {
GNUNET_PQ_query_param_auto_from_type (session_hash),
@@ -3284,7 +3273,7 @@ postgres_get_refresh_commit_link (void *cls,
PGresult *result;
result = GNUNET_PQ_exec_prepared (session->conn,
- "get_refresh_commit_link",
+ "get_refresh_transfer_public_key",
params);
if (PGRES_TUPLES_OK != PQresultStatus (result))
{
@@ -3300,9 +3289,7 @@ postgres_get_refresh_commit_link (void *cls,
{
struct GNUNET_PQ_ResultSpec rs[] = {
GNUNET_PQ_result_spec_auto_from_type ("transfer_pub",
- &link->transfer_pub),
- GNUNET_PQ_result_spec_auto_from_type ("link_secret_enc",
- &link->shared_secret_enc),
+ tp),
GNUNET_PQ_result_spec_end
};
@@ -3376,11 +3363,11 @@ postgres_get_melt_commitment (void *cls,
goto cleanup;
}
if (GNUNET_OK !=
- postgres_get_refresh_commit_link (cls,
- session,
- session_hash,
- cnc_index,
- &mc->commit_links[cnc_index]))
+ postgres_get_refresh_transfer_public_key (cls,
+ session,
+ session_hash,
+ cnc_index,
+ &mc->transfer_pubs[cnc_index]))
{
GNUNET_break (0);
goto cleanup;
@@ -3486,8 +3473,6 @@ postgres_get_link_data_list (void *cls,
pos = GNUNET_new (struct TALER_EXCHANGEDB_LinkDataList);
{
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",
&sig),
GNUNET_PQ_result_spec_rsa_public_key ("denom_pub",
@@ -3567,10 +3552,8 @@ postgres_get_transfer (void *cls,
{
struct GNUNET_HashCode session_hash;
struct TALER_TransferPublicKeyP transfer_pub;
- struct TALER_EncryptedLinkSecretP shared_secret_enc;
struct GNUNET_PQ_ResultSpec rs[] = {
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_end
};
@@ -3584,8 +3567,7 @@ postgres_get_transfer (void *cls,
}
tdc (tdc_cls,
&session_hash,
- &transfer_pub,
- &shared_secret_enc);
+ &transfer_pub);
}
PQclear (result);
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->get_refresh_commit_coins = &postgres_get_refresh_commit_coins;
plugin->free_refresh_commit_coins = &postgres_free_refresh_commit_coins;
- plugin->insert_refresh_commit_link = &postgres_insert_refresh_commit_link;
- plugin->get_refresh_commit_link = &postgres_get_refresh_commit_link;
+ plugin->insert_refresh_transfer_public_key = &postgres_insert_refresh_transfer_public_key;
+ plugin->get_refresh_transfer_public_key = &postgres_get_refresh_transfer_public_key;
plugin->get_melt_commitment = &postgres_get_melt_commitment;
plugin->free_melt_commitment = &common_free_melt_commitment;
plugin->insert_refresh_out = &postgres_insert_refresh_out;
diff --git a/src/include/taler_crypto_lib.h b/src/include/taler_crypto_lib.h
index e1fdeb2bc..e8e8f3a03 100644
--- a/src/include/taler_crypto_lib.h
+++ b/src/include/taler_crypto_lib.h
@@ -412,7 +412,7 @@ GNUNET_NETWORK_STRUCT_BEGIN
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
* #GNUNET_CRYPTO_ecc_ecdh() returns to us.
*/
@@ -421,49 +421,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
* (in binary representation).
*/
@@ -540,44 +497,6 @@ struct TALER_RefreshLinkEncryptedP
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
* 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.
- * Also creates the transfer key.
+ * Decrypt the shared @a secret from the information in the
+ * @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[out] trans_priv set to transfer private key
- * @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
+ * @param[out] secret set to the shared secret
*/
-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);
+void
+TALER_link_reveal_transfer_secret (const struct TALER_TransferPrivateKeyP *trans_priv,
+ const struct TALER_CoinSpendPublicKeyP *coin_pub,
+ struct TALER_TransferSecretP *transfer_secret);
+
/**
- * Use the @a trans_sec (from ECDHE) to decrypt the @a secret_enc
- * to obtain the @a secret to decrypt the linkage data.
+ * Decrypt the shared @a secret from the information in the
+ * @a trans_priv and @a coin_pub.
*
- * @param secret_enc encrypted secret
- * @param trans_sec transfer secret
- * @param secret shared secret for refresh link decryption
- * @return #GNUNET_OK on success
+ * @param trans_pub transfer private key
+ * @param coin_priv coin public key
+ * @param[out] secret set to the shared secret
*/
-int
-TALER_transfer_decrypt (const struct TALER_EncryptedLinkSecretP *secret_enc,
- const struct TALER_TransferSecretP *trans_sec,
- struct TALER_LinkSecretP *secret);
+void
+TALER_link_recover_transfer_secret (const struct TALER_TransferPublicKeyP *trans_pub,
+ const struct TALER_CoinSpendPrivateKeyP *coin_priv,
+ struct TALER_TransferSecretP *transfer_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
+ * Header for serializations of coin-specific information about the
+ * fresh coins we generate during a melt.
*/
-int
-TALER_transfer_encrypt (const struct TALER_LinkSecretP *secret,
- const struct TALER_TransferSecretP *trans_sec,
- struct TALER_EncryptedLinkSecretP *secret_enc);
+struct TALER_FreshCoinP
+{
+ /**
+ * Private key of the coin.
+ */
+ struct TALER_CoinSpendPrivateKeyP coin_priv;
-/**
- * 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
-TALER_refresh_decrypt (const struct TALER_RefreshLinkEncryptedP *input,
- const struct TALER_LinkSecretP *secret,
- struct TALER_RefreshLinkDecryptedP *output);
+ /**
+ * The blinding key.
+ */
+ struct TALER_DenominationBlindingKeyP blinding_key;
+
+};
/**
- * Encrypt refresh link information.
+ * 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 input plaintext refresh link data
- * @param secret shared secret to use for encryption
- * @param[out] output where to write encrypted refresh link
+ * @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_refresh_encrypt (const struct TALER_RefreshLinkDecryptedP *input,
- const struct TALER_LinkSecretP *secret,
- struct TALER_RefreshLinkEncryptedP *output);
+TALER_setup_fresh_coin (const struct TALER_TransferSecretP *secret_seed,
+ unsigned int coin_num_salt,
+ struct TALER_FreshCoinP *fc);
+
#endif
diff --git a/src/include/taler_exchangedb_plugin.h b/src/include/taler_exchangedb_plugin.h
index ddc7f7714..0377806f4 100644
--- a/src/include/taler_exchangedb_plugin.h
+++ b/src/include/taler_exchangedb_plugin.h
@@ -445,12 +445,6 @@ 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.
*/
char *coin_ev;
@@ -474,12 +468,6 @@ struct TALER_EXCHANGEDB_LinkDataList
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.
*/
struct TALER_DenominationPublicKey denom_pub;
@@ -579,9 +567,9 @@ struct TALER_EXCHANGEDB_MeltCommitment
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
(*TALER_EXCHANGEDB_TransferDataCallback)(void *cls,
const struct GNUNET_HashCode *session_hash,
- const struct TALER_TransferPublicKeyP *transfer_pub,
- const struct TALER_EncryptedLinkSecretP *shared_secret_enc);
+ const struct TALER_TransferPublicKeyP *transfer_pub);
/**
@@ -1217,15 +1204,15 @@ struct TALER_EXCHANGEDB_Plugin
* @param session database connection to use
* @param session_hash hash to identify refresh session
* @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
*/
int
- (*insert_refresh_commit_link) (void *cls,
- struct TALER_EXCHANGEDB_Session *session,
- const struct GNUNET_HashCode *session_hash,
- uint16_t cnc_index,
- const struct TALER_RefreshCommitLinkP *link);
+ (*insert_refresh_transfer_public_key) (void *cls,
+ struct TALER_EXCHANGEDB_Session *session,
+ const struct GNUNET_HashCode *session_hash,
+ uint16_t cnc_index,
+ const struct TALER_TransferPublicKeyP *tp);
/**
* Obtain the commited (encrypted) refresh link data
@@ -1235,17 +1222,17 @@ struct TALER_EXCHANGEDB_Plugin
* @param session database connection to use
* @param session_hash hash to identify refresh session
* @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,
* #GNUNET_NO if commitment was not found
* #GNUNET_OK on success
*/
int
- (*get_refresh_commit_link) (void *cls,
- struct TALER_EXCHANGEDB_Session *session,
- const struct GNUNET_HashCode *session_hash,
- uint16_t cnc_index,
- struct TALER_RefreshCommitLinkP *link);
+ (*get_refresh_transfer_public_key) (void *cls,
+ struct TALER_EXCHANGEDB_Session *session,
+ const struct GNUNET_HashCode *session_hash,
+ uint16_t cnc_index,
+ struct TALER_TransferPublicKeyP *tp);
/**
diff --git a/src/include/taler_signatures.h b/src/include/taler_signatures.h
index 098799538..a4d599cd7 100644
--- a/src/include/taler_signatures.h
+++ b/src/include/taler_signatures.h
@@ -878,31 +878,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
* key affirming the SEPA details for the exchange.
*/
diff --git a/src/util/crypto.c b/src/util/crypto.c
index 3200e2a05..771744c7e 100644
--- a/src/util/crypto.c
+++ b/src/util/crypto.c
@@ -73,92 +73,32 @@ TALER_gcrypt_init ()
/**
- * Derive symmetric key material for refresh operations from
- * a given shared secret for link decryption.
- *
- * @param secret the shared secret
- * @param[out] iv set to initialization vector
- * @param[out] skey set to session key
- */
-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.
+ * Check if a coin is valid; that is, whether the denomination key exists,
+ * is not expired, and the signature is correct.
*
- * @param secret_enc encrypted secret
- * @param trans_sec transfer secret
- * @param secret shared secret for refresh link decryption
- * @return #GNUNET_OK on success
+ * @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_transfer_decrypt (const struct TALER_EncryptedLinkSecretP *secret_enc,
- const struct TALER_TransferSecretP *trans_sec,
- struct TALER_LinkSecretP *secret)
+TALER_test_coin_valid (const struct TALER_CoinPublicInfo *coin_public_info)
{
- struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
- struct GNUNET_CRYPTO_SymmetricSessionKey skey;
- ssize_t s;
+ struct GNUNET_HashCode c_hash;
- GNUNET_assert (sizeof (struct TALER_EncryptedLinkSecretP) ==
- sizeof (struct TALER_LinkSecretP));
- derive_transfer_key (trans_sec, &iv, &skey);
- s = GNUNET_CRYPTO_symmetric_decrypt (secret_enc,
- sizeof (struct TALER_LinkSecretP),
- &skey,
- &iv,
- secret);
- if (sizeof (struct TALER_LinkSecretP) != s)
- return GNUNET_SYSERR;
- return GNUNET_OK;
+ 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;
}
@@ -191,244 +131,73 @@ 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
- * encrypted link secret @e secret_enc using the transfer
- * private key and the coin's public key.
+ * @a trans_priv and @a coin_pub.
*
- * @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)
+void
+TALER_link_reveal_transfer_secret (const struct TALER_TransferPrivateKeyP *trans_priv,
+ const struct TALER_CoinSpendPublicKeyP *coin_pub,
+ struct TALER_TransferSecretP *transfer_secret)
{
- struct TALER_TransferSecretP transfer_secret;
-
- if (GNUNET_OK !=
- GNUNET_CRYPTO_ecdh_eddsa (&trans_priv->ecdhe_priv,
- &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;
+ GNUNET_assert (GNUNET_OK ==
+ GNUNET_CRYPTO_ecdh_eddsa (&trans_priv->ecdhe_priv,
+ &coin_pub->eddsa_pub,
+ &transfer_secret->key));
}
/**
* 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.
+ * @a trans_priv and @a coin_pub.
*
- * @param secret_enc encrypted link secret
- * @param trans_pub transfer public key
- * @param coin_priv coin private key
+ * @param trans_pub transfer private key
+ * @param coin_priv coin public 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)
+void
+TALER_link_recover_transfer_secret (const struct TALER_TransferPublicKeyP *trans_pub,
+ const struct TALER_CoinSpendPrivateKeyP *coin_priv,
+ struct TALER_TransferSecretP *transfer_secret)
{
- struct TALER_TransferSecretP transfer_secret;
-
- if (GNUNET_OK !=
- GNUNET_CRYPTO_eddsa_ecdh (&coin_priv->eddsa_priv,
- &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;
+ GNUNET_assert (GNUNET_OK ==
+ GNUNET_CRYPTO_eddsa_ecdh (&coin_priv->eddsa_priv,
+ &trans_pub->ecdhe_pub,
+ &transfer_secret->key));
}
/**
- * Encrypt the shared @a secret to generate the encrypted link secret.
- * Also creates the transfer key.
+ * Setup information for a fresh coin.
*
- * @param secret link secret to encrypt
- * @param coin_pub coin public key
- * @param[out] trans_priv set to transfer private key
- * @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
+ * @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
*/
-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)
+void
+TALER_setup_fresh_coin (const struct TALER_TransferSecretP *secret_seed,
+ unsigned int coin_num_salt,
+ struct TALER_FreshCoinP *fc)
{
- struct TALER_TransferSecretP transfer_secret;
- struct GNUNET_CRYPTO_EcdhePrivateKey *pk;
+ uint32_t be_salt = htonl (coin_num_salt);
- pk = GNUNET_CRYPTO_ecdhe_key_create ();
- if (GNUNET_OK !=
- GNUNET_CRYPTO_ecdh_eddsa (pk,
- &coin_pub->eddsa_pub,
- &transfer_secret.key))
- {
- GNUNET_break (0);
- GNUNET_free (pk);
- return GNUNET_SYSERR;
- }
- if (GNUNET_OK !=
- 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;
+ GNUNET_assert (GNUNET_OK ==
+ GNUNET_CRYPTO_kdf (fc,
+ sizeof (*fc),
+ secret_seed,
+ sizeof (*secret_seed),
+ &be_salt,
+ sizeof (be_salt),
+ "taler-coin-derivation",
+ strlen ("taler-coin-derivation"),
+ NULL, 0));
+ /* FIXME: twiddle the bits of the private key */
}
+
+
/* end of crypto.c */
diff --git a/src/util/test_crypto.c b/src/util/test_crypto.c
index f442cefbd..f28ae8003 100644
--- a/src/util/test_crypto.c
+++ b/src/util/test_crypto.c
@@ -25,58 +25,6 @@
/**
- * 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.
*
* @return 0 on success
@@ -85,46 +33,53 @@ static int
test_high_level ()
{
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_CoinSpendPublicKeyP coin_pub;
+ struct GNUNET_CRYPTO_EcdhePrivateKey *pk2;
struct TALER_TransferPrivateKeyP trans_priv;
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 ();
- GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
- &secret,
- sizeof (secret));
- GNUNET_CRYPTO_eddsa_key_get_public (pk,
+ coin_priv.eddsa_priv = *pk;
+ GNUNET_free (pk);
+ GNUNET_CRYPTO_eddsa_key_get_public (&coin_priv.eddsa_priv,
&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));
+ pk2 = GNUNET_CRYPTO_ecdhe_key_create ();
+ 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 ==
memcmp (&secret,
&secret2,
sizeof (secret)));
- coin_priv.eddsa_priv = *pk;
- GNUNET_assert (GNUNET_OK ==
- TALER_link_decrypt_secret2 (&secret_enc,
- &trans_pub,
- &coin_priv,
- &secret2));
+ TALER_link_recover_transfer_secret (&trans_pub,
+ &coin_priv,
+ &secret2);
GNUNET_assert (0 ==
memcmp (&secret,
&secret2,
sizeof (secret)));
- GNUNET_free (pk);
+ 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;
}
@@ -133,11 +88,9 @@ int
main(int argc,
const char *const argv[])
{
- if (0 != test_basics ())
- return 1;
if (0 != test_high_level ())
return 1;
- return 0;
+ return 0;
}
/* end of test_crypto.c */