pass exchange values to /recoup

This commit is contained in:
Christian Grothoff 2022-02-09 22:02:29 +01:00
parent e6598cfa1a
commit 025922950d
No known key found for this signature in database
GPG Key ID: 939E6BE1E29FC3CC
7 changed files with 178 additions and 24 deletions

View File

@ -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,

View File

@ -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);

View File

@ -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.

View File

@ -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.
*/

View File

@ -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,

View File

@ -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,

View File

@ -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",