diff --git a/src/exchange/taler-exchange-httpd.c b/src/exchange/taler-exchange-httpd.c
index b435ee4ae..12764ca45 100644
--- a/src/exchange/taler-exchange-httpd.c
+++ b/src/exchange/taler-exchange-httpd.c
@@ -1,18 +1,18 @@
/*
- This file is part of TALER
- Copyright (C) 2014-2021 Taler Systems SA
+ This file is part of TALER
+ Copyright (C) 2014-2021 Taler Systems SA
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU Affero General Public License as published by the Free Software
- Foundation; either version 3, or (at your option) any later version.
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU Affero General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+ TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
- You should have received a copy of the GNU Affero General Public License along with
- TALER; see the file COPYING. If not, see
-*/
+ You should have received a copy of the GNU Affero General Public License along with
+ TALER; see the file COPYING. If not, see
+ */
/**
* @file taler-exchange-httpd.c
* @brief Serve the HTTP interface of the exchange
@@ -150,19 +150,33 @@ bool TEH_suicide;
/**
* The global manifest with the list supported extensions, sorted by
* TALER_Extension_Type.
+ *
+ * TODO: This needs to become a dynamic list, once we have a model for
+ * extensions as plugins.
**/
-const struct TALER_Extension TEH_extensions[TALER_Extension_Max] = {
+const struct TALER_Extension TEH_extensions[] = {
+ [TALER_Extension_AgeRestriction] = {
+ .type = TALER_Extension_AgeRestriction,
+ .name = "age_restriction",
+ .critical = false,
+ .config = NULL, // disabled per default
+ /* TODO:
+ .parse_config = &TALER_Extension_AgeRestriction_parse_config,
+ .config_to_json = &TALER_Extension_AgeRestriction_config_to_json,
+ */
+ },
[TALER_Extension_Peer2Peer] = {
.type = TALER_Extension_Peer2Peer,
.name = "peer2peer",
.critical = false,
.config = NULL, // disabled per default
},
- [TALER_Extension_AgeRestriction] = {
- .type = TALER_Extension_AgeRestriction,
- .name = "age_restriction",
+ /* terminator */
+ [TALER_Extension_Max] = {
+ .type = TALER_Extension_Max,
+ .name = NULL,
.critical = false,
- .config = NULL, // disabled per default
+ .config = NULL,
},
};
@@ -485,7 +499,7 @@ proceed_with_handler (struct TEH_RequestContext *rc,
if (GNUNET_SYSERR == res)
{
GNUNET_assert (NULL == root);
- return MHD_NO; /* bad upload, could not even generate error */
+ return MHD_NO; /* bad upload, could not even generate error */
}
if ( (GNUNET_NO == res) ||
(NULL == root) )
@@ -528,8 +542,8 @@ proceed_with_handler (struct TEH_RequestContext *rc,
sizeof (emsg),
"Got %u/%u segments for %s request ('%s')",
(NULL == args[i - 1])
- ? i - 1
- : i + ((NULL != fin) ? 1 : 0),
+ ? i - 1
+ : i + ((NULL != fin) ? 1 : 0),
rh->nargs,
rh->url,
url);
@@ -553,7 +567,7 @@ proceed_with_handler (struct TEH_RequestContext *rc,
root,
args);
else /* We also only have "POST" or "GET" in the API for at this point
- (OPTIONS/HEAD are taken care of earlier) */
+ (OPTIONS/HEAD are taken care of earlier) */
ret = rh->handler.get (rc,
args);
}
@@ -1120,7 +1134,7 @@ handle_mhd_request (void *cls,
if (0 == strcasecmp (method,
MHD_HTTP_METHOD_HEAD))
- method = MHD_HTTP_METHOD_GET; /* treat HEAD as GET here, MHD will do the rest */
+ method = MHD_HTTP_METHOD_GET; /* treat HEAD as GET here, MHD will do the rest */
/* parse first part of URL */
{
@@ -1954,8 +1968,8 @@ run (void *cls,
MHD_OPTION_CONNECTION_TIMEOUT,
connection_timeout,
(0 == allow_address_reuse)
- ? MHD_OPTION_END
- : MHD_OPTION_LISTENING_ADDRESS_REUSE,
+ ? MHD_OPTION_END
+ : MHD_OPTION_LISTENING_ADDRESS_REUSE,
(unsigned int) allow_address_reuse,
MHD_OPTION_END);
if (NULL == mhd)
diff --git a/src/exchange/taler-exchange-httpd.h b/src/exchange/taler-exchange-httpd.h
index fa47af6f4..e252e1c58 100644
--- a/src/exchange/taler-exchange-httpd.h
+++ b/src/exchange/taler-exchange-httpd.h
@@ -202,9 +202,9 @@ extern volatile bool MHD_terminating;
extern struct GNUNET_CURL_Context *TEH_curl_ctx;
/**
- * The manifest of the available extensions
+ * The manifest of the available extensions, NULL terminated
*/
-extern const struct TALER_Extension TEH_extensions[TALER_Extension_Max];
+extern const struct TALER_Extension TEH_extensions[];
/**
* @brief Struct describing an URL and the handler for it.
diff --git a/src/exchange/taler-exchange-httpd_management_extensions.c b/src/exchange/taler-exchange-httpd_management_extensions.c
index 3d86c2d57..319e1882c 100644
--- a/src/exchange/taler-exchange-httpd_management_extensions.c
+++ b/src/exchange/taler-exchange-httpd_management_extensions.c
@@ -32,19 +32,14 @@
#include "taler_dbevents.h"
+/**
+ * Extension carries the necessary data for a particular extension.
+ *
+ */
struct Extension
{
enum TALER_Extension_Type type;
- json_t *config_json;
-
- // This union contains the parsed configuration for each extension.
- union
- {
- // configuration for the age restriction
- struct TALER_AgeMask mask;
-
- /* TODO oec - add peer2peer config */
- };
+ json_t *config;
};
/**
@@ -57,6 +52,38 @@ struct SetExtensionsContext
struct TALER_MasterSignatureP *extensions_sigs;
};
+
+/**
+ * @brief verifies the signature a configuration with the offline master key.
+ *
+ * @param config configuration of an extension given as JSON object
+ * @param master_priv offline master public key of the exchange
+ * @param[out] master_sig signature
+ * @return GNUNET_OK on success, GNUNET_SYSERR otherwise
+ */
+static enum GNUNET_GenericReturnValue
+config_verify (
+ const json_t *config,
+ const struct TALER_MasterPublicKeyP *master_pub,
+ const struct TALER_MasterSignatureP *master_sig
+ )
+{
+ enum GNUNET_GenericReturnValue ret;
+ struct TALER_ExtensionConfigHash h_config;
+
+ ret = TALER_extension_config_hash (config, &h_config);
+ if (GNUNET_OK != ret)
+ {
+ GNUNET_break (0);
+ return ret;
+ }
+
+ return TALER_exchange_offline_extension_config_hash_verify (h_config,
+ master_pub,
+ master_sig);
+}
+
+
/**
* Function implementing database transaction to set the configuration of
* extensions. It runs the transaction logic.
@@ -88,7 +115,7 @@ set_extensions (void *cls,
enum GNUNET_DB_QueryStatus qs;
char *config;
- config = json_dumps (ext->config_json, JSON_COMPACT | JSON_SORT_KEYS);
+ config = json_dumps (ext->config, JSON_COMPACT | JSON_SORT_KEYS);
if (NULL == config)
{
GNUNET_break (0);
@@ -143,7 +170,7 @@ TEH_handler_management_post_extensions (
struct SetExtensionsContext sec = {0};
json_t *extensions;
json_t *extensions_sigs;
- struct GNUNET_JSON_Specification spec[] = {
+ struct GNUNET_JSON_Specification top_spec[] = {
GNUNET_JSON_spec_json ("extensions",
&extensions),
GNUNET_JSON_spec_json ("extensions_sigs",
@@ -157,7 +184,7 @@ TEH_handler_management_post_extensions (
res = TALER_MHD_parse_json_data (connection,
root,
- spec);
+ top_spec);
if (GNUNET_SYSERR == res)
return MHD_NO; /* hard failure */
if (GNUNET_NO == res)
@@ -168,7 +195,7 @@ TEH_handler_management_post_extensions (
json_is_array (extensions_sigs)) )
{
GNUNET_break_op (0);
- GNUNET_JSON_parse_free (spec);
+ GNUNET_JSON_parse_free (top_spec);
return TALER_MHD_reply_with_error (
connection,
MHD_HTTP_BAD_REQUEST,
@@ -180,7 +207,7 @@ TEH_handler_management_post_extensions (
if (json_array_size (extensions) != sec.num_extensions)
{
GNUNET_break_op (0);
- GNUNET_JSON_parse_free (spec);
+ GNUNET_JSON_parse_free (top_spec);
return TALER_MHD_reply_with_error (
connection,
MHD_HTTP_BAD_REQUEST,
@@ -198,105 +225,53 @@ TEH_handler_management_post_extensions (
for (unsigned int i = 0; itype;
+
+ /* 3. Extract the signature out of the json array */
{
enum GNUNET_GenericReturnValue res;
- struct GNUNET_JSON_Specification ispec[] = {
+ struct GNUNET_JSON_Specification sig_spec[] = {
GNUNET_JSON_spec_fixed_auto (NULL,
&sec.extensions_sigs[i]),
GNUNET_JSON_spec_end ()
@@ -304,7 +279,7 @@ TEH_handler_management_post_extensions (
res = TALER_MHD_parse_json_array (connection,
extensions_sigs,
- ispec,
+ sig_spec,
i,
-1);
if (GNUNET_SYSERR == res)
@@ -317,44 +292,41 @@ TEH_handler_management_post_extensions (
ret = MHD_YES;
goto CLEANUP;
}
-
- /* verify the signature */
- res = GNUNET_SYSERR;
-
- switch (sec.extensions[i].type)
- {
- case TALER_Extension_AgeRestriction:
- res = TALER_exchange_offline_extension_agemask_verify (
- sec.extensions[i].mask,
- &TEH_master_public_key,
- &sec.extensions_sigs[i]);
- break;
-
- case TALER_Extension_Peer2Peer:
- /* TODO */
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Peer2peer not yet supported in handler for /management/extensions\n");
- ret = MHD_NO;
- goto CLEANUP;
-
- default:
- /* not reachable */
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "shouldn't be reached in handler for /management/extensions\n");
- ret = MHD_NO;
- goto CLEANUP;
- }
-
- if (GNUNET_OK != res)
- {
- ret = TALER_MHD_reply_with_error (
- connection,
- MHD_HTTP_BAD_REQUEST,
- TALER_EC_GENERIC_PARAMETER_MALFORMED,
- "invalid signature for extension");
- goto CLEANUP;
- }
}
+
+ /* 4. Verify the signature of the config */
+ if (GNUNET_OK != config_verify (
+ sec.extensions[i].config,
+ &TEH_master_public_key,
+ &sec.extensions_sigs[i]))
+ {
+ ret = TALER_MHD_reply_with_error (
+ connection,
+ MHD_HTTP_BAD_REQUEST,
+ TALER_EC_GENERIC_PARAMETER_MALFORMED,
+ "invalid signature for extension");
+ goto CLEANUP;
+ }
+
+ /* 5. Make sure the config is sound */
+ if (GNUNET_OK != extension->parse_config (NULL /* only verify */,
+ sec.extensions[i].config))
+ {
+ GNUNET_JSON_parse_free (ext_spec);
+ ret = TALER_MHD_reply_with_error (
+ connection,
+ MHD_HTTP_BAD_REQUEST,
+ TALER_EC_GENERIC_PARAMETER_MALFORMED,
+ "invalid configuration for extension");
+ goto CLEANUP;
+
+ }
+
+ /* We have a validly signed JSON object for the extension.
+ * Increment its refcount and free the parser for the extension.
+ */
+ json_incref (sec.extensions[i].config);
+ GNUNET_JSON_parse_free (ext_spec);
} /* for-loop */
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
@@ -386,14 +358,14 @@ TEH_handler_management_post_extensions (
CLEANUP:
for (unsigned int i = 0; i < sec.num_extensions; i++)
{
- if (NULL != sec.extensions[i].config_json)
+ if (NULL != sec.extensions[i].config)
{
- json_decref (sec.extensions[i].config_json);
+ json_decref (sec.extensions[i].config);
}
}
GNUNET_free (sec.extensions);
GNUNET_free (sec.extensions_sigs);
- GNUNET_JSON_parse_free (spec);
+ GNUNET_JSON_parse_free (top_spec);
return ret;
}
diff --git a/src/include/taler_crypto_lib.h b/src/include/taler_crypto_lib.h
index 88afb091e..e608effa6 100644
--- a/src/include/taler_crypto_lib.h
+++ b/src/include/taler_crypto_lib.h
@@ -23,7 +23,6 @@
#define TALER_CRYPTO_LIB_H
#include
-#include "taler_extensions.h"
#include "taler_error_codes.h"
#include
@@ -281,6 +280,26 @@ struct TALER_MasterSignatureP
struct GNUNET_CRYPTO_EddsaSignature eddsa_signature;
};
+/*
+ * @brief Type of a list of age groups, represented as bit mask.
+ *
+ * The bits set in the mask mark the edges at the beginning of a next age
+ * group. F.e. for the age groups
+ * 0-7, 8-9, 10-11, 12-14, 14-15, 16-17, 18-21, 21-*
+ * the following bits are set:
+ *
+ * 31 24 16 8 0
+ * | | | | |
+ * oooooooo oo1oo1o1 o1o1o1o1 ooooooo1
+ *
+ * A value of 0 means that the exchange does not support the extension for
+ * age-restriction.
+ */
+struct TALER_AgeMask
+{
+ uint32_t mask;
+};
+
/**
* @brief Age restriction commitment of a coin.
*/
@@ -523,6 +542,19 @@ struct TALER_PickupIdentifierP
};
+/**
+ * @brief Salted hash over the JSON object representing the configuration of an
+ * extension.
+ */
+struct TALER_ExtensionConfigHash
+{
+ /**
+ * Actual hash value.
+ */
+ struct GNUNET_HashCode hash;
+};
+
+
GNUNET_NETWORK_STRUCT_END
@@ -2502,30 +2534,31 @@ TALER_merchant_wire_signature_make (
/* **************** /management/extensions offline signing **************** */
/**
- * Create a signature for age restriction groups
+ * Create a signature for the hash of the configuration of an extension
*
- * @param mask The bitmask representing age groups
+ * @param h_config hash of the JSON object representing the configuration
* @param master_priv private key to sign with
* @param[out] master_sig where to write the signature
*/
void
-TALER_exchange_offline_extension_agemask_sign (
- const struct TALER_AgeMask mask,
+TALER_exchange_offline_extension_config_hash_sign (
+ const struct TALER_ExtensionConfigHash h_config,
const struct TALER_MasterPrivateKeyP *master_priv,
struct TALER_MasterSignatureP *master_sig);
/**
- * Verify the signature in @a master_sig.
+ * Verify the signature in @a master_sig of the given hash, taken over the JSON
+ * blob representing the configuration of an extension
*
- * @param mask bit mask representing an age group for age restriction
+ * @param h_config hash of the JSON blob of a configuration of an extension
* @param master_pub master public key of the exchange
* @param master_sig signature of the exchange
* @return #GNUNET_OK if signature is valid
*/
enum GNUNET_GenericReturnValue
-TALER_exchange_offline_extension_agemask_verify (
- const struct TALER_AgeMask mask,
+TALER_exchange_offline_extension_config_hash_verify (
+ const struct TALER_ExtensionConfigHash h_config,
const struct TALER_MasterPublicKeyP *master_pub,
const struct TALER_MasterSignatureP *master_sig
);
diff --git a/src/include/taler_extensions.h b/src/include/taler_extensions.h
index 019c63be9..62e371312 100644
--- a/src/include/taler_extensions.h
+++ b/src/include/taler_extensions.h
@@ -23,6 +23,7 @@
#include
#include "taler_crypto_lib.h"
+#include "taler_json_lib.h"
#define TALER_EXTENSION_SECTION_PREFIX "exchange-extension-"
@@ -39,41 +40,45 @@ enum TALER_Extension_Type
{
TALER_Extension_AgeRestriction = 0,
TALER_Extension_Peer2Peer = 1,
- TALER_Extension_Max = 2
+ TALER_Extension_Max = 2 // Must be last
};
+/*
+ * TODO oec: documentation
+ */
struct TALER_Extension
{
enum TALER_Extension_Type type;
char *name;
bool critical;
void *config;
+
+ enum GNUNET_GenericReturnValue (*parse_config)(struct TALER_Extension *this,
+ const json_t *config);
+ json_t *(*config_to_json)(const struct TALER_Extension *this);
};
+/**
+ * Generic functions for extensions
+ */
+
+/**
+ * Finds and returns a supported extension by a given name.
+ *
+ * @param name name of the extension to lookup
+ * @param extensions list of TALER_Extensions as haystack, terminated by an entry of type TALER_Extension_Max
+ * @param[out] ext set to the extension, if found, NULL otherwise
+ * @return GNUNET_OK if extension was found, GNUNET_NO otherwise
+ */
+enum GNUNET_GenericReturnValue
+TALER_get_extension_by_name (const char *name,
+ const struct TALER_Extension *extensions,
+ const struct TALER_Extension **ext);
+
/*
* TALER Age Restriction Extension
*/
-/*
- * @brief Type of a list of age groups, represented as bit mask.
- *
- * The bits set in the mask mark the edges at the beginning of a next age
- * group. F.e. for the age groups
- * 0-7, 8-9, 10-11, 12-14, 14-15, 16-17, 18-21, 21-*
- * the following bits are set:
- *
- * 31 24 16 8 0
- * | | | | |
- * oooooooo oo1oo1o1 o1o1o1o1 ooooooo1
- *
- * A value of 0 means that the exchange does not support the extension for
- * age-restriction.
- */
-struct TALER_AgeMask
-{
- uint32_t mask;
-};
-
#define TALER_EXTENSION_SECTION_AGE_RESTRICTION (TALER_EXTENSION_SECTION_PREFIX \
"age_restriction")
@@ -86,7 +91,19 @@ struct TALER_AgeMask
<< 21)
/**
- * @param groups String representation of age groups, like: "8:10:12:14:16:18:21"
+ * @brief Parses a string as a list of age groups.
+ *
+ * The string must consist of a colon-separated list of increasing integers
+ * between 0 and 31. Each entry represents the beginning of a new age group.
+ * F.e. the string "8:10:12:14:16:18:21" parses into the following list of age
+ * groups
+ * 0-7, 8-9, 10-11, 12-13, 14-15, 16-17, 18-20, 21-...
+ * which then is represented as bit mask with the corresponding bits set:
+ * 31 24 16 8 0
+ * | | | | |
+ * oooooooo oo1oo1o1 o1o1o1o1 ooooooo1
+ *
+ * @param groups String representation of age groups
* @param[out] mask Mask representation for age restriction.
* @return Error, if age groups were invalid, OK otherwise.
*/
diff --git a/src/include/taler_json_lib.h b/src/include/taler_json_lib.h
index 888256385..3d6f6a7c8 100644
--- a/src/include/taler_json_lib.h
+++ b/src/include/taler_json_lib.h
@@ -532,7 +532,7 @@ TALER_JSON_wire_to_payto (const json_t *wire_s);
/**
- * Hash @a extensions.
+ * Hash @a extensions in deposits.
*
* @param extensions contract extensions to hash
* @param[out] ech where to write the extension hash
@@ -541,6 +541,16 @@ void
TALER_deposit_extension_hash (const json_t *extensions,
struct TALER_ExtensionContractHash *ech);
+/**
+ * Hash the @a config of an extension, given as JSON
+ *
+ * @param config configuration of the extension
+ * @param[out] eh where to write the extension hash
+ * @return GNUNET_OK on success, GNUNET_SYSERR on failure
+ */
+enum GNUNET_GenericReturnValue
+TALER_extension_config_hash (const json_t *config,
+ struct TALER_ExtensionConfigHash *eh);
/**
* Parses a JSON object { "extension": "age_restriction", "mask": }.
@@ -553,7 +563,6 @@ enum GNUNET_GenericReturnValue
TALER_agemask_parse_json (const json_t *root,
struct TALER_AgeMask *mask);
-
#endif /* TALER_JSON_LIB_H_ */
/* End of taler_json_lib.h */
diff --git a/src/include/taler_signatures.h b/src/include/taler_signatures.h
index d9fa7065b..947c7e831 100644
--- a/src/include/taler_signatures.h
+++ b/src/include/taler_signatures.h
@@ -967,9 +967,9 @@ struct TALER_MasterDelWirePS
/*
* @brief Signature made by the exchange offline key over the
- * configuration of the age restriction extension.
+ * configuration of an extension.
*/
-struct TALER_MasterExtensionAgeRestrictionPS
+struct TALER_MasterExtensionConfigurationPS
{
/**
* Purpose is #TALER_SIGNATURE_MASTER_EXTENSION. Signed
@@ -978,29 +978,11 @@ struct TALER_MasterExtensionAgeRestrictionPS
struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
/**
- * Bit mask representing the lits of age groups, see TALER_AgeMask for a
- * description.
+ * Hash of the JSON object that represents the configuration of an extension.
*/
- struct TALER_AgeMask mask;
+ struct TALER_ExtensionConfigHash h_config GNUNET_PACKED;
};
-#if 0
-/*
- * @brief Signature made by the exchange offline key over the
- * configuration of the peer2peer extension.
- */
-struct TALER_MasterExtensionPeer2PeerPS
-{
- /**
- * Purpose is #TALER_SIGNATURE_MASTER_EXTENSION. Signed
- * by a `struct TALER_MasterPublicKeyP` using EdDSA.
- */
- struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
-
- // TODO oec
-};
-#endif
-
/**
* @brief Information about a denomination key. Denomination keys
* are used to sign coins of a certain value into existence.
diff --git a/src/json/json.c b/src/json/json.c
index af2b84e27..956aad1a5 100644
--- a/src/json/json.c
+++ b/src/json/json.c
@@ -1009,4 +1009,14 @@ TALER_deposit_extension_hash (const json_t *extensions,
}
+enum GNUNET_GenericReturnValue
+TALER_extension_config_hash (const json_t *config,
+ struct TALER_ExtensionConfigHash *ech)
+{
+ return dump_and_hash (config,
+ "taler-extension-configuration",
+ &ech->hash);
+}
+
+
/* End of json/json.c */
diff --git a/src/lib/exchange_api_management_post_extensions.c b/src/lib/exchange_api_management_post_extensions.c
index a2de2454c..862ff7117 100644
--- a/src/lib/exchange_api_management_post_extensions.c
+++ b/src/lib/exchange_api_management_post_extensions.c
@@ -153,32 +153,17 @@ TALER_EXCHANGE_management_post_extensions (
GNUNET_assert (NULL != extensions);
for (unsigned int i = 0; inum_extensions; i++)
{
- json_t *config;
- const struct TALER_AgeMask *mask;
+ const json_t *config;
const struct TALER_Extension *ext = &pkd->extensions[i];
- switch (ext->type)
- {
- // TODO: case TALER_Extension_Peer2Peer
- case TALER_Extension_AgeRestriction:
- mask = (const struct TALER_AgeMask *) (&ext->config);
- config = GNUNET_JSON_PACK (
- GNUNET_JSON_pack_string ("extension",
- ext->name),
- GNUNET_JSON_pack_data_auto ("mask",
- &mask->mask));
- GNUNET_assert (NULL != config);
- break;
- default:
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Extension not supported.\n");
- }
+ config = ext->config_to_json (ext);
+ GNUNET_assert (NULL != config);
GNUNET_assert (0 ==
json_array_append_new (
extensions,
GNUNET_JSON_PACK (
- GNUNET_JSON_pack_data_auto ("name",
+ GNUNET_JSON_pack_data_auto ("extension",
&ext->name),
GNUNET_JSON_pack_data_auto ("config",
config)
diff --git a/src/util/Makefile.am b/src/util/Makefile.am
index cae1a205e..55ebb4dff 100644
--- a/src/util/Makefile.am
+++ b/src/util/Makefile.am
@@ -72,6 +72,7 @@ libtalerutil_la_SOURCES = \
crypto_wire.c \
denom.c \
exchange_signatures.c \
+ extensions.c \
extension_age_restriction.c \
getopt.c \
lang.c \
diff --git a/src/util/extensions.c b/src/util/extensions.c
new file mode 100644
index 000000000..33f76d466
--- /dev/null
+++ b/src/util/extensions.c
@@ -0,0 +1,49 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2014-2021 Taler Systems SA
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ TALER; see the file COPYING. If not, see
+ */
+/**
+ * @file extensions.c
+ * @brief Utility functions for extensions
+ * @author Özgür Kesim
+ */
+#include "platform.h"
+#include "taler_util.h"
+#include "taler_extensions.h"
+#include "stdint.h"
+
+enum GNUNET_GenericReturnValue
+TALER_get_extension_by_name (const char *name,
+ const struct TALER_Extension *extensions,
+ const struct TALER_Extension **ext)
+{
+
+ const struct TALER_Extension *it = extensions;
+
+ for (; it->type != TALER_Extension_Max; it++)
+ {
+ if (0 == strncmp (name,
+ it->name,
+ strlen (it->name)))
+ {
+ *ext = it;
+ return GNUNET_OK;
+ }
+ }
+
+ return GNUNET_NO;
+}
+
+
+/* end of extensions.c */
diff --git a/src/util/offline_signatures.c b/src/util/offline_signatures.c
index 7fbec826b..1240a8bc5 100644
--- a/src/util/offline_signatures.c
+++ b/src/util/offline_signatures.c
@@ -491,66 +491,40 @@ TALER_exchange_offline_wire_fee_verify (
void
-TALER_exchange_offline_extension_agemask_sign (
- const struct TALER_AgeMask mask,
+TALER_exchange_offline_extension_config_hash_sign (
+ const struct TALER_ExtensionConfigHash h_config,
const struct TALER_MasterPrivateKeyP *master_priv,
struct TALER_MasterSignatureP *master_sig)
{
- struct TALER_MasterExtensionAgeRestrictionPS ar = {
+ struct TALER_MasterExtensionConfigurationPS ec = {
.purpose.purpose = htonl (TALER_SIGNATURE_MASTER_EXTENSION),
- .purpose.size = htonl (sizeof(ar)),
- .mask = mask
+ .purpose.size = htonl (sizeof(ec)),
+ .h_config = h_config
};
GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv,
- &ar,
+ &ec,
&master_sig->eddsa_signature);
}
enum GNUNET_GenericReturnValue
-TALER_exchange_offline_extension_agemask_verify (
- const struct TALER_AgeMask mask,
+TALER_exchange_offline_extension_config_hash_verify (
+ const struct TALER_ExtensionConfigHash h_config,
const struct TALER_MasterPublicKeyP *master_pub,
const struct TALER_MasterSignatureP *master_sig
)
{
- struct TALER_MasterExtensionAgeRestrictionPS ar = {
+ struct TALER_MasterExtensionConfigurationPS ec = {
.purpose.purpose = htonl (TALER_SIGNATURE_MASTER_EXTENSION),
- .purpose.size = htonl (sizeof(ar)),
- .mask = mask
+ .purpose.size = htonl (sizeof(ec)),
+ .h_config = h_config
};
- return
- GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MASTER_EXTENSION,
- &ar,
- &master_sig->eddsa_signature,
- &master_pub->eddsa_pub);
+
+ return GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MASTER_EXTENSION,
+ &ec,
+ &master_sig->eddsa_signature,
+ &master_pub->eddsa_pub);
}
-#if 0
-/* TODO peer2peer */
-void
-TALER_exchange_offline_extension_p2p_sign (
- // TODO
- const struct TALER_MasterPrivateKeyP *master_priv,
- struct TALER_MasterSignatureP *master_sig)
-{
- // TODO
-}
-
-
-enum GNUNET_GenericReturnValue
-TALER_exchange_offline_extension_p2p_verify (
- // TODO
- const struct TALER_MasterPublicKeyP *master_pub,
- const struct TALER_MasterSignatureP *master_sig,
- )
-{
- // TODO
- return GNUNET_FALSE;
-}
-
-
-#endif
-
/* end of offline_signatures.c */