-address misc. fixmes
This commit is contained in:
parent
3b1e742dde
commit
94a5359494
@ -508,12 +508,7 @@ handle_reserve_out (void *cls,
|
|||||||
struct GNUNET_TIME_Timestamp valid_start;
|
struct GNUNET_TIME_Timestamp valid_start;
|
||||||
struct GNUNET_TIME_Timestamp expire_withdraw;
|
struct GNUNET_TIME_Timestamp expire_withdraw;
|
||||||
enum GNUNET_DB_QueryStatus qs;
|
enum GNUNET_DB_QueryStatus qs;
|
||||||
struct TALER_WithdrawRequestPS wsrd = {
|
struct TALER_DenominationHash h_denom_pub;
|
||||||
.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW),
|
|
||||||
.purpose.size = htonl (sizeof (wsrd)),
|
|
||||||
.reserve_pub = *reserve_pub,
|
|
||||||
.h_coin_envelope = *h_blind_ev
|
|
||||||
};
|
|
||||||
|
|
||||||
/* should be monotonically increasing */
|
/* should be monotonically increasing */
|
||||||
GNUNET_assert (rowid >= ppr.last_reserve_out_serial_id);
|
GNUNET_assert (rowid >= ppr.last_reserve_out_serial_id);
|
||||||
@ -523,7 +518,7 @@ handle_reserve_out (void *cls,
|
|||||||
initializes wsrd.h_denomination_pub! */
|
initializes wsrd.h_denomination_pub! */
|
||||||
qs = TALER_ARL_get_denomination_info (denom_pub,
|
qs = TALER_ARL_get_denomination_info (denom_pub,
|
||||||
&issue,
|
&issue,
|
||||||
&wsrd.h_denomination_pub);
|
&h_denom_pub);
|
||||||
if (0 > qs)
|
if (0 > qs)
|
||||||
{
|
{
|
||||||
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
|
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
|
||||||
@ -569,17 +564,16 @@ handle_reserve_out (void *cls,
|
|||||||
GNUNET_JSON_pack_data_auto ("reserve_pub",
|
GNUNET_JSON_pack_data_auto ("reserve_pub",
|
||||||
reserve_pub),
|
reserve_pub),
|
||||||
GNUNET_JSON_pack_data_auto ("denompub_h",
|
GNUNET_JSON_pack_data_auto ("denompub_h",
|
||||||
&wsrd.h_denomination_pub)));
|
&h_denom_pub)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check reserve_sig (first: setup remaining members of wsrd) */
|
/* check reserve_sig (first: setup remaining members of wsrd) */
|
||||||
TALER_amount_hton (&wsrd.amount_with_fee,
|
|
||||||
amount_with_fee);
|
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW,
|
TALER_wallet_withdraw_verify (&h_denom_pub,
|
||||||
&wsrd,
|
amount_with_fee,
|
||||||
&reserve_sig->eddsa_signature,
|
h_blind_ev,
|
||||||
&reserve_pub->eddsa_pub))
|
reserve_pub,
|
||||||
|
reserve_sig))
|
||||||
{
|
{
|
||||||
TALER_ARL_report (report_bad_sig_losses,
|
TALER_ARL_report (report_bad_sig_losses,
|
||||||
GNUNET_JSON_PACK (
|
GNUNET_JSON_PACK (
|
||||||
|
@ -90,10 +90,21 @@ reply_withdraw_insufficient_funds (
|
|||||||
*/
|
*/
|
||||||
struct WithdrawContext
|
struct WithdrawContext
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Details about the withdrawal request.
|
* Hash of the (blinded) message to be signed by the Exchange.
|
||||||
*/
|
*/
|
||||||
struct TALER_WithdrawRequestPS wsrd;
|
struct TALER_BlindedCoinHash h_coin_envelope;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Value of the coin being exchanged (matching the denomination key)
|
||||||
|
* plus the transaction fee. We include this in what is being
|
||||||
|
* signed so that we can verify a reserve's remaining total balance
|
||||||
|
* without needing to access the respective denomination key
|
||||||
|
* information each time.
|
||||||
|
*/
|
||||||
|
struct TALER_Amount amount_with_fee;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Blinded planchet.
|
* Blinded planchet.
|
||||||
@ -143,8 +154,6 @@ withdraw_transaction (void *cls,
|
|||||||
uint64_t ruuid;
|
uint64_t ruuid;
|
||||||
|
|
||||||
now = GNUNET_TIME_timestamp_get ();
|
now = GNUNET_TIME_timestamp_get ();
|
||||||
wc->collectable.reserve_pub = wc->wsrd.reserve_pub;
|
|
||||||
wc->collectable.h_coin_envelope = wc->wsrd.h_coin_envelope;
|
|
||||||
qs = TEH_plugin->do_withdraw (TEH_plugin->cls,
|
qs = TEH_plugin->do_withdraw (TEH_plugin->cls,
|
||||||
&wc->collectable,
|
&wc->collectable,
|
||||||
now,
|
now,
|
||||||
@ -173,7 +182,6 @@ withdraw_transaction (void *cls,
|
|||||||
{
|
{
|
||||||
struct TALER_EXCHANGEDB_ReserveHistory *rh;
|
struct TALER_EXCHANGEDB_ReserveHistory *rh;
|
||||||
struct TALER_Amount balance;
|
struct TALER_Amount balance;
|
||||||
struct TALER_Amount requested_amount;
|
|
||||||
|
|
||||||
TEH_plugin->rollback (TEH_plugin->cls);
|
TEH_plugin->rollback (TEH_plugin->cls);
|
||||||
// FIXME: maybe start read-committed here?
|
// FIXME: maybe start read-committed here?
|
||||||
@ -192,7 +200,7 @@ withdraw_transaction (void *cls,
|
|||||||
/* The reserve does not have the required amount (actual
|
/* The reserve does not have the required amount (actual
|
||||||
* amount + withdraw fee) */
|
* amount + withdraw fee) */
|
||||||
qs = TEH_plugin->get_reserve_history (TEH_plugin->cls,
|
qs = TEH_plugin->get_reserve_history (TEH_plugin->cls,
|
||||||
&wc->wsrd.reserve_pub,
|
&wc->collectable.reserve_pub,
|
||||||
&balance,
|
&balance,
|
||||||
&rh);
|
&rh);
|
||||||
if (NULL == rh)
|
if (NULL == rh)
|
||||||
@ -204,12 +212,11 @@ withdraw_transaction (void *cls,
|
|||||||
"reserve history");
|
"reserve history");
|
||||||
return GNUNET_DB_STATUS_HARD_ERROR;
|
return GNUNET_DB_STATUS_HARD_ERROR;
|
||||||
}
|
}
|
||||||
TALER_amount_ntoh (&requested_amount,
|
*mhd_ret = reply_withdraw_insufficient_funds (
|
||||||
&wc->wsrd.amount_with_fee);
|
connection,
|
||||||
*mhd_ret = reply_withdraw_insufficient_funds (connection,
|
&balance,
|
||||||
&balance,
|
&wc->collectable.amount_with_fee,
|
||||||
&requested_amount,
|
rh);
|
||||||
rh);
|
|
||||||
TEH_plugin->free_reserve_history (TEH_plugin->cls,
|
TEH_plugin->free_reserve_history (TEH_plugin->cls,
|
||||||
rh);
|
rh);
|
||||||
return GNUNET_DB_STATUS_HARD_ERROR;
|
return GNUNET_DB_STATUS_HARD_ERROR;
|
||||||
@ -287,7 +294,7 @@ check_request_idempotent (struct TEH_RequestContext *rc,
|
|||||||
enum GNUNET_DB_QueryStatus qs;
|
enum GNUNET_DB_QueryStatus qs;
|
||||||
|
|
||||||
qs = TEH_plugin->get_withdraw_info (TEH_plugin->cls,
|
qs = TEH_plugin->get_withdraw_info (TEH_plugin->cls,
|
||||||
&wc->wsrd.h_coin_envelope,
|
&wc->collectable.h_coin_envelope,
|
||||||
&wc->collectable);
|
&wc->collectable);
|
||||||
if (0 > qs)
|
if (0 > qs)
|
||||||
{
|
{
|
||||||
@ -336,8 +343,8 @@ TEH_handler_withdraw (struct TEH_RequestContext *rc,
|
|||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
GNUNET_STRINGS_string_to_data (args[0],
|
GNUNET_STRINGS_string_to_data (args[0],
|
||||||
strlen (args[0]),
|
strlen (args[0]),
|
||||||
&wc.wsrd.reserve_pub,
|
&wc.collectable.reserve_pub,
|
||||||
sizeof (wc.wsrd.reserve_pub)))
|
sizeof (wc.collectable.reserve_pub)))
|
||||||
{
|
{
|
||||||
GNUNET_break_op (0);
|
GNUNET_break_op (0);
|
||||||
return TALER_MHD_reply_with_error (rc->connection,
|
return TALER_MHD_reply_with_error (rc->connection,
|
||||||
@ -460,21 +467,11 @@ TEH_handler_withdraw (struct TEH_RequestContext *rc,
|
|||||||
TALER_EC_EXCHANGE_WITHDRAW_AMOUNT_FEE_OVERFLOW,
|
TALER_EC_EXCHANGE_WITHDRAW_AMOUNT_FEE_OVERFLOW,
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
TALER_amount_hton (&wc.wsrd.amount_with_fee,
|
|
||||||
&wc.collectable.amount_with_fee);
|
|
||||||
|
|
||||||
// FIXME: move this logic into libtalerutil!
|
|
||||||
/* verify signature! */
|
|
||||||
wc.wsrd.purpose.size
|
|
||||||
= htonl (sizeof (wc.wsrd));
|
|
||||||
wc.wsrd.purpose.purpose
|
|
||||||
= htonl (TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW);
|
|
||||||
wc.wsrd.h_denomination_pub
|
|
||||||
= wc.collectable.denom_pub_hash;
|
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
TALER_coin_ev_hash (&wc.blinded_planchet,
|
TALER_coin_ev_hash (&wc.blinded_planchet,
|
||||||
&wc.collectable.denom_pub_hash,
|
&wc.collectable.denom_pub_hash,
|
||||||
&wc.wsrd.h_coin_envelope))
|
&wc.collectable.h_coin_envelope))
|
||||||
{
|
{
|
||||||
GNUNET_break (0);
|
GNUNET_break (0);
|
||||||
GNUNET_JSON_parse_free (spec);
|
GNUNET_JSON_parse_free (spec);
|
||||||
@ -483,15 +480,15 @@ TEH_handler_withdraw (struct TEH_RequestContext *rc,
|
|||||||
TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE,
|
TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE,
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
GNUNET_CRYPTO_eddsa_verify (
|
TALER_wallet_withdraw_verify (&wc.collectable.denom_pub_hash,
|
||||||
TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW,
|
&wc.collectable.amount_with_fee,
|
||||||
&wc.wsrd,
|
&wc.collectable.h_coin_envelope,
|
||||||
&wc.collectable.reserve_sig.eddsa_signature,
|
&wc.collectable.reserve_pub,
|
||||||
&wc.wsrd.reserve_pub.eddsa_pub))
|
&wc.collectable.reserve_sig))
|
||||||
{
|
{
|
||||||
TALER_LOG_WARNING (
|
GNUNET_break_op (0);
|
||||||
"Client supplied invalid signature for withdraw request\n");
|
|
||||||
GNUNET_JSON_parse_free (spec);
|
GNUNET_JSON_parse_free (spec);
|
||||||
return TALER_MHD_reply_with_error (rc->connection,
|
return TALER_MHD_reply_with_error (rc->connection,
|
||||||
MHD_HTTP_FORBIDDEN,
|
MHD_HTTP_FORBIDDEN,
|
||||||
|
@ -857,9 +857,6 @@ struct TALER_BlindedCsPlanchet
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Public nonce.
|
* Public nonce.
|
||||||
* FIXME: this nonce being here has created TONS
|
|
||||||
* of trouble. Likely split off from this data
|
|
||||||
* structure in the future!
|
|
||||||
*/
|
*/
|
||||||
struct TALER_CsNonce nonce;
|
struct TALER_CsNonce nonce;
|
||||||
};
|
};
|
||||||
@ -1085,31 +1082,12 @@ void
|
|||||||
TALER_denom_sig_free (struct TALER_DenominationSignature *denom_sig);
|
TALER_denom_sig_free (struct TALER_DenominationSignature *denom_sig);
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Function for CS signatures to derive public R_0 and R_1
|
|
||||||
*
|
|
||||||
* @param nonce withdraw nonce from a client
|
|
||||||
* @param denom_priv denomination privkey as long-term secret
|
|
||||||
* @param r_pub the resulting R_0 and R_1
|
|
||||||
* @return enum GNUNET_GenericReturnValue
|
|
||||||
*/
|
|
||||||
enum GNUNET_GenericReturnValue
|
|
||||||
TALER_denom_cs_derive_r_public (
|
|
||||||
const struct TALER_CsNonce *nonce,
|
|
||||||
const struct TALER_DenominationPrivateKey *denom_priv,
|
|
||||||
struct TALER_DenominationCSPublicRPairP *r_pub);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Blind coin for blind signing with @a dk using blinding secret @a coin_bks.
|
* Blind coin for blind signing with @a dk using blinding secret @a coin_bks.
|
||||||
*
|
*
|
||||||
* NOTE/FIXME: As a particular oddity, the @a blinded_planchet
|
* NOTE: As a particular oddity, the @a blinded_planchet is only partially
|
||||||
* is only partially initialized by this function in the
|
* initialized by this function in the case of CS-denominations. Here, the
|
||||||
* case of CS-denominations. Here, the 'nonce' must
|
* 'nonce' must be initialized separately!
|
||||||
* be initialized separately! This has been a MAJOR
|
|
||||||
* source of bugs, and points to a likely need for a
|
|
||||||
* reorganization of either that data structure or
|
|
||||||
* this function!
|
|
||||||
*
|
*
|
||||||
* @param dk denomination public key to blind for
|
* @param dk denomination public key to blind for
|
||||||
* @param coin_bks blinding secret to use
|
* @param coin_bks blinding secret to use
|
||||||
@ -1564,8 +1542,8 @@ TALER_planchet_blinding_secret_create (
|
|||||||
* @param coin_priv coin private key
|
* @param coin_priv coin private key
|
||||||
* @param[out] c_hash set to the hash of the public key of the coin (needed later)
|
* @param[out] c_hash set to the hash of the public key of the coin (needed later)
|
||||||
* @param[out] pd set to the planchet detail for TALER_MERCHANT_tip_pickup() and
|
* @param[out] pd set to the planchet detail for TALER_MERCHANT_tip_pickup() and
|
||||||
* other withdraw operations, pd->blinded_planchet.cipher will be set
|
* other withdraw operations, `pd->blinded_planchet.cipher` will be set
|
||||||
* to cipher from dk
|
* to cipher from @a dk
|
||||||
* @return #GNUNET_OK on success
|
* @return #GNUNET_OK on success
|
||||||
*/
|
*/
|
||||||
enum GNUNET_GenericReturnValue
|
enum GNUNET_GenericReturnValue
|
||||||
@ -1574,8 +1552,7 @@ TALER_planchet_prepare (const struct TALER_DenominationPublicKey *dk,
|
|||||||
const union TALER_DenominationBlindingKeyP *bks,
|
const union TALER_DenominationBlindingKeyP *bks,
|
||||||
const struct TALER_CoinSpendPrivateKeyP *coin_priv,
|
const struct TALER_CoinSpendPrivateKeyP *coin_priv,
|
||||||
struct TALER_CoinPubHash *c_hash,
|
struct TALER_CoinPubHash *c_hash,
|
||||||
struct TALER_PlanchetDetail *pd
|
struct TALER_PlanchetDetail *pd);
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2316,6 +2293,43 @@ TALER_wallet_link_verify (
|
|||||||
const struct TALER_CoinSpendSignatureP *coin_sig);
|
const struct TALER_CoinSpendSignatureP *coin_sig);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sign withdraw request.
|
||||||
|
*
|
||||||
|
* @param h_denom_pub hash of the denomiantion public key of the coin to withdraw
|
||||||
|
* @param amount_with_fee amount to debit the reserve for
|
||||||
|
* @param bch blinded coin hash
|
||||||
|
* @param reserve_priv private key to sign with
|
||||||
|
* @param[out] reserve_sig resulting signature
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
TALER_wallet_withdraw_sign (
|
||||||
|
const struct TALER_DenominationHash *h_denom_pub,
|
||||||
|
const struct TALER_Amount *amount_with_fee,
|
||||||
|
const struct TALER_BlindedCoinHash *bch,
|
||||||
|
const struct TALER_ReservePrivateKeyP *reserve_priv,
|
||||||
|
struct TALER_ReserveSignatureP *reserve_sig);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verify withdraw request.
|
||||||
|
*
|
||||||
|
* @param h_denom_pub hash of the denomiantion public key of the coin to withdraw
|
||||||
|
* @param amount_with_fee amount to debit the reserve for
|
||||||
|
* @param bch blinded coin hash
|
||||||
|
* @param reserve_pub public key of the reserve
|
||||||
|
* @param reserve_sig resulting signature
|
||||||
|
* @return #GNUNET_OK if the signature is valid
|
||||||
|
*/
|
||||||
|
enum GNUNET_GenericReturnValue
|
||||||
|
TALER_wallet_withdraw_verify (
|
||||||
|
const struct TALER_DenominationHash *h_denom_pub,
|
||||||
|
const struct TALER_Amount *amount_with_fee,
|
||||||
|
const struct TALER_BlindedCoinHash *bch,
|
||||||
|
const struct TALER_ReservePublicKeyP *reserve_pub,
|
||||||
|
const struct TALER_ReserveSignatureP *reserve_sig);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify recoup signature.
|
* Verify recoup signature.
|
||||||
*
|
*
|
||||||
|
@ -440,13 +440,7 @@ struct TALER_WithdrawRequestPS
|
|||||||
struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
|
struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reserve public key (which reserve to withdraw from). This is
|
* Value of the coin being exchanged (matching the denomination key)
|
||||||
* the public key which must match the signature.
|
|
||||||
*/
|
|
||||||
struct TALER_ReservePublicKeyP reserve_pub;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Value of the coin being exchangeed (matching the denomination key)
|
|
||||||
* plus the transaction fee. We include this in what is being
|
* plus the transaction fee. We include this in what is being
|
||||||
* signed so that we can verify a reserve's remaining total balance
|
* signed so that we can verify a reserve's remaining total balance
|
||||||
* without needing to access the respective denomination key
|
* without needing to access the respective denomination key
|
||||||
|
@ -124,7 +124,8 @@ TALER_EXCHANGE_parse_reserve_history (
|
|||||||
"WITHDRAW"))
|
"WITHDRAW"))
|
||||||
{
|
{
|
||||||
struct TALER_ReserveSignatureP sig;
|
struct TALER_ReserveSignatureP sig;
|
||||||
struct TALER_WithdrawRequestPS withdraw_purpose;
|
struct TALER_DenominationHash h_denom_pub;
|
||||||
|
struct TALER_BlindedCoinHash bch;
|
||||||
struct TALER_Amount withdraw_fee;
|
struct TALER_Amount withdraw_fee;
|
||||||
struct GNUNET_JSON_Specification withdraw_spec[] = {
|
struct GNUNET_JSON_Specification withdraw_spec[] = {
|
||||||
GNUNET_JSON_spec_fixed_auto ("reserve_sig",
|
GNUNET_JSON_spec_fixed_auto ("reserve_sig",
|
||||||
@ -132,9 +133,9 @@ TALER_EXCHANGE_parse_reserve_history (
|
|||||||
TALER_JSON_spec_amount_any ("withdraw_fee",
|
TALER_JSON_spec_amount_any ("withdraw_fee",
|
||||||
&withdraw_fee),
|
&withdraw_fee),
|
||||||
GNUNET_JSON_spec_fixed_auto ("h_denom_pub",
|
GNUNET_JSON_spec_fixed_auto ("h_denom_pub",
|
||||||
&withdraw_purpose.h_denomination_pub),
|
&h_denom_pub),
|
||||||
GNUNET_JSON_spec_fixed_auto ("h_coin_envelope",
|
GNUNET_JSON_spec_fixed_auto ("h_coin_envelope",
|
||||||
&withdraw_purpose.h_coin_envelope),
|
&bch),
|
||||||
GNUNET_JSON_spec_end ()
|
GNUNET_JSON_spec_end ()
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -147,19 +148,14 @@ TALER_EXCHANGE_parse_reserve_history (
|
|||||||
GNUNET_break_op (0);
|
GNUNET_break_op (0);
|
||||||
return GNUNET_SYSERR;
|
return GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
withdraw_purpose.purpose.size
|
|
||||||
= htonl (sizeof (withdraw_purpose));
|
|
||||||
withdraw_purpose.purpose.purpose
|
|
||||||
= htonl (TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW);
|
|
||||||
withdraw_purpose.reserve_pub = *reserve_pub;
|
|
||||||
TALER_amount_hton (&withdraw_purpose.amount_with_fee,
|
|
||||||
&amount);
|
|
||||||
/* Check that the signature is a valid withdraw request */
|
/* Check that the signature is a valid withdraw request */
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW,
|
TALER_wallet_withdraw_verify (&h_denom_pub,
|
||||||
&withdraw_purpose,
|
&amount,
|
||||||
&sig.eddsa_signature,
|
&bch,
|
||||||
&reserve_pub->eddsa_pub))
|
reserve_pub,
|
||||||
|
&sig))
|
||||||
{
|
{
|
||||||
GNUNET_break_op (0);
|
GNUNET_break_op (0);
|
||||||
GNUNET_JSON_parse_free (withdraw_spec);
|
GNUNET_JSON_parse_free (withdraw_spec);
|
||||||
@ -172,8 +168,7 @@ TALER_EXCHANGE_parse_reserve_history (
|
|||||||
|
|
||||||
key_state = TALER_EXCHANGE_get_keys (exchange);
|
key_state = TALER_EXCHANGE_get_keys (exchange);
|
||||||
dki = TALER_EXCHANGE_get_denomination_key_by_hash (key_state,
|
dki = TALER_EXCHANGE_get_denomination_key_by_hash (key_state,
|
||||||
&withdraw_purpose.
|
&h_denom_pub);
|
||||||
h_denomination_pub);
|
|
||||||
if ( (GNUNET_YES !=
|
if ( (GNUNET_YES !=
|
||||||
TALER_amount_cmp_currency (&withdraw_fee,
|
TALER_amount_cmp_currency (&withdraw_fee,
|
||||||
&dki->fee_withdraw)) ||
|
&dki->fee_withdraw)) ||
|
||||||
@ -193,10 +188,10 @@ TALER_EXCHANGE_parse_reserve_history (
|
|||||||
/* Check check that the same withdraw transaction
|
/* Check check that the same withdraw transaction
|
||||||
isn't listed twice by the exchange. We use the
|
isn't listed twice by the exchange. We use the
|
||||||
"uuid" array to remember the hashes of all
|
"uuid" array to remember the hashes of all
|
||||||
purposes, and compare the hashes to find
|
signatures, and compare the hashes to find
|
||||||
duplicates. *///
|
duplicates. */
|
||||||
GNUNET_CRYPTO_hash (&withdraw_purpose,
|
GNUNET_CRYPTO_hash (&sig,
|
||||||
ntohl (withdraw_purpose.purpose.size),
|
sizeof (sig),
|
||||||
&uuid[uuid_off]);
|
&uuid[uuid_off]);
|
||||||
for (unsigned int i = 0; i<uuid_off; i++)
|
for (unsigned int i = 0; i<uuid_off; i++)
|
||||||
{
|
{
|
||||||
|
@ -399,10 +399,11 @@ TALER_EXCHANGE_refreshes_reveal (
|
|||||||
TALER_planchet_blinding_secret_create (&coin_ps,
|
TALER_planchet_blinding_secret_create (&coin_ps,
|
||||||
&alg_values[i],
|
&alg_values[i],
|
||||||
&bks);
|
&bks);
|
||||||
TALER_cs_refresh_nonce_derive (
|
if (TALER_DENOMINATION_CS == alg_values[i].cipher)
|
||||||
rms,
|
TALER_cs_refresh_nonce_derive (
|
||||||
i,
|
rms,
|
||||||
&pd.blinded_planchet.details.cs_blinded_planchet.nonce);
|
i,
|
||||||
|
&pd.blinded_planchet.details.cs_blinded_planchet.nonce);
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
TALER_planchet_prepare (&md.fresh_pks[i],
|
TALER_planchet_prepare (&md.fresh_pks[i],
|
||||||
&alg_values[i],
|
&alg_values[i],
|
||||||
|
@ -380,6 +380,7 @@ TALER_EXCHANGE_withdraw2 (
|
|||||||
const struct TALER_EXCHANGE_DenomPublicKey *dk;
|
const struct TALER_EXCHANGE_DenomPublicKey *dk;
|
||||||
struct TALER_ReserveSignatureP reserve_sig;
|
struct TALER_ReserveSignatureP reserve_sig;
|
||||||
char arg_str[sizeof (struct TALER_ReservePublicKeyP) * 2 + 32];
|
char arg_str[sizeof (struct TALER_ReservePublicKeyP) * 2 + 32];
|
||||||
|
struct TALER_BlindedCoinHash bch;
|
||||||
|
|
||||||
keys = TALER_EXCHANGE_get_keys (exchange);
|
keys = TALER_EXCHANGE_get_keys (exchange);
|
||||||
if (NULL == keys)
|
if (NULL == keys)
|
||||||
@ -428,31 +429,22 @@ TALER_EXCHANGE_withdraw2 (
|
|||||||
"/reserves/%s/withdraw",
|
"/reserves/%s/withdraw",
|
||||||
pub_str);
|
pub_str);
|
||||||
}
|
}
|
||||||
// FIXME: move this to libtalerutil!
|
|
||||||
{
|
|
||||||
struct TALER_WithdrawRequestPS req = {
|
|
||||||
.purpose.size = htonl (sizeof (req)),
|
|
||||||
.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW),
|
|
||||||
.reserve_pub = wh->reserve_pub,
|
|
||||||
.h_denomination_pub = pd->denom_pub_hash
|
|
||||||
};
|
|
||||||
|
|
||||||
TALER_amount_hton (&req.amount_with_fee,
|
if (GNUNET_OK !=
|
||||||
&wh->requested_amount);
|
TALER_coin_ev_hash (&pd->blinded_planchet,
|
||||||
if (GNUNET_OK !=
|
&pd->denom_pub_hash,
|
||||||
TALER_coin_ev_hash (&pd->blinded_planchet,
|
&bch))
|
||||||
&pd->denom_pub_hash,
|
{
|
||||||
&req.h_coin_envelope))
|
GNUNET_break (0);
|
||||||
{
|
GNUNET_free (wh);
|
||||||
GNUNET_break (0);
|
return NULL;
|
||||||
GNUNET_free (wh);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
GNUNET_CRYPTO_eddsa_sign (&reserve_priv->eddsa_priv,
|
|
||||||
&req,
|
|
||||||
&reserve_sig.eddsa_signature);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TALER_wallet_withdraw_sign (&pd->denom_pub_hash,
|
||||||
|
&wh->requested_amount,
|
||||||
|
&bch,
|
||||||
|
reserve_priv,
|
||||||
|
&reserve_sig);
|
||||||
{
|
{
|
||||||
json_t *withdraw_obj = GNUNET_JSON_PACK (
|
json_t *withdraw_obj = GNUNET_JSON_PACK (
|
||||||
GNUNET_JSON_pack_data_auto ("denom_pub_hash",
|
GNUNET_JSON_pack_data_auto ("denom_pub_hash",
|
||||||
|
@ -246,90 +246,6 @@ TALER_cs_refresh_nonce_derive (
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
TALER_planchet_blinding_secret_create (
|
|
||||||
const struct TALER_PlanchetMasterSecretP *ps,
|
|
||||||
const struct TALER_ExchangeWithdrawValues *alg_values,
|
|
||||||
union TALER_DenominationBlindingKeyP *bks)
|
|
||||||
{
|
|
||||||
switch (alg_values->cipher)
|
|
||||||
{
|
|
||||||
case TALER_DENOMINATION_INVALID:
|
|
||||||
GNUNET_break (0);
|
|
||||||
return;
|
|
||||||
case TALER_DENOMINATION_RSA:
|
|
||||||
GNUNET_assert (GNUNET_YES ==
|
|
||||||
GNUNET_CRYPTO_kdf (&bks->rsa_bks,
|
|
||||||
sizeof (bks->rsa_bks),
|
|
||||||
"bks",
|
|
||||||
strlen ("bks"),
|
|
||||||
ps,
|
|
||||||
sizeof(*ps),
|
|
||||||
NULL,
|
|
||||||
0));
|
|
||||||
return;
|
|
||||||
case TALER_DENOMINATION_CS:
|
|
||||||
GNUNET_assert (GNUNET_YES ==
|
|
||||||
GNUNET_CRYPTO_kdf (&bks->nonce,
|
|
||||||
sizeof (bks->nonce),
|
|
||||||
"bseed",
|
|
||||||
strlen ("bseed"),
|
|
||||||
ps,
|
|
||||||
sizeof(*ps),
|
|
||||||
&alg_values->details.cs_values,
|
|
||||||
sizeof(alg_values->details.cs_values),
|
|
||||||
NULL,
|
|
||||||
0));
|
|
||||||
return;
|
|
||||||
default:
|
|
||||||
GNUNET_break (0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// FIXME: move to denom.c?
|
|
||||||
void
|
|
||||||
TALER_planchet_setup_coin_priv (
|
|
||||||
const struct TALER_PlanchetMasterSecretP *ps,
|
|
||||||
const struct TALER_ExchangeWithdrawValues *alg_values,
|
|
||||||
struct TALER_CoinSpendPrivateKeyP *coin_priv)
|
|
||||||
{
|
|
||||||
switch (alg_values->cipher)
|
|
||||||
{
|
|
||||||
case TALER_DENOMINATION_RSA:
|
|
||||||
GNUNET_assert (GNUNET_YES ==
|
|
||||||
GNUNET_CRYPTO_kdf (coin_priv,
|
|
||||||
sizeof (*coin_priv),
|
|
||||||
"coin",
|
|
||||||
strlen ("coin"),
|
|
||||||
ps,
|
|
||||||
sizeof(*ps),
|
|
||||||
NULL,
|
|
||||||
0));
|
|
||||||
break;
|
|
||||||
case TALER_DENOMINATION_CS:
|
|
||||||
GNUNET_assert (GNUNET_YES ==
|
|
||||||
GNUNET_CRYPTO_kdf (coin_priv,
|
|
||||||
sizeof (*coin_priv),
|
|
||||||
"coin",
|
|
||||||
strlen ("coin"),
|
|
||||||
ps,
|
|
||||||
sizeof(*ps),
|
|
||||||
&alg_values->details.cs_values,
|
|
||||||
sizeof(alg_values->details.cs_values),
|
|
||||||
NULL,
|
|
||||||
0));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
GNUNET_break (0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
coin_priv->eddsa_priv.d[0] &= 248;
|
|
||||||
coin_priv->eddsa_priv.d[31] &= 127;
|
|
||||||
coin_priv->eddsa_priv.d[31] |= 64;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
enum GNUNET_GenericReturnValue
|
enum GNUNET_GenericReturnValue
|
||||||
TALER_planchet_prepare (const struct TALER_DenominationPublicKey *dk,
|
TALER_planchet_prepare (const struct TALER_DenominationPublicKey *dk,
|
||||||
const struct TALER_ExchangeWithdrawValues *alg_values,
|
const struct TALER_ExchangeWithdrawValues *alg_values,
|
||||||
@ -369,26 +285,6 @@ TALER_planchet_detail_free (struct TALER_PlanchetDetail *pd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
TALER_blinded_planchet_free (struct TALER_BlindedPlanchet *blinded_planchet)
|
|
||||||
{
|
|
||||||
switch (blinded_planchet->cipher)
|
|
||||||
{
|
|
||||||
case TALER_DENOMINATION_RSA:
|
|
||||||
GNUNET_free (blinded_planchet->details.rsa_blinded_planchet.blinded_msg);
|
|
||||||
break;
|
|
||||||
case TALER_DENOMINATION_CS:
|
|
||||||
memset (blinded_planchet,
|
|
||||||
0,
|
|
||||||
sizeof (*blinded_planchet));
|
|
||||||
/* nothing to do for CS */
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
GNUNET_break (0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
enum GNUNET_GenericReturnValue
|
enum GNUNET_GenericReturnValue
|
||||||
TALER_planchet_to_coin (
|
TALER_planchet_to_coin (
|
||||||
const struct TALER_DenominationPublicKey *dk,
|
const struct TALER_DenominationPublicKey *dk,
|
||||||
@ -498,44 +394,6 @@ TALER_refresh_get_commitment (struct TALER_RefreshCommitmentP *rc,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
enum GNUNET_GenericReturnValue
|
|
||||||
TALER_coin_ev_hash (const struct TALER_BlindedPlanchet *blinded_planchet,
|
|
||||||
const struct TALER_DenominationHash *denom_hash,
|
|
||||||
struct TALER_BlindedCoinHash *bch)
|
|
||||||
{
|
|
||||||
struct GNUNET_HashContext *hash_context;
|
|
||||||
|
|
||||||
hash_context = GNUNET_CRYPTO_hash_context_start ();
|
|
||||||
GNUNET_CRYPTO_hash_context_read (hash_context,
|
|
||||||
denom_hash,
|
|
||||||
sizeof(*denom_hash));
|
|
||||||
switch (blinded_planchet->cipher)
|
|
||||||
{
|
|
||||||
case TALER_DENOMINATION_RSA:
|
|
||||||
GNUNET_CRYPTO_hash_context_read (
|
|
||||||
hash_context,
|
|
||||||
blinded_planchet->details.rsa_blinded_planchet.blinded_msg,
|
|
||||||
blinded_planchet->details.rsa_blinded_planchet.blinded_msg_size);
|
|
||||||
break;
|
|
||||||
case TALER_DENOMINATION_CS:
|
|
||||||
// FIXME: simplifies once 'nonce' is removed
|
|
||||||
// from TALER_BlindedCsPlanchet!
|
|
||||||
GNUNET_CRYPTO_hash_context_read (
|
|
||||||
hash_context,
|
|
||||||
&blinded_planchet->details.cs_blinded_planchet.c[0],
|
|
||||||
sizeof (struct GNUNET_CRYPTO_CsC) * 2);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
GNUNET_break (0);
|
|
||||||
GNUNET_CRYPTO_hash_context_abort (hash_context);
|
|
||||||
return GNUNET_SYSERR;
|
|
||||||
}
|
|
||||||
GNUNET_CRYPTO_hash_context_finish (hash_context,
|
|
||||||
&bch->hash);
|
|
||||||
return GNUNET_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
TALER_coin_pub_hash (const struct TALER_CoinSpendPublicKeyP *coin_pub,
|
TALER_coin_pub_hash (const struct TALER_CoinSpendPublicKeyP *coin_pub,
|
||||||
const struct TALER_AgeHash *age_commitment_hash,
|
const struct TALER_AgeHash *age_commitment_hash,
|
||||||
|
175
src/util/denom.c
175
src/util/denom.c
@ -82,28 +82,6 @@ TALER_denom_priv_create (struct TALER_DenominationPrivateKey *denom_priv,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
enum GNUNET_GenericReturnValue
|
|
||||||
TALER_denom_cs_derive_r_public (const struct TALER_CsNonce *nonce,
|
|
||||||
const struct
|
|
||||||
TALER_DenominationPrivateKey *denom_priv,
|
|
||||||
struct TALER_DenominationCSPublicRPairP *r_pub)
|
|
||||||
{
|
|
||||||
if (denom_priv->cipher != TALER_DENOMINATION_CS)
|
|
||||||
{
|
|
||||||
GNUNET_break (0);
|
|
||||||
return GNUNET_SYSERR;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct GNUNET_CRYPTO_CsRSecret r[2];
|
|
||||||
GNUNET_CRYPTO_cs_r_derive (&nonce->nonce,
|
|
||||||
&denom_priv->details.cs_private_key,
|
|
||||||
r);
|
|
||||||
GNUNET_CRYPTO_cs_r_get_public (&r[0], &r_pub->r_pub[0]);
|
|
||||||
GNUNET_CRYPTO_cs_r_get_public (&r[1], &r_pub->r_pub[1]);
|
|
||||||
return GNUNET_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
enum GNUNET_GenericReturnValue
|
enum GNUNET_GenericReturnValue
|
||||||
TALER_denom_sign_blinded (struct TALER_BlindedDenominationSignature *denom_sig,
|
TALER_denom_sign_blinded (struct TALER_BlindedDenominationSignature *denom_sig,
|
||||||
const struct TALER_DenominationPrivateKey *denom_priv,
|
const struct TALER_DenominationPrivateKey *denom_priv,
|
||||||
@ -112,13 +90,11 @@ TALER_denom_sign_blinded (struct TALER_BlindedDenominationSignature *denom_sig,
|
|||||||
memset (denom_sig,
|
memset (denom_sig,
|
||||||
0,
|
0,
|
||||||
sizeof (*denom_sig));
|
sizeof (*denom_sig));
|
||||||
|
|
||||||
if (blinded_planchet->cipher != denom_priv->cipher)
|
if (blinded_planchet->cipher != denom_priv->cipher)
|
||||||
{
|
{
|
||||||
GNUNET_break (0);
|
GNUNET_break (0);
|
||||||
return GNUNET_SYSERR;
|
return GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (denom_priv->cipher)
|
switch (denom_priv->cipher)
|
||||||
{
|
{
|
||||||
case TALER_DENOMINATION_INVALID:
|
case TALER_DENOMINATION_INVALID:
|
||||||
@ -140,11 +116,11 @@ TALER_denom_sign_blinded (struct TALER_BlindedDenominationSignature *denom_sig,
|
|||||||
case TALER_DENOMINATION_CS:
|
case TALER_DENOMINATION_CS:
|
||||||
{
|
{
|
||||||
struct GNUNET_CRYPTO_CsRSecret r[2];
|
struct GNUNET_CRYPTO_CsRSecret r[2];
|
||||||
|
|
||||||
GNUNET_CRYPTO_cs_r_derive (
|
GNUNET_CRYPTO_cs_r_derive (
|
||||||
&blinded_planchet->details.cs_blinded_planchet.nonce.nonce,
|
&blinded_planchet->details.cs_blinded_planchet.nonce.nonce,
|
||||||
&denom_priv->details.cs_private_key,
|
&denom_priv->details.cs_private_key,
|
||||||
r);
|
r);
|
||||||
|
|
||||||
denom_sig->details.blinded_cs_answer.b =
|
denom_sig->details.blinded_cs_answer.b =
|
||||||
GNUNET_CRYPTO_cs_sign_derive (&denom_priv->details.cs_private_key,
|
GNUNET_CRYPTO_cs_sign_derive (&denom_priv->details.cs_private_key,
|
||||||
r,
|
r,
|
||||||
@ -154,7 +130,6 @@ TALER_denom_sign_blinded (struct TALER_BlindedDenominationSignature *denom_sig,
|
|||||||
cs_blinded_planchet.nonce.nonce,
|
cs_blinded_planchet.nonce.nonce,
|
||||||
&denom_sig->details.blinded_cs_answer.
|
&denom_sig->details.blinded_cs_answer.
|
||||||
s_scalar);
|
s_scalar);
|
||||||
|
|
||||||
denom_sig->cipher = TALER_DENOMINATION_CS;
|
denom_sig->cipher = TALER_DENOMINATION_CS;
|
||||||
}
|
}
|
||||||
return GNUNET_OK;
|
return GNUNET_OK;
|
||||||
@ -268,8 +243,8 @@ TALER_denom_pub_hash (const struct TALER_DenominationPublicKey *denom_pub,
|
|||||||
htonl (denom_pub->age_mask.mask),
|
htonl (denom_pub->age_mask.mask),
|
||||||
htonl ((uint32_t) denom_pub->cipher)
|
htonl ((uint32_t) denom_pub->cipher)
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GNUNET_HashContext *hc;
|
struct GNUNET_HashContext *hc;
|
||||||
|
|
||||||
hc = GNUNET_CRYPTO_hash_context_start ();
|
hc = GNUNET_CRYPTO_hash_context_start ();
|
||||||
GNUNET_CRYPTO_hash_context_read (hc,
|
GNUNET_CRYPTO_hash_context_read (hc,
|
||||||
opt,
|
opt,
|
||||||
@ -444,7 +419,6 @@ TALER_denom_pub_free (struct TALER_DenominationPublicKey *denom_pub)
|
|||||||
denom_pub->cipher = TALER_DENOMINATION_INVALID;
|
denom_pub->cipher = TALER_DENOMINATION_INVALID;
|
||||||
return;
|
return;
|
||||||
case TALER_DENOMINATION_CS:
|
case TALER_DENOMINATION_CS:
|
||||||
// ATM nothing needs to be freed, but check again after implementation.
|
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
GNUNET_assert (0);
|
GNUNET_assert (0);
|
||||||
@ -468,7 +442,6 @@ TALER_denom_priv_free (struct TALER_DenominationPrivateKey *denom_priv)
|
|||||||
denom_priv->cipher = TALER_DENOMINATION_INVALID;
|
denom_priv->cipher = TALER_DENOMINATION_INVALID;
|
||||||
return;
|
return;
|
||||||
case TALER_DENOMINATION_CS:
|
case TALER_DENOMINATION_CS:
|
||||||
// ATM nothing needs to be freed, but check again after implementation.
|
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
GNUNET_assert (0);
|
GNUNET_assert (0);
|
||||||
@ -492,7 +465,6 @@ TALER_denom_sig_free (struct TALER_DenominationSignature *denom_sig)
|
|||||||
denom_sig->cipher = TALER_DENOMINATION_INVALID;
|
denom_sig->cipher = TALER_DENOMINATION_INVALID;
|
||||||
return;
|
return;
|
||||||
case TALER_DENOMINATION_CS:
|
case TALER_DENOMINATION_CS:
|
||||||
// ATM nothing needs to be freed, but check again after implementation.
|
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
GNUNET_assert (0);
|
GNUNET_assert (0);
|
||||||
@ -518,7 +490,6 @@ TALER_blinded_denom_sig_free (
|
|||||||
denom_sig->cipher = TALER_DENOMINATION_INVALID;
|
denom_sig->cipher = TALER_DENOMINATION_INVALID;
|
||||||
return;
|
return;
|
||||||
case TALER_DENOMINATION_CS:
|
case TALER_DENOMINATION_CS:
|
||||||
// ATM nothing needs to be freed, but check again after implementation.
|
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
GNUNET_assert (0);
|
GNUNET_assert (0);
|
||||||
@ -546,7 +517,6 @@ TALER_denom_pub_deep_copy (struct TALER_DenominationPublicKey *denom_dst,
|
|||||||
denom_src->details.rsa_public_key);
|
denom_src->details.rsa_public_key);
|
||||||
return;
|
return;
|
||||||
case TALER_DENOMINATION_CS:
|
case TALER_DENOMINATION_CS:
|
||||||
// In Case of CS, the above is already a deep copy *denom_dst = *denom_src;
|
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
GNUNET_assert (0);
|
GNUNET_assert (0);
|
||||||
@ -569,7 +539,6 @@ TALER_denom_sig_deep_copy (struct TALER_DenominationSignature *denom_dst,
|
|||||||
denom_src->details.rsa_signature);
|
denom_src->details.rsa_signature);
|
||||||
return;
|
return;
|
||||||
case TALER_DENOMINATION_CS:
|
case TALER_DENOMINATION_CS:
|
||||||
// In Case of CS, the above is already a deep copy *denom_dst = *denom_src;
|
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
GNUNET_assert (0);
|
GNUNET_assert (0);
|
||||||
@ -593,7 +562,6 @@ TALER_blinded_denom_sig_deep_copy (
|
|||||||
denom_src->details.blinded_rsa_signature);
|
denom_src->details.blinded_rsa_signature);
|
||||||
return;
|
return;
|
||||||
case TALER_DENOMINATION_CS:
|
case TALER_DENOMINATION_CS:
|
||||||
// In Case of CS, the above is already a deep copy *denom_dst = *denom_src;
|
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
GNUNET_assert (0);
|
GNUNET_assert (0);
|
||||||
@ -734,4 +702,143 @@ TALER_blinded_planchet_hash (const struct TALER_BlindedPlanchet *bp,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TALER_planchet_blinding_secret_create (
|
||||||
|
const struct TALER_PlanchetMasterSecretP *ps,
|
||||||
|
const struct TALER_ExchangeWithdrawValues *alg_values,
|
||||||
|
union TALER_DenominationBlindingKeyP *bks)
|
||||||
|
{
|
||||||
|
switch (alg_values->cipher)
|
||||||
|
{
|
||||||
|
case TALER_DENOMINATION_INVALID:
|
||||||
|
GNUNET_break (0);
|
||||||
|
return;
|
||||||
|
case TALER_DENOMINATION_RSA:
|
||||||
|
GNUNET_assert (GNUNET_YES ==
|
||||||
|
GNUNET_CRYPTO_kdf (&bks->rsa_bks,
|
||||||
|
sizeof (bks->rsa_bks),
|
||||||
|
"bks",
|
||||||
|
strlen ("bks"),
|
||||||
|
ps,
|
||||||
|
sizeof(*ps),
|
||||||
|
NULL,
|
||||||
|
0));
|
||||||
|
return;
|
||||||
|
case TALER_DENOMINATION_CS:
|
||||||
|
GNUNET_assert (GNUNET_YES ==
|
||||||
|
GNUNET_CRYPTO_kdf (&bks->nonce,
|
||||||
|
sizeof (bks->nonce),
|
||||||
|
"bseed",
|
||||||
|
strlen ("bseed"),
|
||||||
|
ps,
|
||||||
|
sizeof(*ps),
|
||||||
|
&alg_values->details.cs_values,
|
||||||
|
sizeof(alg_values->details.cs_values),
|
||||||
|
NULL,
|
||||||
|
0));
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
GNUNET_break (0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TALER_planchet_setup_coin_priv (
|
||||||
|
const struct TALER_PlanchetMasterSecretP *ps,
|
||||||
|
const struct TALER_ExchangeWithdrawValues *alg_values,
|
||||||
|
struct TALER_CoinSpendPrivateKeyP *coin_priv)
|
||||||
|
{
|
||||||
|
switch (alg_values->cipher)
|
||||||
|
{
|
||||||
|
case TALER_DENOMINATION_RSA:
|
||||||
|
GNUNET_assert (GNUNET_YES ==
|
||||||
|
GNUNET_CRYPTO_kdf (coin_priv,
|
||||||
|
sizeof (*coin_priv),
|
||||||
|
"coin",
|
||||||
|
strlen ("coin"),
|
||||||
|
ps,
|
||||||
|
sizeof(*ps),
|
||||||
|
NULL,
|
||||||
|
0));
|
||||||
|
break;
|
||||||
|
case TALER_DENOMINATION_CS:
|
||||||
|
GNUNET_assert (GNUNET_YES ==
|
||||||
|
GNUNET_CRYPTO_kdf (coin_priv,
|
||||||
|
sizeof (*coin_priv),
|
||||||
|
"coin",
|
||||||
|
strlen ("coin"),
|
||||||
|
ps,
|
||||||
|
sizeof(*ps),
|
||||||
|
&alg_values->details.cs_values,
|
||||||
|
sizeof(alg_values->details.cs_values),
|
||||||
|
NULL,
|
||||||
|
0));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
GNUNET_break (0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
coin_priv->eddsa_priv.d[0] &= 248;
|
||||||
|
coin_priv->eddsa_priv.d[31] &= 127;
|
||||||
|
coin_priv->eddsa_priv.d[31] |= 64;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TALER_blinded_planchet_free (struct TALER_BlindedPlanchet *blinded_planchet)
|
||||||
|
{
|
||||||
|
switch (blinded_planchet->cipher)
|
||||||
|
{
|
||||||
|
case TALER_DENOMINATION_RSA:
|
||||||
|
GNUNET_free (blinded_planchet->details.rsa_blinded_planchet.blinded_msg);
|
||||||
|
break;
|
||||||
|
case TALER_DENOMINATION_CS:
|
||||||
|
memset (blinded_planchet,
|
||||||
|
0,
|
||||||
|
sizeof (*blinded_planchet));
|
||||||
|
/* nothing to do for CS */
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
GNUNET_break (0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
enum GNUNET_GenericReturnValue
|
||||||
|
TALER_coin_ev_hash (const struct TALER_BlindedPlanchet *blinded_planchet,
|
||||||
|
const struct TALER_DenominationHash *denom_hash,
|
||||||
|
struct TALER_BlindedCoinHash *bch)
|
||||||
|
{
|
||||||
|
struct GNUNET_HashContext *hash_context;
|
||||||
|
|
||||||
|
hash_context = GNUNET_CRYPTO_hash_context_start ();
|
||||||
|
GNUNET_CRYPTO_hash_context_read (hash_context,
|
||||||
|
denom_hash,
|
||||||
|
sizeof(*denom_hash));
|
||||||
|
switch (blinded_planchet->cipher)
|
||||||
|
{
|
||||||
|
case TALER_DENOMINATION_RSA:
|
||||||
|
GNUNET_CRYPTO_hash_context_read (
|
||||||
|
hash_context,
|
||||||
|
blinded_planchet->details.rsa_blinded_planchet.blinded_msg,
|
||||||
|
blinded_planchet->details.rsa_blinded_planchet.blinded_msg_size);
|
||||||
|
break;
|
||||||
|
case TALER_DENOMINATION_CS:
|
||||||
|
GNUNET_CRYPTO_hash_context_read (
|
||||||
|
hash_context,
|
||||||
|
&blinded_planchet->details.cs_blinded_planchet.c[0],
|
||||||
|
sizeof (struct GNUNET_CRYPTO_CsC) * 2);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
GNUNET_break (0);
|
||||||
|
GNUNET_CRYPTO_hash_context_abort (hash_context);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
GNUNET_CRYPTO_hash_context_finish (hash_context,
|
||||||
|
&bch->hash);
|
||||||
|
return GNUNET_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* end of denom.c */
|
/* end of denom.c */
|
||||||
|
@ -281,7 +281,6 @@ handle_sign_request (struct TES_Client *client,
|
|||||||
{
|
{
|
||||||
struct DenominationKey *dk;
|
struct DenominationKey *dk;
|
||||||
struct GNUNET_CRYPTO_CsRSecret r[2];
|
struct GNUNET_CRYPTO_CsRSecret r[2];
|
||||||
|
|
||||||
struct TALER_BlindedDenominationCsSignAnswer cs_answer;
|
struct TALER_BlindedDenominationCsSignAnswer cs_answer;
|
||||||
struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ();
|
struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ();
|
||||||
|
|
||||||
@ -326,8 +325,9 @@ handle_sign_request (struct TES_Client *client,
|
|||||||
GNUNET_assert (dk->rc < UINT_MAX);
|
GNUNET_assert (dk->rc < UINT_MAX);
|
||||||
dk->rc++;
|
dk->rc++;
|
||||||
GNUNET_assert (0 == pthread_mutex_unlock (&keys_lock));
|
GNUNET_assert (0 == pthread_mutex_unlock (&keys_lock));
|
||||||
|
GNUNET_CRYPTO_cs_r_derive (&sr->planchet.nonce.nonce,
|
||||||
GNUNET_CRYPTO_cs_r_derive (&sr->planchet.nonce.nonce, &dk->denom_priv, r);
|
&dk->denom_priv,
|
||||||
|
r);
|
||||||
cs_answer.b = GNUNET_CRYPTO_cs_sign_derive (&dk->denom_priv,
|
cs_answer.b = GNUNET_CRYPTO_cs_sign_derive (&dk->denom_priv,
|
||||||
r,
|
r,
|
||||||
sr->planchet.c,
|
sr->planchet.c,
|
||||||
|
@ -175,6 +175,38 @@ test_planchets_rsa (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Function for CS signatures to derive public R_0 and R_1
|
||||||
|
*
|
||||||
|
* @param nonce withdraw nonce from a client
|
||||||
|
* @param denom_priv denomination privkey as long-term secret
|
||||||
|
* @param r_pub the resulting R_0 and R_1
|
||||||
|
* @return enum GNUNET_GenericReturnValue
|
||||||
|
*/
|
||||||
|
static enum GNUNET_GenericReturnValue
|
||||||
|
derive_r_public (
|
||||||
|
const struct TALER_CsNonce *nonce,
|
||||||
|
const struct TALER_DenominationPrivateKey *denom_priv,
|
||||||
|
struct TALER_DenominationCSPublicRPairP *r_pub)
|
||||||
|
{
|
||||||
|
struct GNUNET_CRYPTO_CsRSecret r[2];
|
||||||
|
|
||||||
|
if (denom_priv->cipher != TALER_DENOMINATION_CS)
|
||||||
|
{
|
||||||
|
GNUNET_break (0);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
GNUNET_CRYPTO_cs_r_derive (&nonce->nonce,
|
||||||
|
&denom_priv->details.cs_private_key,
|
||||||
|
r);
|
||||||
|
GNUNET_CRYPTO_cs_r_get_public (&r[0],
|
||||||
|
&r_pub->r_pub[0]);
|
||||||
|
GNUNET_CRYPTO_cs_r_get_public (&r[1],
|
||||||
|
&r_pub->r_pub[1]);
|
||||||
|
return GNUNET_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test the basic planchet functionality of creating a fresh planchet with CS denomination
|
* Test the basic planchet functionality of creating a fresh planchet with CS denomination
|
||||||
* and extracting the respective signature.
|
* and extracting the respective signature.
|
||||||
@ -207,7 +239,7 @@ test_planchets_cs (void)
|
|||||||
&ps,
|
&ps,
|
||||||
&pd.blinded_planchet.details.cs_blinded_planchet.nonce);
|
&pd.blinded_planchet.details.cs_blinded_planchet.nonce);
|
||||||
GNUNET_assert (GNUNET_OK ==
|
GNUNET_assert (GNUNET_OK ==
|
||||||
TALER_denom_cs_derive_r_public (
|
derive_r_public (
|
||||||
&pd.blinded_planchet.details.cs_blinded_planchet.nonce,
|
&pd.blinded_planchet.details.cs_blinded_planchet.nonce,
|
||||||
&dk_priv,
|
&dk_priv,
|
||||||
&alg_values.details.cs_values));
|
&alg_values.details.cs_values));
|
||||||
|
@ -285,4 +285,52 @@ TALER_wallet_melt_verify (
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TALER_wallet_withdraw_sign (
|
||||||
|
const struct TALER_DenominationHash *h_denom_pub,
|
||||||
|
const struct TALER_Amount *amount_with_fee,
|
||||||
|
const struct TALER_BlindedCoinHash *bch,
|
||||||
|
const struct TALER_ReservePrivateKeyP *reserve_priv,
|
||||||
|
struct TALER_ReserveSignatureP *reserve_sig)
|
||||||
|
{
|
||||||
|
struct TALER_WithdrawRequestPS req = {
|
||||||
|
.purpose.size = htonl (sizeof (req)),
|
||||||
|
.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW),
|
||||||
|
.h_denomination_pub = *h_denom_pub,
|
||||||
|
.h_coin_envelope = *bch
|
||||||
|
};
|
||||||
|
|
||||||
|
TALER_amount_hton (&req.amount_with_fee,
|
||||||
|
amount_with_fee);
|
||||||
|
GNUNET_CRYPTO_eddsa_sign (&reserve_priv->eddsa_priv,
|
||||||
|
&req,
|
||||||
|
&reserve_sig->eddsa_signature);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
enum GNUNET_GenericReturnValue
|
||||||
|
TALER_wallet_withdraw_verify (
|
||||||
|
const struct TALER_DenominationHash *h_denom_pub,
|
||||||
|
const struct TALER_Amount *amount_with_fee,
|
||||||
|
const struct TALER_BlindedCoinHash *bch,
|
||||||
|
const struct TALER_ReservePublicKeyP *reserve_pub,
|
||||||
|
const struct TALER_ReserveSignatureP *reserve_sig)
|
||||||
|
{
|
||||||
|
struct TALER_WithdrawRequestPS wsrd = {
|
||||||
|
.purpose.size = htonl (sizeof (wsrd)),
|
||||||
|
.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW),
|
||||||
|
.h_denomination_pub = *h_denom_pub,
|
||||||
|
.h_coin_envelope = *bch
|
||||||
|
};
|
||||||
|
|
||||||
|
TALER_amount_hton (&wsrd.amount_with_fee,
|
||||||
|
amount_with_fee);
|
||||||
|
return GNUNET_CRYPTO_eddsa_verify (
|
||||||
|
TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW,
|
||||||
|
&wsrd,
|
||||||
|
&reserve_sig->eddsa_signature,
|
||||||
|
&reserve_pub->eddsa_pub);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* end of wallet_signatures.c */
|
/* end of wallet_signatures.c */
|
||||||
|
Loading…
Reference in New Issue
Block a user