-move econtract into sub-object with its own parser

This commit is contained in:
Christian Grothoff 2022-06-05 00:25:56 +02:00
parent a17781ba8d
commit efa0ca4ec1
No known key found for this signature in database
GPG Key ID: 939E6BE1E29FC3CC
7 changed files with 312 additions and 211 deletions

View File

@ -107,20 +107,15 @@ struct PurseCreateContext
struct TALER_PurseMergePublicKeyP merge_pub;
/**
* Contract decryption key for the purse.
* Encrypted contract of for the purse.
*/
struct TALER_ContractDiffiePublicP contract_pub;
struct TALER_EncryptedContract econtract;
/**
* Signature of the client affiming this request.
*/
struct TALER_PurseContractSignatureP purse_sig;
/**
* Signature of the client affiming this encrypted contract.
*/
struct TALER_PurseContractSignatureP econtract_sig;
/**
* Hash of the contract terms of the purse.
*/
@ -131,16 +126,6 @@ struct PurseCreateContext
*/
struct Coin *coins;
/**
* Encrypted contract, can be NULL.
*/
void *econtract;
/**
* Number of bytes in @e econtract.
*/
size_t econtract_size;
/**
* Length of the @e coins array.
*/
@ -384,12 +369,13 @@ create_transaction (void *cls,
}
/* 3) if present, persist contract */
in_conflict = true;
// FIXME: combine econtract arguments into one!
qs = TEH_plugin->insert_contract (TEH_plugin->cls,
pcc->purse_pub,
&pcc->contract_pub,
pcc->econtract_size,
pcc->econtract,
&pcc->econtract_sig,
&pcc->econtract.contract_pub,
pcc->econtract.econtract_size,
pcc->econtract.econtract,
&pcc->econtract.econtract_sig,
&in_conflict);
if (qs < 0)
{
@ -404,19 +390,17 @@ create_transaction (void *cls,
}
if (in_conflict)
{
struct TALER_ContractDiffiePublicP pub_ckey;
struct TALER_PurseContractSignatureP econtract_sig;
size_t econtract_size;
void *econtract;
struct TALER_EncryptedContract econtract;
struct GNUNET_HashCode h_econtract;
// FIXME: combine econtract arguments into one!
qs = TEH_plugin->select_contract_by_purse (
TEH_plugin->cls,
pcc->purse_pub,
&pub_ckey,
&econtract_sig,
&econtract_size,
&econtract);
&econtract.contract_pub,
&econtract.econtract_sig,
&econtract.econtract_size,
&econtract.econtract);
if (qs <= 0)
{
if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
@ -430,8 +414,8 @@ create_transaction (void *cls,
"select contract");
return GNUNET_DB_STATUS_HARD_ERROR;
}
GNUNET_CRYPTO_hash (econtract,
econtract_size,
GNUNET_CRYPTO_hash (econtract.econtract,
econtract.econtract_size,
&h_econtract);
*mhd_ret
= TALER_MHD_REPLY_JSON_PACK (
@ -442,9 +426,10 @@ create_transaction (void *cls,
GNUNET_JSON_pack_data_auto ("h_econtract",
&h_econtract),
GNUNET_JSON_pack_data_auto ("econtract_sig",
&econtract_sig),
&econtract.econtract_sig),
GNUNET_JSON_pack_data_auto ("pub_ckey",
&pub_ckey));
&econtract.contract_pub));
GNUNET_free (econtract.econtract);
return GNUNET_DB_STATUS_HARD_ERROR;
}
return qs;
@ -685,6 +670,7 @@ TEH_handler_purses_create (
json_t *deposits;
json_t *deposit;
unsigned int idx;
bool no_econtract = true;
struct GNUNET_JSON_Specification spec[] = {
TALER_JSON_spec_amount ("amount",
TEH_currency,
@ -692,18 +678,9 @@ TEH_handler_purses_create (
GNUNET_JSON_spec_uint32 ("min_age",
&pcc.min_age),
GNUNET_JSON_spec_mark_optional (
GNUNET_JSON_spec_varsize ("econtract",
&pcc.econtract,
&pcc.econtract_size),
NULL),
GNUNET_JSON_spec_mark_optional (
GNUNET_JSON_spec_fixed_auto ("econtract_sig",
&pcc.econtract_sig),
NULL),
GNUNET_JSON_spec_mark_optional (
GNUNET_JSON_spec_fixed_auto ("contract_pub",
&pcc.contract_pub),
NULL),
TALER_JSON_spec_econtract ("econtract",
&pcc.econtract),
&no_econtract),
GNUNET_JSON_spec_fixed_auto ("merge_pub",
&pcc.merge_pub),
GNUNET_JSON_spec_fixed_auto ("purse_sig",
@ -830,13 +807,13 @@ TEH_handler_purses_create (
TALER_EC_EXCHANGE_PURSE_CREATE_SIGNATURE_INVALID,
NULL);
}
if ( (NULL != pcc.econtract) &&
if ( (! no_econtract) &&
(GNUNET_OK !=
TALER_wallet_econtract_upload_verify (pcc.econtract,
pcc.econtract_size,
&pcc.contract_pub,
TALER_wallet_econtract_upload_verify (pcc.econtract.econtract,
pcc.econtract.econtract_size,
&pcc.econtract.contract_pub,
purse_pub,
&pcc.econtract_sig)) )
&pcc.econtract.econtract_sig)) )
{
TALER_LOG_WARNING ("Invalid signature on /purses/$PID/create request\n");
GNUNET_JSON_parse_free (spec);

View File

@ -85,6 +85,11 @@ struct ReservePurseContext
*/
struct GNUNET_TIME_Timestamp exchange_timestamp;
/**
* Details about an encrypted contract, if any.
*/
struct TALER_EncryptedContract econtract;
/**
* Merge key for the purse.
*/
@ -95,11 +100,6 @@ struct ReservePurseContext
*/
struct TALER_PurseMergeSignatureP merge_sig;
/**
* Contract decryption key for the purse.
*/
struct TALER_ContractDiffiePublicP contract_pub;
/**
* Public key of the purse we are creating.
*/
@ -110,26 +110,11 @@ struct ReservePurseContext
*/
struct TALER_PurseContractSignatureP purse_sig;
/**
* Signature of the client affiming this encrypted contract.
*/
struct TALER_PurseContractSignatureP econtract_sig;
/**
* Hash of the contract terms of the purse.
*/
struct TALER_PrivateContractHashP h_contract_terms;
/**
* Encrypted contract, can be NULL.
*/
void *econtract;
/**
* Number of bytes in @e econtract.
*/
size_t econtract_size;
/**
* Minimum age for deposits into this purse.
*/
@ -139,6 +124,12 @@ struct ReservePurseContext
* Flags for the operation.
*/
enum TALER_WalletAccountMergeFlags flags;
/**
* Do we lack an @e econtract?
*/
bool no_econtract;
};
@ -214,17 +205,18 @@ purse_transaction (void *cls,
bool in_conflict = true;
/* 1) store purse */
qs = TEH_plugin->insert_purse_request (TEH_plugin->cls,
&rpc->purse_pub,
&rpc->merge_pub,
rpc->purse_expiration,
&rpc->h_contract_terms,
rpc->min_age,
rpc->flags,
&rpc->purse_fee,
&rpc->amount,
&rpc->purse_sig,
&in_conflict);
qs = TEH_plugin->insert_purse_request (
TEH_plugin->cls,
&rpc->purse_pub,
&rpc->merge_pub,
rpc->purse_expiration,
&rpc->h_contract_terms,
rpc->min_age,
rpc->flags,
&rpc->purse_fee,
&rpc->amount,
&rpc->purse_sig,
&in_conflict);
if (qs < 0)
{
if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
@ -251,15 +243,16 @@ purse_transaction (void *cls,
uint32_t min_age;
TEH_plugin->rollback (TEH_plugin->cls);
qs = TEH_plugin->select_purse_request (TEH_plugin->cls,
&rpc->purse_pub,
&merge_pub,
&purse_expiration,
&h_contract_terms,
&min_age,
&target_amount,
&balance,
&purse_sig);
qs = TEH_plugin->select_purse_request (
TEH_plugin->cls,
&rpc->purse_pub,
&merge_pub,
&purse_expiration,
&h_contract_terms,
&min_age,
&target_amount,
&balance,
&purse_sig);
if (qs <= 0)
{
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR != qs);
@ -414,16 +407,17 @@ purse_transaction (void *cls,
}
}
/* 3) if present, persist contract */
if (NULL != rpc->econtract)
if (! rpc->no_econtract)
{
bool in_conflict = true;
// FIXME: combine econtract args!
qs = TEH_plugin->insert_contract (TEH_plugin->cls,
&rpc->purse_pub,
&rpc->contract_pub,
rpc->econtract_size,
rpc->econtract,
&rpc->econtract_sig,
&rpc->econtract.contract_pub,
rpc->econtract.econtract_size,
rpc->econtract.econtract,
&rpc->econtract.econtract_sig,
&in_conflict);
if (qs < 0)
{
@ -438,18 +432,18 @@ purse_transaction (void *cls,
}
if (in_conflict)
{
struct TALER_ContractDiffiePublicP pub_ckey;
struct TALER_PurseContractSignatureP econtract_sig;
size_t econtract_size;
void *econtract;
struct TALER_EncryptedContract econtract;
struct GNUNET_HashCode h_econtract;
qs = TEH_plugin->select_contract_by_purse (TEH_plugin->cls,
&rpc->purse_pub,
&pub_ckey,
&econtract_sig,
&econtract_size,
&econtract);
/* FIXME: change API to only pass econtract
instead of all members! */
qs = TEH_plugin->select_contract_by_purse (
TEH_plugin->cls,
&rpc->purse_pub,
&econtract.contract_pub,
&econtract.econtract_sig,
&econtract.econtract_size,
&econtract.econtract);
if (qs <= 0)
{
if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
@ -463,8 +457,8 @@ purse_transaction (void *cls,
"select contract");
return GNUNET_DB_STATUS_HARD_ERROR;
}
GNUNET_CRYPTO_hash (econtract,
econtract_size,
GNUNET_CRYPTO_hash (econtract.econtract,
econtract.econtract_size,
&h_econtract);
*mhd_ret
= TALER_MHD_REPLY_JSON_PACK (
@ -475,9 +469,10 @@ purse_transaction (void *cls,
GNUNET_JSON_pack_data_auto ("h_econtract",
&h_econtract),
GNUNET_JSON_pack_data_auto ("econtract_sig",
&econtract_sig),
&econtract.econtract_sig),
GNUNET_JSON_pack_data_auto ("pub_ckey",
&pub_ckey));
&econtract.contract_pub));
GNUNET_free (econtract.econtract);
return GNUNET_DB_STATUS_HARD_ERROR;
}
}
@ -509,18 +504,9 @@ TEH_handler_reserves_purse (
&rpc.purse_fee),
&no_purse_fee),
GNUNET_JSON_spec_mark_optional (
GNUNET_JSON_spec_varsize ("econtract",
&rpc.econtract,
&rpc.econtract_size),
NULL),
GNUNET_JSON_spec_mark_optional (
GNUNET_JSON_spec_fixed_auto ("econtract_sig",
&rpc.econtract_sig),
NULL),
GNUNET_JSON_spec_mark_optional (
GNUNET_JSON_spec_fixed_auto ("contract_pub",
&rpc.contract_pub),
NULL),
TALER_JSON_spec_econtract ("econtract",
&rpc.econtract),
&rpc.no_econtract),
GNUNET_JSON_spec_fixed_auto ("merge_pub",
&rpc.merge_pub),
GNUNET_JSON_spec_fixed_auto ("merge_sig",
@ -667,13 +653,13 @@ TEH_handler_reserves_purse (
TALER_EC_EXCHANGE_RESERVES_PURSE_MERGE_SIGNATURE_INVALID,
NULL);
}
if ( (NULL != rpc.econtract) &&
if ( (! rpc.no_econtract) &&
(GNUNET_OK !=
TALER_wallet_econtract_upload_verify (rpc.econtract,
rpc.econtract_size,
&rpc.contract_pub,
TALER_wallet_econtract_upload_verify (rpc.econtract.econtract,
rpc.econtract.econtract_size,
&rpc.econtract.contract_pub,
&rpc.purse_pub,
&rpc.econtract_sig)) )
&rpc.econtract.econtract_sig)) )
{
TALER_LOG_WARNING ("Invalid signature on /reserves/$PID/purse request\n");
GNUNET_JSON_parse_free (spec);

View File

@ -28,6 +28,37 @@
#include "taler_util.h"
#include "taler_error_codes.h"
/**
* Details about an encrypted contract.
*/
struct TALER_EncryptedContract
{
/**
* Signature of the client affiming this encrypted contract.
*/
struct TALER_PurseContractSignatureP econtract_sig;
/**
* Contract decryption key for the purse.
*/
struct TALER_ContractDiffiePublicP contract_pub;
/**
* Encrypted contract, can be NULL.
*/
void *econtract;
/**
* Number of bytes in @e econtract.
*/
size_t econtract_size;
};
/**
* Print JSON parsing related error information
* @deprecated
@ -171,6 +202,20 @@ TALER_JSON_pack_amount_nbo (const char *name,
const struct TALER_AmountNBO *amount);
/**
* Generate packer instruction for a JSON field of type
* encrypted contract.
*
* @param name name of the field to add to the object
* @param econtract the encrypted contract
* @return json pack specification
*/
struct GNUNET_JSON_PackSpec
TALER_JSON_pack_econtract (
const char *name,
const struct TALER_EncryptedContract *econtract);
/**
* Convert a TALER amount to a JSON object.
*
@ -237,6 +282,18 @@ TALER_JSON_spec_amount_any (const char *name,
struct TALER_Amount *r_amount);
/**
* Provide specification to parse given JSON object to an encrypted contract.
*
* @param name name of the amount field in the JSON
* @param[out] econtract where to store the encrypted contract
* @return spec for parsing an amount
*/
struct GNUNET_JSON_Specification
TALER_JSON_spec_econtract (const char *name,
struct TALER_EncryptedContract *econtract);
/**
* Provide specification to parse given JSON object to an amount
* in any currency in network byte order.

View File

@ -234,6 +234,82 @@ TALER_JSON_spec_amount_any_nbo (const char *name,
}
/**
* Parse given JSON object to an encrypted contract.
*
* @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_econtract (void *cls,
json_t *root,
struct GNUNET_JSON_Specification *spec)
{
struct TALER_EncryptedContract *econtract = spec->ptr;
struct GNUNET_JSON_Specification ispec[] = {
GNUNET_JSON_spec_varsize ("econtract",
&econtract->econtract,
&econtract->econtract_size),
GNUNET_JSON_spec_fixed_auto ("econtract_sig",
&econtract->econtract_sig),
GNUNET_JSON_spec_fixed_auto ("contract_pub",
&econtract->contract_pub),
GNUNET_JSON_spec_end ()
};
const char *emsg;
unsigned int eline;
(void) cls;
if (GNUNET_OK !=
GNUNET_JSON_parse (root,
ispec,
&emsg,
&eline))
{
GNUNET_break_op (0);
return GNUNET_SYSERR;
}
return GNUNET_OK;
}
/**
* Cleanup data left from parsing encrypted contract.
*
* @param cls closure, NULL
* @param[out] spec where to free the data
*/
static void
clean_econtract (void *cls,
struct GNUNET_JSON_Specification *spec)
{
struct TALER_EncryptedContract *econtract = spec->ptr;
(void) cls;
GNUNET_free (econtract->econtract);
}
struct GNUNET_JSON_Specification
TALER_JSON_spec_econtract (const char *name,
struct TALER_EncryptedContract *econtract)
{
struct GNUNET_JSON_Specification ret = {
.parser = &parse_econtract,
.cleaner = &clean_econtract,
.cls = NULL,
.field = name,
.ptr = econtract,
.ptr_size = 0,
.size_ptr = NULL
};
return ret;
}
/**
* Parse given JSON object to denomination public key.
*

View File

@ -47,6 +47,30 @@ TALER_JSON_pack_time_abs_nbo_human (const char *name,
}
struct GNUNET_JSON_PackSpec
TALER_JSON_pack_econtract (
const char *name,
const struct TALER_EncryptedContract *econtract)
{
struct GNUNET_JSON_PackSpec ps = {
.field_name = name,
};
if (NULL == econtract)
return ps;
ps.object
= GNUNET_JSON_PACK (
GNUNET_JSON_pack_data_varsize ("econtract",
econtract->econtract,
econtract->econtract_size),
GNUNET_JSON_pack_data_auto ("econtract_sig",
&econtract->econtract_sig),
GNUNET_JSON_pack_data_auto ("contract_pub",
&econtract->contract_pub));
return ps;
}
struct GNUNET_JSON_PackSpec
TALER_JSON_pack_denom_pub (
const char *name,
@ -56,6 +80,8 @@ TALER_JSON_pack_denom_pub (
.field_name = name,
};
if (NULL == pk)
return ps;
switch (pk->cipher)
{
case TALER_DENOMINATION_RSA:
@ -95,6 +121,8 @@ TALER_JSON_pack_denom_sig (
.field_name = name,
};
if (NULL == sig)
return ps;
switch (sig->cipher)
{
case TALER_DENOMINATION_RSA:
@ -129,6 +157,8 @@ TALER_JSON_pack_exchange_withdraw_values (
.field_name = name,
};
if (NULL == ewv)
return ps;
switch (ewv->cipher)
{
case TALER_DENOMINATION_RSA:
@ -166,6 +196,8 @@ TALER_JSON_pack_blinded_denom_sig (
.field_name = name,
};
if (NULL == sig)
return ps;
switch (sig->cipher)
{
case TALER_DENOMINATION_RSA:
@ -200,6 +232,8 @@ TALER_JSON_pack_blinded_planchet (
.field_name = name,
};
if (NULL == blinded_planchet)
return ps;
switch (blinded_planchet->cipher)
{
case TALER_DENOMINATION_RSA:

View File

@ -253,7 +253,7 @@ TALER_EXCHANGE_purse_create_with_deposit (
json_t *deposit_arr;
CURL *eh;
struct TALER_PurseContractSignatureP purse_sig;
struct TALER_PurseContractSignatureP econtract_sig;
struct TALER_EncryptedContract econtract;
struct TALER_ContractDiffiePublicP contract_pub;
char arg_str[sizeof (pch->purse_pub) * 2 + 32];
char *url;
@ -311,8 +311,6 @@ TALER_EXCHANGE_purse_create_with_deposit (
"/purses/%s/create",
pub_str);
}
GNUNET_CRYPTO_ecdhe_key_get_public (&contract_priv->ecdhe_priv,
&contract_pub.ecdhe_pub);
GNUNET_CRYPTO_eddsa_key_get_public (&merge_priv->eddsa_priv,
&pch->merge_pub.eddsa_pub);
pch->url = TEAH_path_to_url (exchange,
@ -395,58 +393,44 @@ TALER_EXCHANGE_purse_create_with_deposit (
&pch->purse_value_after_fees,
purse_priv,
&purse_sig);
if (upload_contract)
{
void *econtract = NULL;
size_t econtract_size = 0;
if (upload_contract)
{
TALER_CRYPTO_contract_encrypt_for_merge (&pch->purse_pub,
contract_priv,
merge_priv,
contract_terms,
&econtract,
&econtract_size);
TALER_wallet_econtract_upload_sign (econtract,
econtract_size,
&contract_pub,
purse_priv,
&econtract_sig);
}
create_obj = GNUNET_JSON_PACK (
TALER_JSON_pack_amount ("amount",
&pch->purse_value_after_fees),
GNUNET_JSON_pack_uint64 ("min_age",
min_age),
GNUNET_JSON_pack_allow_null (
GNUNET_JSON_pack_data_varsize ("econtract",
econtract,
econtract_size)),
GNUNET_JSON_pack_allow_null (
(upload_contract)
? GNUNET_JSON_pack_data_auto ("contract_pub",
&contract_pub)
: GNUNET_JSON_pack_string ("dummy",
NULL)),
GNUNET_JSON_pack_allow_null (
(upload_contract)
? GNUNET_JSON_pack_data_auto ("econtract_sig",
&econtract_sig)
: GNUNET_JSON_pack_string ("dummy2",
NULL)),
GNUNET_JSON_pack_data_auto ("purse_sig",
&purse_sig),
GNUNET_JSON_pack_data_auto ("merge_pub",
&pch->merge_pub),
GNUNET_JSON_pack_data_auto ("h_contract_terms",
&pch->h_contract_terms),
GNUNET_JSON_pack_timestamp ("purse_expiration",
pch->purse_expiration),
GNUNET_JSON_pack_array_steal ("deposits",
deposit_arr));
GNUNET_free (econtract);
TALER_CRYPTO_contract_encrypt_for_merge (&pch->purse_pub,
contract_priv,
merge_priv,
contract_terms,
&econtract.econtract,
&econtract.econtract_size);
GNUNET_CRYPTO_ecdhe_key_get_public (&contract_priv->ecdhe_priv,
&contract_pub.ecdhe_pub);
TALER_wallet_econtract_upload_sign (econtract.econtract,
econtract.econtract_size,
&contract_pub,
purse_priv,
&econtract.econtract_sig);
}
create_obj = GNUNET_JSON_PACK (
TALER_JSON_pack_amount ("amount",
&pch->purse_value_after_fees),
GNUNET_JSON_pack_uint64 ("min_age",
min_age),
GNUNET_JSON_pack_allow_null (
TALER_JSON_pack_econtract ("econtract",
upload_contract
? &econtract
: NULL)),
GNUNET_JSON_pack_data_auto ("purse_sig",
&purse_sig),
GNUNET_JSON_pack_data_auto ("merge_pub",
&pch->merge_pub),
GNUNET_JSON_pack_data_auto ("h_contract_terms",
&pch->h_contract_terms),
GNUNET_JSON_pack_timestamp ("purse_expiration",
pch->purse_expiration),
GNUNET_JSON_pack_array_steal ("deposits",
deposit_arr));
GNUNET_assert (NULL != create_obj);
GNUNET_free (econtract.econtract);
eh = TALER_EXCHANGE_curl_easy_get_ (pch->url);
if ( (NULL == eh) ||
(GNUNET_OK !=

View File

@ -70,6 +70,11 @@ struct TALER_EXCHANGE_PurseCreateMergeHandle
*/
void *cb_cls;
/**
* The encrypted contract (if any).
*/
struct TALER_EncryptedContract econtract;
/**
* Expected value in the purse after fees.
*/
@ -95,11 +100,6 @@ struct TALER_EXCHANGE_PurseCreateMergeHandle
*/
struct TALER_PurseMergeSignatureP merge_sig;
/**
* Our contract signature (if any).
*/
struct TALER_PurseContractSignatureP contract_sig;
/**
* Public key of the purse.
*/
@ -391,7 +391,7 @@ handle_purse_create_with_merge_finished (void *cls,
}
if (0 ==
GNUNET_memcmp (&contract_sig,
&pcm->contract_sig))
&pcm->econtract.econtract_sig))
{
/* Must be the SAME data, not a conflict! */
GNUNET_break_op (0);
@ -466,9 +466,6 @@ TALER_EXCHANGE_purse_create_with_merge (
CURL *eh;
char arg_str[sizeof (pcm->reserve_pub) * 2 + 32];
uint32_t min_age = 0;
struct TALER_ContractDiffiePublicP contract_pub;
void *econtract = NULL;
size_t econtract_size = 0;
struct TALER_Amount purse_fee;
enum TALER_WalletAccountMergeFlags flags;
@ -492,8 +489,6 @@ TALER_EXCHANGE_purse_create_with_merge (
&pcm->reserve_pub.eddsa_pub);
GNUNET_CRYPTO_eddsa_key_get_public (&merge_priv->eddsa_priv,
&pcm->merge_pub.eddsa_pub);
GNUNET_CRYPTO_ecdhe_key_get_public (&contract_priv->ecdhe_priv,
&contract_pub.ecdhe_pub);
{
struct GNUNET_JSON_Specification spec[] = {
@ -588,14 +583,16 @@ TALER_EXCHANGE_purse_create_with_merge (
&pcm->purse_pub,
contract_priv,
contract_terms,
&econtract,
&econtract_size);
&pcm->econtract.econtract,
&pcm->econtract.econtract_size);
GNUNET_CRYPTO_ecdhe_key_get_public (&contract_priv->ecdhe_priv,
&pcm->econtract.contract_pub.ecdhe_pub);
TALER_wallet_econtract_upload_sign (
econtract,
econtract_size,
&contract_pub,
pcm->econtract.econtract,
pcm->econtract.econtract_size,
&pcm->econtract.contract_pub,
purse_priv,
&pcm->contract_sig);
&pcm->econtract.econtract_sig);
}
create_with_merge_obj = GNUNET_JSON_PACK (
TALER_JSON_pack_amount ("purse_value",
@ -603,21 +600,10 @@ TALER_EXCHANGE_purse_create_with_merge (
GNUNET_JSON_pack_uint64 ("min_age",
min_age),
GNUNET_JSON_pack_allow_null (
GNUNET_JSON_pack_data_varsize ("econtract",
econtract,
econtract_size)),
GNUNET_JSON_pack_allow_null (
upload_contract
? GNUNET_JSON_pack_data_auto ("econtract_sig",
&pcm->contract_sig)
: GNUNET_JSON_pack_string ("dummy",
NULL)),
GNUNET_JSON_pack_allow_null (
upload_contract
? GNUNET_JSON_pack_data_auto ("contract_pub",
&contract_pub)
: GNUNET_JSON_pack_string ("dummy",
NULL)),
TALER_JSON_pack_econtract ("econtract",
upload_contract
? &pcm->econtract
: NULL)),
GNUNET_JSON_pack_allow_null (
pay_for_purse
? TALER_JSON_pack_amount ("purse_fee",
@ -641,7 +627,6 @@ TALER_EXCHANGE_purse_create_with_merge (
GNUNET_JSON_pack_timestamp ("purse_expiration",
pcm->purse_expiration));
GNUNET_assert (NULL != create_with_merge_obj);
GNUNET_free (econtract);
eh = TALER_EXCHANGE_curl_easy_get_ (pcm->url);
if ( (NULL == eh) ||
(GNUNET_OK !=
@ -653,6 +638,7 @@ TALER_EXCHANGE_purse_create_with_merge (
if (NULL != eh)
curl_easy_cleanup (eh);
json_decref (create_with_merge_obj);
GNUNET_free (pcm->econtract.econtract);
GNUNET_free (pcm->url);
GNUNET_free (pcm);
return NULL;
@ -682,6 +668,7 @@ TALER_EXCHANGE_purse_create_with_merge_cancel (
}
GNUNET_free (pcm->url);
TALER_curl_easy_post_finished (&pcm->ctx);
GNUNET_free (pcm->econtract.econtract);
GNUNET_free (pcm);
}