implement /link signatures
This commit is contained in:
parent
30903b9386
commit
3a2f72b4aa
@ -1,3 +1,8 @@
|
||||
Wed 26 Jun 2019 03:31:52 PM CEST
|
||||
Adding link signatures to prevent exchange from tracking
|
||||
users using coins falsely believed to have been recovered via /link,
|
||||
bumping protocol version to 4. -CG
|
||||
|
||||
Sat 08 Jun 2019 07:54:33 PM CEST
|
||||
Change payto://sepa/ to payto://iban/ as per current spec. -CG
|
||||
|
||||
|
@ -39,7 +39,7 @@
|
||||
* release version, and the format is NOT the same that semantic
|
||||
* versioning uses either.
|
||||
*/
|
||||
#define TALER_PROTOCOL_VERSION "3:0:0"
|
||||
#define TALER_PROTOCOL_VERSION "4:0:0"
|
||||
|
||||
|
||||
/**
|
||||
|
@ -92,6 +92,9 @@ handle_link_data (void *cls,
|
||||
json_object_set_new (obj,
|
||||
"ev_sig",
|
||||
GNUNET_JSON_from_rsa_signature (pos->ev_sig.rsa_signature));
|
||||
json_object_set_new (obj,
|
||||
"link_sig",
|
||||
GNUNET_JSON_from_data_auto (&pos->orig_coin_link_sig));
|
||||
if (0 !=
|
||||
json_array_append_new (list,
|
||||
obj))
|
||||
|
@ -144,6 +144,12 @@ struct RevealContext
|
||||
*/
|
||||
const struct TALER_RefreshCoinData *rcds;
|
||||
|
||||
/**
|
||||
* Signatures over the link data (of type
|
||||
* #TALER_SIGNATURE_WALLET_COIN_LINK)
|
||||
*/
|
||||
const struct TALER_CoinSpendSignatureP *link_sigs;
|
||||
|
||||
/**
|
||||
* Envelopes with the signatures to be returned. Initially NULL.
|
||||
*/
|
||||
@ -491,6 +497,7 @@ refresh_reveal_persist (void *cls,
|
||||
struct TALER_EXCHANGEDB_RefreshRevealedCoin *rrc = &rrcs[i];
|
||||
|
||||
rrc->denom_pub = rctx->dkis[i]->denom_pub;
|
||||
rrc->orig_coin_link_sig = rctx->link_sigs[i];
|
||||
rrc->coin_ev = rctx->rcds[i].coin_ev;
|
||||
rrc->coin_ev_size = rctx->rcds[i].coin_ev_size;
|
||||
rrc->coin_sig = rctx->ev_sigs[i];
|
||||
@ -524,6 +531,7 @@ refresh_reveal_persist (void *cls,
|
||||
* @param rctx context for the operation, partially built at this time
|
||||
* @param transfer_pub transfer public key
|
||||
* @param tp_json private transfer keys in JSON format
|
||||
* @param link_sigs_json link signatures in JSON format
|
||||
* @param new_denoms_h_json requests for fresh coins to be created
|
||||
* @param coin_evs envelopes of gamma-selected coins to be signed
|
||||
* @return MHD result code
|
||||
@ -532,12 +540,14 @@ static int
|
||||
handle_refresh_reveal_json (struct MHD_Connection *connection,
|
||||
struct RevealContext *rctx,
|
||||
const json_t *tp_json,
|
||||
const json_t *link_sigs_json,
|
||||
const json_t *new_denoms_h_json,
|
||||
const json_t *coin_evs)
|
||||
{
|
||||
unsigned int num_fresh_coins = json_array_size (new_denoms_h_json);
|
||||
unsigned int num_tprivs = json_array_size (tp_json);
|
||||
struct TEH_KS_StateHandle *key_state;
|
||||
struct TALER_EXCHANGEDB_RefreshMelt refresh_melt;
|
||||
|
||||
GNUNET_assert (num_tprivs == TALER_CNC_KAPPA - 1);
|
||||
if ( (num_fresh_coins >= MAX_FRESH_COINS) ||
|
||||
@ -557,6 +567,14 @@ handle_refresh_reveal_json (struct MHD_Connection *connection,
|
||||
TALER_EC_REFRESH_REVEAL_NEW_DENOMS_ARRAY_SIZE_MISSMATCH,
|
||||
"new_denoms/coin_evs");
|
||||
}
|
||||
if (json_array_size (new_denoms_h_json) !=
|
||||
json_array_size (link_sigs_json))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
return TEH_RESPONSE_reply_arg_invalid (connection,
|
||||
TALER_EC_REFRESH_REVEAL_NEW_DENOMS_ARRAY_SIZE_MISSMATCH,
|
||||
"new_denoms/link_sigs");
|
||||
}
|
||||
|
||||
/* Parse transfer private keys array */
|
||||
for (unsigned int i=0;i<num_tprivs;i++)
|
||||
@ -579,7 +597,9 @@ handle_refresh_reveal_json (struct MHD_Connection *connection,
|
||||
/* Resolve denomination hashes */
|
||||
{
|
||||
const struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dkis[num_fresh_coins];
|
||||
struct GNUNET_HashCode dki_h[num_fresh_coins];
|
||||
struct TALER_RefreshCoinData rcds[num_fresh_coins];
|
||||
struct TALER_CoinSpendSignatureP link_sigs[num_fresh_coins];
|
||||
int res;
|
||||
|
||||
/* Resolve denomination hashes */
|
||||
@ -596,10 +616,9 @@ handle_refresh_reveal_json (struct MHD_Connection *connection,
|
||||
/* Parse denomination key hashes */
|
||||
for (unsigned int i=0;i<num_fresh_coins;i++)
|
||||
{
|
||||
struct GNUNET_HashCode dpk_h;
|
||||
struct GNUNET_JSON_Specification spec[] = {
|
||||
GNUNET_JSON_spec_fixed_auto (NULL,
|
||||
&dpk_h),
|
||||
&dki_h[i]),
|
||||
GNUNET_JSON_spec_end ()
|
||||
};
|
||||
|
||||
@ -614,7 +633,7 @@ handle_refresh_reveal_json (struct MHD_Connection *connection,
|
||||
return (GNUNET_NO == res) ? MHD_YES : MHD_NO;
|
||||
}
|
||||
dkis[i] = TEH_KS_denomination_key_lookup_by_hash (key_state,
|
||||
&dpk_h,
|
||||
&dki_h[i],
|
||||
TEH_KS_DKU_WITHDRAW);
|
||||
if (NULL == dkis[i])
|
||||
{
|
||||
@ -652,9 +671,85 @@ handle_refresh_reveal_json (struct MHD_Connection *connection,
|
||||
rcd->dk = &dkis[i]->denom_pub;
|
||||
}
|
||||
|
||||
/* lookup old_coin_pub in database */
|
||||
{
|
||||
enum GNUNET_DB_QueryStatus qs;
|
||||
|
||||
if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
|
||||
(qs = TEH_plugin->get_melt (TEH_plugin->cls,
|
||||
NULL,
|
||||
&rctx->rc,
|
||||
&refresh_melt)))
|
||||
{
|
||||
switch (qs)
|
||||
{
|
||||
case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
|
||||
res = TEH_RESPONSE_reply_arg_invalid (connection,
|
||||
TALER_EC_REFRESH_REVEAL_SESSION_UNKNOWN,
|
||||
"rc");
|
||||
break;
|
||||
case GNUNET_DB_STATUS_HARD_ERROR:
|
||||
res = TEH_RESPONSE_reply_internal_db_error (connection,
|
||||
TALER_EC_REFRESH_REVEAL_DB_FETCH_SESSION_ERROR);
|
||||
break;
|
||||
case GNUNET_DB_STATUS_SOFT_ERROR:
|
||||
default:
|
||||
GNUNET_break (0); /* should be impossible */
|
||||
res = TEH_RESPONSE_reply_internal_db_error (connection,
|
||||
TALER_EC_INTERNAL_INVARIANT_FAILURE);
|
||||
break;
|
||||
}
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
/* Parse link signatures array */
|
||||
for (unsigned int i=0;i<num_fresh_coins;i++)
|
||||
{
|
||||
struct GNUNET_JSON_Specification link_spec[] = {
|
||||
GNUNET_JSON_spec_fixed_auto (NULL, &link_sigs[i]),
|
||||
GNUNET_JSON_spec_end ()
|
||||
};
|
||||
int res;
|
||||
|
||||
res = TEH_PARSE_json_array (connection,
|
||||
link_sigs_json,
|
||||
link_spec,
|
||||
i,
|
||||
-1);
|
||||
if (GNUNET_OK != res)
|
||||
return (GNUNET_NO == res) ? MHD_YES : MHD_NO;
|
||||
/* Check link_sigs[i] signature */
|
||||
{
|
||||
struct TALER_LinkDataPS ldp;
|
||||
|
||||
ldp.purpose.size = htonl (sizeof (ldp));
|
||||
ldp.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_LINK);
|
||||
ldp.h_denom_pub = dki_h[i];
|
||||
ldp.old_coin_pub = refresh_melt.session.coin.coin_pub;
|
||||
ldp.transfer_pub = rctx->gamma_tp;
|
||||
GNUNET_CRYPTO_hash (rcds[i].coin_ev,
|
||||
rcds[i].coin_ev_size,
|
||||
&ldp.coin_envelope_hash);
|
||||
|
||||
if (GNUNET_OK !=
|
||||
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_LINK,
|
||||
&ldp.purpose,
|
||||
&link_sigs[i].eddsa_signature,
|
||||
&refresh_melt.session.coin.coin_pub.eddsa_pub))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
res = TEH_RESPONSE_reply_signature_invalid (connection,
|
||||
TALER_EC_REFRESH_REVEAL_LINK_SIGNATURE_INVALID,
|
||||
"link_sig");
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rctx->num_fresh_coins = num_fresh_coins;
|
||||
rctx->rcds = rcds;
|
||||
rctx->dkis = dkis;
|
||||
rctx->link_sigs = link_sigs;
|
||||
|
||||
/* sign _early_ (optimistic!) to keep out of transaction scope! */
|
||||
rctx->ev_sigs = GNUNET_new_array (rctx->num_fresh_coins,
|
||||
@ -749,7 +844,6 @@ handle_refresh_reveal_json (struct MHD_Connection *connection,
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Handle a "/refresh/reveal" request. This time, the client reveals
|
||||
* the private transfer keys except for the cut-and-choose value
|
||||
@ -777,12 +871,14 @@ TEH_REFRESH_handler_refresh_reveal (struct TEH_RequestHandler *rh,
|
||||
json_t *root;
|
||||
json_t *coin_evs;
|
||||
json_t *transfer_privs;
|
||||
json_t *link_sigs;
|
||||
json_t *new_denoms_h;
|
||||
struct RevealContext rctx;
|
||||
struct GNUNET_JSON_Specification spec[] = {
|
||||
GNUNET_JSON_spec_fixed_auto ("rc", &rctx.rc),
|
||||
GNUNET_JSON_spec_fixed_auto ("transfer_pub", &rctx.gamma_tp),
|
||||
GNUNET_JSON_spec_json ("transfer_privs", &transfer_privs),
|
||||
GNUNET_JSON_spec_json ("link_sigs", &link_sigs),
|
||||
GNUNET_JSON_spec_json ("coin_evs", &coin_evs),
|
||||
GNUNET_JSON_spec_json ("new_denoms_h", &new_denoms_h),
|
||||
GNUNET_JSON_spec_end ()
|
||||
@ -825,6 +921,7 @@ TEH_REFRESH_handler_refresh_reveal (struct TEH_RequestHandler *rh,
|
||||
res = handle_refresh_reveal_json (connection,
|
||||
&rctx,
|
||||
transfer_privs,
|
||||
link_sigs,
|
||||
new_denoms_h,
|
||||
coin_evs);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
|
@ -315,6 +315,7 @@ postgres_create_tables (void *cls)
|
||||
GNUNET_PQ_make_execute("CREATE TABLE IF NOT EXISTS refresh_revealed_coins "
|
||||
"(rc BYTEA NOT NULL REFERENCES refresh_commitments (rc) ON DELETE CASCADE"
|
||||
",newcoin_index INT4 NOT NULL"
|
||||
",link_sig BYTEA NOT NULL CHECK(LENGTH(link_sig)=64)"
|
||||
",denom_pub_hash BYTEA NOT NULL REFERENCES denominations (denom_pub_hash) ON DELETE CASCADE"
|
||||
",coin_ev BYTEA NOT NULL"
|
||||
",ev_sig BYTEA NOT NULL"
|
||||
@ -951,18 +952,20 @@ postgres_prepare (PGconn *db_conn)
|
||||
"INSERT INTO refresh_revealed_coins "
|
||||
"(rc "
|
||||
",newcoin_index "
|
||||
",link_sig "
|
||||
",denom_pub_hash "
|
||||
",coin_ev"
|
||||
",ev_sig"
|
||||
") VALUES "
|
||||
"($1, $2, $3, $4, $5);",
|
||||
5),
|
||||
"($1, $2, $3, $4, $5, $6);",
|
||||
6),
|
||||
/* Obtain information about the coins created in a refresh
|
||||
operation, used in #postgres_get_refresh_reveal() */
|
||||
GNUNET_PQ_make_prepare ("get_refresh_revealed_coins",
|
||||
"SELECT "
|
||||
" newcoin_index"
|
||||
",denom.denom_pub"
|
||||
",link_sig"
|
||||
",coin_ev"
|
||||
",ev_sig"
|
||||
" FROM refresh_revealed_coins"
|
||||
@ -1239,6 +1242,7 @@ postgres_prepare (PGconn *db_conn)
|
||||
" tp.transfer_pub"
|
||||
",denoms.denom_pub"
|
||||
",rrc.ev_sig"
|
||||
",rrc.link_sig"
|
||||
" FROM refresh_commitments"
|
||||
" JOIN refresh_revealed_coins rrc"
|
||||
" USING (rc)"
|
||||
@ -3641,7 +3645,7 @@ postgres_select_refunds_by_coin (void *cls,
|
||||
* Lookup refresh melt commitment data under the given @a rc.
|
||||
*
|
||||
* @param cls the `struct PostgresClosure` with the plugin-specific state
|
||||
* @param session database handle to use
|
||||
* @param session database handle to use, NULL if not run in any transaction
|
||||
* @param rc commitment hash to use to locate the operation
|
||||
* @param[out] refresh_melt where to store the result
|
||||
* @return transaction status
|
||||
@ -3652,6 +3656,7 @@ postgres_get_melt (void *cls,
|
||||
const struct TALER_RefreshCommitmentP *rc,
|
||||
struct TALER_EXCHANGEDB_RefreshMelt *refresh_melt)
|
||||
{
|
||||
struct PostgresClosure *pc = cls;
|
||||
struct GNUNET_PQ_QueryParam params[] = {
|
||||
GNUNET_PQ_query_param_auto_from_type (rc),
|
||||
GNUNET_PQ_query_param_end
|
||||
@ -3675,6 +3680,8 @@ postgres_get_melt (void *cls,
|
||||
};
|
||||
enum GNUNET_DB_QueryStatus qs;
|
||||
|
||||
if (NULL == session)
|
||||
session = postgres_get_session (pc);
|
||||
qs = GNUNET_PQ_eval_prepared_singleton_select (session->conn,
|
||||
"get_melt",
|
||||
params,
|
||||
@ -3790,6 +3797,7 @@ postgres_insert_refresh_reveal (void *cls,
|
||||
struct GNUNET_PQ_QueryParam params[] = {
|
||||
GNUNET_PQ_query_param_auto_from_type (rc),
|
||||
GNUNET_PQ_query_param_uint32 (&i),
|
||||
GNUNET_PQ_query_param_auto_from_type (&rrc->orig_coin_link_sig),
|
||||
GNUNET_PQ_query_param_auto_from_type (&denom_pub_hash),
|
||||
GNUNET_PQ_query_param_fixed_size (rrc->coin_ev,
|
||||
rrc->coin_ev_size),
|
||||
@ -3876,6 +3884,8 @@ add_revealed_coins (void *cls,
|
||||
&off),
|
||||
GNUNET_PQ_result_spec_rsa_public_key ("denom_pub",
|
||||
&rrc->denom_pub.rsa_public_key),
|
||||
GNUNET_PQ_result_spec_auto_from_type ("link_sig",
|
||||
&rrc->orig_coin_link_sig),
|
||||
GNUNET_PQ_result_spec_variable_size ("coin_ev",
|
||||
(void **) &rrc->coin_ev,
|
||||
&rrc->coin_ev_size),
|
||||
@ -4102,6 +4112,8 @@ add_ldl (void *cls,
|
||||
struct GNUNET_PQ_ResultSpec rs[] = {
|
||||
GNUNET_PQ_result_spec_auto_from_type ("transfer_pub",
|
||||
&transfer_pub),
|
||||
GNUNET_PQ_result_spec_auto_from_type ("link_sig",
|
||||
&pos->orig_coin_link_sig),
|
||||
GNUNET_PQ_result_spec_rsa_signature ("ev_sig",
|
||||
&pos->ev_sig.rsa_signature),
|
||||
GNUNET_PQ_result_spec_rsa_public_key ("denom_pub",
|
||||
|
@ -617,6 +617,13 @@ enum TALER_ErrorCode
|
||||
*/
|
||||
TALER_EC_REFRESH_REVEAL_FRESH_DENOMINATION_KEY_NOT_FOUND = 1361,
|
||||
|
||||
/**
|
||||
* The signature made with the coin over the link data is invalid.
|
||||
* This response is provided with HTTP status code
|
||||
* MHD_HTTP_BAD_REQUEST.
|
||||
*/
|
||||
TALER_EC_REFRESH_REVEAL_LINK_SIGNATURE_INVALID = 1362,
|
||||
|
||||
|
||||
/**
|
||||
* The coin specified in the link request is unknown to the exchange.
|
||||
|
@ -541,6 +541,12 @@ struct TALER_EXCHANGEDB_LinkDataList
|
||||
* Signature over the blinded envelope.
|
||||
*/
|
||||
struct TALER_DenominationSignature ev_sig;
|
||||
|
||||
/**
|
||||
* Signature of the original coin being refreshed over the
|
||||
* link data, of type #TALER_SIGNATURE_WALLET_COIN_LINK
|
||||
*/
|
||||
struct TALER_CoinSpendSignatureP orig_coin_link_sig;
|
||||
};
|
||||
|
||||
|
||||
@ -793,6 +799,12 @@ struct TALER_EXCHANGEDB_RefreshRevealedCoin
|
||||
*/
|
||||
struct TALER_DenominationPublicKey denom_pub;
|
||||
|
||||
/**
|
||||
* Signature of the original coin being refreshed over the
|
||||
* link data, of type #TALER_SIGNATURE_WALLET_COIN_LINK
|
||||
*/
|
||||
struct TALER_CoinSpendSignatureP orig_coin_link_sig;
|
||||
|
||||
/**
|
||||
* Blinded message to be signed (in envelope), with @e coin_env_size bytes.
|
||||
*/
|
||||
@ -1634,7 +1646,7 @@ struct TALER_EXCHANGEDB_Plugin
|
||||
|
||||
|
||||
/**
|
||||
* Lookup refresh metl commitment data under the given @a rc.
|
||||
* Lookup refresh melt commitment data under the given @a rc.
|
||||
*
|
||||
* @param cls the @e cls of this struct with the plugin-specific state
|
||||
* @param session database handle to use
|
||||
|
@ -130,9 +130,9 @@
|
||||
#define TALER_SIGNATURE_EXCHANGE_RESERVE_CLOSED 1040
|
||||
|
||||
|
||||
/*********************/
|
||||
/* Wallet signatures */
|
||||
/*********************/
|
||||
/**********************/
|
||||
/* Auditor signatures */
|
||||
/**********************/
|
||||
|
||||
/**
|
||||
* Signature where the auditor confirms that he is
|
||||
@ -209,6 +209,11 @@
|
||||
*/
|
||||
#define TALER_SIGNATURE_WALLET_COIN_PAYBACK 1203
|
||||
|
||||
/**
|
||||
* Signature using a coin key authenticating link data.
|
||||
*/
|
||||
#define TALER_SIGNATURE_WALLET_COIN_LINK 1204
|
||||
|
||||
|
||||
/*******************/
|
||||
/* Test signatures */
|
||||
@ -228,6 +233,41 @@
|
||||
|
||||
GNUNET_NETWORK_STRUCT_BEGIN
|
||||
|
||||
/**
|
||||
* @brief Format used for to allow the wallet to authenticate
|
||||
* link data provided by the exchange.
|
||||
*/
|
||||
struct TALER_LinkDataPS
|
||||
{
|
||||
|
||||
/**
|
||||
* Purpose must be #TALER_SIGNATURE_WALLET_COIN_LINK.
|
||||
* Used with an EdDSA signature of a `struct TALER_CoinPublicKeyP`.
|
||||
*/
|
||||
struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
|
||||
|
||||
/**
|
||||
* Hash of the denomination public key of the new coin.
|
||||
*/
|
||||
struct GNUNET_HashCode h_denom_pub;
|
||||
|
||||
/**
|
||||
* Public key of the old coin being refreshed.
|
||||
*/
|
||||
struct TALER_CoinSpendPublicKeyP old_coin_pub;
|
||||
|
||||
/**
|
||||
* Transfer public key (for which the private key was not revealed)
|
||||
*/
|
||||
struct TALER_TransferPublicKeyP transfer_pub;
|
||||
|
||||
/**
|
||||
* Hash of the blinded new coin.
|
||||
*/
|
||||
struct GNUNET_HashCode coin_envelope_hash;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief Format used for to generate the signature on a request to withdraw
|
||||
* coins from a reserve.
|
||||
|
@ -1534,6 +1534,7 @@ TALER_EXCHANGE_refresh_reveal (struct TALER_EXCHANGE_Handle *exchange,
|
||||
json_t *new_denoms_h;
|
||||
json_t *coin_evs;
|
||||
json_t *reveal_obj;
|
||||
json_t *link_sigs;
|
||||
CURL *eh;
|
||||
struct GNUNET_CURL_Context *ctx;
|
||||
struct MeltData *md;
|
||||
@ -1565,6 +1566,7 @@ TALER_EXCHANGE_refresh_reveal (struct TALER_EXCHANGE_Handle *exchange,
|
||||
/* now new_denoms */
|
||||
GNUNET_assert (NULL != (new_denoms_h = json_array ()));
|
||||
GNUNET_assert (NULL != (coin_evs = json_array ()));
|
||||
GNUNET_assert (NULL != (link_sigs = json_array ()));
|
||||
for (unsigned int i=0;i<md->num_fresh_coins;i++)
|
||||
{
|
||||
struct GNUNET_HashCode denom_hash;
|
||||
@ -1591,6 +1593,30 @@ TALER_EXCHANGE_refresh_reveal (struct TALER_EXCHANGE_Handle *exchange,
|
||||
json_array_append_new (coin_evs,
|
||||
GNUNET_JSON_from_data (pd.coin_ev,
|
||||
pd.coin_ev_size)));
|
||||
|
||||
/* compute link signature */
|
||||
{
|
||||
struct TALER_CoinSpendSignatureP link_sig;
|
||||
struct TALER_LinkDataPS ldp;
|
||||
|
||||
ldp.purpose.size = htonl (sizeof (ldp));
|
||||
ldp.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_LINK);
|
||||
ldp.h_denom_pub = denom_hash;
|
||||
GNUNET_CRYPTO_eddsa_key_get_public (&md->melted_coin.coin_priv.eddsa_priv,
|
||||
&ldp.old_coin_pub.eddsa_pub);
|
||||
ldp.transfer_pub = transfer_pub;
|
||||
GNUNET_CRYPTO_hash (pd.coin_ev,
|
||||
pd.coin_ev_size,
|
||||
&ldp.coin_envelope_hash);
|
||||
GNUNET_assert (GNUNET_OK ==
|
||||
GNUNET_CRYPTO_eddsa_sign (&md->melted_coin.coin_priv.eddsa_priv,
|
||||
&ldp.purpose,
|
||||
&link_sig.eddsa_signature));
|
||||
GNUNET_assert (0 ==
|
||||
json_array_append_new (link_sigs,
|
||||
GNUNET_JSON_from_data_auto (&link_sig)));
|
||||
}
|
||||
|
||||
GNUNET_free (pd.coin_ev);
|
||||
}
|
||||
|
||||
@ -1610,13 +1636,15 @@ TALER_EXCHANGE_refresh_reveal (struct TALER_EXCHANGE_Handle *exchange,
|
||||
}
|
||||
|
||||
/* build main JSON request */
|
||||
reveal_obj = json_pack ("{s:o, s:o, s:o, s:o, s:o}",
|
||||
reveal_obj = json_pack ("{s:o, s:o, s:o, s:o, s:o, s:o}",
|
||||
"rc",
|
||||
GNUNET_JSON_from_data_auto (&md->rc),
|
||||
"transfer_pub",
|
||||
GNUNET_JSON_from_data_auto (&transfer_pub),
|
||||
"transfer_privs",
|
||||
transfer_privs,
|
||||
"link_sigs",
|
||||
link_sigs,
|
||||
"new_denoms_h",
|
||||
new_denoms_h,
|
||||
"coin_evs",
|
||||
|
Loading…
Reference in New Issue
Block a user