aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2022-02-20 21:51:41 +0100
committerChristian Grothoff <christian@grothoff.org>2022-02-20 21:51:46 +0100
commit19624fd776f28812354f7e2b50b26e984ff077ab (patch)
tree625d0019650cb88d42bbf7f5ac0c1ef51fabac70
parentdbc5adba7f22fb9568be29479ac9cf19463d471f (diff)
-ensure different HKDF is used in melt vs. withdraw
-rw-r--r--src/benchmark/taler-aggregator-benchmark.c1
-rw-r--r--src/exchange/taler-exchange-httpd_csr.c12
-rw-r--r--src/exchange/taler-exchange-httpd_keys.c96
-rw-r--r--src/exchange/taler-exchange-httpd_keys.h47
-rw-r--r--src/exchange/taler-exchange-httpd_refreshes_reveal.c6
-rw-r--r--src/exchange/taler-exchange-httpd_withdraw.c2
-rw-r--r--src/exchangedb/test_exchangedb.c2
-rw-r--r--src/include/taler_crypto_lib.h61
-rw-r--r--src/testing/testing_api_cmd_insert_deposit.c1
-rw-r--r--src/util/crypto_helper_cs.c114
-rw-r--r--src/util/denom.c2
-rw-r--r--src/util/taler-exchange-secmod-cs.c14
-rw-r--r--src/util/taler-exchange-secmod-cs.h8
-rw-r--r--src/util/test_crypto.c3
-rw-r--r--src/util/test_helper_cs.c68
15 files changed, 356 insertions, 81 deletions
diff --git a/src/benchmark/taler-aggregator-benchmark.c b/src/benchmark/taler-aggregator-benchmark.c
index dde8ad401..f9a2880d9 100644
--- a/src/benchmark/taler-aggregator-benchmark.c
+++ b/src/benchmark/taler-aggregator-benchmark.c
@@ -558,6 +558,7 @@ run (void *cls,
GNUNET_assert (GNUNET_OK ==
TALER_denom_sign_blinded (&bds,
&pk,
+ false,
&pd.blinded_planchet));
TALER_blinded_planchet_free (&pd.blinded_planchet);
GNUNET_assert (GNUNET_OK ==
diff --git a/src/exchange/taler-exchange-httpd_csr.c b/src/exchange/taler-exchange-httpd_csr.c
index 423835979..94b55c706 100644
--- a/src/exchange/taler-exchange-httpd_csr.c
+++ b/src/exchange/taler-exchange-httpd_csr.c
@@ -179,9 +179,9 @@ TEH_handler_csr_melt (struct TEH_RequestContext *rc,
/* derive r_pub */
// FIXME: bundle all requests into one derivation request (TEH_keys_..., crypto helper, security module)
- ec = TEH_keys_denomination_cs_r_pub (denom_pub_hash,
- nonce,
- r_pub);
+ ec = TEH_keys_denomination_cs_r_pub_melt (denom_pub_hash,
+ nonce,
+ r_pub);
if (TALER_EC_NONE != ec)
{
GNUNET_break (0);
@@ -316,9 +316,9 @@ TEH_handler_csr_withdraw (struct TEH_RequestContext *rc,
{
enum TALER_ErrorCode ec;
- ec = TEH_keys_denomination_cs_r_pub (&denom_pub_hash,
- &nonce,
- &ewv.details.cs_values);
+ ec = TEH_keys_denomination_cs_r_pub_withdraw (&denom_pub_hash,
+ &nonce,
+ &ewv.details.cs_values);
if (TALER_EC_NONE != ec)
{
GNUNET_break (0);
diff --git a/src/exchange/taler-exchange-httpd_keys.c b/src/exchange/taler-exchange-httpd_keys.c
index 695ce9777..60c9c6eb0 100644
--- a/src/exchange/taler-exchange-httpd_keys.c
+++ b/src/exchange/taler-exchange-httpd_keys.c
@@ -2432,9 +2432,49 @@ TEH_keys_denomination_by_hash2 (
enum TALER_ErrorCode
-TEH_keys_denomination_sign (const struct TALER_DenominationHash *h_denom_pub,
- const struct TALER_BlindedPlanchet *bp,
- struct TALER_BlindedDenominationSignature *bs)
+TEH_keys_denomination_sign_withdraw (
+ const struct TALER_DenominationHash *h_denom_pub,
+ const struct TALER_BlindedPlanchet *bp,
+ struct TALER_BlindedDenominationSignature *bs)
+{
+ struct TEH_KeyStateHandle *ksh;
+ struct HelperDenomination *hd;
+
+ ksh = TEH_keys_get_state ();
+ if (NULL == ksh)
+ return TALER_EC_EXCHANGE_GENERIC_KEYS_MISSING;
+ hd = GNUNET_CONTAINER_multihashmap_get (ksh->helpers->denom_keys,
+ &h_denom_pub->hash);
+ if (NULL == hd)
+ return TALER_EC_EXCHANGE_GENERIC_DENOMINATION_KEY_UNKNOWN;
+ if (bp->cipher != hd->denom_pub.cipher)
+ return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE;
+ switch (hd->denom_pub.cipher)
+ {
+ case TALER_DENOMINATION_RSA:
+ return TALER_CRYPTO_helper_rsa_sign (
+ ksh->helpers->rsadh,
+ &hd->h_details.h_rsa,
+ bp->details.rsa_blinded_planchet.blinded_msg,
+ bp->details.rsa_blinded_planchet.blinded_msg_size,
+ bs);
+ case TALER_DENOMINATION_CS:
+ return TALER_CRYPTO_helper_cs_sign_withdraw (
+ ksh->helpers->csdh,
+ &hd->h_details.h_cs,
+ &bp->details.cs_blinded_planchet,
+ bs);
+ default:
+ return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE;
+ }
+}
+
+
+enum TALER_ErrorCode
+TEH_keys_denomination_sign_melt (
+ const struct TALER_DenominationHash *h_denom_pub,
+ const struct TALER_BlindedPlanchet *bp,
+ struct TALER_BlindedDenominationSignature *bs)
{
struct TEH_KeyStateHandle *ksh;
struct HelperDenomination *hd;
@@ -2458,7 +2498,7 @@ TEH_keys_denomination_sign (const struct TALER_DenominationHash *h_denom_pub,
bp->details.rsa_blinded_planchet.blinded_msg_size,
bs);
case TALER_DENOMINATION_CS:
- return TALER_CRYPTO_helper_cs_sign (
+ return TALER_CRYPTO_helper_cs_sign_melt (
ksh->helpers->csdh,
&hd->h_details.h_cs,
&bp->details.cs_blinded_planchet,
@@ -2470,10 +2510,42 @@ TEH_keys_denomination_sign (const struct TALER_DenominationHash *h_denom_pub,
enum TALER_ErrorCode
-TEH_keys_denomination_cs_r_pub (const struct
- TALER_DenominationHash *h_denom_pub,
- const struct TALER_CsNonce *nonce,
- struct TALER_DenominationCSPublicRPairP *r_pub)
+TEH_keys_denomination_cs_r_pub_melt (
+ const struct TALER_DenominationHash *h_denom_pub,
+ const struct TALER_CsNonce *nonce,
+ struct TALER_DenominationCSPublicRPairP *r_pub)
+{
+ struct TEH_KeyStateHandle *ksh;
+ struct HelperDenomination *hd;
+
+ ksh = TEH_keys_get_state ();
+ if (NULL == ksh)
+ {
+ return TALER_EC_EXCHANGE_GENERIC_KEYS_MISSING;
+ }
+ hd = GNUNET_CONTAINER_multihashmap_get (ksh->helpers->denom_keys,
+ &h_denom_pub->hash);
+ if (NULL == hd)
+ {
+ return TALER_EC_EXCHANGE_GENERIC_DENOMINATION_KEY_UNKNOWN;
+ }
+ if (TALER_DENOMINATION_CS != hd->denom_pub.cipher)
+ {
+ return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE;
+ }
+
+ return TALER_CRYPTO_helper_cs_r_derive_melt (ksh->helpers->csdh,
+ &hd->h_details.h_cs,
+ nonce,
+ r_pub);
+}
+
+
+enum TALER_ErrorCode
+TEH_keys_denomination_cs_r_pub_withdraw (
+ const struct TALER_DenominationHash *h_denom_pub,
+ const struct TALER_CsNonce *nonce,
+ struct TALER_DenominationCSPublicRPairP *r_pub)
{
struct TEH_KeyStateHandle *ksh;
struct HelperDenomination *hd;
@@ -2494,10 +2566,10 @@ TEH_keys_denomination_cs_r_pub (const struct
return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE;
}
- return TALER_CRYPTO_helper_cs_r_derive (ksh->helpers->csdh,
- &hd->h_details.h_cs,
- nonce,
- r_pub);
+ return TALER_CRYPTO_helper_cs_r_derive_withdraw (ksh->helpers->csdh,
+ &hd->h_details.h_cs,
+ nonce,
+ r_pub);
}
diff --git a/src/exchange/taler-exchange-httpd_keys.h b/src/exchange/taler-exchange-httpd_keys.h
index a329c4f12..7c6fb3e33 100644
--- a/src/exchange/taler-exchange-httpd_keys.h
+++ b/src/exchange/taler-exchange-httpd_keys.h
@@ -169,22 +169,57 @@ TEH_keys_denomination_by_hash2 (
/**
* Request to sign @a msg using the public key corresponding to
- * @a h_denom_pub.
+ * @a h_denom_pub during a withdraw operation.
*
* @param h_denom_pub hash of the public key to use to sign
* @param bp blinded planchet to sign
+ * @param is_melt should we use the KDF for melting?
* @param[out] bs set to the blind signature on success
* @return #TALER_EC_NONE on success
*/
enum TALER_ErrorCode
-TEH_keys_denomination_sign (const struct TALER_DenominationHash *h_denom_pub,
- const struct TALER_BlindedPlanchet *bp,
- struct TALER_BlindedDenominationSignature *bs);
+TEH_keys_denomination_sign_withdraw (
+ const struct TALER_DenominationHash *h_denom_pub,
+ const struct TALER_BlindedPlanchet *bp,
+ struct TALER_BlindedDenominationSignature *bs);
+
+
+/**
+ * Request to sign @a msg using the public key corresponding to
+ * @a h_denom_pub during a refresh operation.
+ *
+ * @param h_denom_pub hash of the public key to use to sign
+ * @param bp blinded planchet to sign
+ * @param is_melt should we use the KDF for melting?
+ * @param[out] bs set to the blind signature on success
+ * @return #TALER_EC_NONE on success
+ */
+enum TALER_ErrorCode
+TEH_keys_denomination_sign_melt (
+ const struct TALER_DenominationHash *h_denom_pub,
+ const struct TALER_BlindedPlanchet *bp,
+ struct TALER_BlindedDenominationSignature *bs);
+
+
+/**
+ * Request to derive CS @a r_pub using the denomination corresponding to @a h_denom_pub
+ * and @a nonce for withdrawing.
+ *
+ * @param h_denom_pub hash of the public key to use to derive r_pub
+ * @param nonce withdraw/refresh nonce
+ * @param[out] r_pub where to write the result
+ * @return #TALER_EC_NONE on success
+ */
+enum TALER_ErrorCode
+TEH_keys_denomination_cs_r_pub_withdraw (
+ const struct TALER_DenominationHash *h_denom_pub,
+ const struct TALER_CsNonce *nonce,
+ struct TALER_DenominationCSPublicRPairP *r_pub);
/**
* Request to derive CS @a r_pub using the denomination corresponding to @a h_denom_pub
- * and @a nonce.
+ * and @a nonce for melting.
*
* @param h_denom_pub hash of the public key to use to derive r_pub
* @param nonce withdraw/refresh nonce
@@ -192,7 +227,7 @@ TEH_keys_denomination_sign (const struct TALER_DenominationHash *h_denom_pub,
* @return #TALER_EC_NONE on success
*/
enum TALER_ErrorCode
-TEH_keys_denomination_cs_r_pub (
+TEH_keys_denomination_cs_r_pub_melt (
const struct TALER_DenominationHash *h_denom_pub,
const struct TALER_CsNonce *nonce,
struct TALER_DenominationCSPublicRPairP *r_pub);
diff --git a/src/exchange/taler-exchange-httpd_refreshes_reveal.c b/src/exchange/taler-exchange-httpd_refreshes_reveal.c
index 9e47f4664..0a4dd638b 100644
--- a/src/exchange/taler-exchange-httpd_refreshes_reveal.c
+++ b/src/exchange/taler-exchange-httpd_refreshes_reveal.c
@@ -216,7 +216,7 @@ check_commitment (struct RevealContext *rctx,
{
enum TALER_ErrorCode ec;
- ec = TEH_keys_denomination_cs_r_pub (
+ ec = TEH_keys_denomination_cs_r_pub_melt (
&rctx->rrcs[j].h_denom_pub,
&nonces[aoff],
&alg_values->details.cs_values);
@@ -733,7 +733,9 @@ clean_age:
{
enum TALER_ErrorCode ec;
- ec = TEH_keys_denomination_sign (
+ // FIXME: replace with a batch call that
+ // passes all coins in once go!
+ ec = TEH_keys_denomination_sign_melt (
&rrcs[i].h_denom_pub,
&rcds[i].blinded_planchet,
&rrcs[i].coin_sig);
diff --git a/src/exchange/taler-exchange-httpd_withdraw.c b/src/exchange/taler-exchange-httpd_withdraw.c
index cc6e92edf..5f159a429 100644
--- a/src/exchange/taler-exchange-httpd_withdraw.c
+++ b/src/exchange/taler-exchange-httpd_withdraw.c
@@ -505,7 +505,7 @@ TEH_handler_withdraw (struct TEH_RequestContext *rc,
}
/* Sign before transaction! */
- ec = TEH_keys_denomination_sign (
+ ec = TEH_keys_denomination_sign_withdraw (
&wc.collectable.denom_pub_hash,
&wc.blinded_planchet,
&wc.collectable.sig);
diff --git a/src/exchangedb/test_exchangedb.c b/src/exchangedb/test_exchangedb.c
index 807407145..7cb481712 100644
--- a/src/exchangedb/test_exchangedb.c
+++ b/src/exchangedb/test_exchangedb.c
@@ -1490,6 +1490,7 @@ run (void *cls)
TALER_denom_sign_blinded (
&cbc.sig,
&dkp->priv,
+ false,
&pd.blinded_planchet));
TALER_blinded_planchet_free (&pd.blinded_planchet);
}
@@ -1759,6 +1760,7 @@ run (void *cls)
GNUNET_assert (GNUNET_OK ==
TALER_denom_sign_blinded (&ccoin->coin_sig,
&new_dkp[cnt]->priv,
+ true,
bp));
}
RND_BLK (&tprivs);
diff --git a/src/include/taler_crypto_lib.h b/src/include/taler_crypto_lib.h
index 8a1c7bf12..793b16eec 100644
--- a/src/include/taler_crypto_lib.h
+++ b/src/include/taler_crypto_lib.h
@@ -1236,12 +1236,14 @@ TALER_denom_blind (const struct TALER_DenominationPublicKey *dk,
*
* @param[out] denom_sig where to write the signature
* @param denom_priv private key to use for signing
+ * @param for_melt true to use the HKDF for melt
* @param blinded_planchet the planchet already blinded
* @return #GNUNET_OK on success
*/
enum GNUNET_GenericReturnValue
TALER_denom_sign_blinded (struct TALER_BlindedDenominationSignature *denom_sig,
const struct TALER_DenominationPrivateKey *denom_priv,
+ bool for_melt,
const struct TALER_BlindedPlanchet *blinded_planchet);
@@ -2048,7 +2050,31 @@ TALER_CRYPTO_helper_cs_poll (struct TALER_CRYPTO_CsDenominationHelper *dh);
* @return #TALER_EC_NONE on success
*/
enum TALER_ErrorCode
-TALER_CRYPTO_helper_cs_sign (
+TALER_CRYPTO_helper_cs_sign_melt (
+ struct TALER_CRYPTO_CsDenominationHelper *dh,
+ const struct TALER_CsPubHashP *h_cs,
+ const struct TALER_BlindedCsPlanchet *blinded_planchet,
+ struct TALER_BlindedDenominationSignature *bs);
+
+
+/**
+ * Request helper @a dh to sign @a msg using the public key corresponding to
+ * @a h_denom_pub.
+ *
+ * This operation will block until the signature has been obtained. Should
+ * this process receive a signal (that is not ignored) while the operation is
+ * pending, the operation will fail. Note that the helper may still believe
+ * that it created the signature. Thus, signals may result in a small
+ * differences in the signature counters. Retrying in this case may work.
+ *
+ * @param dh helper process connection
+ * @param h_cs hash of the CS public key to use to sign
+ * @param blinded_planchet blinded planchet containing c and nonce
+ * @param[out] bs set to the blind signature
+ * @return #TALER_EC_NONE on success
+ */
+enum TALER_ErrorCode
+TALER_CRYPTO_helper_cs_sign_withdraw (
struct TALER_CRYPTO_CsDenominationHelper *dh,
const struct TALER_CsPubHashP *h_cs,
const struct TALER_BlindedCsPlanchet *blinded_planchet,
@@ -2093,10 +2119,35 @@ TALER_CRYPTO_helper_cs_revoke (
* @return set to the error code (or #TALER_EC_NONE on success)
*/
enum TALER_ErrorCode
-TALER_CRYPTO_helper_cs_r_derive (struct TALER_CRYPTO_CsDenominationHelper *dh,
- const struct TALER_CsPubHashP *h_cs,
- const struct TALER_CsNonce *nonce,
- struct TALER_DenominationCSPublicRPairP *crp);
+TALER_CRYPTO_helper_cs_r_derive_withdraw (
+ struct TALER_CRYPTO_CsDenominationHelper *dh,
+ const struct TALER_CsPubHashP *h_cs,
+ const struct TALER_CsNonce *nonce,
+ struct TALER_DenominationCSPublicRPairP *crp);
+
+
+/**
+ * Ask the helper to derive R using the @a nonce and denomination key
+ * associated with @a h_cs.
+ *
+ * This operation will block until the R has been obtained. Should
+ * this process receive a signal (that is not ignored) while the operation is
+ * pending, the operation will fail. Note that the helper may still believe
+ * that it created the signature. Thus, signals may result in a small
+ * differences in the signature counters. Retrying in this case may work.
+ *
+ * @param dh helper to process connection
+ * @param h_cs hash of the CS public key to revoke
+ * @param nonce witdhraw nonce
+ * @param[out] crp set to the pair of R values
+ * @return set to the error code (or #TALER_EC_NONE on success)
+ */
+enum TALER_ErrorCode
+TALER_CRYPTO_helper_cs_r_derive_melt (
+ struct TALER_CRYPTO_CsDenominationHelper *dh,
+ const struct TALER_CsPubHashP *h_cs,
+ const struct TALER_CsNonce *nonce,
+ struct TALER_DenominationCSPublicRPairP *crp);
/**
diff --git a/src/testing/testing_api_cmd_insert_deposit.c b/src/testing/testing_api_cmd_insert_deposit.c
index b1e732975..7404b8b70 100644
--- a/src/testing/testing_api_cmd_insert_deposit.c
+++ b/src/testing/testing_api_cmd_insert_deposit.c
@@ -220,6 +220,7 @@ insert_deposit_run (void *cls,
GNUNET_assert (GNUNET_OK ==
TALER_denom_sign_blinded (&bds,
&denom_priv,
+ false,
&pd.blinded_planchet));
TALER_blinded_planchet_free (&pd.blinded_planchet);
GNUNET_assert (GNUNET_OK ==
diff --git a/src/util/crypto_helper_cs.c b/src/util/crypto_helper_cs.c
index 874679cf0..e12d5ad61 100644
--- a/src/util/crypto_helper_cs.c
+++ b/src/util/crypto_helper_cs.c
@@ -378,11 +378,29 @@ more:
}
-enum TALER_ErrorCode
-TALER_CRYPTO_helper_cs_sign (
+/**
+ * Request helper @a dh to sign @a msg using the public key corresponding to
+ * @a h_denom_pub.
+ *
+ * This operation will block until the signature has been obtained. Should
+ * this process receive a signal (that is not ignored) while the operation is
+ * pending, the operation will fail. Note that the helper may still believe
+ * that it created the signature. Thus, signals may result in a small
+ * differences in the signature counters. Retrying in this case may work.
+ *
+ * @param dh helper process connection
+ * @param h_cs hash of the CS public key to use to sign
+ * @param blinded_planchet blinded planchet containing c and nonce
+ * @param for_melt true if the HKDF for melt should be used
+ * @param[out] bs set to the blind signature
+ * @return #TALER_EC_NONE on success
+ */
+static enum TALER_ErrorCode
+helper_cs_sign (
struct TALER_CRYPTO_CsDenominationHelper *dh,
const struct TALER_CsPubHashP *h_cs,
const struct TALER_BlindedCsPlanchet *blinded_planchet,
+ bool for_melt,
struct TALER_BlindedDenominationSignature *bs)
{
enum TALER_ErrorCode ec = TALER_EC_INVALID;
@@ -407,7 +425,7 @@ TALER_CRYPTO_helper_cs_sign (
sr->header.size = htons (sizeof (buf));
sr->header.type = htons (TALER_HELPER_CS_MT_REQ_SIGN);
- sr->reserved = htonl (0);
+ sr->for_melt = htonl (for_melt ? 1 : 0);
sr->h_cs = *h_cs;
sr->planchet = *blinded_planchet;
if (GNUNET_OK !=
@@ -573,6 +591,36 @@ end:
}
+enum TALER_ErrorCode
+TALER_CRYPTO_helper_cs_sign_melt (
+ struct TALER_CRYPTO_CsDenominationHelper *dh,
+ const struct TALER_CsPubHashP *h_cs,
+ const struct TALER_BlindedCsPlanchet *blinded_planchet,
+ struct TALER_BlindedDenominationSignature *bs)
+{
+ return helper_cs_sign (dh,
+ h_cs,
+ blinded_planchet,
+ true,
+ bs);
+}
+
+
+enum TALER_ErrorCode
+TALER_CRYPTO_helper_cs_sign_withdraw (
+ struct TALER_CRYPTO_CsDenominationHelper *dh,
+ const struct TALER_CsPubHashP *h_cs,
+ const struct TALER_BlindedCsPlanchet *blinded_planchet,
+ struct TALER_BlindedDenominationSignature *bs)
+{
+ return helper_cs_sign (dh,
+ h_cs,
+ blinded_planchet,
+ false,
+ bs);
+}
+
+
void
TALER_CRYPTO_helper_cs_revoke (
struct TALER_CRYPTO_CsDenominationHelper *dh,
@@ -603,11 +651,29 @@ TALER_CRYPTO_helper_cs_revoke (
}
-enum TALER_ErrorCode
-TALER_CRYPTO_helper_cs_r_derive (struct TALER_CRYPTO_CsDenominationHelper *dh,
- const struct TALER_CsPubHashP *h_cs,
- const struct TALER_CsNonce *nonce,
- struct TALER_DenominationCSPublicRPairP *crp)
+/**
+ * Ask the helper to derive R using the @a nonce and denomination key
+ * associated with @a h_cs.
+ *
+ * This operation will block until the R has been obtained. Should
+ * this process receive a signal (that is not ignored) while the operation is
+ * pending, the operation will fail. Note that the helper may still believe
+ * that it created the signature. Thus, signals may result in a small
+ * differences in the signature counters. Retrying in this case may work.
+ *
+ * @param dh helper to process connection
+ * @param h_cs hash of the CS public key to revoke
+ * @param nonce witdhraw nonce
+ * @param for_melt true if the HKDF for melt should be used
+ * @param[out] crp set to the pair of R values
+ * @return set to the error code (or #TALER_EC_NONE on success)
+ */
+static enum TALER_ErrorCode
+helper_cs_r_derive (struct TALER_CRYPTO_CsDenominationHelper *dh,
+ const struct TALER_CsPubHashP *h_cs,
+ const struct TALER_CsNonce *nonce,
+ bool for_melt,
+ struct TALER_DenominationCSPublicRPairP *crp)
{
enum TALER_ErrorCode ec = TALER_EC_INVALID;
@@ -630,7 +696,7 @@ TALER_CRYPTO_helper_cs_r_derive (struct TALER_CRYPTO_CsDenominationHelper *dh,
struct TALER_CRYPTO_CsRDeriveRequest rdr = {
.header.size = htons (sizeof (rdr)),
.header.type = htons (TALER_HELPER_CS_MT_REQ_RDERIVE),
- .reserved = htonl (0),
+ .for_melt = htonl (for_melt ? 1 : 0),
.h_cs = *h_cs,
.nonce = *nonce
};
@@ -786,6 +852,36 @@ more:
}
+enum TALER_ErrorCode
+TALER_CRYPTO_helper_cs_r_derive_withdraw (
+ struct TALER_CRYPTO_CsDenominationHelper *dh,
+ const struct TALER_CsPubHashP *h_cs,
+ const struct TALER_CsNonce *nonce,
+ struct TALER_DenominationCSPublicRPairP *crp)
+{
+ return helper_cs_r_derive (dh,
+ h_cs,
+ nonce,
+ false,
+ crp);
+}
+
+
+enum TALER_ErrorCode
+TALER_CRYPTO_helper_cs_r_derive_melt (
+ struct TALER_CRYPTO_CsDenominationHelper *dh,
+ const struct TALER_CsPubHashP *h_cs,
+ const struct TALER_CsNonce *nonce,
+ struct TALER_DenominationCSPublicRPairP *crp)
+{
+ return helper_cs_r_derive (dh,
+ h_cs,
+ nonce,
+ true,
+ crp);
+}
+
+
void
TALER_CRYPTO_helper_cs_disconnect (
struct TALER_CRYPTO_CsDenominationHelper *dh)
diff --git a/src/util/denom.c b/src/util/denom.c
index 7afc7f408..86c83d7cf 100644
--- a/src/util/denom.c
+++ b/src/util/denom.c
@@ -85,6 +85,7 @@ TALER_denom_priv_create (struct TALER_DenominationPrivateKey *denom_priv,
enum GNUNET_GenericReturnValue
TALER_denom_sign_blinded (struct TALER_BlindedDenominationSignature *denom_sig,
const struct TALER_DenominationPrivateKey *denom_priv,
+ bool for_melt,
const struct TALER_BlindedPlanchet *blinded_planchet)
{
memset (denom_sig,
@@ -119,6 +120,7 @@ TALER_denom_sign_blinded (struct TALER_BlindedDenominationSignature *denom_sig,
GNUNET_CRYPTO_cs_r_derive (
&blinded_planchet->details.cs_blinded_planchet.nonce.nonce,
+ for_melt ? "rm" : "rw",
&denom_priv->details.cs_private_key,
r);
denom_sig->details.blinded_cs_answer.b =
diff --git a/src/util/taler-exchange-secmod-cs.c b/src/util/taler-exchange-secmod-cs.c
index 6e4e163b2..33167c8ea 100644
--- a/src/util/taler-exchange-secmod-cs.c
+++ b/src/util/taler-exchange-secmod-cs.c
@@ -283,6 +283,7 @@ handle_sign_request (struct TES_Client *client,
struct GNUNET_CRYPTO_CsRSecret r[2];
struct TALER_BlindedDenominationCsSignAnswer cs_answer;
struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ();
+ bool for_melt;
GNUNET_assert (0 == pthread_mutex_lock (&keys_lock));
dk = GNUNET_CONTAINER_multihashmap_get (keys,
@@ -318,7 +319,7 @@ handle_sign_request (struct TES_Client *client,
return TES_transmit (client->csock,
&sf.header);
}
-
+ for_melt = (0 != ntohl (sr->for_melt));
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Received request to sign over bytes with key %s\n",
GNUNET_h2s (&sr->h_cs.hash));
@@ -326,6 +327,7 @@ handle_sign_request (struct TES_Client *client,
dk->rc++;
GNUNET_assert (0 == pthread_mutex_unlock (&keys_lock));
GNUNET_CRYPTO_cs_r_derive (&sr->planchet.nonce.nonce,
+ for_melt ? "rm" : "rw",
&dk->denom_priv,
r);
cs_answer.b = GNUNET_CRYPTO_cs_sign_derive (&dk->denom_priv,
@@ -552,6 +554,7 @@ handle_r_derive_request (struct TES_Client *client,
struct TALER_DenominationCSPrivateRPairP r_priv;
struct TALER_DenominationCSPublicRPairP r_pub;
struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ();
+ bool for_melt;
GNUNET_assert (0 == pthread_mutex_lock (&keys_lock));
dk = GNUNET_CONTAINER_multihashmap_get (keys,
@@ -587,7 +590,7 @@ handle_r_derive_request (struct TES_Client *client,
return TES_transmit (client->csock,
&rdf.header);
}
-
+ for_melt = (0 != ntohl (rdr->for_melt));
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Received request to derive R with key %s\n",
GNUNET_h2s (&rdr->h_cs.hash));
@@ -595,10 +598,13 @@ handle_r_derive_request (struct TES_Client *client,
dk->rc++;
GNUNET_assert (0 == pthread_mutex_unlock (&keys_lock));
GNUNET_CRYPTO_cs_r_derive (&rdr->nonce.nonce,
+ for_melt ? "rm" : "rw",
&dk->denom_priv,
r_priv.r);
- GNUNET_CRYPTO_cs_r_get_public (&r_priv.r[0], &r_pub.r_pub[0]);
- GNUNET_CRYPTO_cs_r_get_public (&r_priv.r[1], &r_pub.r_pub[1]);
+ GNUNET_CRYPTO_cs_r_get_public (&r_priv.r[0],
+ &r_pub.r_pub[0]);
+ GNUNET_CRYPTO_cs_r_get_public (&r_priv.r[1],
+ &r_pub.r_pub[1]);
GNUNET_assert (0 == pthread_mutex_lock (&keys_lock));
GNUNET_assert (dk->rc > 0);
dk->rc--;
diff --git a/src/util/taler-exchange-secmod-cs.h b/src/util/taler-exchange-secmod-cs.h
index c090e5cd1..c71c3b9af 100644
--- a/src/util/taler-exchange-secmod-cs.h
+++ b/src/util/taler-exchange-secmod-cs.h
@@ -122,9 +122,9 @@ struct TALER_CRYPTO_CsSignRequest
struct GNUNET_MessageHeader header;
/**
- * For now, always zero.
+ * 0 for withdraw, 1 for melt, in NBO.
*/
- uint32_t reserved;
+ uint32_t for_melt;
/**
* Hash of the public key of the CS key to use for the signature.
@@ -150,9 +150,9 @@ struct TALER_CRYPTO_CsRDeriveRequest
struct GNUNET_MessageHeader header;
/**
- * For now, always zero.
+ * 0 for withdraw, 1 for melt, in NBO.
*/
- uint32_t reserved;
+ uint32_t for_melt;
/**
* Hash of the public key of the CS key to use for the derivation.
diff --git a/src/util/test_crypto.c b/src/util/test_crypto.c
index d85dad609..35b964021 100644
--- a/src/util/test_crypto.c
+++ b/src/util/test_crypto.c
@@ -158,6 +158,7 @@ test_planchets_rsa (void)
GNUNET_assert (GNUNET_OK ==
TALER_denom_sign_blinded (&blind_sig,
&dk_priv,
+ false,
&pd.blinded_planchet));
TALER_planchet_detail_free (&pd);
GNUNET_assert (GNUNET_OK ==
@@ -201,6 +202,7 @@ derive_r_public (
return GNUNET_SYSERR;
}
GNUNET_CRYPTO_cs_r_derive (&nonce->nonce,
+ "rw",
&denom_priv->details.cs_private_key,
r);
GNUNET_CRYPTO_cs_r_get_public (&r[0],
@@ -264,6 +266,7 @@ test_planchets_cs (void)
GNUNET_assert (GNUNET_OK ==
TALER_denom_sign_blinded (&blind_sig,
&dk_priv,
+ false,
&pd.blinded_planchet));
TALER_planchet_detail_free (&pd);
GNUNET_assert (GNUNET_OK ==
diff --git a/src/util/test_helper_cs.c b/src/util/test_helper_cs.c
index b6b72e2e1..c2708353d 100644
--- a/src/util/test_helper_cs.c
+++ b/src/util/test_helper_cs.c
@@ -289,7 +289,7 @@ test_r_derive (struct TALER_CRYPTO_CsDenominationHelper *dh)
"Requesting R derivation with key %s\n",
GNUNET_h2s (&keys[i].h_cs.hash));
alg_values.cipher = TALER_DENOMINATION_CS;
- ec = TALER_CRYPTO_helper_cs_r_derive (
+ ec = TALER_CRYPTO_helper_cs_r_derive_withdraw (
dh,
&keys[i].h_cs,
&pd.blinded_planchet.details.cs_blinded_planchet.nonce,
@@ -381,10 +381,10 @@ test_r_derive (struct TALER_CRYPTO_CsDenominationHelper *dh)
GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
&nonce,
sizeof (nonce));
- ec = TALER_CRYPTO_helper_cs_r_derive (dh,
- &rnd,
- &nonce,
- &crp);
+ ec = TALER_CRYPTO_helper_cs_r_derive_withdraw (dh,
+ &rnd,
+ &nonce,
+ &crp);
if (TALER_EC_EXCHANGE_GENERIC_DENOMINATION_KEY_UNKNOWN != ec)
{
GNUNET_break (0);
@@ -431,12 +431,13 @@ test_signing (struct TALER_CRYPTO_CsDenominationHelper *dh)
&pd.blinded_planchet.details.
cs_blinded_planchet.nonce);
alg_values.cipher = TALER_DENOMINATION_CS;
- ec = TALER_CRYPTO_helper_cs_r_derive (dh,
- &keys[i].h_cs,
- &pd.blinded_planchet.
- details.
- cs_blinded_planchet.nonce,
- &alg_values.details.cs_values);
+ ec = TALER_CRYPTO_helper_cs_r_derive_withdraw (
+ dh,
+ &keys[i].h_cs,
+ &pd.blinded_planchet.
+ details.
+ cs_blinded_planchet.nonce,
+ &alg_values.details.cs_values);
if (TALER_EC_NONE != ec)
continue;
TALER_planchet_setup_coin_priv (&ps,
@@ -457,11 +458,12 @@ test_signing (struct TALER_CRYPTO_CsDenominationHelper *dh)
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Requesting signature with key %s\n",
GNUNET_h2s (&keys[i].h_cs.hash));
- ec = TALER_CRYPTO_helper_cs_sign (dh,
- &keys[i].h_cs,
- &pd.blinded_planchet.details.
- cs_blinded_planchet,
- &ds);
+ ec = TALER_CRYPTO_helper_cs_sign_withdraw (
+ dh,
+ &keys[i].h_cs,
+ &pd.blinded_planchet.details.
+ cs_blinded_planchet,
+ &ds);
}
switch (ec)
{
@@ -556,11 +558,11 @@ test_signing (struct TALER_CRYPTO_CsDenominationHelper *dh)
&c_hash,
&pd));
- ec = TALER_CRYPTO_helper_cs_sign (dh,
- &rnd,
- &pd.blinded_planchet.details.
- cs_blinded_planchet,
- &ds);
+ ec = TALER_CRYPTO_helper_cs_sign_withdraw (
+ dh,
+ &rnd,
+ &pd.blinded_planchet.details.cs_blinded_planchet,
+ &ds);
if (TALER_EC_EXCHANGE_GENERIC_DENOMINATION_KEY_UNKNOWN != ec)
{
if (TALER_EC_NONE == ec)
@@ -622,12 +624,13 @@ perf_signing (struct TALER_CRYPTO_CsDenominationHelper *dh,
&pd.blinded_planchet.details.
cs_blinded_planchet.nonce);
alg_values.cipher = TALER_DENOMINATION_CS;
- ec = TALER_CRYPTO_helper_cs_r_derive (dh,
- &keys[i].h_cs,
- &pd.blinded_planchet.
- details.
- cs_blinded_planchet.nonce,
- &alg_values.details.cs_values);
+ ec = TALER_CRYPTO_helper_cs_r_derive_melt (
+ dh,
+ &keys[i].h_cs,
+ &pd.blinded_planchet.
+ details.
+ cs_blinded_planchet.nonce,
+ &alg_values.details.cs_values);
if (TALER_EC_NONE != ec)
continue;
TALER_planchet_setup_coin_priv (&ps,
@@ -650,11 +653,12 @@ perf_signing (struct TALER_CRYPTO_CsDenominationHelper *dh,
struct GNUNET_TIME_Absolute start = GNUNET_TIME_absolute_get ();
struct GNUNET_TIME_Relative delay;
- ec = TALER_CRYPTO_helper_cs_sign (dh,
- &keys[i].h_cs,
- &pd.blinded_planchet.details.
- cs_blinded_planchet,
- &ds);
+ ec = TALER_CRYPTO_helper_cs_sign_melt (
+ dh,
+ &keys[i].h_cs,
+ &pd.blinded_planchet.details.
+ cs_blinded_planchet,
+ &ds);
if (TALER_EC_NONE != ec)
break;
delay = GNUNET_TIME_absolute_get_duration (start);