diff options
author | Christian Grothoff <christian@grothoff.org> | 2022-06-05 00:25:56 +0200 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2022-06-05 00:25:56 +0200 |
commit | efa0ca4ec18d636f9950cb03a192cf9a6484fadb (patch) | |
tree | f2d5c8697ffb235e1dc582965e1cbcf2a7d48d81 | |
parent | a17781ba8d5f875b5150e524174c5f144aa6c0ba (diff) |
-move econtract into sub-object with its own parser
-rw-r--r-- | src/exchange/taler-exchange-httpd_purses_create.c | 77 | ||||
-rw-r--r-- | src/exchange/taler-exchange-httpd_reserves_purse.c | 138 | ||||
-rw-r--r-- | src/include/taler_json_lib.h | 57 | ||||
-rw-r--r-- | src/json/json_helper.c | 76 | ||||
-rw-r--r-- | src/json/json_pack.c | 34 | ||||
-rw-r--r-- | src/lib/exchange_api_purse_create_with_deposit.c | 88 | ||||
-rw-r--r-- | src/lib/exchange_api_purse_create_with_merge.c | 53 |
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); } |