diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/taler-merchant-httpd.c | 47 | ||||
-rw-r--r-- | src/backend/taler-merchant-httpd.h | 29 | ||||
-rw-r--r-- | src/backend/taler-merchant-httpd_private-patch-instances-ID.c | 27 | ||||
-rw-r--r-- | src/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 index bf1c4db3..6e6318d2 100644 --- 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 index 2e33b852..c3300e42 100644 --- 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 index 755e6f02..4590e6c5 100644 --- 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 index 1cd1a0bb..79c78f38 100644 --- 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; |