From 8d85c8b5b6c514ce093d856a2e4b931b4108ece5 Mon Sep 17 00:00:00 2001 From: Lucien Heuzeveldt Date: Sun, 16 Jan 2022 17:02:15 +0100 Subject: implement feedback --- src/benchmark/taler-aggregator-benchmark.c | 8 +- src/exchange/taler-exchange-httpd_csr.c | 44 +++----- src/exchange/taler-exchange-httpd_deposit.c | 7 +- src/exchange/taler-exchange-httpd_keys.c | 28 ++--- src/exchange/taler-exchange-httpd_keys.h | 4 +- src/exchange/taler-exchange-httpd_recoup.c | 16 ++- .../taler-exchange-httpd_refreshes_reveal.c | 5 +- src/exchange/taler-exchange-httpd_responses.c | 47 ++++++++ src/exchange/taler-exchange-httpd_responses.h | 13 +++ src/exchange/taler-exchange-httpd_withdraw.c | 96 ++-------------- src/exchangedb/test_exchangedb.c | 26 +++-- src/include/taler_crypto_lib.h | 25 +++-- src/include/taler_exchange_service.h | 1 + src/include/taler_json_lib.h | 27 +++++ src/json/json_helper.c | 123 +++++++++++++++++++++ src/json/json_pack.c | 41 +++++++ src/lib/exchange_api_link.c | 10 +- src/lib/exchange_api_refresh_common.c | 5 +- src/lib/exchange_api_refreshes_reveal.c | 12 +- src/lib/exchange_api_withdraw.c | 14 +-- src/lib/exchange_api_withdraw2.c | 63 ++--------- src/testing/testing_api_cmd_insert_deposit.c | 9 +- src/testing/testing_api_cmd_withdraw.c | 11 +- src/util/crypto.c | 58 ++++++++-- src/util/test_crypto.c | 15 ++- src/util/test_helper_cs.c | 44 ++++---- src/util/test_helper_rsa.c | 25 +++-- 27 files changed, 488 insertions(+), 289 deletions(-) diff --git a/src/benchmark/taler-aggregator-benchmark.c b/src/benchmark/taler-aggregator-benchmark.c index 1515798c3..062cb1da9 100644 --- a/src/benchmark/taler-aggregator-benchmark.c +++ b/src/benchmark/taler-aggregator-benchmark.c @@ -491,6 +491,7 @@ run (void *cls, struct TALER_PlanchetDetail pd; struct TALER_BlindedDenominationSignature bds; struct TALER_PlanchetSecretsP ps; + struct TALER_ExchangeWithdrawValues alg_values; struct TALER_CoinSpendPublicKeyP coin_pub; RANDOMIZE (&coin_pub); @@ -519,20 +520,21 @@ run (void *cls, } - TALER_planchet_blinding_secret_create (&ps, TALER_DENOMINATION_RSA, NULL); + TALER_planchet_blinding_secret_create (&ps, + &alg_values); GNUNET_assert (GNUNET_OK == TALER_denom_blind (&denom_pub, &ps.blinding_key, NULL, /* FIXME-oec */ &coin_pub, - NULL, /* Not needed in RSA */ + &alg_values, &c_hash, &pd.blinded_planchet)); GNUNET_assert (GNUNET_OK == TALER_denom_sign_blinded (&bds, &pk, &pd.blinded_planchet)); - GNUNET_free (pd.blinded_planchet.details.rsa_blinded_planchet.blinded_msg); + TALER_blinded_planchet_free (&pd.blinded_planchet); GNUNET_assert (GNUNET_OK == TALER_denom_sig_unblind (&denom_sig, &bds, diff --git a/src/exchange/taler-exchange-httpd_csr.c b/src/exchange/taler-exchange-httpd_csr.c index 415dc7acf..e1c9037df 100644 --- a/src/exchange/taler-exchange-httpd_csr.c +++ b/src/exchange/taler-exchange-httpd_csr.c @@ -54,16 +54,6 @@ TEH_handler_csr (struct TEH_RequestContext *rc, (void) args; - memset (&nonce, - 0, - sizeof (nonce)); - memset (&denom_pub_hash, - 0, - sizeof (denom_pub_hash)); - memset (&r_pub, - 0, - sizeof (r_pub)); - // parse input { enum GNUNET_GenericReturnValue res; @@ -78,7 +68,6 @@ TEH_handler_csr (struct TEH_RequestContext *rc, // check denomination referenced by denom_pub_hash { - MHD_RESULT mret; struct TEH_KeyStateHandle *ksh; ksh = TEH_keys_get_state (); @@ -88,7 +77,6 @@ TEH_handler_csr (struct TEH_RequestContext *rc, MHD_HTTP_INTERNAL_SERVER_ERROR, TALER_EC_EXCHANGE_GENERIC_KEYS_MISSING, NULL); - return mret; } dk = TEH_keys_denomination_by_hash2 (ksh, &denom_pub_hash, @@ -134,17 +122,16 @@ TEH_handler_csr (struct TEH_RequestContext *rc, if (TALER_DENOMINATION_CS != dk->denom_pub.cipher) { // denomination is valid but not CS - return TEH_RESPONSE_reply_unknown_denom_pub_hash ( + return TEH_RESPONSE_reply_invalid_denom_cipher_for_operation ( rc->connection, &denom_pub_hash); } } // derive r_pub - ec = TALER_EC_NONE; - r_pub = TEH_keys_denomination_cs_r_pub (&denom_pub_hash, - &nonce, - &ec); + ec = TEH_keys_denomination_cs_r_pub (&denom_pub_hash, + &nonce, + &r_pub); if (TALER_EC_NONE != ec) { GNUNET_break (0); @@ -154,20 +141,15 @@ TEH_handler_csr (struct TEH_RequestContext *rc, } // send response - { - MHD_RESULT ret; - - ret = TALER_MHD_REPLY_JSON_PACK ( - rc->connection, - MHD_HTTP_OK, - GNUNET_JSON_pack_data_varsize ("r_pub_0", - &r_pub.r_pub[0], - sizeof(struct GNUNET_CRYPTO_CsRPublic)), - GNUNET_JSON_pack_data_varsize ("r_pub_1", - &r_pub.r_pub[1], - sizeof(struct GNUNET_CRYPTO_CsRPublic))); - return ret; - } + return TALER_MHD_REPLY_JSON_PACK ( + rc->connection, + MHD_HTTP_OK, + GNUNET_JSON_pack_data_varsize ("r_pub_0", + &r_pub.r_pub[0], + sizeof(struct GNUNET_CRYPTO_CsRPublic)), + GNUNET_JSON_pack_data_varsize ("r_pub_1", + &r_pub.r_pub[1], + sizeof(struct GNUNET_CRYPTO_CsRPublic))); } diff --git a/src/exchange/taler-exchange-httpd_deposit.c b/src/exchange/taler-exchange-httpd_deposit.c index 11f94f2c5..50ddba604 100644 --- a/src/exchange/taler-exchange-httpd_deposit.c +++ b/src/exchange/taler-exchange-httpd_deposit.c @@ -360,9 +360,10 @@ TEH_handler_deposit (struct MHD_Connection *connection, { /* denomination cipher and denomination signature cipher not the same */ GNUNET_JSON_parse_free (spec); - return TEH_RESPONSE_reply_unknown_denom_pub_hash ( - connection, - &deposit.coin.denom_pub_hash); + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_BAD_REQUEST, + TALER_EC_EXCHANGE_GENERIC_CIPHER_MISMATCH, + NULL); } deposit.deposit_fee = dk->meta.fee_deposit; diff --git a/src/exchange/taler-exchange-httpd_keys.c b/src/exchange/taler-exchange-httpd_keys.c index 42f351b75..39c5b760f 100644 --- a/src/exchange/taler-exchange-httpd_keys.c +++ b/src/exchange/taler-exchange-httpd_keys.c @@ -974,7 +974,6 @@ helper_cs_cb ( GNUNET_assert (TALER_DENOMINATION_CS == denom_pub->cipher); TALER_denom_pub_deep_copy (&hd->denom_pub, denom_pub); - GNUNET_assert (TALER_DENOMINATION_CS == hd->denom_pub.cipher); /* load the age mask for the denomination, if applicable */ hd->denom_pub.age_mask = load_age_mask (section_name); TALER_denom_pub_hash (&hd->denom_pub, @@ -2458,42 +2457,37 @@ TEH_keys_denomination_sign (const struct TALER_DenominationHash *h_denom_pub, } -struct TALER_DenominationCsPublicR +enum TALER_ErrorCode TEH_keys_denomination_cs_r_pub (const struct TALER_DenominationHash *h_denom_pub, const struct TALER_WithdrawNonce *nonce, - enum TALER_ErrorCode *ec) + struct TALER_DenominationCsPublicR *r_pub) { struct TEH_KeyStateHandle *ksh; - struct TALER_DenominationCsPublicR none; struct HelperDenomination *hd; + enum TALER_ErrorCode r_derive_ec; - memset (&none, - 0, - sizeof (none)); ksh = TEH_keys_get_state (); if (NULL == ksh) { - *ec = TALER_EC_EXCHANGE_GENERIC_KEYS_MISSING; - return none; + return TALER_EC_EXCHANGE_GENERIC_KEYS_MISSING; } hd = GNUNET_CONTAINER_multihashmap_get (ksh->helpers->denom_keys, &h_denom_pub->hash); if (NULL == hd) { - *ec = TALER_EC_EXCHANGE_GENERIC_DENOMINATION_KEY_UNKNOWN; - return none; + return TALER_EC_EXCHANGE_GENERIC_DENOMINATION_KEY_UNKNOWN; } if (TALER_DENOMINATION_CS != hd->denom_pub.cipher) { - *ec = TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - return none; + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; } - return TALER_CRYPTO_helper_cs_r_derive (ksh->helpers->csdh, - &hd->h_details.h_cs, - nonce, - ec); + *r_pub = TALER_CRYPTO_helper_cs_r_derive (ksh->helpers->csdh, + &hd->h_details.h_cs, + nonce, + &r_derive_ec); + return r_derive_ec; } diff --git a/src/exchange/taler-exchange-httpd_keys.h b/src/exchange/taler-exchange-httpd_keys.h index 7e75c80a9..2cc7d7d7c 100644 --- a/src/exchange/taler-exchange-httpd_keys.h +++ b/src/exchange/taler-exchange-httpd_keys.h @@ -229,11 +229,11 @@ TEH_keys_denomination_sign (const struct TALER_DenominationHash *h_denom_pub, * @return r_pub, the value inside the structure will be NULL on failure, * see @a ec for details about the failure */ -struct TALER_DenominationCsPublicR +enum TALER_ErrorCode TEH_keys_denomination_cs_r_pub (const struct TALER_DenominationHash *h_denom_pub, const struct TALER_WithdrawNonce *nonce, - enum TALER_ErrorCode *ec); + struct TALER_DenominationCsPublicR *r_pub); /** diff --git a/src/exchange/taler-exchange-httpd_recoup.c b/src/exchange/taler-exchange-httpd_recoup.c index 1abb88531..cb77ba3f8 100644 --- a/src/exchange/taler-exchange-httpd_recoup.c +++ b/src/exchange/taler-exchange-httpd_recoup.c @@ -265,12 +265,16 @@ verify_and_execute_recoup ( TALER_EC_EXCHANGE_RECOUP_BLINDING_FAILED, NULL); } - TALER_coin_ev_hash ( - blinded_planchet.details.rsa_blinded_planchet.blinded_msg, - blinded_planchet.details.rsa_blinded_planchet. - blinded_msg_size, - &pc.h_blind); - GNUNET_free (blinded_planchet.details.rsa_blinded_planchet.blinded_msg); + if (GNUNET_OK != TALER_coin_ev_hash (&blinded_planchet, + &pc.h_blind)) + { + GNUNET_break (0); + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE, + NULL); + } + TALER_blinded_planchet_free (&blinded_planchet); } pc.coin_sig = coin_sig; diff --git a/src/exchange/taler-exchange-httpd_refreshes_reveal.c b/src/exchange/taler-exchange-httpd_refreshes_reveal.c index 5a46aa22e..eba8efbda 100644 --- a/src/exchange/taler-exchange-httpd_refreshes_reveal.c +++ b/src/exchange/taler-exchange-httpd_refreshes_reveal.c @@ -181,6 +181,7 @@ check_commitment (struct RevealContext *rctx, { struct TALER_RefreshCoinData *rcd = &rce->new_coins[j]; struct TALER_PlanchetSecretsP ps; + struct TALER_ExchangeWithdrawValues alg_values; struct TALER_PlanchetDetail pd; struct TALER_CoinPubHash c_hash; @@ -188,9 +189,11 @@ check_commitment (struct RevealContext *rctx, TALER_planchet_setup_refresh (&ts, j, &ps); + // TODO: implement cipher handling + alg_values.cipher = TALER_DENOMINATION_RSA; GNUNET_assert (GNUNET_OK == TALER_planchet_prepare (rcd->dk, - NULL, /* not needed in RSA*/ + &alg_values, &ps, &c_hash, &pd)); diff --git a/src/exchange/taler-exchange-httpd_responses.c b/src/exchange/taler-exchange-httpd_responses.c index 66a3b0af9..8aa54712c 100644 --- a/src/exchange/taler-exchange-httpd_responses.c +++ b/src/exchange/taler-exchange-httpd_responses.c @@ -491,6 +491,53 @@ TEH_RESPONSE_reply_expired_denom_pub_hash ( } +MHD_RESULT +TEH_RESPONSE_reply_invalid_denom_cipher_for_operation ( + struct MHD_Connection *connection, + const struct TALER_DenominationHash *dph) +{ + struct TALER_ExchangePublicKeyP epub; + struct TALER_ExchangeSignatureP esig; + struct GNUNET_TIME_Timestamp now; + enum TALER_ErrorCode ec; + + now = GNUNET_TIME_timestamp_get (); + { + struct TALER_DenominationUnknownAffirmationPS dua = { + .purpose.size = htonl (sizeof (dua)), + .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_UNKNOWN), + .timestamp = GNUNET_TIME_timestamp_hton (now), + .h_denom_pub = *dph, + }; + + ec = TEH_keys_exchange_sign (&dua, + &epub, + &esig); + } + if (TALER_EC_NONE != ec) + { + GNUNET_break (0); + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + ec, + NULL); + } + return TALER_MHD_REPLY_JSON_PACK ( + connection, + MHD_HTTP_NOT_FOUND, + TALER_JSON_pack_ec ( + TALER_EC_EXCHANGE_GENERIC_INVALID_DENOMINATION_CIPHER_FOR_OPERATION), + GNUNET_JSON_pack_timestamp ("timestamp", + now), + GNUNET_JSON_pack_data_auto ("exchange_pub", + &epub), + GNUNET_JSON_pack_data_auto ("exchange_sig", + &esig), + GNUNET_JSON_pack_data_auto ("h_denom_pub", + dph)); +} + + /** * Send proof that a request is invalid to client because of * insufficient funds. This function will create a message with all diff --git a/src/exchange/taler-exchange-httpd_responses.h b/src/exchange/taler-exchange-httpd_responses.h index db2286ffa..48309a41d 100644 --- a/src/exchange/taler-exchange-httpd_responses.h +++ b/src/exchange/taler-exchange-httpd_responses.h @@ -79,6 +79,19 @@ TEH_RESPONSE_reply_expired_denom_pub_hash ( const char *oper); +/** + * Send assertion that the given denomination cannot be used for this operation. + * + * @param connection connection to the client + * @param dph denomination public key hash + * @return MHD result code + */ +MHD_RESULT +TEH_RESPONSE_reply_invalid_denom_cipher_for_operation ( + struct MHD_Connection *connection, + const struct TALER_DenominationHash *dph); + + /** * Send proof that a request is invalid to client because of * insufficient funds. This function will create a message with all diff --git a/src/exchange/taler-exchange-httpd_withdraw.c b/src/exchange/taler-exchange-httpd_withdraw.c index 9925fa8e6..a82a6daa0 100644 --- a/src/exchange/taler-exchange-httpd_withdraw.c +++ b/src/exchange/taler-exchange-httpd_withdraw.c @@ -332,36 +332,8 @@ TEH_handler_withdraw (struct TEH_RequestContext *rc, &wc.collectable.reserve_sig), GNUNET_JSON_spec_fixed_auto ("denom_pub_hash", &wc.collectable.denom_pub_hash), - GNUNET_JSON_spec_end () - }; - // holds pointer to coin_ev_rsa/cs_spec for freeing - struct GNUNET_JSON_Specification *coin_ev_spec = NULL; - struct GNUNET_JSON_Specification coin_ev_rsa_spec[] = { - GNUNET_JSON_spec_varsize ( - "coin_ev", - (void **) &wc.blinded_planchet.details.rsa_blinded_planchet.blinded_msg, - &wc.blinded_planchet.details.rsa_blinded_planchet.blinded_msg_size), - GNUNET_JSON_spec_end () - }; - json_t *coin_ev_cs_json; - struct GNUNET_JSON_Specification coin_ev_cs_json_spec[] = { - GNUNET_JSON_spec_json ("coin_ev", - &coin_ev_cs_json), - GNUNET_JSON_spec_end () - }; - struct GNUNET_JSON_Specification coin_ev_cs_spec[] = { - GNUNET_JSON_spec_fixed ( - "nonce", - &wc.blinded_planchet.details.cs_blinded_planchet.nonce, - sizeof (wc.blinded_planchet.details.cs_blinded_planchet.nonce)), - GNUNET_JSON_spec_fixed ( - "c0", - &wc.blinded_planchet.details.cs_blinded_planchet.c[0], - sizeof (wc.blinded_planchet.details.cs_blinded_planchet.c[0])), - GNUNET_JSON_spec_fixed ( - "c1", - &wc.blinded_planchet.details.cs_blinded_planchet.c[1], - sizeof (wc.blinded_planchet.details.cs_blinded_planchet.c[1])), + TALER_JSON_spec_blinded_planchet ("coin_ev", + &wc.blinded_planchet), GNUNET_JSON_spec_end () }; enum TALER_ErrorCode ec; @@ -492,36 +464,14 @@ TEH_handler_withdraw (struct TEH_RequestContext *rc, enum GNUNET_GenericReturnValue res; wc.blinded_planchet.cipher = dk->denom_pub.cipher; switch (wc.blinded_planchet.cipher) + + if (dk->denom_pub.cipher != wc.blinded_planchet.cipher) { - case TALER_DENOMINATION_RSA: - res = TALER_MHD_parse_json_data (rc->connection, - root, - coin_ev_rsa_spec); - if (GNUNET_OK != res) - return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES; - coin_ev_spec = coin_ev_rsa_spec; - break; - case TALER_DENOMINATION_CS: - // coin_ev for CS is nested - res = TALER_MHD_parse_json_data (rc->connection, - root, - coin_ev_cs_json_spec); - if (GNUNET_OK != res) - return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES; - res = TALER_MHD_parse_json_data (rc->connection, - coin_ev_cs_json, - coin_ev_cs_spec); - GNUNET_JSON_parse_free (coin_ev_cs_json_spec); - if (GNUNET_OK != res) - return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES; - coin_ev_spec = coin_ev_cs_spec; - break; - default: - GNUNET_break (0); + /* denomination cipher and blinded planchet cipher not the same */ GNUNET_JSON_parse_free (spec); return TALER_MHD_reply_with_error (rc->connection, - MHD_HTTP_FORBIDDEN, - TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE, + MHD_HTTP_BAD_REQUEST, + TALER_EC_EXCHANGE_GENERIC_CIPHER_MISMATCH, NULL); } } @@ -533,8 +483,6 @@ TEH_handler_withdraw (struct TEH_RequestContext *rc, &dk->meta.fee_withdraw)) { GNUNET_JSON_parse_free (spec); - if (NULL != coin_ev_spec) - GNUNET_JSON_parse_free (coin_ev_spec); return TALER_MHD_reply_with_error (rc->connection, MHD_HTTP_INTERNAL_SERVER_ERROR, TALER_EC_EXCHANGE_WITHDRAW_AMOUNT_FEE_OVERFLOW, @@ -554,27 +502,13 @@ TEH_handler_withdraw (struct TEH_RequestContext *rc, = htonl (TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW); wc.wsrd.h_denomination_pub = wc.collectable.denom_pub_hash; - switch (wc.blinded_planchet.cipher) + if (GNUNET_OK != TALER_coin_ev_hash (&wc.blinded_planchet, + &wc.wsrd.h_coin_envelope)) { - case TALER_DENOMINATION_RSA: - TALER_coin_ev_hash ( - wc.blinded_planchet.details.rsa_blinded_planchet.blinded_msg, - wc.blinded_planchet.details.rsa_blinded_planchet.blinded_msg_size, - &wc.wsrd.h_coin_envelope); - break; - case TALER_DENOMINATION_CS: - TALER_coin_ev_hash ( - &wc.blinded_planchet.details.cs_blinded_planchet, - sizeof (wc.blinded_planchet.details.cs_blinded_planchet), - &wc.wsrd.h_coin_envelope); - break; - default: GNUNET_break (0); GNUNET_JSON_parse_free (spec); - if (NULL != coin_ev_spec) - GNUNET_JSON_parse_free (coin_ev_spec); return TALER_MHD_reply_with_error (rc->connection, - MHD_HTTP_FORBIDDEN, + MHD_HTTP_INTERNAL_SERVER_ERROR, TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE, NULL); } @@ -588,8 +522,6 @@ TEH_handler_withdraw (struct TEH_RequestContext *rc, TALER_LOG_WARNING ( "Client supplied invalid signature for withdraw request\n"); GNUNET_JSON_parse_free (spec); - if (NULL != coin_ev_spec) - GNUNET_JSON_parse_free (coin_ev_spec); return TALER_MHD_reply_with_error (rc->connection, MHD_HTTP_FORBIDDEN, TALER_EC_EXCHANGE_WITHDRAW_RESERVE_SIGNATURE_INVALID, @@ -618,8 +550,6 @@ TEH_handler_withdraw (struct TEH_RequestContext *rc, default: GNUNET_break (0); GNUNET_JSON_parse_free (spec); - if (NULL != coin_ev_spec) - GNUNET_JSON_parse_free (coin_ev_spec); return TALER_MHD_reply_with_error (rc->connection, MHD_HTTP_FORBIDDEN, TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE, @@ -634,8 +564,6 @@ TEH_handler_withdraw (struct TEH_RequestContext *rc, { GNUNET_break (0); GNUNET_JSON_parse_free (spec); - if (NULL != coin_ev_spec) - GNUNET_JSON_parse_free (coin_ev_spec); return TALER_MHD_reply_with_ec (rc->connection, ec, NULL); @@ -657,16 +585,12 @@ TEH_handler_withdraw (struct TEH_RequestContext *rc, (or we might have done it optimistically above). */ TALER_blinded_denom_sig_free (&wc.collectable.sig); GNUNET_JSON_parse_free (spec); - if (NULL != coin_ev_spec) - GNUNET_JSON_parse_free (coin_ev_spec); return mhd_ret; } } /* Clean up and send back final response */ GNUNET_JSON_parse_free (spec); - if (NULL != coin_ev_spec) - GNUNET_JSON_parse_free (coin_ev_spec); { MHD_RESULT ret; diff --git a/src/exchangedb/test_exchangedb.c b/src/exchangedb/test_exchangedb.c index 75517ca18..97acab2a3 100644 --- a/src/exchangedb/test_exchangedb.c +++ b/src/exchangedb/test_exchangedb.c @@ -576,22 +576,25 @@ test_melting (void) struct TALER_PlanchetDetail pd; struct TALER_BlindedDenominationSignature bds; struct TALER_PlanchetSecretsP ps; + struct TALER_ExchangeWithdrawValues alg_values; RND_BLK (&refresh_session.coin.coin_pub); - TALER_planchet_blinding_secret_create (&ps, TALER_DENOMINATION_RSA, NULL); + alg_values.cipher = TALER_DENOMINATION_RSA; + TALER_planchet_blinding_secret_create (&ps, + &alg_values); GNUNET_assert (GNUNET_OK == TALER_denom_blind (&dkp->pub, &ps.blinding_key, NULL, /* FIXME-Oec */ &refresh_session.coin.coin_pub, - NULL, /* Not needed in RSA */ + &alg_values, &c_hash, &pd.blinded_planchet)); GNUNET_assert (GNUNET_OK == TALER_denom_sign_blinded (&bds, &dkp->priv, &pd.blinded_planchet)); - GNUNET_free (pd.blinded_planchet.details.rsa_blinded_planchet.blinded_msg); + TALER_blinded_planchet_free (&pd.blinded_planchet); GNUNET_assert (GNUNET_OK == TALER_denom_sig_unblind (&refresh_session.coin.denom_sig, &bds, @@ -1713,27 +1716,28 @@ run (void *cls) pd.coin_ev_size)); GNUNET_free (pd.coin_ev); } + struct TALER_ExchangeWithdrawValues alg_values; + RND_BLK (&coin_pub); - TALER_planchet_blinding_secret_create (&ps, TALER_DENOMINATION_RSA,NULL); + alg_values.cipher = TALER_DENOMINATION_RSA; + TALER_planchet_blinding_secret_create (&ps, + &alg_values); GNUNET_assert (GNUNET_OK == TALER_denom_blind (&dkp->pub, &ps.blinding_key, NULL, /* FIXME-Oec */ &coin_pub, - NULL, /* Not needed in RSA */ + &alg_values, &c_hash, &pd.blinded_planchet)); - TALER_coin_ev_hash ( - pd.blinded_planchet.details.rsa_blinded_planchet.blinded_msg, - pd.blinded_planchet.details.rsa_blinded_planchet. - blinded_msg_size, - &cbc.h_coin_envelope); + GNUNET_assert (GNUNET_OK == TALER_coin_ev_hash (&pd.blinded_planchet, + &cbc.h_coin_envelope)); GNUNET_assert (GNUNET_OK == TALER_denom_sign_blinded (&cbc.sig, &dkp->priv, &pd.blinded_planchet)); - GNUNET_free (pd.blinded_planchet.details.rsa_blinded_planchet.blinded_msg); + TALER_blinded_planchet_free (&pd.blinded_planchet); } cbc.reserve_pub = reserve_pub; diff --git a/src/include/taler_crypto_lib.h b/src/include/taler_crypto_lib.h index c02ab4fbd..c6e2185f0 100644 --- a/src/include/taler_crypto_lib.h +++ b/src/include/taler_crypto_lib.h @@ -1230,13 +1230,12 @@ TALER_test_coin_valid (const struct TALER_CoinPublicInfo *coin_public_info, /** * Compute the hash of a blinded coin. * - * @param coin_ev blinded coin - * @param coin_ev_size number of bytes in @a coin_ev + * @param blinded_planchet blinded planchet * @param[out] bch where to write the hash + * @return #GNUNET_OK when successful, #GNUNET_SYSERR if an internal error occured */ -void -TALER_coin_ev_hash (const void *coin_ev, - size_t coin_ev_size, +enum GNUNET_GenericReturnValue +TALER_coin_ev_hash (const struct TALER_BlindedPlanchet *blinded_planchet, struct TALER_BlindedCoinHash *bch); @@ -1441,19 +1440,21 @@ TALER_planchet_setup_refresh (const struct TALER_TransferSecretP *secret_seed, * Setup information for a fresh coin. * * @param[out] ps value to initialize + * @oaram alg_values WitdrawValues containing cipher */ void TALER_planchet_setup_random (struct TALER_PlanchetSecretsP *ps, - enum TALER_DenominationCipher cipher); + const struct + TALER_ExchangeWithdrawValues *alg_values); /** * Create a blinding secret @a bs for @a cipher. * * @param[out] ps planchet with blinding secret to initialize + * @param alg_values withdraw values containing cipher and additional CS values */ void TALER_planchet_blinding_secret_create (struct TALER_PlanchetSecretsP *ps, - enum TALER_DenominationCipher cipher, const struct TALER_ExchangeWithdrawValues *alg_values); @@ -1476,6 +1477,16 @@ TALER_planchet_prepare (const struct TALER_DenominationPublicKey *dk, struct TALER_PlanchetDetail *pd); +/** + * Frees blinded message inside blinded planchet depending on blinded_planchet->cipher + * Does not free the @a blinded_planchet itself! + * + * @param blinded_planchet blnded planchet + */ +void +TALER_blinded_planchet_free (struct TALER_BlindedPlanchet *blinded_planchet); + + /** * Obtain a coin from the planchet's secrets and the blind signature * of the exchange. diff --git a/src/include/taler_exchange_service.h b/src/include/taler_exchange_service.h index b4142d6f9..fcf907c58 100644 --- a/src/include/taler_exchange_service.h +++ b/src/include/taler_exchange_service.h @@ -1461,6 +1461,7 @@ TALER_EXCHANGE_withdraw ( const struct TALER_EXCHANGE_DenomPublicKey *pk, const struct TALER_ReservePrivateKeyP *reserve_priv, struct TALER_PlanchetSecretsP *ps, + struct TALER_ExchangeWithdrawValues *alg_values, TALER_EXCHANGE_WithdrawCallback res_cb, void *res_cb_cls); diff --git a/src/include/taler_json_lib.h b/src/include/taler_json_lib.h index 51ebe6d90..ea6926226 100644 --- a/src/include/taler_json_lib.h +++ b/src/include/taler_json_lib.h @@ -117,6 +117,20 @@ TALER_JSON_pack_blinded_denom_sig ( const struct TALER_BlindedDenominationSignature *sig); +/** + * Generate packer instruction for a JSON field of type + * blinded planchet. + * + * @param name name of the field to add to the object + * @param blinded_planchet blinded planchet + * @return json pack specification + */ +struct GNUNET_JSON_PackSpec +TALER_JSON_pack_blinded_planchet ( + const char *name, + const struct TALER_BlindedPlanchet *blinded_planchet); + + /** * Generate packer instruction for a JSON field of type * amount. @@ -260,6 +274,19 @@ TALER_JSON_spec_blinded_denom_sig ( struct TALER_BlindedDenominationSignature *sig); +/** + * Generate line in parser specification for a + * blinded planchet. + * + * @param field name of the field + * @param[out] blinded_planchet the blinded planchet to initialize + * @return corresponding field spec + */ +struct GNUNET_JSON_Specification +TALER_JSON_spec_blinded_planchet (const char *field, + struct TALER_BlindedPlanchet *blinded_planchet); + + /** * The expected field stores a possibly internationalized string. * Internationalization means that there is another field "$name_i18n" diff --git a/src/json/json_helper.c b/src/json/json_helper.c index 41d5c82e0..c6dee2480 100644 --- a/src/json/json_helper.c +++ b/src/json/json_helper.c @@ -567,6 +567,129 @@ TALER_JSON_spec_blinded_denom_sig ( } +/** + * Parse given JSON object to blinded planchet. + * + * @param cls closure, NULL + * @param root the json object representing data + * @param[out] spec where to write the data + * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error + */ +static enum GNUNET_GenericReturnValue +parse_blinded_planchet (void *cls, + json_t *root, + struct GNUNET_JSON_Specification *spec) +{ + struct TALER_BlindedPlanchet *blinded_planchet = spec->ptr; + uint32_t cipher; + struct GNUNET_JSON_Specification dspec[] = { + GNUNET_JSON_spec_uint32 ("cipher", + &cipher), + GNUNET_JSON_spec_end () + }; + const char *emsg; + unsigned int eline; + + (void) cls; + if (GNUNET_OK != + GNUNET_JSON_parse (root, + dspec, + &emsg, + &eline)) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + blinded_planchet->cipher = (enum TALER_DenominationCipher) cipher; + switch (blinded_planchet->cipher) + { + case TALER_DENOMINATION_RSA: + { + struct GNUNET_JSON_Specification ispec[] = { + GNUNET_JSON_spec_varsize ( + "rsa_blinded_planchet", + &blinded_planchet->details.rsa_blinded_planchet.blinded_msg, + &blinded_planchet->details.rsa_blinded_planchet.blinded_msg_size), + GNUNET_JSON_spec_end () + }; + + if (GNUNET_OK != + GNUNET_JSON_parse (root, + ispec, + &emsg, + &eline)) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + return GNUNET_OK; + } + case TALER_DENOMINATION_CS: + { + struct GNUNET_JSON_Specification ispec[] = { + GNUNET_JSON_spec_fixed_auto ( + "cs_nonce", + &blinded_planchet->details.cs_blinded_planchet.nonce), + GNUNET_JSON_spec_fixed_auto ( + "cs_blinded_c0", + &blinded_planchet->details.cs_blinded_planchet.c[0]), + GNUNET_JSON_spec_fixed_auto ( + "cs_blinded_c1", + &blinded_planchet->details.cs_blinded_planchet.c[1]), + GNUNET_JSON_spec_end () + }; + + if (GNUNET_OK != + GNUNET_JSON_parse (root, + ispec, + &emsg, + &eline)) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + return GNUNET_OK; + } + break; + default: + GNUNET_break_op (0); + return GNUNET_SYSERR; + } +} + + +/** + * Cleanup data left from parsing blinded planchet. + * + * @param cls closure, NULL + * @param[out] spec where to free the data + */ +static void +clean_blinded_planchet (void *cls, + struct GNUNET_JSON_Specification *spec) +{ + struct TALER_BlindedPlanchet *blinded_planchet = spec->ptr; + + (void) cls; + TALER_blinded_planchet_free (blinded_planchet); +} + + +struct GNUNET_JSON_Specification +TALER_JSON_spec_blinded_planchet (const char *field, + struct TALER_BlindedPlanchet *blinded_planchet) +{ + struct GNUNET_JSON_Specification ret = { + .parser = &parse_blinded_planchet, + .cleaner = &clean_blinded_planchet, + .field = field, + .ptr = blinded_planchet + }; + + return ret; +} + + /** * Closure for #parse_i18n_string. */ diff --git a/src/json/json_pack.c b/src/json/json_pack.c index 8b056f34e..cf6504c06 100644 --- a/src/json/json_pack.c +++ b/src/json/json_pack.c @@ -154,6 +154,47 @@ TALER_JSON_pack_blinded_denom_sig ( } +struct GNUNET_JSON_PackSpec +TALER_JSON_pack_blinded_planchet ( + const char *name, + const struct TALER_BlindedPlanchet *blinded_planchet) +{ + struct GNUNET_JSON_PackSpec ps = { + .field_name = name, + }; + + switch (blinded_planchet->cipher) + { + case TALER_DENOMINATION_RSA: + ps.object = GNUNET_JSON_PACK ( + GNUNET_JSON_pack_uint64 ("cipher", + TALER_DENOMINATION_RSA), + GNUNET_JSON_pack_data_varsize ( + "rsa_blinded_planchet", + blinded_planchet->details.rsa_blinded_planchet.blinded_msg, + blinded_planchet->details.rsa_blinded_planchet.blinded_msg_size)); + break; + case TALER_DENOMINATION_CS: + ps.object = GNUNET_JSON_PACK ( + GNUNET_JSON_pack_uint64 ("cipher", + TALER_DENOMINATION_CS), + GNUNET_JSON_pack_data_auto ( + "cs_nonce", + &blinded_planchet->details.cs_blinded_planchet.nonce), + GNUNET_JSON_pack_data_auto ( + "cs_blinded_c0", + &blinded_planchet->details.cs_blinded_planchet.c[0]), + GNUNET_JSON_pack_data_auto ( + "cs_blinded_c1", + &blinded_planchet->details.cs_blinded_planchet.c[1])); + break; + default: + GNUNET_assert (0); + } + return ps; +} + + struct GNUNET_JSON_PackSpec TALER_JSON_pack_amount (const char *name, const struct TALER_Amount *amount) diff --git a/src/lib/exchange_api_link.c b/src/lib/exchange_api_link.c index f2ef26d1a..78f8804a1 100644 --- a/src/lib/exchange_api_link.c +++ b/src/lib/exchange_api_link.c @@ -135,6 +135,7 @@ parse_link_coin (const struct TALER_EXCHANGE_LinkHandle *lh, *coin_priv = fc.coin_priv; /* verify link_sig */ { + struct TALER_ExchangeWithdrawValues alg_values; struct TALER_PlanchetDetail pd; struct TALER_CoinPubHash c_hash; struct TALER_CoinSpendPublicKeyP old_coin_pub; @@ -142,9 +143,11 @@ parse_link_coin (const struct TALER_EXCHANGE_LinkHandle *lh, GNUNET_CRYPTO_eddsa_key_get_public (&lh->coin_priv.eddsa_priv, &old_coin_pub.eddsa_pub); + // TODO: implement cipher handling + alg_values.cipher = TALER_DENOMINATION_RSA; if (GNUNET_OK != TALER_planchet_prepare (&rpub, - NULL, /* not needed in RSA*/ + &alg_values, &fc, &c_hash, &pd)) @@ -169,12 +172,11 @@ parse_link_coin (const struct TALER_EXCHANGE_LinkHandle *lh, &link_sig)) { GNUNET_break_op (0); - GNUNET_free ( - pd.blinded_planchet.details.rsa_blinded_planchet.blinded_msg); + TALER_blinded_planchet_free (&pd.blinded_planchet); GNUNET_JSON_parse_free (spec); return GNUNET_SYSERR; } - GNUNET_free (pd.blinded_planchet.details.rsa_blinded_planchet.blinded_msg); + TALER_blinded_planchet_free (&pd.blinded_planchet); } /* clean up */ diff --git a/src/lib/exchange_api_refresh_common.c b/src/lib/exchange_api_refresh_common.c index 171b9adb1..65c7d6ba4 100644 --- a/src/lib/exchange_api_refresh_common.c +++ b/src/lib/exchange_api_refresh_common.c @@ -424,15 +424,18 @@ TALER_EXCHANGE_refresh_prepare ( { struct TALER_PlanchetSecretsP *fc = &md.fresh_coins[i][j]; struct TALER_RefreshCoinData *rcd = &rce[i].new_coins[j]; + struct TALER_ExchangeWithdrawValues alg_values; struct TALER_PlanchetDetail pd; struct TALER_CoinPubHash c_hash; TALER_planchet_setup_refresh (&trans_sec[i], j, fc); + // TODO: implement cipher handling + alg_values.cipher = TALER_DENOMINATION_RSA; if (GNUNET_OK != TALER_planchet_prepare (&md.fresh_pks[j], - NULL, /* not needed in RSA*/ + &alg_values, fc, &c_hash, &pd)) diff --git a/src/lib/exchange_api_refreshes_reveal.c b/src/lib/exchange_api_refreshes_reveal.c index 42e0cc328..82f92322a 100644 --- a/src/lib/exchange_api_refreshes_reveal.c +++ b/src/lib/exchange_api_refreshes_reveal.c @@ -138,6 +138,7 @@ refresh_reveal_ok (struct TALER_EXCHANGE_RefreshesRevealHandle *rrh, struct TALER_DenominationPublicKey *pk; json_t *jsonai; struct TALER_BlindedDenominationSignature blind_sig; + struct TALER_ExchangeWithdrawValues alg_values; struct TALER_CoinSpendPublicKeyP coin_pub; struct TALER_CoinPubHash coin_hash; struct GNUNET_JSON_Specification spec[] = { @@ -170,12 +171,14 @@ refresh_reveal_ok (struct TALER_EXCHANGE_RefreshesRevealHandle *rrh, TALER_coin_pub_hash (&coin_pub, NULL, /* FIXME-Oec */ &coin_hash); + // TODO: implement cipher handling + alg_values.cipher = TALER_DENOMINATION_RSA; if (GNUNET_OK != TALER_planchet_to_coin (pk, &blind_sig, fc, &coin_hash, - NULL, /* Not needed in RSA case */ + &alg_values, &coin)) { GNUNET_break_op (0); @@ -347,6 +350,7 @@ TALER_EXCHANGE_refreshes_reveal ( for (unsigned int i = 0; inum_fresh_coins; i++) { struct TALER_DenominationHash denom_hash; + struct TALER_ExchangeWithdrawValues alg_values; struct TALER_PlanchetDetail pd; struct TALER_CoinPubHash c_hash; @@ -357,9 +361,11 @@ TALER_EXCHANGE_refreshes_reveal ( GNUNET_JSON_from_data_auto ( &denom_hash))); + // TODO: implement cipher handling + alg_values.cipher = TALER_DENOMINATION_RSA; if (GNUNET_OK != TALER_planchet_prepare (&md->fresh_pks[i], - NULL, /* not needed in RSA*/ + &alg_values, &md->fresh_coins[noreveal_index][i], &c_hash, &pd)) @@ -395,7 +401,7 @@ TALER_EXCHANGE_refreshes_reveal ( link_sigs, GNUNET_JSON_from_data_auto (&link_sig))); } - GNUNET_free (pd.blinded_planchet.details.rsa_blinded_planchet.blinded_msg); + TALER_blinded_planchet_free (&pd.blinded_planchet); } /* build array of transfer private keys */ diff --git a/src/lib/exchange_api_withdraw.c b/src/lib/exchange_api_withdraw.c index 5102b35a3..204c72359 100644 --- a/src/lib/exchange_api_withdraw.c +++ b/src/lib/exchange_api_withdraw.c @@ -186,10 +186,8 @@ withdraw_cs_stage_two_callback (void *cls, switch (csrr->hr.http_status) { case MHD_HTTP_OK: - wh->alg_values.cipher = TALER_DENOMINATION_CS; wh->alg_values.details.cs_values.r_pub = csrr->details.success.r_pubs; TALER_planchet_blinding_secret_create (&wh->ps, - wh->pk.key.cipher, &wh->alg_values); if (GNUNET_OK != TALER_planchet_prepare (&wh->pk.key, @@ -244,6 +242,7 @@ TALER_EXCHANGE_withdraw ( const struct TALER_EXCHANGE_DenomPublicKey *pk, const struct TALER_ReservePrivateKeyP *reserve_priv, struct TALER_PlanchetSecretsP *ps, + struct TALER_ExchangeWithdrawValues *alg_values, TALER_EXCHANGE_WithdrawCallback res_cb, void *res_cb_cls) { @@ -255,6 +254,7 @@ TALER_EXCHANGE_withdraw ( wh->cb_cls = res_cb_cls; wh->reserve_priv = reserve_priv; wh->ps = *ps; + wh->alg_values = *alg_values, wh->pk = *pk; wh->csrh = NULL; @@ -265,7 +265,7 @@ TALER_EXCHANGE_withdraw ( case TALER_DENOMINATION_RSA: if (GNUNET_OK != TALER_planchet_prepare (&pk->key, - NULL, /* not needed in RSA*/ + &wh->alg_values, ps, &wh->c_hash, &wh->pd)) @@ -279,9 +279,7 @@ TALER_EXCHANGE_withdraw ( wh->reserve_priv, &handle_reserve_withdraw_finished, wh); - GNUNET_free ( - wh->pd.blinded_planchet.details.rsa_blinded_planchet.blinded_msg); - return wh; + break; case TALER_DENOMINATION_CS: TALER_cs_withdraw_nonce_derive (&ps->coin_priv, &wh->pd.blinded_planchet.details. @@ -292,12 +290,14 @@ TALER_EXCHANGE_withdraw ( cs_blinded_planchet.nonce, &withdraw_cs_stage_two_callback, wh); - return wh; + break; default: GNUNET_break (0); GNUNET_free (wh); return NULL; } + TALER_blinded_planchet_free (&wh->pd.blinded_planchet); + return wh; } diff --git a/src/lib/exchange_api_withdraw2.c b/src/lib/exchange_api_withdraw2.c index cb767e434..6db0815c6 100644 --- a/src/lib/exchange_api_withdraw2.c +++ b/src/lib/exchange_api_withdraw2.c @@ -437,22 +437,9 @@ TALER_EXCHANGE_withdraw2 ( TALER_amount_hton (&req.amount_with_fee, &wh->requested_amount); - switch (dk->key.cipher) + if (GNUNET_OK != TALER_coin_ev_hash (&pd->blinded_planchet, + &req.h_coin_envelope)) { - case TALER_DENOMINATION_RSA: - TALER_coin_ev_hash ( - pd->blinded_planchet.details.rsa_blinded_planchet.blinded_msg, - pd->blinded_planchet.details.rsa_blinded_planchet. - blinded_msg_size, - &req.h_coin_envelope); - break; - case TALER_DENOMINATION_CS: - TALER_coin_ev_hash ( - &pd->blinded_planchet.details.cs_blinded_planchet, - sizeof (pd->blinded_planchet.details.cs_blinded_planchet), - &req.h_coin_envelope); - break; - default: GNUNET_break (0); GNUNET_free (wh); return NULL; @@ -463,45 +450,13 @@ TALER_EXCHANGE_withdraw2 ( } { - json_t *withdraw_obj; - switch (dk->key.cipher) - { - case TALER_DENOMINATION_RSA: - withdraw_obj = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_data_auto ("denom_pub_hash", - &pd->denom_pub_hash), - GNUNET_JSON_pack_data_varsize ("coin_ev", - pd->blinded_planchet.details. - rsa_blinded_planchet.blinded_msg, - pd->blinded_planchet.details. - rsa_blinded_planchet.blinded_msg_size), - GNUNET_JSON_pack_data_auto ("reserve_sig", - &reserve_sig)); - break; - case TALER_DENOMINATION_CS: - json_t *coin_ev_object = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_data_auto ("nonce", - &pd->blinded_planchet.details. - cs_blinded_planchet.nonce), - GNUNET_JSON_pack_data_auto ("c0", - &pd->blinded_planchet.details. - cs_blinded_planchet.c[0]), - GNUNET_JSON_pack_data_auto ("c1", - &pd->blinded_planchet.details. - cs_blinded_planchet.c[1])); - withdraw_obj = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_data_auto ("denom_pub_hash", - &pd->denom_pub_hash), - GNUNET_JSON_pack_object_steal ("coin_ev", - coin_ev_object), - GNUNET_JSON_pack_data_auto ("reserve_sig", - &reserve_sig)); - break; - default: - GNUNET_break (0); - GNUNET_free (wh); - return NULL; - } + json_t *withdraw_obj = GNUNET_JSON_PACK ( + GNUNET_JSON_pack_data_auto ("denom_pub_hash", + &pd->denom_pub_hash), + TALER_JSON_pack_blinded_planchet ("coin_ev", + &pd->blinded_planchet), + GNUNET_JSON_pack_data_auto ("reserve_sig", + &reserve_sig)); GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Attempting to withdraw from reserve %s\n", TALER_B2S (&wh->reserve_pub)); diff --git a/src/testing/testing_api_cmd_insert_deposit.c b/src/testing/testing_api_cmd_insert_deposit.c index eb1697d44..013c22932 100644 --- a/src/testing/testing_api_cmd_insert_deposit.c +++ b/src/testing/testing_api_cmd_insert_deposit.c @@ -202,21 +202,24 @@ insert_deposit_run (void *cls, struct TALER_PlanchetDetail pd; struct TALER_BlindedDenominationSignature bds; struct TALER_PlanchetSecretsP ps; + struct TALER_ExchangeWithdrawValues alg_values; - TALER_planchet_blinding_secret_create (&ps, TALER_DENOMINATION_RSA, NULL); + alg_values.cipher = TALER_DENOMINATION_RSA; + TALER_planchet_blinding_secret_create (&ps, + &alg_values); GNUNET_assert (GNUNET_OK == TALER_denom_blind (&dpk, &ps.blinding_key, NULL, /* FIXME-Oec */ &deposit.coin.coin_pub, - NULL, /* Not needed in RSA */ + &alg_values, &c_hash, &pd.blinded_planchet)); GNUNET_assert (GNUNET_OK == TALER_denom_sign_blinded (&bds, &denom_priv, &pd.blinded_planchet)); - GNUNET_free (pd.blinded_planchet.details.rsa_blinded_planchet.blinded_msg); + TALER_blinded_planchet_free (&pd.blinded_planchet); GNUNET_assert (GNUNET_OK == TALER_denom_sig_unblind (&deposit.coin.denom_sig, &bds, diff --git a/src/testing/testing_api_cmd_withdraw.c b/src/testing/testing_api_cmd_withdraw.c index 2a98765f4..da514ddfa 100644 --- a/src/testing/testing_api_cmd_withdraw.c +++ b/src/testing/testing_api_cmd_withdraw.c @@ -120,6 +120,11 @@ struct WithdrawState */ struct TALER_PlanchetSecretsP ps; + /** + * Withdraw Values used for planchet creation + */ + struct TALER_ExchangeWithdrawValues alg_values; + /** * Reserve history entry that corresponds to this operation. * Will be of type #TALER_EXCHANGE_RTT_WITHDRAWAL. @@ -391,9 +396,10 @@ withdraw_run (void *cls, ws->reserve_payto_uri = TALER_payto_from_reserve (ws->exchange_url, &ws->reserve_pub); + ws->alg_values.cipher = ws->cipher; if (NULL == ws->reuse_coin_key_ref) { - TALER_planchet_setup_random (&ws->ps, ws->cipher); + TALER_planchet_setup_random (&ws->ps, &ws->alg_values); } else { @@ -414,7 +420,7 @@ withdraw_run (void *cls, TALER_TESTING_get_trait_coin_priv (cref, index, &coin_priv)); - TALER_planchet_setup_random (&ws->ps, ws->cipher); + TALER_planchet_setup_random (&ws->ps, &ws->alg_values); ws->ps.coin_priv = *coin_priv; } if (NULL == ws->pk) @@ -449,6 +455,7 @@ withdraw_run (void *cls, ws->pk, rp, &ws->ps, + &ws->alg_values, &reserve_withdraw_cb, ws); if (NULL == ws->wsh) diff --git a/src/util/crypto.c b/src/util/crypto.c index 3e759e71b..50f2d97d3 100644 --- a/src/util/crypto.c +++ b/src/util/crypto.c @@ -209,11 +209,10 @@ TALER_cs_withdraw_nonce_derive (const struct void TALER_planchet_blinding_secret_create (struct TALER_PlanchetSecretsP *ps, - enum TALER_DenominationCipher cipher, const struct TALER_ExchangeWithdrawValues *alg_values) { - switch (cipher) + switch (alg_values->cipher) { case TALER_DENOMINATION_INVALID: GNUNET_break (0); @@ -244,18 +243,20 @@ TALER_planchet_blinding_secret_create (struct TALER_PlanchetSecretsP *ps, */ void TALER_planchet_setup_random (struct TALER_PlanchetSecretsP *ps, - enum TALER_DenominationCipher cipher) + const struct + TALER_ExchangeWithdrawValues *alg_values) { GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_STRONG, &ps->coin_priv, sizeof (struct TALER_CoinSpendPrivateKeyP)); - switch (cipher) + switch (alg_values->cipher) { case TALER_DENOMINATION_INVALID: GNUNET_break (0); return; case TALER_DENOMINATION_RSA: - TALER_planchet_blinding_secret_create (ps, TALER_DENOMINATION_RSA, NULL); + TALER_planchet_blinding_secret_create (ps, + alg_values); return; case TALER_DENOMINATION_CS: // Will be set in a later stage for Clause Blind Schnorr Scheme @@ -275,6 +276,8 @@ TALER_planchet_prepare (const struct TALER_DenominationPublicKey *dk, { struct TALER_CoinSpendPublicKeyP coin_pub; + GNUNET_assert (alg_values->cipher == dk->cipher); + GNUNET_CRYPTO_eddsa_key_get_public (&ps->coin_priv.eddsa_priv, &coin_pub.eddsa_pub); @@ -286,7 +289,7 @@ TALER_planchet_prepare (const struct TALER_DenominationPublicKey *dk, &ps->blinding_key, NULL, /* FIXME-Oec */ &coin_pub, - NULL, /* RSA has no alg Values */ + alg_values, c_hash, &pd->blinded_planchet)) { @@ -320,6 +323,23 @@ TALER_planchet_prepare (const struct TALER_DenominationPublicKey *dk, } +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: + // nothing to do for CS + break; + default: + GNUNET_break (0); + } +} + + enum GNUNET_GenericReturnValue TALER_planchet_to_coin (const struct TALER_DenominationPublicKey *dk, const struct @@ -471,14 +491,28 @@ TALER_refresh_get_commitment (struct TALER_RefreshCommitmentP *rc, } -void -TALER_coin_ev_hash (const void *coin_ev, - size_t coin_ev_size, +enum GNUNET_GenericReturnValue +TALER_coin_ev_hash (const struct TALER_BlindedPlanchet *blinded_planchet, struct TALER_BlindedCoinHash *bch) { - GNUNET_CRYPTO_hash (coin_ev, - coin_ev_size, - &bch->hash); + switch (blinded_planchet->cipher) + { + case TALER_DENOMINATION_RSA: + GNUNET_CRYPTO_hash ( + blinded_planchet->details.rsa_blinded_planchet.blinded_msg, + blinded_planchet->details.rsa_blinded_planchet.blinded_msg_size, + &bch->hash); + return GNUNET_OK; + case TALER_DENOMINATION_CS: + GNUNET_CRYPTO_hash ( + &blinded_planchet->details.cs_blinded_planchet, + sizeof (blinded_planchet->details.cs_blinded_planchet), + &bch->hash); + return GNUNET_OK; + default: + GNUNET_break (0); + return GNUNET_SYSERR; + } } diff --git a/src/util/test_crypto.c b/src/util/test_crypto.c index 28352a678..9f01b74c7 100644 --- a/src/util/test_crypto.c +++ b/src/util/test_crypto.c @@ -87,6 +87,7 @@ test_planchets_rsa (void) struct TALER_PlanchetSecretsP ps; struct TALER_DenominationPrivateKey dk_priv; struct TALER_DenominationPublicKey dk_pub; + struct TALER_ExchangeWithdrawValues alg_values; struct TALER_PlanchetDetail pd; struct TALER_BlindedDenominationSignature blind_sig; struct TALER_FreshCoin coin; @@ -108,10 +109,12 @@ test_planchets_rsa (void) &dk_pub, TALER_DENOMINATION_RSA, 1024)); - TALER_planchet_setup_random (&ps, TALER_DENOMINATION_RSA); + alg_values.cipher = TALER_DENOMINATION_RSA; + TALER_planchet_setup_random (&ps, + &alg_values); GNUNET_assert (GNUNET_OK == TALER_planchet_prepare (&dk_pub, - NULL, /* not needed in RSA*/ + &alg_values, &ps, &c_hash, &pd)); @@ -124,7 +127,7 @@ test_planchets_rsa (void) &blind_sig, &ps, &c_hash, - NULL, /* Not needed in RSA case */ + &alg_values, &coin)); TALER_blinded_denom_sig_free (&blind_sig); TALER_denom_sig_free (&coin.sig); @@ -157,7 +160,9 @@ test_planchets_cs (void) &dk_pub, TALER_DENOMINATION_CS)); - TALER_planchet_setup_random (&ps, TALER_DENOMINATION_CS); + alg_values.cipher = TALER_DENOMINATION_CS; + TALER_planchet_setup_random (&ps, + &alg_values); TALER_cs_withdraw_nonce_derive (&ps.coin_priv, &pd.blinded_planchet.details. cs_blinded_planchet.nonce); @@ -166,9 +171,7 @@ test_planchets_cs (void) &pd.blinded_planchet.details.cs_blinded_planchet.nonce, &dk_priv, &alg_values.details.cs_values.r_pub)); - // TODO: eliminate r_pubs parameter TALER_planchet_blinding_secret_create (&ps, - TALER_DENOMINATION_CS, &alg_values); GNUNET_assert (GNUNET_OK == diff --git a/src/util/test_helper_cs.c b/src/util/test_helper_cs.c index 22f39b34f..5a41c7fa1 100644 --- a/src/util/test_helper_cs.c +++ b/src/util/test_helper_cs.c @@ -268,9 +268,11 @@ test_r_derive (struct TALER_CRYPTO_CsDenominationHelper *dh) bool success = false; struct TALER_PlanchetSecretsP ps; struct TALER_CoinPubHash c_hash; - struct TALER_ExchangeWithdrawValues values; + struct TALER_ExchangeWithdrawValues alg_values; - TALER_planchet_setup_random (&ps, TALER_DENOMINATION_CS); + alg_values.cipher = TALER_DENOMINATION_CS; + TALER_planchet_setup_random (&ps, + &alg_values); for (unsigned int i = 0; i, @@ -452,7 +460,7 @@ perf_signing (struct TALER_CRYPTO_RsaDenominationHelper *dh, GNUNET_assert (GNUNET_YES == TALER_planchet_prepare (&keys[i].denom_pub, - NULL, /* not needed in RSA*/ + &alg_values, &ps, &c_hash, &pd)); @@ -480,8 +488,7 @@ perf_signing (struct TALER_CRYPTO_RsaDenominationHelper *dh, if (NUM_SIGN_PERFS <= j) break; } - GNUNET_free ( - pd.blinded_planchet.details.rsa_blinded_planchet.blinded_msg); + TALER_blinded_planchet_free (&pd.blinded_planchet); } } /* for i */ } /* for j */ -- cgit v1.2.3