-towards fixing the protocol
This commit is contained in:
parent
f4f40a31ef
commit
bd77bcb52d
@ -91,7 +91,13 @@ handle_link_data (void *cls,
|
|||||||
TALER_JSON_pack_exchange_withdraw_values ("ewv",
|
TALER_JSON_pack_exchange_withdraw_values ("ewv",
|
||||||
&pos->alg_values),
|
&pos->alg_values),
|
||||||
GNUNET_JSON_pack_data_auto ("link_sig",
|
GNUNET_JSON_pack_data_auto ("link_sig",
|
||||||
&pos->orig_coin_link_sig));
|
&pos->orig_coin_link_sig),
|
||||||
|
GNUNET_JSON_pack_allow_null (
|
||||||
|
pos->have_nonce
|
||||||
|
? GNUNET_JSON_pack_data_auto ("cs_nonce",
|
||||||
|
&pos->nonce)
|
||||||
|
: GNUNET_JSON_pack_string ("cs_nonce",
|
||||||
|
NULL)));
|
||||||
if ( (NULL == obj) ||
|
if ( (NULL == obj) ||
|
||||||
(0 !=
|
(0 !=
|
||||||
json_array_append_new (list,
|
json_array_append_new (list,
|
||||||
|
@ -174,6 +174,7 @@ verify_and_execute_recoup_refresh (
|
|||||||
const struct TALER_CoinPublicInfo *coin,
|
const struct TALER_CoinPublicInfo *coin,
|
||||||
const struct TALER_ExchangeWithdrawValues *exchange_vals,
|
const struct TALER_ExchangeWithdrawValues *exchange_vals,
|
||||||
const union TALER_DenominationBlindingKeyP *coin_bks,
|
const union TALER_DenominationBlindingKeyP *coin_bks,
|
||||||
|
const struct TALER_CsNonce *nonce,
|
||||||
const struct TALER_CoinSpendSignatureP *coin_sig)
|
const struct TALER_CoinSpendSignatureP *coin_sig)
|
||||||
{
|
{
|
||||||
struct RecoupContext pc;
|
struct RecoupContext pc;
|
||||||
@ -263,6 +264,9 @@ verify_and_execute_recoup_refresh (
|
|||||||
TALER_EC_EXCHANGE_RECOUP_REFRESH_BLINDING_FAILED,
|
TALER_EC_EXCHANGE_RECOUP_REFRESH_BLINDING_FAILED,
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
if (TALER_DENOMINATION_CS == blinded_planchet.cipher)
|
||||||
|
blinded_planchet.details.cs_blinded_planchet.nonce
|
||||||
|
= *nonce;
|
||||||
TALER_coin_ev_hash (&blinded_planchet,
|
TALER_coin_ev_hash (&blinded_planchet,
|
||||||
&coin->denom_pub_hash,
|
&coin->denom_pub_hash,
|
||||||
&h_blind);
|
&h_blind);
|
||||||
@ -360,6 +364,7 @@ TEH_handler_recoup_refresh (struct MHD_Connection *connection,
|
|||||||
union TALER_DenominationBlindingKeyP coin_bks;
|
union TALER_DenominationBlindingKeyP coin_bks;
|
||||||
struct TALER_CoinSpendSignatureP coin_sig;
|
struct TALER_CoinSpendSignatureP coin_sig;
|
||||||
struct TALER_ExchangeWithdrawValues exchange_vals;
|
struct TALER_ExchangeWithdrawValues exchange_vals;
|
||||||
|
struct TALER_CsNonce nonce;
|
||||||
struct GNUNET_JSON_Specification spec[] = {
|
struct GNUNET_JSON_Specification spec[] = {
|
||||||
GNUNET_JSON_spec_fixed_auto ("denom_pub_hash",
|
GNUNET_JSON_spec_fixed_auto ("denom_pub_hash",
|
||||||
&coin.denom_pub_hash),
|
&coin.denom_pub_hash),
|
||||||
@ -371,12 +376,18 @@ TEH_handler_recoup_refresh (struct MHD_Connection *connection,
|
|||||||
&coin_bks),
|
&coin_bks),
|
||||||
GNUNET_JSON_spec_fixed_auto ("coin_sig",
|
GNUNET_JSON_spec_fixed_auto ("coin_sig",
|
||||||
&coin_sig),
|
&coin_sig),
|
||||||
|
GNUNET_JSON_spec_mark_optional (
|
||||||
|
GNUNET_JSON_spec_fixed_auto ("cs_nonce",
|
||||||
|
&nonce)),
|
||||||
GNUNET_JSON_spec_end ()
|
GNUNET_JSON_spec_end ()
|
||||||
};
|
};
|
||||||
|
|
||||||
memset (&coin,
|
memset (&coin,
|
||||||
0,
|
0,
|
||||||
sizeof (coin));
|
sizeof (coin));
|
||||||
|
memset (&nonce,
|
||||||
|
0,
|
||||||
|
sizeof (nonce));
|
||||||
coin.coin_pub = *coin_pub;
|
coin.coin_pub = *coin_pub;
|
||||||
ret = TALER_MHD_parse_json_data (connection,
|
ret = TALER_MHD_parse_json_data (connection,
|
||||||
root,
|
root,
|
||||||
@ -392,6 +403,7 @@ TEH_handler_recoup_refresh (struct MHD_Connection *connection,
|
|||||||
&coin,
|
&coin,
|
||||||
&exchange_vals,
|
&exchange_vals,
|
||||||
&coin_bks,
|
&coin_bks,
|
||||||
|
&nonce,
|
||||||
&coin_sig);
|
&coin_sig);
|
||||||
GNUNET_JSON_parse_free (spec);
|
GNUNET_JSON_parse_free (spec);
|
||||||
return res;
|
return res;
|
||||||
|
@ -177,6 +177,7 @@ verify_and_execute_recoup (
|
|||||||
const struct TALER_CoinPublicInfo *coin,
|
const struct TALER_CoinPublicInfo *coin,
|
||||||
const struct TALER_ExchangeWithdrawValues *exchange_vals,
|
const struct TALER_ExchangeWithdrawValues *exchange_vals,
|
||||||
const union TALER_DenominationBlindingKeyP *coin_bks,
|
const union TALER_DenominationBlindingKeyP *coin_bks,
|
||||||
|
const struct TALER_CsNonce *nonce,
|
||||||
const struct TALER_CoinSpendSignatureP *coin_sig)
|
const struct TALER_CoinSpendSignatureP *coin_sig)
|
||||||
{
|
{
|
||||||
struct RecoupContext pc;
|
struct RecoupContext pc;
|
||||||
@ -268,6 +269,9 @@ verify_and_execute_recoup (
|
|||||||
TALER_EC_EXCHANGE_RECOUP_BLINDING_FAILED,
|
TALER_EC_EXCHANGE_RECOUP_BLINDING_FAILED,
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
if (TALER_DENOMINATION_CS == blinded_planchet.cipher)
|
||||||
|
blinded_planchet.details.cs_blinded_planchet.nonce
|
||||||
|
= *nonce;
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
TALER_coin_ev_hash (&blinded_planchet,
|
TALER_coin_ev_hash (&blinded_planchet,
|
||||||
&coin->denom_pub_hash,
|
&coin->denom_pub_hash,
|
||||||
@ -373,6 +377,7 @@ TEH_handler_recoup (struct MHD_Connection *connection,
|
|||||||
union TALER_DenominationBlindingKeyP coin_bks;
|
union TALER_DenominationBlindingKeyP coin_bks;
|
||||||
struct TALER_CoinSpendSignatureP coin_sig;
|
struct TALER_CoinSpendSignatureP coin_sig;
|
||||||
struct TALER_ExchangeWithdrawValues exchange_vals;
|
struct TALER_ExchangeWithdrawValues exchange_vals;
|
||||||
|
struct TALER_CsNonce nonce;
|
||||||
struct GNUNET_JSON_Specification spec[] = {
|
struct GNUNET_JSON_Specification spec[] = {
|
||||||
GNUNET_JSON_spec_fixed_auto ("denom_pub_hash",
|
GNUNET_JSON_spec_fixed_auto ("denom_pub_hash",
|
||||||
&coin.denom_pub_hash),
|
&coin.denom_pub_hash),
|
||||||
@ -384,12 +389,18 @@ TEH_handler_recoup (struct MHD_Connection *connection,
|
|||||||
&coin_bks),
|
&coin_bks),
|
||||||
GNUNET_JSON_spec_fixed_auto ("coin_sig",
|
GNUNET_JSON_spec_fixed_auto ("coin_sig",
|
||||||
&coin_sig),
|
&coin_sig),
|
||||||
|
GNUNET_JSON_spec_mark_optional (
|
||||||
|
GNUNET_JSON_spec_fixed_auto ("cs_nonce",
|
||||||
|
&nonce)),
|
||||||
GNUNET_JSON_spec_end ()
|
GNUNET_JSON_spec_end ()
|
||||||
};
|
};
|
||||||
|
|
||||||
memset (&coin,
|
memset (&coin,
|
||||||
0,
|
0,
|
||||||
sizeof (coin));
|
sizeof (coin));
|
||||||
|
memset (&nonce,
|
||||||
|
0,
|
||||||
|
sizeof (nonce));
|
||||||
coin.coin_pub = *coin_pub;
|
coin.coin_pub = *coin_pub;
|
||||||
ret = TALER_MHD_parse_json_data (connection,
|
ret = TALER_MHD_parse_json_data (connection,
|
||||||
root,
|
root,
|
||||||
@ -408,6 +419,7 @@ TEH_handler_recoup (struct MHD_Connection *connection,
|
|||||||
&coin,
|
&coin,
|
||||||
&exchange_vals,
|
&exchange_vals,
|
||||||
&coin_bks,
|
&coin_bks,
|
||||||
|
&nonce,
|
||||||
&coin_sig);
|
&coin_sig);
|
||||||
GNUNET_JSON_parse_free (spec);
|
GNUNET_JSON_parse_free (spec);
|
||||||
return res;
|
return res;
|
||||||
|
@ -634,6 +634,13 @@ resolve_refreshes_reveal_denominations (struct MHD_Connection *connection,
|
|||||||
|
|
||||||
rrc->blinded_planchet = rcds[i].blinded_planchet;
|
rrc->blinded_planchet = rcds[i].blinded_planchet;
|
||||||
}
|
}
|
||||||
|
// FIXME: in CS-case, we MUST check if signatures
|
||||||
|
// already exist under the given nonce
|
||||||
|
// (TODO: check: refresh session hash OK?), and if so,
|
||||||
|
// we MUST return the existing signatures (c0/c1 may have changed!)
|
||||||
|
// and MUST NOT return the fresh signatures!
|
||||||
|
// => change this to a 'do_refresh_reveal' and
|
||||||
|
// change SQL to return existing signatures (if any)!
|
||||||
qs = TEH_plugin->insert_refresh_reveal (TEH_plugin->cls,
|
qs = TEH_plugin->insert_refresh_reveal (TEH_plugin->cls,
|
||||||
melt_serial_id,
|
melt_serial_id,
|
||||||
num_fresh_coins,
|
num_fresh_coins,
|
||||||
|
@ -535,6 +535,10 @@ TEH_handler_withdraw (struct TEH_RequestContext *rc,
|
|||||||
/* Clean up and send back final response */
|
/* Clean up and send back final response */
|
||||||
GNUNET_JSON_parse_free (spec);
|
GNUNET_JSON_parse_free (spec);
|
||||||
|
|
||||||
|
// FIXME: in CS-case, we MUST re-transmit any _existing_ signature
|
||||||
|
// (if database had a record matching the nonce)
|
||||||
|
// instead of sending a 'fresh' one back (as c0/c1 may differ in
|
||||||
|
// a client attack!
|
||||||
{
|
{
|
||||||
MHD_RESULT ret;
|
MHD_RESULT ret;
|
||||||
|
|
||||||
|
@ -1218,6 +1218,7 @@ prepare_statements (struct PostgresClosure *pg)
|
|||||||
",rrc.ewv"
|
",rrc.ewv"
|
||||||
",rrc.link_sig"
|
",rrc.link_sig"
|
||||||
",rrc.freshcoin_index"
|
",rrc.freshcoin_index"
|
||||||
|
",rrc.coin_ev"
|
||||||
" FROM refresh_commitments"
|
" FROM refresh_commitments"
|
||||||
" JOIN refresh_revealed_coins rrc"
|
" JOIN refresh_revealed_coins rrc"
|
||||||
" USING (melt_serial_id)"
|
" USING (melt_serial_id)"
|
||||||
@ -6385,6 +6386,7 @@ add_ldl (void *cls,
|
|||||||
|
|
||||||
pos = GNUNET_new (struct TALER_EXCHANGEDB_LinkList);
|
pos = GNUNET_new (struct TALER_EXCHANGEDB_LinkList);
|
||||||
{
|
{
|
||||||
|
struct TALER_BlindedPlanchet bp;
|
||||||
struct GNUNET_PQ_ResultSpec rs[] = {
|
struct GNUNET_PQ_ResultSpec rs[] = {
|
||||||
GNUNET_PQ_result_spec_auto_from_type ("transfer_pub",
|
GNUNET_PQ_result_spec_auto_from_type ("transfer_pub",
|
||||||
&transfer_pub),
|
&transfer_pub),
|
||||||
@ -6398,6 +6400,8 @@ add_ldl (void *cls,
|
|||||||
&pos->alg_values),
|
&pos->alg_values),
|
||||||
TALER_PQ_result_spec_denom_pub ("denom_pub",
|
TALER_PQ_result_spec_denom_pub ("denom_pub",
|
||||||
&pos->denom_pub),
|
&pos->denom_pub),
|
||||||
|
TALER_PQ_result_spec_blinded_planchet ("coin_ev",
|
||||||
|
&bp),
|
||||||
GNUNET_PQ_result_spec_end
|
GNUNET_PQ_result_spec_end
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -6411,6 +6415,12 @@ add_ldl (void *cls,
|
|||||||
ldctx->status = GNUNET_SYSERR;
|
ldctx->status = GNUNET_SYSERR;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (TALER_DENOMINATION_CS == bp.cipher)
|
||||||
|
{
|
||||||
|
pos->nonce = bp.details.cs_blinded_planchet.nonce;
|
||||||
|
pos->have_nonce = true;
|
||||||
|
}
|
||||||
|
TALER_blinded_planchet_free (&bp);
|
||||||
}
|
}
|
||||||
if ( (NULL != ldctx->last) &&
|
if ( (NULL != ldctx->last) &&
|
||||||
(0 == GNUNET_memcmp (&transfer_pub,
|
(0 == GNUNET_memcmp (&transfer_pub,
|
||||||
|
@ -1380,12 +1380,21 @@ struct TALER_EXCHANGEDB_LinkList
|
|||||||
*/
|
*/
|
||||||
struct TALER_CoinSpendSignatureP orig_coin_link_sig;
|
struct TALER_CoinSpendSignatureP orig_coin_link_sig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CS nonce, if cipher is CS.
|
||||||
|
*/
|
||||||
|
struct TALER_CsNonce nonce;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Offset that generated this coin in the refresh
|
* Offset that generated this coin in the refresh
|
||||||
* operation.
|
* operation.
|
||||||
*/
|
*/
|
||||||
uint32_t coin_refresh_offset;
|
uint32_t coin_refresh_offset;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set to true if @e nonce was initialized.
|
||||||
|
*/
|
||||||
|
bool have_nonce;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -92,6 +92,7 @@ parse_link_coin (const struct TALER_EXCHANGE_LinkHandle *lh,
|
|||||||
struct TALER_CoinSpendSignatureP link_sig;
|
struct TALER_CoinSpendSignatureP link_sig;
|
||||||
union TALER_DenominationBlindingKeyP bks;
|
union TALER_DenominationBlindingKeyP bks;
|
||||||
struct TALER_ExchangeWithdrawValues alg_values;
|
struct TALER_ExchangeWithdrawValues alg_values;
|
||||||
|
struct TALER_CsNonce nonce;
|
||||||
uint32_t coin_idx;
|
uint32_t coin_idx;
|
||||||
struct GNUNET_JSON_Specification spec[] = {
|
struct GNUNET_JSON_Specification spec[] = {
|
||||||
TALER_JSON_spec_denom_pub ("denom_pub",
|
TALER_JSON_spec_denom_pub ("denom_pub",
|
||||||
@ -104,6 +105,9 @@ parse_link_coin (const struct TALER_EXCHANGE_LinkHandle *lh,
|
|||||||
&link_sig),
|
&link_sig),
|
||||||
GNUNET_JSON_spec_uint32 ("coin_idx",
|
GNUNET_JSON_spec_uint32 ("coin_idx",
|
||||||
&coin_idx),
|
&coin_idx),
|
||||||
|
GNUNET_JSON_spec_mark_optional (
|
||||||
|
GNUNET_JSON_spec_fixed_auto ("cs_nonce",
|
||||||
|
&nonce)),
|
||||||
GNUNET_JSON_spec_end ()
|
GNUNET_JSON_spec_end ()
|
||||||
};
|
};
|
||||||
struct TALER_TransferSecretP secret;
|
struct TALER_TransferSecretP secret;
|
||||||
@ -111,6 +115,9 @@ parse_link_coin (const struct TALER_EXCHANGE_LinkHandle *lh,
|
|||||||
struct TALER_CoinPubHash c_hash;
|
struct TALER_CoinPubHash c_hash;
|
||||||
|
|
||||||
/* parse reply */
|
/* parse reply */
|
||||||
|
memset (&nonce,
|
||||||
|
0,
|
||||||
|
sizeof (nonce));
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
GNUNET_JSON_parse (json,
|
GNUNET_JSON_parse (json,
|
||||||
spec,
|
spec,
|
||||||
@ -143,6 +150,16 @@ parse_link_coin (const struct TALER_EXCHANGE_LinkHandle *lh,
|
|||||||
GNUNET_JSON_parse_free (spec);
|
GNUNET_JSON_parse_free (spec);
|
||||||
return GNUNET_SYSERR;
|
return GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
|
if (TALER_DENOMINATION_CS == alg_values.cipher)
|
||||||
|
{
|
||||||
|
if (GNUNET_is_zero (&nonce))
|
||||||
|
{
|
||||||
|
GNUNET_break_op (0);
|
||||||
|
GNUNET_JSON_parse_free (spec);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
pd.blinded_planchet.details.cs_blinded_planchet.nonce = nonce;
|
||||||
|
}
|
||||||
/* extract coin and signature */
|
/* extract coin and signature */
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
TALER_denom_sig_unblind (&lci->sig,
|
TALER_denom_sig_unblind (&lci->sig,
|
||||||
|
@ -328,6 +328,25 @@ TALER_EXCHANGE_recoup (struct TALER_EXCHANGE_Handle *exchange,
|
|||||||
&coin_sig),
|
&coin_sig),
|
||||||
GNUNET_JSON_pack_data_auto ("coin_blind_key_secret",
|
GNUNET_JSON_pack_data_auto ("coin_blind_key_secret",
|
||||||
&bks));
|
&bks));
|
||||||
|
if (TALER_DENOMINATION_CS == denom_sig->cipher)
|
||||||
|
{
|
||||||
|
struct TALER_CsNonce nonce;
|
||||||
|
|
||||||
|
// FIXME: add this to the spec!
|
||||||
|
/* NOTE: this is not elegant, and as per the note in TALER_coin_ev_hash()
|
||||||
|
it is not strictly clear that the nonce is needed. Best case would be
|
||||||
|
to find a way to include it more 'naturally' somehow, for example with
|
||||||
|
the variant union version of bks! */
|
||||||
|
TALER_cs_withdraw_nonce_derive (ps,
|
||||||
|
&nonce);
|
||||||
|
GNUNET_assert (
|
||||||
|
0 ==
|
||||||
|
json_object_set_new (recoup_obj,
|
||||||
|
"cs_nonce",
|
||||||
|
GNUNET_JSON_from_data_auto (
|
||||||
|
&nonce)));
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
char pub_str[sizeof (struct TALER_CoinSpendPublicKeyP) * 2];
|
char pub_str[sizeof (struct TALER_CoinSpendPublicKeyP) * 2];
|
||||||
char *end;
|
char *end;
|
||||||
|
@ -332,6 +332,27 @@ TALER_EXCHANGE_recoup_refresh (
|
|||||||
&coin_sig),
|
&coin_sig),
|
||||||
GNUNET_JSON_pack_data_auto ("coin_blind_key_secret",
|
GNUNET_JSON_pack_data_auto ("coin_blind_key_secret",
|
||||||
&bks));
|
&bks));
|
||||||
|
|
||||||
|
if (TALER_DENOMINATION_CS == denom_sig->cipher)
|
||||||
|
{
|
||||||
|
struct TALER_CsNonce nonce;
|
||||||
|
|
||||||
|
// FIXME: add this to the spec!
|
||||||
|
/* NOTE: this is not elegant, and as per the note in TALER_coin_ev_hash()
|
||||||
|
it is not strictly clear that the nonce is needed. Best case would be
|
||||||
|
to find a way to include it more 'naturally' somehow, for example with
|
||||||
|
the variant union version of bks! */
|
||||||
|
TALER_cs_refresh_nonce_derive (rms,
|
||||||
|
idx,
|
||||||
|
&nonce);
|
||||||
|
GNUNET_assert (
|
||||||
|
0 ==
|
||||||
|
json_object_set_new (recoup_obj,
|
||||||
|
"cs_nonce",
|
||||||
|
GNUNET_JSON_from_data_auto (
|
||||||
|
&nonce)));
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
char pub_str[sizeof (struct TALER_CoinSpendPublicKeyP) * 2];
|
char pub_str[sizeof (struct TALER_CoinSpendPublicKeyP) * 2];
|
||||||
char *end;
|
char *end;
|
||||||
|
@ -806,18 +806,16 @@ TALER_coin_ev_hash (const struct TALER_BlindedPlanchet *blinded_planchet,
|
|||||||
blinded_planchet->details.rsa_blinded_planchet.blinded_msg_size);
|
blinded_planchet->details.rsa_blinded_planchet.blinded_msg_size);
|
||||||
break;
|
break;
|
||||||
case TALER_DENOMINATION_CS:
|
case TALER_DENOMINATION_CS:
|
||||||
|
// FIMXE: c-values MUST NOT be included in idempotency check
|
||||||
|
// during withdraw/refresh, but right now they are!!!
|
||||||
GNUNET_CRYPTO_hash_context_read (
|
GNUNET_CRYPTO_hash_context_read (
|
||||||
hash_context,
|
hash_context,
|
||||||
&blinded_planchet->details.cs_blinded_planchet.c[0],
|
&blinded_planchet->details.cs_blinded_planchet.c[0],
|
||||||
sizeof (struct GNUNET_CRYPTO_CsC) * 2);
|
sizeof (struct GNUNET_CRYPTO_CsC) * 2);
|
||||||
#if FIXME
|
|
||||||
/* Must include this for refresh check, but
|
|
||||||
must EXCLUDE this in link signature (see TALER_LinkDataPS!) */
|
|
||||||
GNUNET_CRYPTO_hash_context_read (
|
GNUNET_CRYPTO_hash_context_read (
|
||||||
hash_context,
|
hash_context,
|
||||||
&blinded_planchet->details.cs_blinded_planchet.nonce,
|
&blinded_planchet->details.cs_blinded_planchet.nonce,
|
||||||
sizeof (struct TALER_CsNonce));
|
sizeof (struct TALER_CsNonce));
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
GNUNET_break (0);
|
GNUNET_break (0);
|
||||||
|
Loading…
Reference in New Issue
Block a user