summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/taler-merchant-httpd.c47
-rw-r--r--src/backend/taler-merchant-httpd.h29
-rw-r--r--src/backend/taler-merchant-httpd_private-patch-instances-ID.c27
-rw-r--r--src/backend/taler-merchant-httpd_private-post-instances.c27
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;