update GET attest logic now that it is clear that we must store KYC attributes locally:

This commit is contained in:
Christian Grothoff 2023-01-27 14:43:25 +01:00
parent 42bd2dadcf
commit 32fac55f7e
No known key found for this signature in database
GPG Key ID: 939E6BE1E29FC3CC
8 changed files with 115 additions and 138 deletions

View File

@ -6,6 +6,10 @@
# This must be adjusted to your actual installation. # This must be adjusted to your actual installation.
# MASTER_PUBLIC_KEY = 98NJW3CQHZQGQXTY3K85K531XKPAPAVV4Q5V8PYYRR00NJGZWNVG # MASTER_PUBLIC_KEY = 98NJW3CQHZQGQXTY3K85K531XKPAPAVV4Q5V8PYYRR00NJGZWNVG
# Attribute encryption key for storing attributes encrypted
# in the database. Should be a high-entropy nonce.
ATTRIBUTE_ENCRYPTION_KEY = SET_ME_PLEASE
# How long do we allow /keys to be cached at most? The actual # How long do we allow /keys to be cached at most? The actual
# limit is the minimum of this value and the first expected # limit is the minimum of this value and the first expected
# significant change in /keys based on the expiration times. # significant change in /keys based on the expiration times.

View File

@ -132,6 +132,11 @@ struct GNUNET_TIME_Relative TEH_reserve_closing_delay;
*/ */
struct TALER_MasterPublicKeyP TEH_master_public_key; struct TALER_MasterPublicKeyP TEH_master_public_key;
/**
* Key used to encrypt KYC attribute data in our database.
*/
struct TALER_AttributeEncryptionKeyP TEH_attribute_key;
/** /**
* Our DB plugin. (global) * Our DB plugin. (global)
*/ */
@ -1862,6 +1867,26 @@ exchange_serve_process_config (void)
} }
GNUNET_free (master_public_key_str); GNUNET_free (master_public_key_str);
} }
{
char *attr_enc_key_str;
if (GNUNET_OK !=
GNUNET_CONFIGURATION_get_value_string (TEH_cfg,
"exchange",
"ATTRIBUTE_ENCRYPTION_KEY",
&attr_enc_key_str))
{
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
"exchange",
"ATTRIBUTE_ENCRYPTION_KEY");
return GNUNET_SYSERR;
}
GNUNET_CRYPTO_hash (attr_enc_key_str,
strlen (attr_enc_key_str),
&TEH_attribute_key.hash);
GNUNET_free (attr_enc_key_str);
}
GNUNET_log (GNUNET_ERROR_TYPE_INFO, GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Launching exchange with public key `%s'...\n", "Launching exchange with public key `%s'...\n",
GNUNET_p2s (&TEH_master_public_key.eddsa_pub)); GNUNET_p2s (&TEH_master_public_key.eddsa_pub));

View File

@ -82,6 +82,11 @@ extern bool TEH_suicide;
*/ */
extern struct TALER_MasterPublicKeyP TEH_master_public_key; extern struct TALER_MasterPublicKeyP TEH_master_public_key;
/**
* Key used to encrypt KYC attribute data in our database.
*/
extern struct TALER_AttributeEncryptionKeyP TEH_attribute_key;
/** /**
* Our DB plugin. * Our DB plugin.
*/ */

View File

