diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/exchange/taler-exchange-httpd_purses_merge.c | 30 | ||||
-rw-r--r-- | src/exchange/taler-exchange-httpd_reserves_purse.c | 7 | ||||
-rw-r--r-- | src/exchangedb/exchange-0001-part.sql | 15 | ||||
-rw-r--r-- | src/exchangedb/plugin_exchangedb_postgres.c | 16 | ||||
-rw-r--r-- | src/include/taler_crypto_lib.h | 17 | ||||
-rw-r--r-- | src/include/taler_exchangedb_plugin.h | 4 | ||||
-rw-r--r-- | src/lib/exchange_api_common.c | 11 | ||||
-rw-r--r-- | src/lib/exchange_api_purse_create_with_merge.c | 236 | ||||
-rw-r--r-- | src/testing/Makefile.am | 8 | ||||
-rw-r--r-- | src/testing/test_exchange_p2p.c | 16 | ||||
-rw-r--r-- | src/testing/testing_api_cmd_purse_deposit.c | 29 | ||||
-rw-r--r-- | src/testing/testing_api_cmd_reserve_purse.c | 2 | ||||
-rw-r--r-- | src/util/wallet_signatures.c | 41 |
13 files changed, 346 insertions, 86 deletions
diff --git a/src/exchange/taler-exchange-httpd_purses_merge.c b/src/exchange/taler-exchange-httpd_purses_merge.c index 14dba5232..d87fb16de 100644 --- a/src/exchange/taler-exchange-httpd_purses_merge.c +++ b/src/exchange/taler-exchange-httpd_purses_merge.c @@ -226,19 +226,20 @@ merge_transaction (void *cls, bool no_kyc = true; bool no_reserve = true; - // FIXME: add KYC-check logic! - qs = TEH_plugin->do_purse_merge (TEH_plugin->cls, - pcc->purse_pub, - &pcc->merge_sig, - pcc->merge_timestamp, - &pcc->reserve_sig, - pcc->provider_url, - &pcc->reserve_pub, - &no_partner, - &no_balance, - &no_reserve, - &no_kyc, - &in_conflict); + qs = TEH_plugin->do_purse_merge ( + TEH_plugin->cls, + pcc->purse_pub, + &pcc->merge_sig, + pcc->merge_timestamp, + &pcc->reserve_sig, + pcc->provider_url, + &pcc->reserve_pub, + TEH_KYC_NONE != TEH_kyc_config.mode, + &no_partner, + &no_balance, + &no_reserve, + &no_kyc, + &in_conflict); if (qs < 0) { if (GNUNET_DB_STATUS_SOFT_ERROR == qs) @@ -270,7 +271,8 @@ merge_transaction (void *cls, NULL); return GNUNET_DB_STATUS_HARD_ERROR; } - if (no_kyc) + if ( (no_kyc) && + (TEH_KYC_NONE != TEH_kyc_config.mode) ) { *mhd_ret = TALER_MHD_REPLY_JSON_PACK ( diff --git a/src/exchange/taler-exchange-httpd_reserves_purse.c b/src/exchange/taler-exchange-httpd_reserves_purse.c index f56852d53..44f3e85c3 100644 --- a/src/exchange/taler-exchange-httpd_reserves_purse.c +++ b/src/exchange/taler-exchange-httpd_reserves_purse.c @@ -301,6 +301,9 @@ purse_transaction (void *cls, bool no_reserve = true; bool no_kyc = true; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Creating purse with flags %d\n", + rpc->flags); qs = TEH_plugin->do_reserve_purse ( TEH_plugin->cls, &rpc->purse_pub, @@ -312,6 +315,7 @@ purse_transaction (void *cls, ? NULL : &rpc->gf->fees.purse, rpc->reserve_pub, + TEH_KYC_NONE != TEH_kyc_config.mode, &in_conflict, &no_reserve, &no_kyc, @@ -387,7 +391,8 @@ purse_transaction (void *cls, TALER_EC_EXCHANGE_GENERIC_RESERVE_UNKNOWN)); return GNUNET_DB_STATUS_HARD_ERROR; } - if (no_kyc) + if ( (no_kyc) && + (TEH_KYC_NONE != TEH_kyc_config.mode) ) { *mhd_ret = TALER_MHD_REPLY_JSON_PACK ( diff --git a/src/exchangedb/exchange-0001-part.sql b/src/exchangedb/exchange-0001-part.sql index 0b99e25f9..c79fdf840 100644 --- a/src/exchangedb/exchange-0001-part.sql +++ b/src/exchangedb/exchange-0001-part.sql @@ -3090,6 +3090,7 @@ CREATE OR REPLACE FUNCTION exchange_do_purse_merge( IN in_reserve_sig BYTEA, IN in_partner_url VARCHAR, IN in_reserve_pub BYTEA, + IN in_require_kyc BOOLEAN, OUT out_no_partner BOOLEAN, OUT out_no_balance BOOLEAN, OUT out_no_kyc BOOLEAN, @@ -3197,7 +3198,8 @@ out_conflict=FALSE; ASSERT NOT my_finished, 'internal invariant failed'; -IF in_partner_url IS NULL +IF ( (in_partner_url IS NULL) AND + (in_require_kyc) ) THEN -- Need to do KYC check. SELECT NOT kyc_passed @@ -3272,7 +3274,7 @@ RETURN; END $$; -COMMENT ON FUNCTION exchange_do_purse_merge(BYTEA, BYTEA, INT8, BYTEA, VARCHAR, BYTEA) +COMMENT ON FUNCTION exchange_do_purse_merge(BYTEA, BYTEA, INT8, BYTEA, VARCHAR, BYTEA, BOOLEAN) IS 'Checks that the partner exists, the purse has not been merged with a different reserve and that the purse is full. If so, persists the merge data and either merges the purse with the reserve or marks it as ready for the taler-exchange-router. Caller MUST abort the transaction on failures so as to not persist data by accident.'; @@ -3285,6 +3287,7 @@ CREATE OR REPLACE FUNCTION exchange_do_reserve_purse( IN in_purse_fee_val INT8, IN in_purse_fee_frac INT4, IN in_reserve_pub BYTEA, + IN in_require_kyc BOOLEAN, OUT out_no_funds BOOLEAN, OUT out_no_kyc BOOLEAN, OUT out_no_reserve BOOLEAN, @@ -3350,7 +3353,7 @@ THEN END IF; out_no_reserve=FALSE; -IF (out_no_kyc) +IF (out_no_kyc AND in_require_kyc) THEN out_no_funds=FALSE; RETURN; @@ -3412,6 +3415,12 @@ INSERT INTO account_merges END $$; +COMMENT ON FUNCTION exchange_do_reserve_purse(BYTEA, BYTEA, INT8, BYTEA, BOOLEAN, INT8, INT4, BYTEA, BOOLEAN) + IS 'Create a purse for a reserve.'; + + + + CREATE OR REPLACE FUNCTION exchange_do_account_merge( diff --git a/src/exchangedb/plugin_exchangedb_postgres.c b/src/exchangedb/plugin_exchangedb_postgres.c index 01869d592..9fcd6203a 100644 --- a/src/exchangedb/plugin_exchangedb_postgres.c +++ b/src/exchangedb/plugin_exchangedb_postgres.c @@ -3977,8 +3977,8 @@ prepare_statements (struct PostgresClosure *pg) ",out_no_reserve AS no_reserve" ",out_conflict AS conflict" " FROM exchange_do_purse_merge" - " ($1, $2, $3, $4, $5, $6);", - 6), + " ($1, $2, $3, $4, $5, $6, $7);", + 7), /* Used in #postgres_do_reserve_purse() */ GNUNET_PQ_make_prepare ( "call_reserve_purse", @@ -3988,8 +3988,8 @@ prepare_statements (struct PostgresClosure *pg) ",out_no_kyc AS no_kyc" ",out_conflict AS conflict" " FROM exchange_do_reserve_purse" - " ($1, $2, $3, $4, $5, $6, $7, $8);", - 8), + " ($1, $2, $3, $4, $5, $6, $7, $8, $9);", + 9), /* Used in #postgres_select_purse_merge */ GNUNET_PQ_make_prepare ( "select_purse_merge", @@ -14492,6 +14492,7 @@ postgres_get_purse_deposit ( * @param reserve_sig signature of the reserve affirming the merge * @param partner_url URL of the partner exchange, can be NULL if the reserves lives with us * @param reserve_pub public key of the reserve to credit + * @param require_kyc true if we should check for KYC * @param[out] no_partner set to true if @a partner_url is unknown * @param[out] no_balance set to true if the @a purse_pub is not paid up yet * @param[out] no_reserve set to true if the @a reserve_pub is not known @@ -14508,6 +14509,7 @@ postgres_do_purse_merge ( const struct TALER_ReserveSignatureP *reserve_sig, const char *partner_url, const struct TALER_ReservePublicKeyP *reserve_pub, + bool require_kyc, bool *no_partner, bool *no_balance, bool *no_reserve, @@ -14524,6 +14526,7 @@ postgres_do_purse_merge ( ? GNUNET_PQ_query_param_null () : GNUNET_PQ_query_param_string (partner_url), GNUNET_PQ_query_param_auto_from_type (reserve_pub), + GNUNET_PQ_query_param_bool (require_kyc), GNUNET_PQ_query_param_end }; struct GNUNET_PQ_ResultSpec rs[] = { @@ -14559,7 +14562,10 @@ postgres_do_purse_merge ( * @param reserve_sig signature of the reserve affirming the merge * @param purse_fee amount to charge the reserve for the purse creation, NULL to use the quota * @param reserve_pub public key of the reserve to credit + * @param require_kyc true if we should check for KYC * @param[out] in_conflict set to true if @a purse_pub was merged into a different reserve already + * @param[out] no_reserve set to true if @a reserve_pub is not a known reserve + * @param[out] no_kyc set to true if @a reserve_pub has not passed KYC checks * @param[out] insufficient_funds set to true if @a reserve_pub has insufficient capacity to create another purse * @return transaction status code */ @@ -14572,6 +14578,7 @@ postgres_do_reserve_purse ( const struct TALER_ReserveSignatureP *reserve_sig, const struct TALER_Amount *purse_fee, const struct TALER_ReservePublicKeyP *reserve_pub, + bool require_kyc, bool *in_conflict, bool *no_reserve, bool *no_kyc, @@ -14589,6 +14596,7 @@ postgres_do_reserve_purse ( ? &zero_fee : purse_fee), GNUNET_PQ_query_param_auto_from_type (reserve_pub), + GNUNET_PQ_query_param_bool (require_kyc), GNUNET_PQ_query_param_end }; struct GNUNET_PQ_ResultSpec rs[] = { diff --git a/src/include/taler_crypto_lib.h b/src/include/taler_crypto_lib.h index c4c439af1..63fb56cee 100644 --- a/src/include/taler_crypto_lib.h +++ b/src/include/taler_crypto_lib.h @@ -2840,6 +2840,23 @@ TALER_wallet_econtract_upload_verify ( /** + * Verify a signature over encrypted contract. + * + * @param h_econtract hashed encrypted contract + * @param contract_pub public key for the DH-encryption + * @param purse_pub purse’s public key + * @param purse_sig the signature made with purpose #TALER_SIGNATURE_WALLET_PURSE_CREATE + * @return #GNUNET_OK if the signature is valid + */ +enum GNUNET_GenericReturnValue +TALER_wallet_econtract_upload_verify2 ( + const struct GNUNET_HashCode *h_econtract, + const struct TALER_ContractDiffiePublicP *contract_pub, + const struct TALER_PurseContractPublicKeyP *purse_pub, + const struct TALER_PurseContractSignatureP *purse_sig); + + +/** * Sign a request to inquire about a purse's status. * * @param purse_priv key identifying the purse diff --git a/src/include/taler_exchangedb_plugin.h b/src/include/taler_exchangedb_plugin.h index a88f34b01..394177751 100644 --- a/src/include/taler_exchangedb_plugin.h +++ b/src/include/taler_exchangedb_plugin.h @@ -5037,6 +5037,7 @@ struct TALER_EXCHANGEDB_Plugin * @param reserve_sig signature of the reserve affirming the merge * @param partner_url URL of the partner exchange, can be NULL if the reserves lives with us * @param reserve_pub public key of the reserve to credit + * @param require_kyc true if we should check for KYC * @param[out] no_partner set to true if @a partner_url is unknown * @param[out] no_balance set to true if the @a purse_pub is not paid up yet * @param[out] no_reserve set to true if the @a reserve_pub is not known @@ -5053,6 +5054,7 @@ struct TALER_EXCHANGEDB_Plugin const struct TALER_ReserveSignatureP *reserve_sig, const char *partner_url, const struct TALER_ReservePublicKeyP *reserve_pub, + bool require_kyc, bool *no_partner, bool *no_balance, bool *no_reserve, @@ -5072,6 +5074,7 @@ struct TALER_EXCHANGEDB_Plugin * @param reserve_sig signature of the reserve affirming the merge * @param purse_fee amount to charge the reserve for the purse creation, NULL to use the quota * @param reserve_pub public key of the reserve to credit + * @param require_kyc true if we should check for KYC * @param[out] in_conflict set to true if @a purse_pub was merged into a different reserve already * @param[out] no_reserve set to true if @a reserve_pub is not a known reserve * @param[out] no_kyc set to true if @a reserve_pub has not passed KYC checks @@ -5087,6 +5090,7 @@ struct TALER_EXCHANGEDB_Plugin const struct TALER_ReserveSignatureP *reserve_sig, const struct TALER_Amount *purse_fee, const struct TALER_ReservePublicKeyP *reserve_pub, + bool require_kyc, bool *in_conflict, bool *no_reserve, bool *no_kyc, diff --git a/src/lib/exchange_api_common.c b/src/lib/exchange_api_common.c index d60327831..9cbcdeb26 100644 --- a/src/lib/exchange_api_common.c +++ b/src/lib/exchange_api_common.c @@ -398,6 +398,7 @@ parse_merge (struct TALER_EXCHANGE_ReserveHistoryEntry *rh, const json_t *transaction) { uint32_t flags32; + struct TALER_Amount total; struct GNUNET_JSON_Specification merge_spec[] = { GNUNET_JSON_spec_fixed_auto ("h_contract_terms", &rh->details.merge_details.h_contract_terms), @@ -433,13 +434,21 @@ parse_merge (struct TALER_EXCHANGE_ReserveHistoryEntry *rh, } rh->details.merge_details.flags = (enum TALER_WalletAccountMergeFlags) flags32; + if (0 > + TALER_amount_add (&total, + &rh->amount, + &rh->details.merge_details.purse_fee)) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } if (GNUNET_OK != TALER_wallet_account_merge_verify ( rh->details.merge_details.merge_timestamp, &rh->details.merge_details.purse_pub, rh->details.merge_details.purse_expiration, &rh->details.merge_details.h_contract_terms, - &rh->amount, + &total, &rh->details.merge_details.purse_fee, rh->details.merge_details.min_age, rh->details.merge_details.flags, diff --git a/src/lib/exchange_api_purse_create_with_merge.c b/src/lib/exchange_api_purse_create_with_merge.c index af5b554e4..fcc68e699 100644 --- a/src/lib/exchange_api_purse_create_with_merge.c +++ b/src/lib/exchange_api_purse_create_with_merge.c @@ -86,11 +86,31 @@ struct TALER_EXCHANGE_PurseCreateMergeHandle struct TALER_ReserveSignatureP reserve_sig; /** + * Merge capability key. + */ + struct TALER_PurseMergePublicKeyP merge_pub; + + /** + * Our merge signature (if any). + */ + 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; /** + * Request data we signed over. + */ + struct TALER_PurseContractSignatureP purse_sig; + + /** * Hash over the purse's contrac terms. */ struct TALER_PrivateContractHashP h_contract_terms; @@ -136,13 +156,14 @@ handle_purse_create_with_merge_finished (void *cls, break; case MHD_HTTP_OK: { -#if FIXME const struct TALER_EXCHANGE_Keys *key_state; struct GNUNET_TIME_Timestamp etime; struct TALER_Amount total_deposited; struct TALER_ExchangeSignatureP exchange_sig; struct TALER_ExchangePublicKeyP exchange_pub; struct GNUNET_JSON_Specification spec[] = { + TALER_JSON_spec_amount_any ("total_deposited", + &total_deposited), GNUNET_JSON_spec_fixed_auto ("exchange_sig", &exchange_sig), GNUNET_JSON_spec_fixed_auto ("exchange_pub", @@ -169,29 +190,25 @@ handle_purse_create_with_merge_finished (void *cls, { GNUNET_break_op (0); dr.hr.http_status = 0; - dr.hr.ec = - TALER_EC_EXCHANGE_PURSE_CREATE_WITH_MERGE_EXCHANGE_SIGNATURE_INVALID; + dr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; break; } if (GNUNET_OK != - TALER_exchange_online_purse_create_with_merged_verify ( + TALER_exchange_online_purse_created_verify ( etime, pcm->purse_expiration, &pcm->purse_value_after_fees, + &total_deposited, &pcm->purse_pub, &pcm->h_contract_terms, - &pcm->reserve_pub, - pcm->provider_url, &exchange_pub, &exchange_sig)) { GNUNET_break_op (0); dr.hr.http_status = 0; - dr.hr.ec = - TALER_EC_EXCHANGE_PURSE_CREATE_WITH_MERGE_EXCHANGE_SIGNATURE_INVALID; + dr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; break; } -#endif } break; case MHD_HTTP_BAD_REQUEST: @@ -214,7 +231,184 @@ handle_purse_create_with_merge_finished (void *cls, happen, we should pass the JSON reply to the application */ break; case MHD_HTTP_CONFLICT: - // FIXME: check reply! + dr.hr.ec = TALER_JSON_get_error_code (j); + switch (dr.hr.ec) + { + case TALER_EC_EXCHANGE_RESERVES_PURSE_CREATE_CONFLICTING_META_DATA: + { + struct TALER_Amount amount; + uint32_t min_age; + struct GNUNET_TIME_Timestamp purse_expiration; + struct TALER_PurseContractSignatureP purse_sig; + struct TALER_PrivateContractHashP h_contract_terms; + struct TALER_PurseMergePublicKeyP merge_pub; + struct GNUNET_JSON_Specification spec[] = { + TALER_JSON_spec_amount_any ("amount", + &amount), + GNUNET_JSON_spec_uint32 ("min_age", + &min_age), + GNUNET_JSON_spec_timestamp ("purse_expiration", + &purse_expiration), + GNUNET_JSON_spec_fixed_auto ("purse_sig", + &purse_sig), + GNUNET_JSON_spec_fixed_auto ("h_contract_terms", + &h_contract_terms), + GNUNET_JSON_spec_fixed_auto ("merge_pub", + &merge_pub), + GNUNET_JSON_spec_end () + }; + + if (GNUNET_OK != + GNUNET_JSON_parse (j, + spec, + NULL, NULL)) + { + GNUNET_break_op (0); + dr.hr.http_status = 0; + dr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; + break; + } + if (GNUNET_OK != + TALER_wallet_purse_create_verify (purse_expiration, + &h_contract_terms, + &merge_pub, + min_age, + &amount, + &pcm->purse_pub, + &purse_sig)) + { + GNUNET_break_op (0); + dr.hr.http_status = 0; + dr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; + break; + } + if (0 == + GNUNET_memcmp (&purse_sig, + &pcm->purse_sig)) + { + /* Must be the SAME data, not a conflict! */ + GNUNET_break_op (0); + dr.hr.http_status = 0; + dr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; + break; + } + break; + } + case TALER_EC_EXCHANGE_RESERVES_PURSE_MERGE_CONFLICTING_META_DATA: + { + struct TALER_PurseMergeSignatureP merge_sig; + struct GNUNET_TIME_Timestamp merge_timestamp; + const char *partner_url = pcm->exchange->url; + struct TALER_ReservePublicKeyP reserve_pub; + struct GNUNET_JSON_Specification spec[] = { + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_string ("partner_url", + &partner_url), + NULL), + GNUNET_JSON_spec_timestamp ("merge_timestamp", + &merge_timestamp), + GNUNET_JSON_spec_fixed_auto ("merge_sig", + &merge_sig), + GNUNET_JSON_spec_fixed_auto ("reserve_pub", + &reserve_pub), + GNUNET_JSON_spec_end () + }; + + if (GNUNET_OK != + GNUNET_JSON_parse (j, + spec, + NULL, NULL)) + { + GNUNET_break_op (0); + dr.hr.http_status = 0; + dr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; + break; + } + if (GNUNET_OK != + TALER_wallet_purse_merge_verify ( + partner_url, + merge_timestamp, + &pcm->purse_pub, + &pcm->merge_pub, + &merge_sig)) + { + GNUNET_break_op (0); + dr.hr.http_status = 0; + dr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; + break; + } + if (0 == + GNUNET_memcmp (&merge_sig, + &pcm->merge_sig)) + { + /* Must be the SAME data, not a conflict! */ + GNUNET_break_op (0); + dr.hr.http_status = 0; + dr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; + break; + } + } + break; + case TALER_EC_EXCHANGE_RESERVES_PURSE_CREATE_INSUFFICIENT_FUNDS: + /* nothing to verify */ + break; + case TALER_EC_EXCHANGE_PURSE_ECONTRACT_CONFLICTING_META_DATA: + { + struct TALER_ContractDiffiePublicP pub_ckey; + struct TALER_PurseContractSignatureP contract_sig; + struct GNUNET_HashCode h_econtract; + struct GNUNET_JSON_Specification spec[] = { + GNUNET_JSON_spec_fixed_auto ("h_econtract", + &h_econtract), + GNUNET_JSON_spec_fixed_auto ("econtract_sig", + &contract_sig), + GNUNET_JSON_spec_fixed_auto ("pub_ckey", + &pub_ckey), + GNUNET_JSON_spec_end () + }; + + if (GNUNET_OK != + GNUNET_JSON_parse (j, + spec, + NULL, NULL)) + { + GNUNET_break_op (0); + dr.hr.http_status = 0; + dr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; + break; + } + if (GNUNET_OK != + TALER_wallet_econtract_upload_verify2 ( + &h_econtract, + &pub_ckey, + &pcm->purse_pub, + &contract_sig)) + { + GNUNET_break_op (0); + dr.hr.http_status = 0; + dr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; + break; + } + if (0 == + GNUNET_memcmp (&contract_sig, + &pcm->contract_sig)) + { + /* Must be the SAME data, not a conflict! */ + GNUNET_break_op (0); + dr.hr.http_status = 0; + dr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; + break; + } + + break; + } + default: + /* unexpected EC! */ + GNUNET_break_op (0); + dr.hr.http_status = 0; + dr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; + break; + } /* end inner (EC) switch */ break; case MHD_HTTP_GONE: /* could happen if denomination was revoked */ @@ -272,11 +466,7 @@ TALER_EXCHANGE_purse_create_with_merge ( CURL *eh; char arg_str[sizeof (pcm->reserve_pub) * 2 + 32]; uint32_t min_age = 0; - struct TALER_PurseMergePublicKeyP merge_pub; - struct TALER_PurseMergeSignatureP merge_sig; struct TALER_ContractDiffiePublicP contract_pub; - struct TALER_PurseContractSignatureP contract_sig; - struct TALER_PurseContractSignatureP purse_sig; void *econtract = NULL; size_t econtract_size = 0; struct TALER_Amount purse_fee; @@ -301,7 +491,7 @@ TALER_EXCHANGE_purse_create_with_merge ( GNUNET_CRYPTO_eddsa_key_get_public (&reserve_priv->eddsa_priv, &pcm->reserve_pub.eddsa_pub); GNUNET_CRYPTO_eddsa_key_get_public (&merge_priv->eddsa_priv, - &merge_pub.eddsa_pub); + &pcm->merge_pub.eddsa_pub); GNUNET_CRYPTO_ecdhe_key_get_public (&contract_priv->ecdhe_priv, &contract_pub.ecdhe_pub); @@ -372,16 +562,16 @@ TALER_EXCHANGE_purse_create_with_merge ( } TALER_wallet_purse_create_sign (pcm->purse_expiration, &pcm->h_contract_terms, - &merge_pub, + &pcm->merge_pub, min_age, &pcm->purse_value_after_fees, purse_priv, - &purse_sig); + &pcm->purse_sig); TALER_wallet_purse_merge_sign (exchange->url, merge_timestamp, &pcm->purse_pub, merge_priv, - &merge_sig); + &pcm->merge_sig); TALER_wallet_account_merge_sign (merge_timestamp, &pcm->purse_pub, pcm->purse_expiration, @@ -405,7 +595,7 @@ TALER_EXCHANGE_purse_create_with_merge ( econtract_size, &contract_pub, purse_priv, - &contract_sig); + &pcm->contract_sig); } create_with_merge_obj = GNUNET_JSON_PACK ( TALER_JSON_pack_amount ("purse_value", @@ -419,7 +609,7 @@ TALER_EXCHANGE_purse_create_with_merge ( GNUNET_JSON_pack_allow_null ( upload_contract ? GNUNET_JSON_pack_data_auto ("econtract_sig", - &contract_sig) + &pcm->contract_sig) : GNUNET_JSON_pack_string ("dummy", NULL)), GNUNET_JSON_pack_allow_null ( @@ -435,15 +625,15 @@ TALER_EXCHANGE_purse_create_with_merge ( : GNUNET_JSON_pack_string ("dummy2", NULL)), GNUNET_JSON_pack_data_auto ("merge_pub", - &merge_pub), + &pcm->merge_pub), GNUNET_JSON_pack_data_auto ("merge_sig", - &merge_sig), + &pcm->merge_sig), GNUNET_JSON_pack_data_auto ("reserve_sig", &pcm->reserve_sig), GNUNET_JSON_pack_data_auto ("purse_pub", &pcm->purse_pub), GNUNET_JSON_pack_data_auto ("purse_sig", - &purse_sig), + &pcm->purse_sig), GNUNET_JSON_pack_data_auto ("h_contract_terms", &pcm->h_contract_terms), GNUNET_JSON_pack_timestamp ("merge_timestamp", diff --git a/src/testing/Makefile.am b/src/testing/Makefile.am index fefb7c984..7da713beb 100644 --- a/src/testing/Makefile.am +++ b/src/testing/Makefile.am @@ -127,10 +127,6 @@ libtalertesting_la_LIBADD = \ AM_TESTS_ENVIRONMENT=export TALER_PREFIX=$${TALER_PREFIX:-@libdir@};export PATH=$${TALER_PREFIX:-@prefix@}/bin:$$PATH; -noinst_PROGRAMS = \ - test_exchange_p2p_cs \ - test_exchange_p2p_rsa - .NOTPARALLEL: check_PROGRAMS = \ @@ -152,7 +148,9 @@ check_PROGRAMS = \ test_exchange_management_api_rsa \ test_kyc_api \ test_taler_exchange_aggregator-postgres \ - test_taler_exchange_wirewatch-postgres + test_taler_exchange_wirewatch-postgres \ + test_exchange_p2p_cs \ + test_exchange_p2p_rsa if HAVE_TWISTER check_PROGRAMS += \ test_exchange_api_twisted_cs \ diff --git a/src/testing/test_exchange_p2p.c b/src/testing/test_exchange_p2p.c index 647c56c8f..ba6d5bbf2 100644 --- a/src/testing/test_exchange_p2p.c +++ b/src/testing/test_exchange_p2p.c @@ -116,16 +116,16 @@ run (void *cls, * Move money to the exchange's bank account. */ CMD_TRANSFER_TO_EXCHANGE ("create-reserve-1", - "EUR:5.01"), + "EUR:5.04"), CMD_TRANSFER_TO_EXCHANGE ("create-reserve-2", "EUR:5.01"), TALER_TESTING_cmd_reserve_poll ("poll-reserve-1", "create-reserve-1", - "EUR:5.01", + "EUR:5.04", GNUNET_TIME_UNIT_MINUTES, MHD_HTTP_OK), TALER_TESTING_cmd_check_bank_admin_transfer ("check-create-reserve-1", - "EUR:5.01", + "EUR:5.04", bc.user42_payto, bc.exchange_payto, "create-reserve-1"), @@ -155,7 +155,7 @@ run (void *cls, */ TALER_TESTING_cmd_status ("status-1", "create-reserve-1", - "EUR:0", + "EUR:0.03", MHD_HTTP_OK), TALER_TESTING_cmd_end () }; @@ -195,13 +195,13 @@ run (void *cls, TALER_TESTING_cmd_status ( "push-check-post-merge-reserve-balance-get", "create-reserve-1", - "EUR:1", + "EUR:1.03", MHD_HTTP_OK), /* POST history doesn't yet support P2P transfers */ TALER_TESTING_cmd_reserve_status ( "push-check-post-merge-reserve-balance-post", "create-reserve-1", - "EUR:1", + "EUR:1.03", MHD_HTTP_OK), /* Test conflicting merge */ TALER_TESTING_cmd_purse_merge ( @@ -249,13 +249,13 @@ run (void *cls, TALER_TESTING_cmd_status ( "pull-check-post-merge-reserve-balance-get", "create-reserve-1", - "EUR:2", + "EUR:2.02", MHD_HTTP_OK), /* POST history doesn't yet support P2P transfers */ TALER_TESTING_cmd_reserve_status ( "push-check-post-merge-reserve-balance-post", "create-reserve-1", - "EUR:2", + "EUR:2.02", MHD_HTTP_OK), /* create 2nd purse for a deposit conflict */ TALER_TESTING_cmd_purse_create_with_reserve ( diff --git a/src/testing/testing_api_cmd_purse_deposit.c b/src/testing/testing_api_cmd_purse_deposit.c index fa1b900da..0fa0998d2 100644 --- a/src/testing/testing_api_cmd_purse_deposit.c +++ b/src/testing/testing_api_cmd_purse_deposit.c @@ -201,9 +201,6 @@ deposit_cb (void *cls, /* Deposits complete, create trait! */ ds->reserve_history.type = TALER_EXCHANGE_RTT_MERGE; - ds->reserve_history.amount - = dr->details.success.purse_value_after_fees; -#if 0 { const struct TALER_EXCHANGE_Keys *keys; const struct TALER_EXCHANGE_GlobalFee *gf; @@ -213,12 +210,26 @@ deposit_cb (void *cls, gf = TALER_EXCHANGE_get_global_fee (keys, *merge_timestamp); GNUNET_assert (NULL != gf); + + /* Note: change when flags below changes! */ + if (true) + { + /* If we paid a purse fee, we need to subtract the + purse fee from the reserve history amount */ + TALER_amount_subtract (&ds->reserve_history.amount, + &dr->details.success.purse_value_after_fees, + &gf->fees.purse); + ds->reserve_history.details.merge_details.purse_fee = gf->fees.purse; + } + else + { + ds->reserve_history.amount + = dr->details.success.purse_value_after_fees; + TALER_amount_set_zero ( + ds->reserve_history.amount.currency, + &ds->reserve_history.details.merge_details.purse_fee); + } } -#endif - /* Note: change when flags below changes! */ - TALER_amount_set_zero ( - ds->reserve_history.amount.currency, - &ds->reserve_history.details.merge_details.purse_fee); ds->reserve_history.details.merge_details.h_contract_terms = dr->details.success.h_contract_terms; ds->reserve_history.details.merge_details.merge_pub @@ -234,7 +245,7 @@ deposit_cb (void *cls, ds->reserve_history.details.merge_details.min_age = ds->min_age; ds->reserve_history.details.merge_details.flags - = TALER_WAMF_MODE_CREATE_FROM_PURSE_QUOTA; + = TALER_WAMF_MODE_CREATE_WITH_PURSE_FEE; ds->purse_complete = true; } } diff --git a/src/testing/testing_api_cmd_reserve_purse.c b/src/testing/testing_api_cmd_reserve_purse.c index 42aff80e3..4106600cb 100644 --- a/src/testing/testing_api_cmd_reserve_purse.c +++ b/src/testing/testing_api_cmd_reserve_purse.c @@ -208,7 +208,7 @@ purse_run (void *cls, &ds->contract_priv, ds->contract_terms, true /* upload contract */, - false /* do not pay purse fee -- FIXME: make this a choice to test this case; then update testing_api_cmd_purse_deposit flags logic to match! */, + true /* do pay purse fee -- FIXME: make this a choice to test this case; then update testing_api_cmd_purse_deposit flags logic to match! */, ds->merge_timestamp, &purse_cb, ds); diff --git a/src/util/wallet_signatures.c b/src/util/wallet_signatures.c index 9c5669650..41e272eb0 100644 --- a/src/util/wallet_signatures.c +++ b/src/util/wallet_signatures.c @@ -1248,20 +1248,9 @@ TALER_wallet_econtract_upload_sign ( } -/** - * Verify a signature over encrypted contract. - * - * @param econtract encrypted contract - * @param econtract_size number of bytes in @a econtract - * @param contract_pub public key for the DH-encryption - * @param purse_pub purse’s public key - * @param purse_sig the signature made with purpose #TALER_SIGNATURE_WALLET_PURSE_CREATE - * @return #GNUNET_OK if the signature is valid - */ enum GNUNET_GenericReturnValue -TALER_wallet_econtract_upload_verify ( - const void *econtract, - size_t econtract_size, +TALER_wallet_econtract_upload_verify2 ( + const struct GNUNET_HashCode *h_econtract, const struct TALER_ContractDiffiePublicP *contract_pub, const struct TALER_PurseContractPublicKeyP *purse_pub, const struct TALER_PurseContractSignatureP *purse_sig) @@ -1269,12 +1258,10 @@ TALER_wallet_econtract_upload_verify ( struct TALER_PurseContractPS pc = { .purpose.size = htonl (sizeof (pc)), .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_ECONTRACT), - .contract_pub = *contract_pub + .contract_pub = *contract_pub, + .h_econtract = *h_econtract }; - GNUNET_CRYPTO_hash (econtract, - econtract_size, - &pc.h_econtract); return GNUNET_CRYPTO_eddsa_verify_ (TALER_SIGNATURE_WALLET_PURSE_ECONTRACT, &pc.purpose, &purse_sig->eddsa_signature, @@ -1282,4 +1269,24 @@ TALER_wallet_econtract_upload_verify ( } +enum GNUNET_GenericReturnValue +TALER_wallet_econtract_upload_verify ( + const void *econtract, + size_t econtract_size, + const struct TALER_ContractDiffiePublicP *contract_pub, + const struct TALER_PurseContractPublicKeyP *purse_pub, + const struct TALER_PurseContractSignatureP *purse_sig) +{ + struct GNUNET_HashCode h_econtract; + + GNUNET_CRYPTO_hash (econtract, + econtract_size, + &h_econtract); + return TALER_wallet_econtract_upload_verify2 (&h_econtract, + contract_pub, + purse_pub, + purse_sig); +} + + /* end of wallet_signatures.c */ |