From 025922950dcf39700625e04be9f6037af67dddf5 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Wed, 9 Feb 2022 22:02:29 +0100 Subject: pass exchange values to /recoup --- src/exchange/taler-exchange-httpd_csr.c | 16 +++--- src/exchange/taler-exchange-httpd_recoup.c | 19 +++++-- src/include/taler_json_lib.h | 28 ++++++++++ src/json/json_helper.c | 85 ++++++++++++++++++++++++++++++ src/json/json_pack.c | 39 +++++++++++++- src/lib/exchange_api_csr.c | 12 ++--- src/lib/exchange_api_recoup.c | 3 ++ 7 files changed, 178 insertions(+), 24 deletions(-) diff --git a/src/exchange/taler-exchange-httpd_csr.c b/src/exchange/taler-exchange-httpd_csr.c index 7417996dc..02bdb7dd6 100644 --- a/src/exchange/taler-exchange-httpd_csr.c +++ b/src/exchange/taler-exchange-httpd_csr.c @@ -41,7 +41,6 @@ TEH_handler_csr (struct TEH_RequestContext *rc, json_t *csr_requests; json_t *csr_response_ewvs; json_t *csr_response; - struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_json ("nks", &csr_requests), @@ -103,13 +102,15 @@ TEH_handler_csr (struct TEH_RequestContext *rc, } GNUNET_JSON_parse_free (spec); - struct TALER_DenominationCSPublicRPairP r_pubs[GNUNET_NZL (csr_requests_num)]; + struct TALER_ExchangeWithdrawValues ewvs[GNUNET_NZL (csr_requests_num)]; for (unsigned int i = 0; i < csr_requests_num; i++) { const struct TALER_CsNonce *nonce = &nonces[i]; const struct TALER_DenominationHash *denom_pub_hash = &denom_pub_hashes[i]; - struct TALER_DenominationCSPublicRPairP *r_pub = &r_pubs[i]; + struct TALER_DenominationCSPublicRPairP *r_pub + = &ewvs[i].details.cs_values.r_pub_pair; + ewvs[i].cipher = TALER_DENOMINATION_CS; // check denomination referenced by denom_pub_hash { struct TEH_KeyStateHandle *ksh; @@ -187,16 +188,11 @@ TEH_handler_csr (struct TEH_RequestContext *rc, csr_response_ewvs = json_array (); for (unsigned int i = 0; i < csr_requests_num; i++) { - const struct TALER_DenominationCSPublicRPairP *r_pub = &r_pubs[i]; json_t *csr_obj; csr_obj = GNUNET_JSON_PACK ( - 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))); + TALER_JSON_pack_exchange_withdraw_values ("ewv", + &ewvs[i])); GNUNET_assert (NULL != csr_obj); GNUNET_assert (0 == json_array_append_new (csr_response_ewvs, diff --git a/src/exchange/taler-exchange-httpd_recoup.c b/src/exchange/taler-exchange-httpd_recoup.c index 416eaf69d..d4ff52376 100644 --- a/src/exchange/taler-exchange-httpd_recoup.c +++ b/src/exchange/taler-exchange-httpd_recoup.c @@ -165,6 +165,8 @@ recoup_transaction (void *cls, * * @param connection the MHD connection to handle * @param coin information about the coin + * @param exchange_vals values contributed by the exchange + * during withdrawal * @param coin_bks blinding data of the coin (to be checked) * @param coin_sig signature of the coin * @return MHD result code @@ -173,6 +175,7 @@ static MHD_RESULT verify_and_execute_recoup ( struct MHD_Connection *connection, const struct TALER_CoinPublicInfo *coin, + const struct TALER_ExchangeWithdrawValues *exchange_vals, const union TALER_DenominationBlindingKeyP *coin_bks, const struct TALER_CoinSpendSignatureP *coin_sig) { @@ -242,6 +245,9 @@ verify_and_execute_recoup ( NULL); } + /* re-compute client-side blinding so we can + (a bit later) check that this coin was indeed + signed by us. */ { struct TALER_CoinPubHash c_hash; struct TALER_BlindedPlanchet blinded_planchet; @@ -251,7 +257,7 @@ verify_and_execute_recoup ( coin_bks, NULL, /* FIXME-Oec: TALER_AgeHash * */ &coin->coin_pub, - NULL, /* FIXME: handle CS */ + exchange_vals, &c_hash, &blinded_planchet)) { @@ -262,9 +268,10 @@ verify_and_execute_recoup ( TALER_EC_EXCHANGE_RECOUP_BLINDING_FAILED, NULL); } - if (GNUNET_OK != TALER_coin_ev_hash (&blinded_planchet, - &coin->denom_pub_hash, - &pc.h_blind)) + if (GNUNET_OK != + TALER_coin_ev_hash (&blinded_planchet, + &coin->denom_pub_hash, + &pc.h_blind)) { GNUNET_break (0); return TALER_MHD_reply_with_error (connection, @@ -365,11 +372,14 @@ TEH_handler_recoup (struct MHD_Connection *connection, struct TALER_CoinPublicInfo coin; union TALER_DenominationBlindingKeyP coin_bks; struct TALER_CoinSpendSignatureP coin_sig; + struct TALER_ExchangeWithdrawValues exchange_vals; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_fixed_auto ("denom_pub_hash", &coin.denom_pub_hash), TALER_JSON_spec_denom_sig ("denom_sig", &coin.denom_sig), + TALER_JSON_spec_exchange_withdraw_values ("ewv", + &exchange_vals), GNUNET_JSON_spec_fixed_auto ("coin_blind_key_secret", &coin_bks), GNUNET_JSON_spec_fixed_auto ("coin_sig", @@ -393,6 +403,7 @@ TEH_handler_recoup (struct MHD_Connection *connection, res = verify_and_execute_recoup (connection, &coin, + &exchange_vals, &coin_bks, &coin_sig); GNUNET_JSON_parse_free (spec); diff --git a/src/include/taler_json_lib.h b/src/include/taler_json_lib.h index 21b6d4e79..fef733917 100644 --- a/src/include/taler_json_lib.h +++ b/src/include/taler_json_lib.h @@ -131,6 +131,20 @@ TALER_JSON_pack_blinded_planchet ( const struct TALER_BlindedPlanchet *blinded_planchet); +/** + * Generate packer instruction for a JSON field of type + * exchange withdraw values (/csr). + * + * @param name name of the field to add to the object + * @param ewv values to transmit + * @return json pack specification + */ +struct GNUNET_JSON_PackSpec +TALER_JSON_pack_exchange_withdraw_values ( + const char *name, + const struct TALER_ExchangeWithdrawValues *ewv); + + /** * Generate packer instruction for a JSON field of type * amount. @@ -274,6 +288,20 @@ TALER_JSON_spec_blinded_denom_sig ( struct TALER_BlindedDenominationSignature *sig); +/** + * Generate line in parser specification for + * exchange withdraw values (/csr). + * + * @param field name of the field + * @param[out] ewv the exchange withdraw values to initialize + * @return corresponding field spec + */ +struct GNUNET_JSON_Specification +TALER_JSON_spec_exchange_withdraw_values ( + const char *field, + struct TALER_ExchangeWithdrawValues *ewv); + + /** * Generate line in parser specification for a * blinded planchet. diff --git a/src/json/json_helper.c b/src/json/json_helper.c index 4acac5061..c304bf22f 100644 --- a/src/json/json_helper.c +++ b/src/json/json_helper.c @@ -690,6 +690,91 @@ TALER_JSON_spec_blinded_planchet (const char *field, } +/** + * Parse given JSON object to exchange withdraw values (/csr). + * + * @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_exchange_withdraw_values (void *cls, + json_t *root, + struct GNUNET_JSON_Specification *spec) +{ + struct TALER_ExchangeWithdrawValues *ewv = 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; + } + ewv->cipher = (enum TALER_DenominationCipher) cipher; + switch (cipher) + { + case TALER_DENOMINATION_RSA: + return GNUNET_OK; + case TALER_DENOMINATION_CS: + { + struct GNUNET_JSON_Specification ispec[] = { + GNUNET_JSON_spec_fixed ( + "r_pub_0", + &ewv->details.cs_values.r_pub_pair.r_pub[0], + sizeof (struct GNUNET_CRYPTO_CsRPublic)), + GNUNET_JSON_spec_fixed ( + "r_pub_1", + &ewv->details.cs_values.r_pub_pair.r_pub[1], + sizeof (struct GNUNET_CRYPTO_CsRPublic)), + GNUNET_JSON_spec_end () + }; + + if (GNUNET_OK != + GNUNET_JSON_parse (root, + ispec, + &emsg, + &eline)) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + return GNUNET_OK; + } + default: + GNUNET_break_op (0); + return GNUNET_SYSERR; + } +} + + +struct GNUNET_JSON_Specification +TALER_JSON_spec_exchange_withdraw_values (const char *field, + struct TALER_ExchangeWithdrawValues * + ewv) +{ + struct GNUNET_JSON_Specification ret = { + .parser = &parse_exchange_withdraw_values, + .field = field, + .ptr = ewv + }; + + return ret; +} + + /** * Closure for #parse_i18n_string. */ diff --git a/src/json/json_pack.c b/src/json/json_pack.c index cf6504c06..043fa8463 100644 --- a/src/json/json_pack.c +++ b/src/json/json_pack.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2021 Taler Systems SA + Copyright (C) 2021, 2022 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -120,6 +120,43 @@ TALER_JSON_pack_denom_sig ( } +struct GNUNET_JSON_PackSpec +TALER_JSON_pack_exchange_withdraw_values ( + const char *name, + const struct TALER_ExchangeWithdrawValues *ewv) +{ + struct GNUNET_JSON_PackSpec ps = { + .field_name = name, + }; + + switch (ewv->cipher) + { + case TALER_DENOMINATION_RSA: + ps.object = GNUNET_JSON_PACK ( + GNUNET_JSON_pack_uint64 ("cipher", + TALER_DENOMINATION_RSA)); + break; + case TALER_DENOMINATION_CS: + ps.object = GNUNET_JSON_PACK ( + GNUNET_JSON_pack_uint64 ("cipher", + TALER_DENOMINATION_CS), + GNUNET_JSON_pack_data_varsize ( + "r_pub_0", + &ewv->details.cs_values.r_pub_pair.r_pub[0], + sizeof(struct GNUNET_CRYPTO_CsRPublic)), + GNUNET_JSON_pack_data_varsize ( + "r_pub_1", + &ewv->details.cs_values.r_pub_pair.r_pub[1], + sizeof(struct GNUNET_CRYPTO_CsRPublic)) + ); + break; + default: + GNUNET_assert (0); + } + return ps; +} + + struct GNUNET_JSON_PackSpec TALER_JSON_pack_blinded_denom_sig ( const char *name, diff --git a/src/lib/exchange_api_csr.c b/src/lib/exchange_api_csr.c index 968f13adf..220dfba11 100644 --- a/src/lib/exchange_api_csr.c +++ b/src/lib/exchange_api_csr.c @@ -103,18 +103,12 @@ csr_ok (struct TALER_EXCHANGE_CsRHandle *csrh, json_t *av = json_array_get (arr, i); struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_fixed ( - "r_pub_0", - &alg_values[i].details.cs_values.r_pub_pair.r_pub[0], - sizeof (struct GNUNET_CRYPTO_CsRPublic)), - GNUNET_JSON_spec_fixed ( - "r_pub_1", - &alg_values[i].details.cs_values.r_pub_pair.r_pub[1], - sizeof (struct GNUNET_CRYPTO_CsRPublic)), + TALER_JSON_spec_exchange_withdraw_values ( + "ewv", + &alg_values[i]), GNUNET_JSON_spec_end () }; - alg_values[i].cipher = TALER_DENOMINATION_CS; if (GNUNET_OK != GNUNET_JSON_parse (av, spec, diff --git a/src/lib/exchange_api_recoup.c b/src/lib/exchange_api_recoup.c index be26dc982..c507d1e6a 100644 --- a/src/lib/exchange_api_recoup.c +++ b/src/lib/exchange_api_recoup.c @@ -322,6 +322,9 @@ TALER_EXCHANGE_recoup (struct TALER_EXCHANGE_Handle *exchange, &h_denom_pub), TALER_JSON_pack_denom_sig ("denom_sig", denom_sig), + // FIXME: add this to the spec! + TALER_JSON_pack_exchange_withdraw_values ("ewv", + exchange_vals), GNUNET_JSON_pack_data_auto ("coin_sig", &coin_sig), GNUNET_JSON_pack_data_auto ("coin_blind_key_secret", -- cgit v1.2.3