@ -81,9 +81,9 @@ struct ReserveAttestContext
json_t *json_attest; json_t *json_attest;
/** /**
* Error code encountered in interaction with KYC provider. * Database error codes encountered.
*/ */
enum TALER_ErrorCode ec; enum GNUNET_DB_QueryStatus qs;
/** /**
* Set to true if we did not find the reserve. * Set to true if we did not find the reserve.
@ -152,37 +152,36 @@ reply_reserve_attest_success (struct MHD_Connection *connection,
* set based on the details requested by the client. * set based on the details requested by the client.
* *
* @param cls our `struct ReserveAttestContext *` * @param cls our `struct ReserveAttestContext *`
* @param provider_section KYC provider configuration section * @param h_payto account for which the attribute data is stored
* @param provider_user_id UID at a provider (can be NULL) * @param provider_section provider that must be checked
* @param legi_id legitimization process ID (can be NULL) * @param birthdate birthdate of user, in format YYYY-MM-DD; can be NULL;
* digits can be 0 if exact day, month or year are unknown
* @param collection_time when was the data collected
* @param expiration_time when does the data expire
* @param enc_attributes_size number of bytes in @a enc_attributes
* @param enc_attributes encrypted attribute data
*/ */
static void static void
kyc_process_cb (void *cls, kyc_process_cb (void *cls,
const struct TALER_PaytoHashP *h_payto,
const char *provider_section, const char *provider_section,
const char *provider_user_id, const char *birthdate,
const char *legi_id) struct GNUNET_TIME_Timestamp collection_time,
struct GNUNET_TIME_Timestamp expiration_time,
size_t enc_attributes_size,
const void *enc_attributes)
{ {
struct ReserveAttestContext *rsc = cls; struct ReserveAttestContext *rsc = cls;
struct GNUNET_TIME_Timestamp etime;
json_t *attrs; json_t *attrs;
bool match = false;
rsc->ec = TALER_KYCLOGIC_user_to_attributes (provider_section,
provider_user_id,
legi_id,
&etime,
&attrs);
if (TALER_EC_NONE != rsc->ec)
return;
if (GNUNET_TIME_absolute_is_past (etime.abs_time))
{
json_decref (attrs);
return;
}
{
json_t *val; json_t *val;
const char *name; const char *name;
bool match = false;
if (GNUNET_TIME_absolute_is_past (expiration_time.abs_time))
return;
attrs = TALER_CRYPTO_kyc_attributes_decrypt (&TEH_attribute_key,
enc_attributes,
enc_attributes_size);
json_object_foreach (attrs, name, val) json_object_foreach (attrs, name, val)
{ {
bool requested = false; bool requested = false;
@ -209,11 +208,10 @@ kyc_process_cb (void *cls,
name, name,
val)); val));
} }
}
json_decref (attrs); json_decref (attrs);
if (! match) if (! match)
return; return;
rsc->etime = GNUNET_TIME_timestamp_min (etime, rsc->etime = GNUNET_TIME_timestamp_min (expiration_time,
rsc->etime); rsc->etime);
} }
@ -243,7 +241,7 @@ reserve_attest_transaction (void *cls,
rsc->json_attest = json_array (); rsc->json_attest = json_array ();
GNUNET_assert (NULL != rsc->json_attest); GNUNET_assert (NULL != rsc->json_attest);
qs = TEH_plugin->iterate_kyc_reference (TEH_plugin->cls, qs = TEH_plugin->select_kyc_attributes (TEH_plugin->cls,
&rsc->h_payto, &rsc->h_payto,
&kyc_process_cb, &kyc_process_cb,
rsc); rsc);
@ -255,7 +253,7 @@ reserve_attest_transaction (void *cls,
= TALER_MHD_reply_with_error (connection, = TALER_MHD_reply_with_error (connection,
MHD_HTTP_INTERNAL_SERVER_ERROR, MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_GENERIC_DB_FETCH_FAILED, TALER_EC_GENERIC_DB_FETCH_FAILED,
"iterate_kyc_reference"); "select_kyc_attributes");
return qs; return qs;
case GNUNET_DB_STATUS_SOFT_ERROR: case GNUNET_DB_STATUS_SOFT_ERROR:
GNUNET_break (0); GNUNET_break (0);
@ -373,16 +371,8 @@ TEH_handler_reserves_attest (struct TEH_RequestContext *rc,
TALER_EC_EXCHANGE_GENERIC_RESERVE_UNKNOWN, TALER_EC_EXCHANGE_GENERIC_RESERVE_UNKNOWN,
args[0]); args[0]);
} }
if (TALER_EC_NONE != rsc.ec) return reply_reserve_attest_success (rc->connection,
{
json_decref (rsc.json_attest);
return TALER_MHD_reply_with_ec (rc->connection,
rsc.ec,
NULL);
}
mhd_ret = reply_reserve_attest_success (rc->connection,
&rsc); &rsc);
return mhd_ret;
} }

View File

