completing TALER_MINT_refresh_melt implementation
This commit is contained in:
parent
ce4f6e2106
commit
00d613728f
@ -468,6 +468,23 @@ TALER_link_decrypt_secret2 (const struct TALER_EncryptedLinkSecretP *secret_enc,
|
|||||||
struct TALER_LinkSecretP *secret);
|
struct TALER_LinkSecretP *secret);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given the coin and the transfer private keys, compute the
|
||||||
|
* transfer secret. (Technically, we only need one of the two
|
||||||
|
* private keys, but the caller currently trivially only has
|
||||||
|
* the two private keys, so we derive one of the public keys
|
||||||
|
* internally to this function.)
|
||||||
|
*
|
||||||
|
* @param coin_priv coin key
|
||||||
|
* @param trans_priv transfer private key
|
||||||
|
* @param[out] computed transfer secret
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
TALER_link_derive_transfer_secret (const struct TALER_CoinSpendPrivateKeyP *coin_priv,
|
||||||
|
const struct TALER_TransferPrivateKeyP *trans_priv,
|
||||||
|
struct TALER_TransferSecretP *ts);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encrypt the shared @a secret to generate the encrypted link secret.
|
* Encrypt the shared @a secret to generate the encrypted link secret.
|
||||||
* Also creates the transfer key.
|
* Also creates the transfer key.
|
||||||
|
@ -181,7 +181,7 @@ struct TALER_MINT_DenomPublicKey
|
|||||||
struct TALER_Amount fee_deposit;
|
struct TALER_Amount fee_deposit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*The applicable fee to refresh a coin of this denomination
|
*The applicable fee to melt/refresh a coin of this denomination
|
||||||
*/
|
*/
|
||||||
struct TALER_Amount fee_refresh;
|
struct TALER_Amount fee_refresh;
|
||||||
};
|
};
|
||||||
|
@ -56,7 +56,7 @@ struct MeltedCoinP
|
|||||||
/**
|
/**
|
||||||
* The applicable fee for withdrawing a coin of this denomination
|
* The applicable fee for withdrawing a coin of this denomination
|
||||||
*/
|
*/
|
||||||
struct TALER_AmountNBO fee_withdraw;
|
struct TALER_AmountNBO fee_melt;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transfer private keys for each cut-and-choose dimension.
|
* Transfer private keys for each cut-and-choose dimension.
|
||||||
@ -165,9 +165,9 @@ struct MeltedCoin
|
|||||||
struct TALER_Amount melt_amount_with_fee;
|
struct TALER_Amount melt_amount_with_fee;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The applicable fee for withdrawing a coin of this denomination
|
* The applicable fee for melting a coin of this denomination
|
||||||
*/
|
*/
|
||||||
struct TALER_Amount fee_withdraw;
|
struct TALER_Amount fee_melt;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transfer private keys for each cut-and-choose dimension.
|
* Transfer private keys for each cut-and-choose dimension.
|
||||||
@ -382,8 +382,8 @@ serialize_melted_coin (const struct MeltedCoin *mc,
|
|||||||
TALER_amount_hton (&mcp.melt_amount_with_fee,
|
TALER_amount_hton (&mcp.melt_amount_with_fee,
|
||||||
&mc->melt_amount_with_fee);
|
&mc->melt_amount_with_fee);
|
||||||
|
|
||||||
TALER_amount_hton (&mcp.fee_withdraw,
|
TALER_amount_hton (&mcp.fee_melt,
|
||||||
&mc->fee_withdraw);
|
&mc->fee_melt);
|
||||||
for (i=0;i<TALER_CNC_KAPPA;i++)
|
for (i=0;i<TALER_CNC_KAPPA;i++)
|
||||||
mcp.transfer_priv[i] = mc->transfer_priv[i];
|
mcp.transfer_priv[i] = mc->transfer_priv[i];
|
||||||
mcp.deposit_valid_until = GNUNET_TIME_absolute_hton (mc->deposit_valid_until);
|
mcp.deposit_valid_until = GNUNET_TIME_absolute_hton (mc->deposit_valid_until);
|
||||||
@ -462,8 +462,8 @@ deserialize_melted_coin (struct MeltedCoin *mc,
|
|||||||
mc->coin_priv = mcp.coin_priv;
|
mc->coin_priv = mcp.coin_priv;
|
||||||
TALER_amount_ntoh (&mc->melt_amount_with_fee,
|
TALER_amount_ntoh (&mc->melt_amount_with_fee,
|
||||||
&mcp.melt_amount_with_fee);
|
&mcp.melt_amount_with_fee);
|
||||||
TALER_amount_ntoh (&mc->fee_withdraw,
|
TALER_amount_ntoh (&mc->fee_melt,
|
||||||
&mcp.fee_withdraw);
|
&mcp.fee_melt);
|
||||||
for (i=0;i<TALER_CNC_KAPPA;i++)
|
for (i=0;i<TALER_CNC_KAPPA;i++)
|
||||||
mc->transfer_priv[i] = mcp.transfer_priv[i];
|
mc->transfer_priv[i] = mcp.transfer_priv[i];
|
||||||
mc->deposit_valid_until = GNUNET_TIME_absolute_ntoh (mcp.deposit_valid_until);
|
mc->deposit_valid_until = GNUNET_TIME_absolute_ntoh (mcp.deposit_valid_until);
|
||||||
@ -867,7 +867,7 @@ TALER_MINT_refresh_prepare (unsigned int num_melts,
|
|||||||
{
|
{
|
||||||
md.melted_coins[i].coin_priv = melt_privs[i];
|
md.melted_coins[i].coin_priv = melt_privs[i];
|
||||||
md.melted_coins[i].melt_amount_with_fee = melt_amounts[i];
|
md.melted_coins[i].melt_amount_with_fee = melt_amounts[i];
|
||||||
md.melted_coins[i].fee_withdraw = melt_pks[i].fee_withdraw;
|
md.melted_coins[i].fee_melt = melt_pks[i].fee_refresh;
|
||||||
for (j=0;j<TALER_CNC_KAPPA;j++)
|
for (j=0;j<TALER_CNC_KAPPA;j++)
|
||||||
{
|
{
|
||||||
struct GNUNET_CRYPTO_EcdhePrivateKey *tpk;
|
struct GNUNET_CRYPTO_EcdhePrivateKey *tpk;
|
||||||
@ -1095,6 +1095,48 @@ handle_refresh_melt_finished (void *cls,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a coin to be melted to the respective JSON encoding.
|
||||||
|
*
|
||||||
|
* @param melt_session_hash session hash to use
|
||||||
|
* @param mc coin to be melted
|
||||||
|
* @return JSON encoding of the melting request
|
||||||
|
*/
|
||||||
|
static json_t *
|
||||||
|
melted_coin_to_json (const struct GNUNET_HashCode *melt_session_hash,
|
||||||
|
const struct MeltedCoin *mc)
|
||||||
|
{
|
||||||
|
struct TALER_CoinSpendSignatureP confirm_sig;
|
||||||
|
struct TALER_RefreshMeltCoinAffirmationPS melt;
|
||||||
|
|
||||||
|
melt.purpose.purpose = htonl (TALER_SIGNATURE_MINT_CONFIRM_MELT);
|
||||||
|
melt.purpose.size = htonl (sizeof (melt));
|
||||||
|
melt.session_hash = *melt_session_hash;
|
||||||
|
TALER_amount_hton (&melt.amount_with_fee,
|
||||||
|
&mc->melt_amount_with_fee);
|
||||||
|
TALER_amount_hton (&melt.melt_fee,
|
||||||
|
&mc->fee_melt);
|
||||||
|
GNUNET_CRYPTO_eddsa_key_get_public (&mc->coin_priv.eddsa_priv,
|
||||||
|
&melt.coin_pub.eddsa_pub);
|
||||||
|
GNUNET_CRYPTO_eddsa_sign (&mc->coin_priv.eddsa_priv,
|
||||||
|
&melt.purpose,
|
||||||
|
&confirm_sig.eddsa_signature);
|
||||||
|
return json_pack ("{s:o, s:o, s:o, s:o, s:o}",
|
||||||
|
"coin_pub",
|
||||||
|
TALER_json_from_data (&melt.coin_pub,
|
||||||
|
sizeof (melt.coin_pub)),
|
||||||
|
"denom_pub",
|
||||||
|
TALER_json_from_rsa_public_key (mc->pub_key.rsa_public_key),
|
||||||
|
"denom_sig", 42,
|
||||||
|
TALER_json_from_rsa_signature (mc->sig.rsa_signature),
|
||||||
|
"confirm_sig",
|
||||||
|
TALER_json_from_data (&confirm_sig,
|
||||||
|
sizeof (confirm_sig)),
|
||||||
|
"value_with_fee",
|
||||||
|
TALER_json_from_amount (&mc->melt_amount_with_fee));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Submit a melt request to the mint and get the mint's
|
* Submit a melt request to the mint and get the mint's
|
||||||
* response.
|
* response.
|
||||||
@ -1129,6 +1171,7 @@ TALER_MINT_refresh_melt (struct TALER_MINT_Handle *mint,
|
|||||||
json_t *transfer_pubs;
|
json_t *transfer_pubs;
|
||||||
json_t *secret_encs;
|
json_t *secret_encs;
|
||||||
json_t *link_encs;
|
json_t *link_encs;
|
||||||
|
json_t *tmp;
|
||||||
struct TALER_MINT_RefreshMeltHandle *rmh;
|
struct TALER_MINT_RefreshMeltHandle *rmh;
|
||||||
CURL *eh;
|
CURL *eh;
|
||||||
struct TALER_MINT_Context *ctx;
|
struct TALER_MINT_Context *ctx;
|
||||||
@ -1150,7 +1193,7 @@ TALER_MINT_refresh_melt (struct TALER_MINT_Handle *mint,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: inomplete request building here: */
|
/* build JSON request, each of the 6 arrays first */
|
||||||
new_denoms = json_array ();
|
new_denoms = json_array ();
|
||||||
melt_coins = json_array ();
|
melt_coins = json_array ();
|
||||||
coin_evs = json_array ();
|
coin_evs = json_array ();
|
||||||
@ -1159,16 +1202,111 @@ TALER_MINT_refresh_melt (struct TALER_MINT_Handle *mint,
|
|||||||
link_encs = json_array ();
|
link_encs = json_array ();
|
||||||
for (i=0;i<md->num_melted_coins;i++)
|
for (i=0;i<md->num_melted_coins;i++)
|
||||||
{
|
{
|
||||||
|
const struct MeltedCoin *mc = &md->melted_coins[i];
|
||||||
|
|
||||||
|
/* now melt_coins */
|
||||||
|
json_array_append (melt_coins,
|
||||||
|
melted_coin_to_json (&md->melt_session_hash,
|
||||||
|
mc));
|
||||||
|
|
||||||
|
/* now transfer_pubs */
|
||||||
|
tmp = json_array ();
|
||||||
for (j=0;j<TALER_CNC_KAPPA;j++)
|
for (j=0;j<TALER_CNC_KAPPA;j++)
|
||||||
{
|
{
|
||||||
|
struct TALER_TransferPublicKeyP transfer_pub;
|
||||||
|
|
||||||
|
GNUNET_CRYPTO_ecdhe_key_get_public (&mc->transfer_priv[j].ecdhe_priv,
|
||||||
|
&transfer_pub.ecdhe_pub);
|
||||||
|
json_array_append (tmp,
|
||||||
|
TALER_json_from_data (&transfer_pub,
|
||||||
|
sizeof (transfer_pub)));
|
||||||
}
|
}
|
||||||
|
json_array_append (transfer_pubs,
|
||||||
|
tmp);
|
||||||
|
|
||||||
|
/* now secret_encs */
|
||||||
|
tmp = json_array ();
|
||||||
|
for (j=0;j<TALER_CNC_KAPPA;j++)
|
||||||
|
{
|
||||||
|
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));
|
||||||
|
json_array_append (tmp,
|
||||||
|
TALER_json_from_data (&els,
|
||||||
|
sizeof (els)));
|
||||||
|
}
|
||||||
|
json_array_append (secret_encs,
|
||||||
|
tmp);
|
||||||
}
|
}
|
||||||
for (i=0;i<md->num_fresh_coins;i++)
|
for (i=0;i<md->num_fresh_coins;i++)
|
||||||
{
|
{
|
||||||
|
/* now new_denoms */
|
||||||
|
json_array_append (new_denoms,
|
||||||
|
TALER_json_from_rsa_public_key
|
||||||
|
(md->fresh_pks[i].rsa_public_key));
|
||||||
|
|
||||||
|
/* now link_encs */
|
||||||
|
tmp = json_array ();
|
||||||
for (j=0;j<TALER_CNC_KAPPA;j++)
|
for (j=0;j<TALER_CNC_KAPPA;j++)
|
||||||
{
|
{
|
||||||
|
const struct FreshCoin *fc = &md->fresh_coins[j][i];
|
||||||
|
struct TALER_RefreshLinkDecrypted rld;
|
||||||
|
struct TALER_RefreshLinkEncrypted *rle;
|
||||||
|
char *buf;
|
||||||
|
size_t buf_len;
|
||||||
|
|
||||||
|
rld.coin_priv = fc->coin_priv;
|
||||||
|
rld.blinding_key = fc->blinding_key;
|
||||||
|
rle = TALER_refresh_encrypt (&rld,
|
||||||
|
&md->link_secrets[j]);
|
||||||
|
GNUNET_assert (NULL != rle);
|
||||||
|
buf = TALER_refresh_link_encrypted_encode (rle,
|
||||||
|
&buf_len);
|
||||||
|
GNUNET_assert (NULL != buf);
|
||||||
|
json_array_append (tmp,
|
||||||
|
TALER_json_from_data (buf,
|
||||||
|
buf_len));
|
||||||
|
GNUNET_free (buf);
|
||||||
|
GNUNET_free (rle);
|
||||||
}
|
}
|
||||||
|
json_array_append (link_encs,
|
||||||
|
tmp);
|
||||||
|
|
||||||
|
/* now coin_evs */
|
||||||
|
tmp = json_array ();
|
||||||
|
for (j=0;j<TALER_CNC_KAPPA;j++)
|
||||||
|
{
|
||||||
|
const struct FreshCoin *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 */
|
||||||
|
size_t coin_ev_size;
|
||||||
|
|
||||||
|
GNUNET_CRYPTO_eddsa_key_get_public (&fc->coin_priv.eddsa_priv,
|
||||||
|
&coin_pub.eddsa_pub);
|
||||||
|
GNUNET_CRYPTO_hash (&coin_pub.eddsa_pub,
|
||||||
|
sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey),
|
||||||
|
&coin_hash);
|
||||||
|
coin_ev_size = GNUNET_CRYPTO_rsa_blind (&coin_hash,
|
||||||
|
fc->blinding_key.rsa_blinding_key,
|
||||||
|
md->fresh_pks[j].rsa_public_key,
|
||||||
|
&coin_ev);
|
||||||
|
json_array_append (tmp,
|
||||||
|
TALER_json_from_data (coin_ev,
|
||||||
|
coin_ev_size));
|
||||||
|
GNUNET_free (coin_ev);
|
||||||
|
}
|
||||||
|
json_array_append (coin_evs,
|
||||||
|
tmp);
|
||||||
}
|
}
|
||||||
|
/* 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, s:o, s:o}",
|
||||||
"new_denoms", new_denoms,
|
"new_denoms", new_denoms,
|
||||||
"melt_coins", melt_coins,
|
"melt_coins", melt_coins,
|
||||||
@ -1177,7 +1315,7 @@ TALER_MINT_refresh_melt (struct TALER_MINT_Handle *mint,
|
|||||||
"secret_encs", secret_encs,
|
"secret_encs", secret_encs,
|
||||||
"link_encs", link_encs);
|
"link_encs", link_encs);
|
||||||
|
|
||||||
|
/* and now we can at last begin the actual request handling */
|
||||||
rmh = GNUNET_new (struct TALER_MINT_RefreshMeltHandle);
|
rmh = GNUNET_new (struct TALER_MINT_RefreshMeltHandle);
|
||||||
rmh->mint = mint;
|
rmh->mint = mint;
|
||||||
rmh->melt_cb = melt_cb;
|
rmh->melt_cb = melt_cb;
|
||||||
|
@ -162,6 +162,34 @@ TALER_transfer_decrypt (const struct TALER_EncryptedLinkSecretP *secret_enc,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given the coin and the transfer private keys, compute the
|
||||||
|
* transfer secret. (Technically, we only need one of the two
|
||||||
|
* private keys, but the caller currently trivially only has
|
||||||
|
* the two private keys, so we derive one of the public keys
|
||||||
|
* internally to this function.)
|
||||||
|
*
|
||||||
|
* @param coin_priv coin key
|
||||||
|
* @param trans_priv transfer private key
|
||||||
|
* @param[out] computed transfer secret
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
TALER_link_derive_transfer_secret (const struct TALER_CoinSpendPrivateKeyP *coin_priv,
|
||||||
|
const struct TALER_TransferPrivateKeyP *trans_priv,
|
||||||
|
struct TALER_TransferSecretP *ts)
|
||||||
|
{
|
||||||
|
struct TALER_CoinSpendPublicKeyP coin_pub;
|
||||||
|
|
||||||
|
GNUNET_CRYPTO_eddsa_key_get_public (&coin_priv->eddsa_priv,
|
||||||
|
&coin_pub.eddsa_pub);
|
||||||
|
GNUNET_assert (GNUNET_OK ==
|
||||||
|
GNUNET_CRYPTO_ecdh_eddsa (&trans_priv->ecdhe_priv,
|
||||||
|
&coin_pub.eddsa_pub,
|
||||||
|
&ts->key));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use the @a trans_sec (from ECDHE) to encrypt the @a secret
|
* Use the @a trans_sec (from ECDHE) to encrypt the @a secret
|
||||||
* to obtain the @a secret_enc.
|
* to obtain the @a secret_enc.
|
||||||
|
Loading…
Reference in New Issue
Block a user