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 */