aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2022-06-05 00:25:56 +0200
committerChristian Grothoff <christian@grothoff.org>2022-06-05 00:25:56 +0200
commitefa0ca4ec18d636f9950cb03a192cf9a6484fadb (patch)
treef2d5c8697ffb235e1dc582965e1cbcf2a7d48d81
parenta17781ba8d5f875b5150e524174c5f144aa6c0ba (diff)
-move econtract into sub-object with its own parser
-rw-r--r--src/exchange/taler-exchange-httpd_purses_create.c77
-rw-r--r--src/exchange/taler-exchange-httpd_reserves_purse.c138
-rw-r--r--src/include/taler_json_lib.h57
-rw-r--r--src/json/json_helper.c76
-rw-r--r--src/json/json_pack.c34
-rw-r--r--src/lib/exchange_api_purse_create_with_deposit.c88
-rw-r--r--src/lib/exchange_api_purse_create_with_merge.c53
7 files changed, 312 insertions, 211 deletions
diff --git a/src/exchange/taler-exchange-httpd_purses_create.c b/src/exchange/taler-exchange-httpd_purses_create.c
index b46d27958..65cd5d455 100644
--- a/src/exchange/taler-exchange-httpd_purses_create.c
+++ b/src/exchange/taler-exchange-httpd_purses_create.c
@@ -107,9 +107,9 @@ 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.
@@ -117,11 +117,6 @@ struct PurseCreateContext
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;
@@ -132,16 +127,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.
*/
unsigned int num_coins;
@@ -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);
diff --git a/src/exchange/taler-exchange-httpd_reserves_purse.c b/src/exchange/taler-exchange-httpd_reserves_purse.c
index 44f3e85c3..af86bc91e 100644
--- a/src/exchange/taler-exchange-httpd_reserves_purse.c
+++ b/src/exchange/taler-exchange-httpd_reserves_purse.c
@@ -86,6 +86,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.
*/
struct TALER_PurseMergePublicKeyP merge_pub;
@@ -96,11 +101,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.
*/
struct TALER_PurseContractPublicKeyP purse_pub;
@@ -111,26 +111,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.
*/
uint32_t min_age;
@@ -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);
diff --git a/src/include/taler_json_lib.h b/src/include/taler_json_lib.h
index b4f999001..a8ad6f243 100644
--- a/src/include/taler_json_lib.h
+++ b/src/include/taler_json_lib.h
@@ -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
@@ -172,6 +203,20 @@ TALER_JSON_pack_amount_nbo (const char *name,
/**
+ * 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.
*
* @param amount the amount
@@ -238,6 +283,18 @@ TALER_JSON_spec_amount_any (const char *name,
/**
+ * 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.
*
diff --git a/src/json/json_helper.c b/src/json/json_helper.c
index 50d4705d5..2e5241b5a 100644
--- a/src/json/json_helper.c
+++ b/src/json/json_helper.c
@@ -235,6 +235,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.
*
* @param cls closure, NULL
diff --git a/src/json/json_pack.c b/src/json/json_pack.c
index ad41eb955..090a8b96b 100644
--- a/src/json/json_pack.c
+++ b/src/json/json_pack.c
@@ -48,6 +48,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,
const struct TALER_DenominationPublicKey *pk)
@@ -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:
diff --git a/src/lib/exchange_api_purse_create_with_deposit.c b/src/lib/exchange_api_purse_create_with_deposit.c
index 42dd6914b..e77bbf2da 100644
--- a/src/lib/exchange_api_purse_create_with_deposit.c
+++ b/src/lib/exchange_api_purse_create_with_deposit.c
@@ -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 !=
diff --git a/src/lib/exchange_api_purse_create_with_merge.c b/src/lib/exchange_api_purse_create_with_merge.c
index fcc68e699..90301b869 100644
--- a/src/lib/exchange_api_purse_create_with_merge.c
+++ b/src/lib/exchange_api_purse_create_with_merge.c
@@ -71,6 +71,11 @@ struct TALER_EXCHANGE_PurseCreateMergeHandle
void *cb_cls;
/**
+ * The encrypted contract (if any).
+ */
+ struct TALER_EncryptedContract econtract;
+
+ /**
* Expected value in the purse after fees.
*/
struct TALER_Amount purse_value_after_fees;
@@ -96,11 +101,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.
*/
struct TALER_PurseContractPublicKeyP purse_pub;
@@ -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);
}