aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2022-02-12 00:52:19 +0100
committerChristian Grothoff <christian@grothoff.org>2022-02-12 00:52:19 +0100
commit94a5359494bcc24916c9f7f8323ace4643bc0065 (patch)
tree2d012532facb3d805487ad5bd9c07ebde2e1deb6
parent3b1e742dde4c386b38fc77147127b4bf6119d9e5 (diff)
downloadexchange-94a5359494bcc24916c9f7f8323ace4643bc0065.tar.xz
-address misc. fixmes
-rw-r--r--src/auditor/taler-helper-auditor-reserves.c22
-rw-r--r--src/exchange/taler-exchange-httpd_withdraw.c65
-rw-r--r--src/include/taler_crypto_lib.h72
-rw-r--r--src/include/taler_signatures.h8
-rw-r--r--src/lib/exchange_api_common.c35
-rw-r--r--src/lib/exchange_api_refreshes_reveal.c9
-rw-r--r--src/lib/exchange_api_withdraw2.c36
-rw-r--r--src/util/crypto.c142
-rw-r--r--src/util/denom.c175
-rw-r--r--src/util/taler-exchange-secmod-cs.c6
-rw-r--r--src/util/test_crypto.c34
-rw-r--r--src/util/wallet_signatures.c48
12 files changed, 342 insertions, 310 deletions
diff --git a/src/auditor/taler-helper-auditor-reserves.c b/src/auditor/taler-helper-auditor-reserves.c
index 610193187..e9cd51d8c 100644
--- a/src/auditor/taler-helper-auditor-reserves.c
+++ b/src/auditor/taler-helper-auditor-reserves.c
@@ -508,12 +508,7 @@ handle_reserve_out (void *cls,
struct GNUNET_TIME_Timestamp valid_start;
struct GNUNET_TIME_Timestamp expire_withdraw;
enum GNUNET_DB_QueryStatus qs;
- struct TALER_WithdrawRequestPS wsrd = {
- .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW),
- .purpose.size = htonl (sizeof (wsrd)),
- .reserve_pub = *reserve_pub,
- .h_coin_envelope = *h_blind_ev
- };
+ struct TALER_DenominationHash h_denom_pub;
/* should be monotonically increasing */
GNUNET_assert (rowid >= ppr.last_reserve_out_serial_id);
@@ -523,7 +518,7 @@ handle_reserve_out (void *cls,
initializes wsrd.h_denomination_pub! */
qs = TALER_ARL_get_denomination_info (denom_pub,
&issue,
- &wsrd.h_denomination_pub);
+ &h_denom_pub);
if (0 > 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",
reserve_pub),
GNUNET_JSON_pack_data_auto ("denompub_h",
- &wsrd.h_denomination_pub)));
+ &h_denom_pub)));
}
/* check reserve_sig (first: setup remaining members of wsrd) */
- TALER_amount_hton (&wsrd.amount_with_fee,
- amount_with_fee);
if (GNUNET_OK !=
- GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW,
- &wsrd,
- &reserve_sig->eddsa_signature,
- &reserve_pub->eddsa_pub))
+ TALER_wallet_withdraw_verify (&h_denom_pub,
+ amount_with_fee,
+ h_blind_ev,
+ reserve_pub,
+ reserve_sig))
{
TALER_ARL_report (report_bad_sig_losses,
GNUNET_JSON_PACK (
diff --git a/src/exchange/taler-exchange-httpd_withdraw.c b/src/exchange/taler-exchange-httpd_withdraw.c
index 8e4bbb475..8598f1322 100644
--- a/src/exchange/taler-exchange-httpd_withdraw.c
+++ b/src/exchange/taler-exchange-httpd_withdraw.c
@@ -90,10 +90,21 @@ reply_withdraw_insufficient_funds (
*/
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.
@@ -143,8 +154,6 @@ withdraw_transaction (void *cls,
uint64_t ruuid;
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,
&wc->collectable,
now,
@@ -173,7 +182,6 @@ withdraw_transaction (void *cls,
{
struct TALER_EXCHANGEDB_ReserveHistory *rh;
struct TALER_Amount balance;
- struct TALER_Amount requested_amount;
TEH_plugin->rollback (TEH_plugin->cls);
// FIXME: maybe start read-committed here?
@@ -192,7 +200,7 @@ withdraw_transaction (void *cls,
/* The reserve does not have the required amount (actual
* amount + withdraw fee) */
qs = TEH_plugin->get_reserve_history (TEH_plugin->cls,
- &wc->wsrd.reserve_pub,
+ &wc->collectable.reserve_pub,
&balance,
&rh);
if (NULL == rh)
@@ -204,12 +212,11 @@ withdraw_transaction (void *cls,
"reserve history");
return GNUNET_DB_STATUS_HARD_ERROR;
}
- TALER_amount_ntoh (&requested_amount,
- &wc->wsrd.amount_with_fee);
- *mhd_ret = reply_withdraw_insufficient_funds (connection,
- &balance,
- &requested_amount,
- rh);
+ *mhd_ret = reply_withdraw_insufficient_funds (
+ connection,
+ &balance,
+ &wc->collectable.amount_with_fee,
+ rh);
TEH_plugin->free_reserve_history (TEH_plugin->cls,
rh);
return GNUNET_DB_STATUS_HARD_ERROR;
@@ -287,7 +294,7 @@ check_request_idempotent (struct TEH_RequestContext *rc,
enum GNUNET_DB_QueryStatus qs;
qs = TEH_plugin->get_withdraw_info (TEH_plugin->cls,
- &wc->wsrd.h_coin_envelope,
+ &wc->collectable.h_coin_envelope,
&wc->collectable);
if (0 > qs)
{
@@ -336,8 +343,8 @@ TEH_handler_withdraw (struct TEH_RequestContext *rc,
if (GNUNET_OK !=
GNUNET_STRINGS_string_to_data (args[0],
strlen (args[0]),
- &wc.wsrd.reserve_pub,
- sizeof (wc.wsrd.reserve_pub)))
+ &wc.collectable.reserve_pub,
+ sizeof (wc.collectable.reserve_pub)))
{
GNUNET_break_op (0);
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,
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 !=
TALER_coin_ev_hash (&wc.blinded_planchet,
&wc.collectable.denom_pub_hash,
- &wc.wsrd.h_coin_envelope))
+ &wc.collectable.h_coin_envelope))
{
GNUNET_break (0);
GNUNET_JSON_parse_free (spec);
@@ -483,15 +480,15 @@ TEH_handler_withdraw (struct TEH_RequestContext *rc,
TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE,
NULL);
}
+
if (GNUNET_OK !=
- GNUNET_CRYPTO_eddsa_verify (
- TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW,
- &wc.wsrd,
- &wc.collectable.reserve_sig.eddsa_signature,
- &wc.wsrd.reserve_pub.eddsa_pub))
+ TALER_wallet_withdraw_verify (&wc.collectable.denom_pub_hash,
+ &wc.collectable.amount_with_fee,
+ &wc.collectable.h_coin_envelope,
+ &wc.collectable.reserve_pub,
+ &wc.collectable.reserve_sig))
{
- TALER_LOG_WARNING (
- "Client supplied invalid signature for withdraw request\n");
+ GNUNET_break_op (0);
GNUNET_JSON_parse_free (spec);
return TALER_MHD_reply_with_error (rc->connection,
MHD_HTTP_FORBIDDEN,
diff --git a/src/include/taler_crypto_lib.h b/src/include/taler_crypto_lib.h
index 5e531d90c..6f64de2ea 100644
--- a/src/include/taler_crypto_lib.h
+++ b/src/include/taler_crypto_lib.h
@@ -857,9 +857,6 @@ struct TALER_BlindedCsPlanchet
/**
* 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;
};
@@ -1086,30 +1083,11 @@ 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.
*
- * NOTE/FIXME: As a particular oddity, the @a blinded_planchet
- * is only partially initialized by this function in the
- * case of CS-denominations. Here, the 'nonce' must
- * 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!
+ * NOTE: As a particular oddity, the @a blinded_planchet is only partially
+ * initialized by this function in the case of CS-denominations. Here, the
+ * 'nonce' must be initialized separately!
*
* @param dk denomination public key to blind for
* @param coin_bks blinding secret to use
@@ -1564,8 +1542,8 @@ TALER_planchet_blinding_secret_create (
* @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] pd set to the planchet detail for TALER_MERCHANT_tip_pickup() and
- * other withdraw operations, pd->blinded_planchet.cipher will be set
- * to cipher from dk
+ * other withdraw operations, `pd->blinded_planchet.cipher` will be set
+ * to cipher from @a dk
* @return #GNUNET_OK on success
*/
enum GNUNET_GenericReturnValue
@@ -1574,8 +1552,7 @@ TALER_planchet_prepare (const struct TALER_DenominationPublicKey *dk,
const union TALER_DenominationBlindingKeyP *bks,
const struct TALER_CoinSpendPrivateKeyP *coin_priv,
struct TALER_CoinPubHash *c_hash,
- struct TALER_PlanchetDetail *pd
- );
+ struct TALER_PlanchetDetail *pd);
/**
@@ -2317,6 +2294,43 @@ TALER_wallet_link_verify (
/**
+ * 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.
*
* @param h_denom_pub hash of the denomiantion public key of the coin
diff --git a/src/include/taler_signatures.h b/src/include/taler_signatures.h
index 3c31a4b60..037955096 100644
--- a/src/include/taler_signatures.h
+++ b/src/include/taler_signatures.h
@@ -440,13 +440,7 @@ struct TALER_WithdrawRequestPS
struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
/**
- * Reserve public key (which reserve to withdraw from). This is
- * the public key which must match the signature.
- */
- struct TALER_ReservePublicKeyP reserve_pub;
-
- /**
- * Value of the coin being exchangeed (matching the denomination key)
+ * 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
diff --git a/src/lib/exchange_api_common.c b/src/lib/exchange_api_common.c
index 399eb280a..53a75a934 100644
--- a/src/lib/exchange_api_common.c
+++ b/src/lib/exchange_api_common.c
@@ -124,7 +124,8 @@ TALER_EXCHANGE_parse_reserve_history (
"WITHDRAW"))
{
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 GNUNET_JSON_Specification withdraw_spec[] = {
GNUNET_JSON_spec_fixed_auto ("reserve_sig",
@@ -132,9 +133,9 @@ TALER_EXCHANGE_parse_reserve_history (
TALER_JSON_spec_amount_any ("withdraw_fee",
&withdraw_fee),
GNUNET_JSON_spec_fixed_auto ("h_denom_pub",
- &withdraw_purpose.h_denomination_pub),
+ &h_denom_pub),
GNUNET_JSON_spec_fixed_auto ("h_coin_envelope",
- &withdraw_purpose.h_coin_envelope),
+ &bch),
GNUNET_JSON_spec_end ()
};
@@ -147,19 +148,14 @@ TALER_EXCHANGE_parse_reserve_history (
GNUNET_break_op (0);
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 */
if (GNUNET_OK !=
- GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW,
- &withdraw_purpose,
- &sig.eddsa_signature,
- &reserve_pub->eddsa_pub))
+ TALER_wallet_withdraw_verify (&h_denom_pub,
+ &amount,
+ &bch,
+ reserve_pub,
+ &sig))
{
GNUNET_break_op (0);
GNUNET_JSON_parse_free (withdraw_spec);
@@ -172,8 +168,7 @@ TALER_EXCHANGE_parse_reserve_history (
key_state = TALER_EXCHANGE_get_keys (exchange);
dki = TALER_EXCHANGE_get_denomination_key_by_hash (key_state,
- &withdraw_purpose.
- h_denomination_pub);
+ &h_denom_pub);
if ( (GNUNET_YES !=
TALER_amount_cmp_currency (&withdraw_fee,
&dki->fee_withdraw)) ||
@@ -193,10 +188,10 @@ TALER_EXCHANGE_parse_reserve_history (
/* Check check that the same withdraw transaction
isn't listed twice by the exchange. We use the
"uuid" array to remember the hashes of all
- purposes, and compare the hashes to find
- duplicates. *///
- GNUNET_CRYPTO_hash (&withdraw_purpose,
- ntohl (withdraw_purpose.purpose.size),
+ signatures, and compare the hashes to find
+ duplicates. */
+ GNUNET_CRYPTO_hash (&sig,
+ sizeof (sig),
&uuid[uuid_off]);
for (unsigned int i = 0; i<uuid_off; i++)
{
diff --git a/src/lib/exchange_api_refreshes_reveal.c b/src/lib/exchange_api_refreshes_reveal.c
index ca49f7782..2fc02d330 100644
--- a/src/lib/exchange_api_refreshes_reveal.c
+++ b/src/lib/exchange_api_refreshes_reveal.c
@@ -399,10 +399,11 @@ TALER_EXCHANGE_refreshes_reveal (
TALER_planchet_blinding_secret_create (&coin_ps,
&alg_values[i],
&bks);
- TALER_cs_refresh_nonce_derive (
- rms,
- i,
- &pd.blinded_planchet.details.cs_blinded_planchet.nonce);
+ if (TALER_DENOMINATION_CS == alg_values[i].cipher)
+ TALER_cs_refresh_nonce_derive (
+ rms,
+ i,
+ &pd.blinded_planchet.details.cs_blinded_planchet.nonce);
if (GNUNET_OK !=
TALER_planchet_prepare (&md.fresh_pks[i],
&alg_values[i],
diff --git a/src/lib/exchange_api_withdraw2.c b/src/lib/exchange_api_withdraw2.c
index d354946e1..c0643b9af 100644
--- a/src/lib/exchange_api_withdraw2.c
+++ b/src/lib/exchange_api_withdraw2.c
@@ -380,6 +380,7 @@ TALER_EXCHANGE_withdraw2 (
const struct TALER_EXCHANGE_DenomPublicKey *dk;
struct TALER_ReserveSignatureP reserve_sig;
char arg_str[sizeof (struct TALER_ReservePublicKeyP) * 2 + 32];
+ struct TALER_BlindedCoinHash bch;
keys = TALER_EXCHANGE_get_keys (exchange);
if (NULL == keys)
@@ -428,31 +429,22 @@ TALER_EXCHANGE_withdraw2 (
"/reserves/%s/withdraw",
pub_str);
}
- // FIXME: move this to libtalerutil!
+
+ if (GNUNET_OK !=
+ TALER_coin_ev_hash (&pd->blinded_planchet,
+ &pd->denom_pub_hash,
+ &bch))
{
- 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,
- &wh->requested_amount);
- if (GNUNET_OK !=
- TALER_coin_ev_hash (&pd->blinded_planchet,
- &pd->denom_pub_hash,
- &req.h_coin_envelope))
- {
- GNUNET_break (0);
- GNUNET_free (wh);
- return NULL;
- }
- GNUNET_CRYPTO_eddsa_sign (&reserve_priv->eddsa_priv,
- &req,
- &reserve_sig.eddsa_signature);
+ GNUNET_break (0);
+ GNUNET_free (wh);
+ return NULL;
}
+ TALER_wallet_withdraw_sign (&pd->denom_pub_hash,
+ &wh->requested_amount,
+ &bch,
+ reserve_priv,
+ &reserve_sig);
{
json_t *withdraw_obj = GNUNET_JSON_PACK (
GNUNET_JSON_pack_data_auto ("denom_pub_hash",
diff --git a/src/util/crypto.c b/src/util/crypto.c
index 1b486d404..13b9188c5 100644
--- a/src/util/crypto.c
+++ b/src/util/crypto.c
@@ -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
TALER_planchet_prepare (const struct TALER_DenominationPublicKey *dk,
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
TALER_planchet_to_coin (
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
TALER_coin_pub_hash (const struct TALER_CoinSpendPublicKeyP *coin_pub,
const struct TALER_AgeHash *age_commitment_hash,
diff --git a/src/util/denom.c b/src/util/denom.c
index 68ad04f39..ee488192b 100644
--- a/src/util/denom.c
+++ b/src/util/denom.c
@@ -83,28 +83,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
TALER_denom_sign_blinded (struct TALER_BlindedDenominationSignature *denom_sig,
const struct TALER_DenominationPrivateKey *denom_priv,
const struct TALER_BlindedPlanchet *blinded_planchet)
@@ -112,13 +90,11 @@ TALER_denom_sign_blinded (struct TALER_BlindedDenominationSignature *denom_sig,
memset (denom_sig,
0,
sizeof (*denom_sig));
-
if (blinded_planchet->cipher != denom_priv->cipher)
{
GNUNET_break (0);
return GNUNET_SYSERR;
}
-
switch (denom_priv->cipher)
{
case TALER_DENOMINATION_INVALID:
@@ -140,11 +116,11 @@ TALER_denom_sign_blinded (struct TALER_BlindedDenominationSignature *denom_sig,
case TALER_DENOMINATION_CS:
{
struct GNUNET_CRYPTO_CsRSecret r[2];
+
GNUNET_CRYPTO_cs_r_derive (
&blinded_planchet->details.cs_blinded_planchet.nonce.nonce,
&denom_priv->details.cs_private_key,
r);
-
denom_sig->details.blinded_cs_answer.b =
GNUNET_CRYPTO_cs_sign_derive (&denom_priv->details.cs_private_key,
r,
@@ -154,7 +130,6 @@ TALER_denom_sign_blinded (struct TALER_BlindedDenominationSignature *denom_sig,
cs_blinded_planchet.nonce.nonce,
&denom_sig->details.blinded_cs_answer.
s_scalar);
-
denom_sig->cipher = TALER_DENOMINATION_CS;
}
return GNUNET_OK;
@@ -268,8 +243,8 @@ TALER_denom_pub_hash (const struct TALER_DenominationPublicKey *denom_pub,
htonl (denom_pub->age_mask.mask),
htonl ((uint32_t) denom_pub->cipher)
};
-
struct GNUNET_HashContext *hc;
+
hc = GNUNET_CRYPTO_hash_context_start ();
GNUNET_CRYPTO_hash_context_read (hc,
opt,
@@ -444,7 +419,6 @@ TALER_denom_pub_free (struct TALER_DenominationPublicKey *denom_pub)
denom_pub->cipher = TALER_DENOMINATION_INVALID;
return;
case TALER_DENOMINATION_CS:
- // ATM nothing needs to be freed, but check again after implementation.
return;
default:
GNUNET_assert (0);
@@ -468,7 +442,6 @@ TALER_denom_priv_free (struct TALER_DenominationPrivateKey *denom_priv)
denom_priv->cipher = TALER_DENOMINATION_INVALID;
return;
case TALER_DENOMINATION_CS:
- // ATM nothing needs to be freed, but check again after implementation.
return;
default:
GNUNET_assert (0);
@@ -492,7 +465,6 @@ TALER_denom_sig_free (struct TALER_DenominationSignature *denom_sig)
denom_sig->cipher = TALER_DENOMINATION_INVALID;
return;
case TALER_DENOMINATION_CS:
- // ATM nothing needs to be freed, but check again after implementation.
return;
default:
GNUNET_assert (0);
@@ -518,7 +490,6 @@ TALER_blinded_denom_sig_free (
denom_sig->cipher = TALER_DENOMINATION_INVALID;
return;
case TALER_DENOMINATION_CS:
- // ATM nothing needs to be freed, but check again after implementation.
return;
default:
GNUNET_assert (0);
@@ -546,7 +517,6 @@ TALER_denom_pub_deep_copy (struct TALER_DenominationPublicKey *denom_dst,
denom_src->details.rsa_public_key);
return;
case TALER_DENOMINATION_CS:
- // In Case of CS, the above is already a deep copy *denom_dst = *denom_src;
return;
default:
GNUNET_assert (0);
@@ -569,7 +539,6 @@ TALER_denom_sig_deep_copy (struct TALER_DenominationSignature *denom_dst,
denom_src->details.rsa_signature);
return;
case TALER_DENOMINATION_CS:
- // In Case of CS, the above is already a deep copy *denom_dst = *denom_src;
return;
default:
GNUNET_assert (0);
@@ -593,7 +562,6 @@ TALER_blinded_denom_sig_deep_copy (
denom_src->details.blinded_rsa_signature);
return;
case TALER_DENOMINATION_CS:
- // In Case of CS, the above is already a deep copy *denom_dst = *denom_src;
return;
default:
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 */
diff --git a/src/util/taler-exchange-secmod-cs.c b/src/util/taler-exchange-secmod-cs.c
index 17fb23b3d..ab3a86fa8 100644
--- a/src/util/taler-exchange-secmod-cs.c
+++ b/src/util/taler-exchange-secmod-cs.c
@@ -281,7 +281,6 @@ handle_sign_request (struct TES_Client *client,
{
struct DenominationKey *dk;
struct GNUNET_CRYPTO_CsRSecret r[2];
-
struct TALER_BlindedDenominationCsSignAnswer cs_answer;
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);
dk->rc++;
GNUNET_assert (0 == pthread_mutex_unlock (&keys_lock));
-
- GNUNET_CRYPTO_cs_r_derive (&sr->planchet.nonce.nonce, &dk->denom_priv, r);
+ GNUNET_CRYPTO_cs_r_derive (&sr->planchet.nonce.nonce,
+ &dk->denom_priv,
+ r);
cs_answer.b = GNUNET_CRYPTO_cs_sign_derive (&dk->denom_priv,
r,
sr->planchet.c,
diff --git a/src/util/test_crypto.c b/src/util/test_crypto.c
index 94d3167e3..fbf30e3a4 100644
--- a/src/util/test_crypto.c
+++ b/src/util/test_crypto.c
@@ -176,6 +176,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
* and extracting the respective signature.
*
@@ -207,7 +239,7 @@ test_planchets_cs (void)
&ps,
&pd.blinded_planchet.details.cs_blinded_planchet.nonce);
GNUNET_assert (GNUNET_OK ==
- TALER_denom_cs_derive_r_public (
+ derive_r_public (
&pd.blinded_planchet.details.cs_blinded_planchet.nonce,
&dk_priv,
&alg_values.details.cs_values));
diff --git a/src/util/wallet_signatures.c b/src/util/wallet_signatures.c
index 669ea6dd5..1dd2302b4 100644
--- a/src/util/wallet_signatures.c
+++ b/src/util/wallet_signatures.c
@@ -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 */