exchange

Base system with REST service to issue digital coins, run by the payment service provider
Log | Files | Refs | Submodules | README | LICENSE

commit ed93a77ce51c41c52868318bb955e3462e171251
parent a14ef50b776e583c5730ea7b0a514c04322c3ee0
Author: Christian Grothoff <christian@grothoff.org>
Date:   Wed, 28 May 2025 19:49:13 +0200

fix #10044

Diffstat:
Msrc/exchange/taler-exchange-httpd_kyc-check.c | 28++++++++++++++++++++++------
Msrc/exchangedb/exchange_do_lookup_kyc_requirement_by_row.sql | 25++++++++++++++++++++++++-
Msrc/exchangedb/pg_lookup_kyc_requirement_by_row.c | 6+++++-
Msrc/exchangedb/pg_lookup_kyc_requirement_by_row.h | 3+++
Msrc/include/taler_crypto_lib.h | 5+++++
Msrc/include/taler_exchangedb_plugin.h | 5++++-
Msrc/include/taler_mhd_lib.h | 11++++++-----
7 files changed, 69 insertions(+), 14 deletions(-)

diff --git a/src/exchange/taler-exchange-httpd_kyc-check.c b/src/exchange/taler-exchange-httpd_kyc-check.c @@ -77,6 +77,12 @@ struct KycPoller union TALER_AccountSignatureP account_sig; /** + * Public key from the account owner authorizing this + * operation. Optional, see @e have_pub. + */ + union TALER_AccountPublicKeyP account_pub; + + /** * Generation of KYC rules already known to the client * (when long-polling). Do not send these rules again. */ @@ -92,6 +98,11 @@ struct KycPoller */ bool suspended; + /** + * True if we have an @e account_pub. + */ + bool have_pub; + }; @@ -197,7 +208,6 @@ TEH_handler_kyc_check ( struct KycPoller *kyp = rc->rh_ctx; json_t *jrules = NULL; json_t *jlimits = NULL; - union TALER_AccountPublicKeyP account_pub; union TALER_AccountPublicKeyP reserve_pub; struct TALER_AccountAccessTokenP access_token; bool aml_review; @@ -236,6 +246,11 @@ TEH_handler_kyc_check ( TALER_HTTP_HEADER_ACCOUNT_OWNER_SIGNATURE, &kyp->account_sig, sig_required); + TALER_MHD_parse_request_header_auto ( + rc->connection, + TALER_HTTP_HEADER_ACCOUNT_OWNER_PUBKEY, + &kyp->account_pub, + kyp->have_pub); TALER_MHD_parse_request_timeout (rc->connection, &kyp->timeout); { @@ -308,7 +323,8 @@ TEH_handler_kyc_check ( qs = TEH_plugin->lookup_kyc_requirement_by_row ( TEH_plugin->cls, &kyp->h_payto, - &account_pub, + kyp->have_pub, + &kyp->account_pub, &is_wallet, &reserve_pub.reserve_pub, &access_token, @@ -345,9 +361,9 @@ TEH_handler_kyc_check ( else { access_ok = - ( (! GNUNET_is_zero (&account_pub) && + ( (! GNUNET_is_zero (&kyp->account_pub) && (GNUNET_OK == - TALER_account_kyc_auth_verify (&account_pub, + TALER_account_kyc_auth_verify (&kyp->account_pub, &kyp->account_sig)) ) || (! GNUNET_is_zero (&reserve_pub) && (GNUNET_OK == @@ -410,7 +426,7 @@ TEH_handler_kyc_check ( { json_decref (jrules); jrules = NULL; - if (GNUNET_is_zero (&account_pub)) + if (GNUNET_is_zero (&kyp->account_pub)) { GNUNET_break_op (0); return TALER_MHD_reply_with_error ( @@ -427,7 +443,7 @@ TEH_handler_kyc_check ( TALER_JSON_pack_ec ( TALER_EC_EXCHANGE_KYC_CHECK_AUTHORIZATION_FAILED), GNUNET_JSON_pack_data_auto ("expected_account_pub", - &account_pub)); + &kyp->account_pub)); } GNUNET_log (GNUNET_ERROR_TYPE_INFO, diff --git a/src/exchangedb/exchange_do_lookup_kyc_requirement_by_row.sql b/src/exchangedb/exchange_do_lookup_kyc_requirement_by_row.sql @@ -19,6 +19,7 @@ DROP FUNCTION IF EXISTS exchange_do_lookup_kyc_requirement_by_row; CREATE FUNCTION exchange_do_lookup_kyc_requirement_by_row( IN in_h_normalized_payto BYTEA, + IN in_account_pub BYTEA, -- NULL allowed OUT out_account_pub BYTEA, -- NULL allowed OUT out_reserve_pub BYTEA, -- NULL allowed OUT out_access_token BYTEA, -- NULL if 'out_not_found' @@ -33,6 +34,7 @@ AS $$ DECLARE my_wtrec RECORD; my_lorec RECORD; + my_ok BOOL; BEGIN -- Find the access token and the current account public key. @@ -43,7 +45,28 @@ SELECT access_token FROM kyc_targets WHERE h_normalized_payto=in_h_normalized_payto; -IF NOT FOUND +my_ok = FOUND; + +IF ( (NOT my_ok) AND + (in_account_pub IS NOT NULL) AND + (my_wtrec.target_pub!=in_account_pub) ) +THEN + -- Try to see if the in_account_pub appears in ANY reserve_in + -- for this account. + PERFORM + FROM reserves_in + WHERE wire_source_h_payto IN + (SELECT wire_target_h_payto + FROM wire_targets + WHERE h_normalized_payto=in_h_normalized_payto); + IF FOUND + THEN + my_wtrec.target_pub = in_account_pub; + my_ok = TRUE; + END IF; +END IF; + +IF NOT my_ok THEN out_not_found = TRUE; out_kyc_required = FALSE; diff --git a/src/exchangedb/pg_lookup_kyc_requirement_by_row.c b/src/exchangedb/pg_lookup_kyc_requirement_by_row.c @@ -30,6 +30,7 @@ enum GNUNET_DB_QueryStatus TEH_PG_lookup_kyc_requirement_by_row ( void *cls, const struct TALER_NormalizedPaytoHashP *h_payto, + bool have_pub, union TALER_AccountPublicKeyP *account_pub, bool *is_wallet, struct TALER_ReservePublicKeyP *reserve_pub, @@ -42,6 +43,9 @@ TEH_PG_lookup_kyc_requirement_by_row ( struct PostgresClosure *pg = cls; struct GNUNET_PQ_QueryParam params[] = { GNUNET_PQ_query_param_auto_from_type (h_payto), + have_pub + ? GNUNET_PQ_query_param_auto_from_type (account_pub) + : GNUNET_PQ_query_param_null (), GNUNET_PQ_query_param_end }; bool not_found; @@ -111,7 +115,7 @@ TEH_PG_lookup_kyc_requirement_by_row ( ",out_kyc_required AS kyc_required" ",out_rule_gen AS rule_gen" " FROM exchange_do_lookup_kyc_requirement_by_row" - " ($1);"); + " ($1, $2);"); qs = GNUNET_PQ_eval_prepared_singleton_select ( pg->conn, "lookup_kyc_requirement_by_row", diff --git a/src/exchangedb/pg_lookup_kyc_requirement_by_row.h b/src/exchangedb/pg_lookup_kyc_requirement_by_row.h @@ -31,6 +31,8 @@ * * @param cls closure * @param h_payto identifies account to look up requirement for + * @param have_pub true if @a account_pub is provided as an input, + * false if it is merely provided for the public key to be returned * @param[out] account_pub set to public key of the account * needed to authorize access, all zeros if not known * @param[out] is_wallet set to true if the account is @@ -55,6 +57,7 @@ enum GNUNET_DB_QueryStatus TEH_PG_lookup_kyc_requirement_by_row ( void *cls, const struct TALER_NormalizedPaytoHashP *h_payto, + bool have_pub, union TALER_AccountPublicKeyP *account_pub, bool *is_wallet, struct TALER_ReservePublicKeyP *reserve_pub, diff --git a/src/include/taler_crypto_lib.h b/src/include/taler_crypto_lib.h @@ -61,6 +61,11 @@ #define TALER_HTTP_HEADER_ACCOUNT_OWNER_SIGNATURE "Account-Owner-Signature" /** + * Account owner public key for KYC. + */ +#define TALER_HTTP_HEADER_ACCOUNT_OWNER_PUBKEY "Account-Owner-Pub" + +/** * Possible algorithms for confirmation code generation. */ enum TALER_MerchantConfirmationAlgorithm diff --git a/src/include/taler_exchangedb_plugin.h b/src/include/taler_exchangedb_plugin.h @@ -7158,7 +7158,9 @@ struct TALER_EXCHANGEDB_Plugin * * @param cls closure * @param h_payto identifies account to look up requirement for - * @param[out] account_pub set to public key of the account + * @param have_pub true if @a account_pub is provided as an input, + * false if it is merely provided for the public key to be returned + * @param[in,out] account_pub set to public key of the account * needed to authorize access, all zeros if not known * @param[out] is_wallet set to true if the account is * that of a wallet (false is used if unknown) @@ -7182,6 +7184,7 @@ struct TALER_EXCHANGEDB_Plugin (*lookup_kyc_requirement_by_row)( void *cls, const struct TALER_NormalizedPaytoHashP *h_payto, + bool have_pub, union TALER_AccountPublicKeyP *account_pub, bool *is_wallet, struct TALER_ReservePublicKeyP *reserve_pub, diff --git a/src/include/taler_mhd_lib.h b/src/include/taler_mhd_lib.h @@ -788,11 +788,12 @@ TALER_MHD_parse_request_header_data (struct MHD_Connection *connection, * #GNUNET_NO if the argument is absent or malformed * #GNUNET_SYSERR on internal error (error response could not be sent) */ -#define TALER_MHD_parse_request_header_auto(connection,name,val,required) \ - do { \ - bool p; \ - switch (TALER_MHD_parse_request_header_data (connection, name, \ - val, sizeof (*val), &p)) \ +#define TALER_MHD_parse_request_header_auto(connection,name,val,required) \ + do { \ + bool p; \ + switch (TALER_MHD_parse_request_header_data (connection, name, \ + val, sizeof (*val), \ + &p)) \ { \ case GNUNET_SYSERR: \ GNUNET_break (0); \