merchant

Merchant backend to process payments, run by merchants
Log | Files | Refs | Submodules | README | LICENSE

commit 83f0cd871092dcd547eee18c2b67ec10ac1828ff
parent 9dded1aec4e5e62dce29ac86bc486112c7bff60d
Author: Christian Grothoff <christian@grothoff.org>
Date:   Sun, 31 Jan 2021 13:12:04 +0100

implement import of auth_token into merchant DB when configuring instances (#6731)

Diffstat:
Msrc/backend/taler-merchant-httpd.c | 47+++++++++++++++++++++++++++++++++++++++++++++++
Msrc/backend/taler-merchant-httpd.h | 29+++++++++++++++++++++++++++++
Msrc/backend/taler-merchant-httpd_private-patch-instances-ID.c | 27+++++++++++++++++++++++++++
Msrc/backend/taler-merchant-httpd_private-post-instances.c | 27+++++++++++++++++++++++++++
4 files changed, 130 insertions(+), 0 deletions(-)

diff --git a/src/backend/taler-merchant-httpd.c b/src/backend/taler-merchant-httpd.c @@ -172,6 +172,53 @@ struct ResumeData }; +int +TMH_check_auth (const char *token, + const struct GNUNET_ShortHashCode *salt, + const struct GNUNET_HashCode *hash) +{ + struct GNUNET_HashCode val; + + GNUNET_assert (GNUNET_YES == + GNUNET_CRYPTO_kdf (&val, + sizeof (val), + salt, + sizeof (*salt), + token, + strlen (token), + "merchant-instance-auth", + strlen ("merchant-instance-auth"), + NULL, + 0)); + return (0 == GNUNET_memcmp (&val, + hash)) + ? GNUNET_OK + : GNUNET_SYSERR; +} + + +void +TMH_compute_auth (const char *token, + struct GNUNET_ShortHashCode *salt, + struct GNUNET_HashCode *hash) +{ + GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE, + salt, + sizeof (*salt)); + GNUNET_assert (GNUNET_YES == + GNUNET_CRYPTO_kdf (hash, + sizeof (*hash), + salt, + sizeof (*salt), + token, + strlen (token), + "merchant-instance-auth", + strlen ("merchant-instance-auth"), + NULL, + 0)); +} + + /** * Decrement reference counter of @a mi, and free if it hits zero. * diff --git a/src/backend/taler-merchant-httpd.h b/src/backend/taler-merchant-httpd.h @@ -494,4 +494,33 @@ struct TMH_MerchantInstance * TMH_lookup_instance (const char *instance_id); +/** + * Check that @a token hashes to @a hash under @a salt for + * merchant instance authentication. + * + * @param token the token to check + * @param salt the salt to use when hashing + * @param hash the hash to check against + * @return #GNUNET_OK if the @a token matches + */ +int +TMH_check_auth (const char *token, + const struct GNUNET_ShortHashCode *salt, + const struct GNUNET_HashCode *hash); + + +/** + * Compute a @a hash from @a token hashes for + * merchant instance authentication. + * + * @param token the token to check + * @param[out] salt set to a fresh random salt + * @param[out] hash set to the hash of @a token under @a salt + */ +void +TMH_compute_auth (const char *token, + struct GNUNET_ShortHashCode *salt, + struct GNUNET_HashCode *hash); + + #endif diff --git a/src/backend/taler-merchant-httpd_private-patch-instances-ID.c b/src/backend/taler-merchant-httpd_private-patch-instances-ID.c @@ -63,10 +63,14 @@ TMH_private_patch_instances_ID (const struct TMH_RequestHandler *rh, struct TMH_MerchantInstance *mi = hc->instance; struct TALER_MERCHANTDB_InstanceSettings is; json_t *payto_uris; + const char *auth_token = NULL; const char *name; struct TMH_WireMethod *wm_head = NULL; struct TMH_WireMethod *wm_tail = NULL; struct GNUNET_JSON_Specification spec[] = { + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_string ("auth_token", + &auth_token)), GNUNET_JSON_spec_json ("payto_uris", &payto_uris), GNUNET_JSON_spec_string ("name", @@ -145,6 +149,14 @@ TMH_private_patch_instances_ID (const struct TMH_RequestHandler *rh, /* Check for equality of settings */ if (! ( (0 == strcmp (mi->settings.name, name)) && + ( ( (NULL != auth_token) && + (GNUNET_OK == + TMH_check_auth (auth_token, + &mi->settings.auth_salt, + &mi->settings.auth_hash)) ) || + ( (NULL == auth_token) && + (GNUNET_YES == + GNUNET_is_zero (&mi->settings.auth_hash))) ) && (1 == json_equal (mi->settings.address, is.address)) && (1 == json_equal (mi->settings.jurisdiction, @@ -356,6 +368,21 @@ giveup: json_decref (mi->settings.address); json_decref (mi->settings.jurisdiction); is.id = mi->settings.id; + if (NULL == auth_token) + { + memset (&is.auth_salt, + 0, + sizeof (is.auth_salt)); + memset (&is.auth_hash, + 0, + sizeof (is.auth_hash)); + } + else + { + TMH_compute_auth (auth_token, + &is.auth_salt, + &is.auth_hash); + } mi->settings = is; mi->settings.address = json_incref (mi->settings.address); mi->settings.jurisdiction = json_incref (mi->settings.jurisdiction); diff --git a/src/backend/taler-merchant-httpd_private-post-instances.c b/src/backend/taler-merchant-httpd_private-post-instances.c @@ -142,9 +142,13 @@ TMH_private_post_instances (const struct TMH_RequestHandler *rh, { struct TALER_MERCHANTDB_InstanceSettings is; json_t *payto_uris; + const char *auth_token = NULL; struct TMH_WireMethod *wm_head = NULL; struct TMH_WireMethod *wm_tail = NULL; struct GNUNET_JSON_Specification spec[] = { + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_string ("auth_token", + &auth_token)), GNUNET_JSON_spec_json ("payto_uris", &payto_uris), GNUNET_JSON_spec_string ("id", @@ -205,6 +209,14 @@ TMH_private_post_instances (const struct TMH_RequestHandler *rh, is.id)) && (0 == strcmp (mi->settings.name, is.name)) && + ( ( (NULL != auth_token) && + (GNUNET_OK == + TMH_check_auth (auth_token, + &mi->settings.auth_salt, + &mi->settings.auth_hash)) ) || + ( (NULL == auth_token) && + (GNUNET_YES == + GNUNET_is_zero (&mi->settings.auth_hash))) ) && (1 == json_equal (mi->settings.address, is.address)) && (1 == json_equal (mi->settings.jurisdiction, @@ -343,6 +355,21 @@ TMH_private_post_instances (const struct TMH_RequestHandler *rh, } } + if (NULL == auth_token) + { + memset (&is.auth_salt, + 0, + sizeof (is.auth_salt)); + memset (&is.auth_hash, + 0, + sizeof (is.auth_hash)); + } + else + { + TMH_compute_auth (auth_token, + &is.auth_salt, + &is.auth_hash); + } { struct TMH_MerchantInstance *mi; enum GNUNET_DB_QueryStatus qs;