exchange

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

commit 3f5793d9924515dfbd709c76b9286a77c3c16aa4
parent 3285288e9e6a467cab4a0065609b2971295ac98d
Author: Florian Dold <florian@dold.me>
Date:   Sun, 23 Feb 2025 11:33:19 +0100

handle AMLO attribute insertion

Diffstat:
Msrc/exchange/taler-exchange-httpd_aml-decision.c | 36+++++++++++++++++++++++++++++++-----
Msrc/exchange/taler-exchange-httpd_common_kyc.c | 2+-
Msrc/exchangedb/exchangedb_aml.c | 2+-
Msrc/exchangedb/pg_insert_aml_decision.c | 6++----
Msrc/exchangedb/pg_insert_aml_decision.h | 2+-
Msrc/include/taler_crypto_lib.h | 7++++++-
Msrc/include/taler_exchangedb_plugin.h | 2+-
Msrc/util/aml_signatures.c | 19++++++++++++++++++-
8 files changed, 61 insertions(+), 15 deletions(-)

diff --git a/src/exchange/taler-exchange-httpd_aml-decision.c b/src/exchange/taler-exchange-httpd_aml-decision.c @@ -177,9 +177,12 @@ TEH_handler_post_aml_decision ( const char *new_measures = NULL; bool to_investigate; struct GNUNET_TIME_Timestamp decision_time; + struct GNUNET_TIME_Timestamp attributes_expiration + = GNUNET_TIME_UNIT_ZERO_TS; const json_t *new_rules; const json_t *events = NULL; const json_t *properties = NULL; + const json_t *attributes = NULL; struct TALER_FullPayto payto_uri = { .full_payto = NULL }; @@ -218,6 +221,14 @@ TEH_handler_post_aml_decision ( &officer_sig), GNUNET_JSON_spec_timestamp ("decision_time", &decision_time), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_timestamp ("attributes_expiration", + &attributes_expiration), + NULL), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_object_const ("attributes", + &attributes), + NULL), GNUNET_JSON_spec_end () }; struct GNUNET_TIME_Timestamp expiration_time; @@ -289,7 +300,9 @@ TEH_handler_post_aml_decision ( new_measures, to_investigate, officer_pub, - &officer_sig)) + &officer_sig, + attributes_expiration, + attributes)) { GNUNET_break_op (0); ret = TALER_MHD_reply_with_error ( @@ -339,6 +352,19 @@ TEH_handler_post_aml_decision ( struct GNUNET_TIME_Timestamp last_date; bool invalid_officer = true; bool unknown_account = false; + struct GNUNET_HashCode h_attr = { 0 }; + size_t eas = 0; + void *ea = NULL; + + if (NULL != attributes) + { + TALER_json_hash (attributes, + &h_attr); + TALER_CRYPTO_kyc_attributes_encrypt (&TEH_attribute_key, + attributes, + &ea, + &eas); + } for (size_t i = 0; i<num_events; i++) { @@ -372,10 +398,10 @@ TEH_handler_post_aml_decision ( &officer_sig, num_events, sevents, - 0, /* enc_attributes_size*/ - NULL, /* enc_attributes*/ - NULL, /* attributes_hash */ - NULL, /* attributes_expiration_time */ + eas, /* enc_attributes_size*/ + ea, /* enc_attributes*/ + &h_attr, /* attributes_hash */ + attributes_expiration, &invalid_officer, &unknown_account, &last_date, diff --git a/src/exchange/taler-exchange-httpd_common_kyc.c b/src/exchange/taler-exchange-httpd_common_kyc.c @@ -679,7 +679,7 @@ handle_aml_fallback_result ( 0, /* enc_attributes_size*/ NULL, /* enc_attributes*/ NULL, /* attributes_hash */ - NULL, /* attributes_expiration_time */ + GNUNET_TIME_UNIT_ZERO_TS, /* attributes_expiration_time */ &invalid_officer, &unknown_account, &last_date, diff --git a/src/exchangedb/exchangedb_aml.c b/src/exchangedb/exchangedb_aml.c @@ -94,7 +94,7 @@ TALER_EXCHANGEDB_persist_aml_program_result ( 0, /* enc_attributes_size*/ NULL, /* enc_attributes*/ NULL, /* attributes_hash */ - NULL, /* attributes_expiration_time */ + GNUNET_TIME_UNIT_ZERO_TS, /* attributes_expiration_time */ &invalid_officer, &unknown_account, &last_date, diff --git a/src/exchangedb/pg_insert_aml_decision.c b/src/exchangedb/pg_insert_aml_decision.c @@ -47,7 +47,7 @@ TEH_PG_insert_aml_decision ( size_t enc_attributes_size, const void *enc_attributes, struct GNUNET_HashCode *attributes_hash, - struct GNUNET_TIME_Timestamp *attributes_expiration_time, + struct GNUNET_TIME_Timestamp attributes_expiration_time, bool *invalid_officer, bool *unknown_account, struct GNUNET_TIME_Timestamp *last_date, @@ -91,9 +91,7 @@ TEH_PG_insert_aml_decision ( ? GNUNET_PQ_query_param_auto_from_type (attributes_hash) : GNUNET_PQ_query_param_null (), /* $9: in_kyc_attributes_expiration */ - NULL != attributes_expiration_time - ? GNUNET_PQ_query_param_timestamp (attributes_expiration_time) - : GNUNET_PQ_query_param_null (), + GNUNET_PQ_query_param_timestamp (&attributes_expiration_time), /* $10: in_new_rules */ TALER_PQ_query_param_json (new_rules), /* $11: in_to_investigate */ diff --git a/src/exchangedb/pg_insert_aml_decision.h b/src/exchangedb/pg_insert_aml_decision.h @@ -79,7 +79,7 @@ TEH_PG_insert_aml_decision ( size_t enc_attributes_size, const void *enc_attributes, struct GNUNET_HashCode *attributes_hash, - struct GNUNET_TIME_Timestamp *attributes_expiration_time, + struct GNUNET_TIME_Timestamp attributes_expiration_time, bool *invalid_officer, bool *unknown_account, struct GNUNET_TIME_Timestamp *last_date, diff --git a/src/include/taler_crypto_lib.h b/src/include/taler_crypto_lib.h @@ -2772,6 +2772,9 @@ TALER_officer_aml_decision_sign ( * @param to_investigate true if the account should be investigated by AML staff * @param officer_pub public key of AML officer * @param officer_sig signature to verify + * @param attributes_expiration expiration time of attributes, + * #GNUNET_TIME_UNIT_ZERO_ABS if no attributes given + * @param attributes attributes set by the AMLO, may be NULL * @return #GNUNET_OK if the signature is valid */ enum GNUNET_GenericReturnValue @@ -2784,7 +2787,9 @@ TALER_officer_aml_decision_verify ( const char *new_measures, bool to_investigate, const struct TALER_AmlOfficerPublicKeyP *officer_pub, - const struct TALER_AmlOfficerSignatureP *officer_sig); + const struct TALER_AmlOfficerSignatureP *officer_sig, + struct GNUNET_TIME_Timestamp attributes_expiration, + const json_t *attributes); /* **************** Helper-based RSA operations **************** */ diff --git a/src/include/taler_exchangedb_plugin.h b/src/include/taler_exchangedb_plugin.h @@ -7824,7 +7824,7 @@ struct TALER_EXCHANGEDB_Plugin size_t enc_attributes_size, const void *enc_attributes, struct GNUNET_HashCode *attributes_hash, - struct GNUNET_TIME_Timestamp *attributes_expiration_time, + struct GNUNET_TIME_Timestamp attributes_expiration_time, bool *invalid_officer, bool *unknown_account, struct GNUNET_TIME_Timestamp *last_date, diff --git a/src/util/aml_signatures.c b/src/util/aml_signatures.c @@ -42,6 +42,11 @@ struct TALER_AmlDecisionPS struct GNUNET_TIME_TimestampNBO decision_time; /** + * Time when attributes expire, if any. + */ + struct GNUNET_TIME_TimestampNBO attributes_expiration_time; + + /** * Hash of the account identifier to which the decision applies. */ struct TALER_NormalizedPaytoHashP h_payto GNUNET_PACKED; @@ -67,6 +72,12 @@ struct TALER_AmlDecisionPS struct GNUNET_HashCode h_new_measure; /** + * Hash over new attributes, all zeroes + * if no attributes are being set. + */ + struct GNUNET_HashCode h_attributes; + + /** * 0: no investigation, 1: yes investigation. */ uint64_t flags; @@ -122,12 +133,15 @@ TALER_officer_aml_decision_verify ( const char *new_measures, bool to_investigate, const struct TALER_AmlOfficerPublicKeyP *officer_pub, - const struct TALER_AmlOfficerSignatureP *officer_sig) + const struct TALER_AmlOfficerSignatureP *officer_sig, + struct GNUNET_TIME_Timestamp attributes_expiration, + const json_t *attributes) { struct TALER_AmlDecisionPS ad = { .purpose.purpose = htonl (TALER_SIGNATURE_AML_DECISION), .purpose.size = htonl (sizeof (ad)), .decision_time = GNUNET_TIME_timestamp_hton (decision_time), + .attributes_expiration_time = GNUNET_TIME_timestamp_hton (attributes_expiration), .h_payto = *h_payto, .flags = GNUNET_htonll (to_investigate ? 1 : 0) }; @@ -144,6 +158,9 @@ TALER_officer_aml_decision_verify ( GNUNET_CRYPTO_hash (new_measures, strlen (new_measures), &ad.h_new_measure); + if (NULL != attributes) + TALER_json_hash (attributes, + &ad.h_attributes); return GNUNET_CRYPTO_eddsa_verify ( TALER_SIGNATURE_AML_DECISION, &ad,