@ -50,11 +50,6 @@ struct ReserveAttestContext
*/ */
json_t *attributes; json_t *attributes;
/**
* Error code encountered in interaction with KYC provider.
*/
enum TALER_ErrorCode ec;
/** /**
* Set to true if we did not find the reserve. * Set to true if we did not find the reserve.
*/ */
@ -67,32 +62,35 @@ struct ReserveAttestContext
* legitimization processes for the given user. * legitimization processes for the given user.
* *
* @param cls our `struct ReserveAttestContext *` * @param cls our `struct ReserveAttestContext *`
* @param provider_section KYC provider configuration section * @param h_payto account for which the attribute data is stored
* @param provider_user_id UID at a provider (can be NULL) * @param provider_section provider that must be checked
* @param legi_id legitimization process ID (can be NULL) * @param birthdate birthdate of user, in format YYYY-MM-DD; can be NULL;
* digits can be 0 if exact day, month or year are unknown
* @param collection_time when was the data collected
* @param expiration_time when does the data expire
* @param enc_attributes_size number of bytes in @a enc_attributes
* @param enc_attributes encrypted attribute data
*/ */
static void static void
kyc_process_cb (void *cls, kyc_process_cb (void *cls,
const struct TALER_PaytoHashP *h_payto,
const char *provider_section, const char *provider_section,
const char *provider_user_id, const char *birthdate,
const char *legi_id) struct GNUNET_TIME_Timestamp collection_time,
struct GNUNET_TIME_Timestamp expiration_time,
size_t enc_attributes_size,
const void *enc_attributes)
{ {
struct ReserveAttestContext *rsc = cls; struct ReserveAttestContext *rsc = cls;
struct GNUNET_TIME_Timestamp etime;
json_t *attrs; json_t *attrs;
rsc->ec = TALER_KYCLOGIC_user_to_attributes (provider_section,
provider_user_id,
legi_id,
&etime,
&attrs);
if (TALER_EC_NONE != rsc->ec)
return;
{
json_t *val; json_t *val;
const char *name; const char *name;
if (GNUNET_TIME_absolute_is_past (expiration_time.abs_time))
return;
attrs = TALER_CRYPTO_kyc_attributes_decrypt (&TEH_attribute_key,
enc_attributes,
enc_attributes_size);
json_object_foreach (attrs, name, val) json_object_foreach (attrs, name, val)
{ {
bool duplicate = false; bool duplicate = false;
@ -115,7 +113,6 @@ kyc_process_cb (void *cls,
json_string (name))); json_string (name)));
} }
} }
}
/** /**
@ -144,7 +141,7 @@ reserve_attest_transaction (void *cls,
rsc->attributes = json_array (); rsc->attributes = json_array ();
GNUNET_assert (NULL != rsc->attributes); GNUNET_assert (NULL != rsc->attributes);
qs = TEH_plugin->iterate_kyc_reference (TEH_plugin->cls, qs = TEH_plugin->select_kyc_attributes (TEH_plugin->cls,
&rsc->h_payto, &rsc->h_payto,
&kyc_process_cb, &kyc_process_cb,
rsc); rsc);
@ -225,13 +222,6 @@ TEH_handler_reserves_get_attest (struct TEH_RequestContext *rc,
TALER_EC_EXCHANGE_GENERIC_RESERVE_UNKNOWN, TALER_EC_EXCHANGE_GENERIC_RESERVE_UNKNOWN,
args[0]); args[0]);
} }
if (TALER_EC_NONE != rsc.ec)
{
json_decref (rsc.attributes);
return TALER_MHD_reply_with_ec (rc->connection,
rsc.ec,
NULL);
}
return TALER_MHD_REPLY_JSON_PACK ( return TALER_MHD_REPLY_JSON_PACK (
rc->connection, rc->connection,
MHD_HTTP_OK, MHD_HTTP_OK,

View File

@ -6500,8 +6500,6 @@ struct TALER_EXCHANGEDB_Plugin
void *kac_cls); void *kac_cls);
// FIXME: functions below here not yet implemented!
/** /**
* Store KYC attribute data. * Store KYC attribute data.
* *

View File

@ -313,27 +313,6 @@ TALER_KYCLOGIC_requirements_to_logic (const char *requirements,
const char **configuration_section); const char **configuration_section);
/**
* Obtain attributes we collected about a user from a
* provider.
*
* @param provider_section configuration section of a
* provider that triggered KYC process for a user
* @param provider_user_id user ID of the user at the provider
* @param legitimization_id legitimizatin ID of a process
* of that user at the provider
* @param[out] attr_expiration set to when the @a attrs expire
* @param[out] attrs attributes we have about the user
* @return error code, #TALER_EC_NONE on success
*/
enum TALER_ErrorCode
TALER_KYCLOGIC_user_to_attributes (const char *provider_section,
const char *provider_user_id,
const char *legitimization_id,
struct GNUNET_TIME_Timestamp *attr_expiration,
json_t **attrs);
/** /**
* Obtain the provider logic for a given @a name. * Obtain the provider logic for a given @a name.
* *

View File

@ -1371,18 +1371,4 @@ TALER_KYCLOGIC_kyc_iterate_thresholds (
} }
enum TALER_ErrorCode
TALER_KYCLOGIC_user_to_attributes (const char *provider_section,
const char *provider_user_id,
const char *legitimization_id,
struct GNUNET_TIME_Timestamp *attr_expiration,
json_t **attrs)
{
GNUNET_break (0); // FIXME: not yet implemented!!!
*attrs = json_object ();
*attr_expiration = GNUNET_TIME_UNIT_ZERO_TS;
return TALER_EC_NONE;
}
/* end of taler-exchange-httpd_kyc.c */ /* end of taler-exchange-httpd_kyc.c */