Simplify extension verification
- simplify signature verification for extensions - remove per-extension signatures from DB schema - adjust prepared statements accordingly - adjust DB event handler for extensions
This commit is contained in:
parent
ccc4034084
commit
ba3be90ed4
@ -796,7 +796,7 @@ static enum GNUNET_GenericReturnValue
|
||||
postgres_gc (void *cls)
|
||||
{
|
||||
struct PostgresClosure *pg = cls;
|
||||
struct GNUNET_TIME_Absolute now;
|
||||
struct GNUNET_TIME_Absolute now = {0};
|
||||
struct GNUNET_PQ_QueryParam params_time[] = {
|
||||
GNUNET_PQ_query_param_absolute_time (&now),
|
||||
GNUNET_PQ_query_param_end
|
||||
|
@ -1680,9 +1680,76 @@ upload_extensions (const char *exchange_url,
|
||||
size_t idx,
|
||||
const json_t *value)
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, "uploading extensions %s\n",
|
||||
json_dumps (value, JSON_INDENT (2)));
|
||||
json_t *extensions;
|
||||
struct TALER_MasterSignatureP sig;
|
||||
const char *err_name;
|
||||
unsigned int err_line;
|
||||
struct GNUNET_JSON_Specification spec[] = {
|
||||
GNUNET_JSON_spec_json ("extensions",
|
||||
&extensions),
|
||||
GNUNET_JSON_spec_fixed_auto ("extensions_sig",
|
||||
&sig),
|
||||
GNUNET_JSON_spec_end ()
|
||||
};
|
||||
|
||||
/* 1. Parse the signed extensions */
|
||||
if (GNUNET_OK !=
|
||||
GNUNET_JSON_parse (value,
|
||||
spec,
|
||||
&err_name,
|
||||
&err_line))
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Invalid input to set extensions: %s#%u at %u (skipping)\n",
|
||||
err_name,
|
||||
err_line,
|
||||
(unsigned int) idx);
|
||||
json_dumpf (value,
|
||||
stderr,
|
||||
JSON_INDENT (2));
|
||||
global_ret = EXIT_FAILURE;
|
||||
test_shutdown ();
|
||||
return;
|
||||
}
|
||||
|
||||
/* 2. Verify the signature */
|
||||
{
|
||||
struct TALER_ExtensionConfigHash h_config;
|
||||
|
||||
if (GNUNET_OK != TALER_extension_config_hash (extensions, &h_config))
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"couldn't hash extensions\n");
|
||||
global_ret = EXIT_FAILURE;
|
||||
test_shutdown ();
|
||||
return;
|
||||
}
|
||||
|
||||
if (GNUNET_OK !=
|
||||
load_offline_key (GNUNET_NO))
|
||||
return;
|
||||
|
||||
if (GNUNET_OK != TALER_exchange_offline_extension_config_hash_verify (
|
||||
&h_config,
|
||||
&master_pub,
|
||||
&sig))
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"invalid signature for extensions\n");
|
||||
global_ret = EXIT_FAILURE;
|
||||
test_shutdown ();
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* 3. Upload */
|
||||
|
||||
/* TODO */
|
||||
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
|
||||
"\e[33m*TODO*\e[0m\nuploading extensions %s\n",
|
||||
json_dumps (value, JSON_INDENT (2)));
|
||||
}
|
||||
|
||||
|
||||
@ -3537,43 +3604,36 @@ static void
|
||||
do_extensions_sign (char *const *args)
|
||||
{
|
||||
json_t *obj = json_object ();
|
||||
json_t *exts = json_object ();
|
||||
json_t *sigs = json_object ();
|
||||
json_t *extensions = json_object ();
|
||||
struct TALER_ExtensionConfigHash h_config;
|
||||
struct TALER_MasterSignatureP sig;
|
||||
|
||||
GNUNET_CONFIGURATION_iterate_sections (kcfg,
|
||||
&collect_extensions,
|
||||
exts);
|
||||
json_object_set (obj, "extensions", exts);
|
||||
extensions);
|
||||
|
||||
/* sign the extensions */
|
||||
// TODO: check size of extensions?
|
||||
if (GNUNET_OK != TALER_extension_config_hash (extensions, &h_config))
|
||||
{
|
||||
const char *name;
|
||||
json_t *config;
|
||||
|
||||
json_object_foreach (exts, name, config){
|
||||
struct TALER_ExtensionConfigHash h_config;
|
||||
struct TALER_MasterSignatureP sig;
|
||||
|
||||
if (GNUNET_OK != TALER_extension_config_hash (config, &h_config))
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"error while hashing config for extension %s\n",
|
||||
name);
|
||||
return;
|
||||
}
|
||||
|
||||
TALER_exchange_offline_extension_config_hash_sign (h_config, &master_priv,
|
||||
&sig);
|
||||
json_object_update (sigs,
|
||||
GNUNET_JSON_PACK (
|
||||
GNUNET_JSON_pack_data_auto (
|
||||
name,
|
||||
&sig)));
|
||||
}
|
||||
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"error while hashing config for extensions\n");
|
||||
return;
|
||||
}
|
||||
|
||||
json_object_set (obj, "extensions_sigs", sigs);
|
||||
if (GNUNET_OK !=
|
||||
load_offline_key (GNUNET_NO))
|
||||
return;
|
||||
|
||||
|
||||
TALER_exchange_offline_extension_config_hash_sign (&h_config,
|
||||
&master_priv,
|
||||
&sig);
|
||||
json_object_set (obj, "extensions", extensions);
|
||||
json_object_update (obj,
|
||||
GNUNET_JSON_PACK (
|
||||
GNUNET_JSON_pack_data_auto (
|
||||
"extensions_sig",
|
||||
&sig)));
|
||||
|
||||
output_operation (OP_EXTENSIONS, obj);
|
||||
}
|
||||
|
@ -171,7 +171,6 @@ extension_update_event_cb (void *cls,
|
||||
// Get the config from the database as string
|
||||
{
|
||||
char *config_str;
|
||||
struct TALER_MasterSignatureP config_sig; // ignored
|
||||
enum GNUNET_DB_QueryStatus qs;
|
||||
struct TALER_Extension *extension;
|
||||
json_error_t err;
|
||||
@ -183,8 +182,7 @@ extension_update_event_cb (void *cls,
|
||||
|
||||
qs = TEH_plugin->get_extension_config (TEH_plugin->cls,
|
||||
extension->name,
|
||||
&config_str,
|
||||
&config_sig);
|
||||
&config_str);
|
||||
|
||||
if (qs < 0)
|
||||
{
|
||||
|
@ -49,41 +49,8 @@ struct SetExtensionsContext
|
||||
{
|
||||
uint32_t num_extensions;
|
||||
struct Extension *extensions;
|
||||
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.
|
||||
@ -111,7 +78,6 @@ set_extensions (void *cls,
|
||||
for (uint32_t i = 0; i<sec->num_extensions; i++)
|
||||
{
|
||||
struct Extension *ext = &sec->extensions[i];
|
||||
struct TALER_MasterSignatureP *sig = &sec->extensions_sigs[i];
|
||||
enum GNUNET_DB_QueryStatus qs;
|
||||
char *config;
|
||||
|
||||
@ -138,8 +104,7 @@ set_extensions (void *cls,
|
||||
qs = TEH_plugin->set_extension_config (
|
||||
TEH_plugin->cls,
|
||||
TEH_extensions[ext->type]->name,
|
||||
config,
|
||||
sig);
|
||||
config);
|
||||
|
||||
if (qs < 0)
|
||||
{
|
||||
@ -178,12 +143,12 @@ TEH_handler_management_post_extensions (
|
||||
{
|
||||
MHD_RESULT ret;
|
||||
json_t *extensions;
|
||||
json_t *extensions_sigs;
|
||||
struct TALER_MasterSignatureP sig = {0};
|
||||
struct GNUNET_JSON_Specification top_spec[] = {
|
||||
GNUNET_JSON_spec_json ("extensions",
|
||||
&extensions),
|
||||
GNUNET_JSON_spec_json ("extensions_sigs",
|
||||
&extensions_sigs),
|
||||
GNUNET_JSON_spec_fixed_auto ("extensions_sig",
|
||||
&sig),
|
||||
GNUNET_JSON_spec_end ()
|
||||
};
|
||||
struct SetExtensionsContext sec = {0};
|
||||
@ -201,38 +166,51 @@ TEH_handler_management_post_extensions (
|
||||
return MHD_YES; /* failure */
|
||||
}
|
||||
|
||||
/* Ensure we have two objects of the same size */
|
||||
if (! (json_is_object (extensions) &&
|
||||
json_is_object (extensions_sigs)) )
|
||||
/* Ensure we have an object */
|
||||
if (! json_is_object (extensions))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
GNUNET_JSON_parse_free (top_spec);
|
||||
return TALER_MHD_reply_with_error (
|
||||
connection,
|
||||
MHD_HTTP_BAD_REQUEST,
|
||||
TALER_EC_GENERIC_PARAMETER_MALFORMED,
|
||||
"objects expected for extensions and extensions_sigs");
|
||||
"invalid object");
|
||||
}
|
||||
|
||||
sec.num_extensions = json_object_size (extensions);
|
||||
if (json_object_size (extensions_sigs) != sec.num_extensions)
|
||||
/* Verify the signature */
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
GNUNET_JSON_parse_free (top_spec);
|
||||
return TALER_MHD_reply_with_error (
|
||||
connection,
|
||||
MHD_HTTP_BAD_REQUEST,
|
||||
TALER_EC_GENERIC_PARAMETER_MALFORMED,
|
||||
"objects extensions and extensions_sigs are not of the same size");
|
||||
struct TALER_ExtensionConfigHash h_config;
|
||||
if (GNUNET_OK != TALER_extension_config_hash (extensions, &h_config))
|
||||
{
|
||||
GNUNET_JSON_parse_free (top_spec);
|
||||
return TALER_MHD_reply_with_error (
|
||||
connection,
|
||||
MHD_HTTP_BAD_REQUEST,
|
||||
TALER_EC_GENERIC_PARAMETER_MALFORMED,
|
||||
"invalid object, non-hashable");
|
||||
}
|
||||
|
||||
if (GNUNET_OK != TALER_exchange_offline_extension_config_hash_verify (
|
||||
&h_config,
|
||||
&TEH_master_public_key,
|
||||
&sig))
|
||||
{
|
||||
GNUNET_JSON_parse_free (top_spec);
|
||||
return TALER_MHD_reply_with_error (
|
||||
connection,
|
||||
MHD_HTTP_BAD_REQUEST,
|
||||
TALER_EC_GENERIC_PARAMETER_MALFORMED,
|
||||
"invalid signuture");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||
"Received /management/extensions\n");
|
||||
|
||||
sec.num_extensions = json_object_size (extensions);
|
||||
sec.extensions = GNUNET_new_array (sec.num_extensions,
|
||||
struct Extension);
|
||||
sec.extensions_sigs = GNUNET_new_array (sec.num_extensions,
|
||||
struct TALER_MasterSignatureP);
|
||||
|
||||
/* Now parse individual extensions and signatures from those objects. */
|
||||
{
|
||||
@ -261,45 +239,7 @@ TEH_handler_management_post_extensions (
|
||||
sec.extensions[idx].config = config;
|
||||
sec.extensions[idx].type = extension->type;
|
||||
|
||||
/* 2. Extract the corresponding signature */
|
||||
{
|
||||
struct GNUNET_JSON_Specification sig_spec[] = {
|
||||
GNUNET_JSON_spec_fixed_auto (name,
|
||||
&sec.extensions_sigs[idx]),
|
||||
GNUNET_JSON_spec_end ()
|
||||
};
|
||||
|
||||
if (GNUNET_OK != TALER_MHD_parse_json_data (connection,
|
||||
extensions_sigs,
|
||||
sig_spec))
|
||||
{
|
||||
GNUNET_JSON_parse_free (sig_spec);
|
||||
ret = TALER_MHD_reply_with_error (
|
||||
connection,
|
||||
MHD_HTTP_BAD_REQUEST,
|
||||
TALER_EC_GENERIC_PARAMETER_MALFORMED,
|
||||
"extension signature missing");
|
||||
goto CLEANUP;
|
||||
}
|
||||
|
||||
GNUNET_JSON_parse_free (sig_spec);
|
||||
}
|
||||
|
||||
/* 3. Verify the signature of the config */
|
||||
if (GNUNET_OK != config_verify (
|
||||
sec.extensions[idx].config,
|
||||
&TEH_master_public_key,
|
||||
&sec.extensions_sigs[idx]))
|
||||
{
|
||||
ret = TALER_MHD_reply_with_error (
|
||||
connection,
|
||||
MHD_HTTP_BAD_REQUEST,
|
||||
TALER_EC_GENERIC_PARAMETER_MALFORMED,
|
||||
"invalid signature for extension");
|
||||
goto CLEANUP;
|
||||
}
|
||||
|
||||
/* 4. Make sure the config is sound */
|
||||
/* 2. Make sure the config is sound */
|
||||
if (GNUNET_OK != extension->test_config (sec.extensions[idx].config))
|
||||
{
|
||||
ret = TALER_MHD_reply_with_error (
|
||||
@ -356,7 +296,6 @@ CLEANUP:
|
||||
}
|
||||
}
|
||||
GNUNET_free (sec.extensions);
|
||||
GNUNET_free (sec.extensions_sigs);
|
||||
GNUNET_JSON_parse_free (top_spec);
|
||||
return ret;
|
||||
}
|
||||
|
@ -298,7 +298,6 @@ CREATE TABLE IF NOT EXISTS extensions
|
||||
(extension_id BIGSERIAL UNIQUE
|
||||
,name VARCHAR NOT NULL UNIQUE
|
||||
,config BYTEA NOT NULL
|
||||
,config_sig BYTEA NOT NULL
|
||||
);
|
||||
COMMENT ON TABLE extensions
|
||||
IS 'Configurations of the activated extensions';
|
||||
@ -306,8 +305,6 @@ COMMENT ON COLUMN extensions.name
|
||||
IS 'Name of the extension';
|
||||
COMMENT ON COLUMN extensions.config
|
||||
IS 'Configuration of the extension as JSON-blob';
|
||||
COMMENT ON COLUMN extensions.config
|
||||
IS 'Signature of the configuration of an extension, signed with the master key of the exchange';
|
||||
|
||||
|
||||
CREATE TABLE IF NOT EXISTS known_coins
|
||||
|
@ -2745,16 +2745,15 @@ prepare_statements (struct PostgresClosure *pg)
|
||||
/* Used in #postgres_set_extension_config */
|
||||
GNUNET_PQ_make_prepare (
|
||||
"set_extension_config",
|
||||
"INSERT INTO extensions (name, config, config_sig) VALUES ($1, $2, $3) "
|
||||
"INSERT INTO extensions (name, config) VALUES ($1, $2) "
|
||||
"ON CONFLICT (name) "
|
||||
"DO UPDATE SET (config, config_sig) = ($2, $3)",
|
||||
3),
|
||||
"DO UPDATE SET config=$2",
|
||||
2),
|
||||
/* Used in #postgres_get_extension_config */
|
||||
GNUNET_PQ_make_prepare (
|
||||
"get_extension_config",
|
||||
"SELECT "
|
||||
" config, "
|
||||
" config_sig "
|
||||
" config "
|
||||
"FROM extensions"
|
||||
" WHERE name=$1;",
|
||||
1),
|
||||
@ -11413,20 +11412,17 @@ postgres_delete_shard_locks (void *cls)
|
||||
* @param cls the @e cls of this struct with the plugin-specific state
|
||||
* @param extension_name the name of the extension
|
||||
* @param config JSON object of the configuration as string
|
||||
* @param config_sig signature of the configuration by the offline master key
|
||||
* @return transaction status code
|
||||
*/
|
||||
enum GNUNET_DB_QueryStatus
|
||||
postgres_set_extension_config (void *cls,
|
||||
const char *extension_name,
|
||||
const char *config,
|
||||
const struct TALER_MasterSignatureP *config_sig)
|
||||
const char *config)
|
||||
{
|
||||
struct PostgresClosure *pg = cls;
|
||||
struct GNUNET_PQ_QueryParam params[] = {
|
||||
GNUNET_PQ_query_param_string (extension_name),
|
||||
GNUNET_PQ_query_param_string (config),
|
||||
GNUNET_PQ_query_param_auto_from_type (config_sig),
|
||||
GNUNET_PQ_query_param_end
|
||||
};
|
||||
|
||||
@ -11448,8 +11444,7 @@ postgres_set_extension_config (void *cls,
|
||||
enum GNUNET_DB_QueryStatus
|
||||
postgres_get_extension_config (void *cls,
|
||||
const char *extension_name,
|
||||
char **config,
|
||||
struct TALER_MasterSignatureP *config_sig)
|
||||
char **config)
|
||||
{
|
||||
struct PostgresClosure *pg = cls;
|
||||
struct GNUNET_PQ_QueryParam params[] = {
|
||||
@ -11458,7 +11453,6 @@ postgres_get_extension_config (void *cls,
|
||||
};
|
||||
struct GNUNET_PQ_ResultSpec rs[] = {
|
||||
GNUNET_PQ_result_spec_string ("config", config),
|
||||
GNUNET_PQ_result_spec_auto_from_type ("config_sig", config_sig),
|
||||
GNUNET_PQ_result_spec_end
|
||||
};
|
||||
|
||||
|
@ -115,51 +115,36 @@ static enum GNUNET_GenericReturnValue
|
||||
test_extension_config (void)
|
||||
{
|
||||
char *config;
|
||||
struct TALER_MasterSignatureP sig;
|
||||
|
||||
memset (&sig, 0x42, sizeof(sig));
|
||||
|
||||
FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=
|
||||
plugin->get_extension_config (plugin->cls,
|
||||
"fnord",
|
||||
&config,
|
||||
&sig));
|
||||
&config));
|
||||
|
||||
sig.eddsa_signature.r[23] = 0x23;
|
||||
FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
|
||||
plugin->set_extension_config (plugin->cls,
|
||||
"fnord",
|
||||
"bar",
|
||||
&sig));
|
||||
"bar"));
|
||||
|
||||
memset (&sig, 0, sizeof(sig));
|
||||
FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
|
||||
plugin->get_extension_config (plugin->cls,
|
||||
"fnord",
|
||||
&config,
|
||||
&sig));
|
||||
&config));
|
||||
|
||||
FAILIF (0 != strcmp ("bar", config));
|
||||
FAILIF (0x23 != sig.eddsa_signature.r[23]);
|
||||
|
||||
|
||||
/* let's do this again! */
|
||||
memset (&sig, 0x42, sizeof(sig));
|
||||
FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
|
||||
plugin->set_extension_config (plugin->cls,
|
||||
"fnord",
|
||||
"buzz",
|
||||
&sig));
|
||||
"buzz"));
|
||||
|
||||
memset (&sig, 0, sizeof(sig));
|
||||
FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
|
||||
plugin->get_extension_config (plugin->cls,
|
||||
"fnord",
|
||||
&config,
|
||||
&sig));
|
||||
&config));
|
||||
|
||||
FAILIF (0 != strcmp ("buzz", config));
|
||||
FAILIF (0x42 != sig.eddsa_signature.r[23]);
|
||||
|
||||
return GNUNET_OK;
|
||||
drop:
|
||||
|
@ -2536,7 +2536,7 @@ TALER_merchant_wire_signature_make (
|
||||
*/
|
||||
void
|
||||
TALER_exchange_offline_extension_config_hash_sign (
|
||||
const struct TALER_ExtensionConfigHash h_config,
|
||||
const struct TALER_ExtensionConfigHash *h_config,
|
||||
const struct TALER_MasterPrivateKeyP *master_priv,
|
||||
struct TALER_MasterSignatureP *master_sig);
|
||||
|
||||
@ -2552,7 +2552,7 @@ TALER_exchange_offline_extension_config_hash_sign (
|
||||
*/
|
||||
enum GNUNET_GenericReturnValue
|
||||
TALER_exchange_offline_extension_config_hash_verify (
|
||||
const struct TALER_ExtensionConfigHash h_config,
|
||||
const struct TALER_ExtensionConfigHash *h_config,
|
||||
const struct TALER_MasterPublicKeyP *master_pub,
|
||||
const struct TALER_MasterSignatureP *master_sig
|
||||
);
|
||||
|
@ -4027,14 +4027,12 @@ struct TALER_EXCHANGEDB_Plugin
|
||||
* @param cls the @e cls of this struct with the plugin-specific state
|
||||
* @param extension_name the name of the extension
|
||||
* @param config JSON object of the configuration as string
|
||||
* @param config_sig signature of the configuration by the offline master key
|
||||
* @return transaction status code
|
||||
*/
|
||||
enum GNUNET_DB_QueryStatus
|
||||
(*set_extension_config)(void *cls,
|
||||
const char *extension_name,
|
||||
const char *config,
|
||||
const struct TALER_MasterSignatureP *config_sig);
|
||||
const char *config);
|
||||
|
||||
/**
|
||||
* Function called to retrieve the configuration of an extension
|
||||
@ -4049,8 +4047,7 @@ struct TALER_EXCHANGEDB_Plugin
|
||||
enum GNUNET_DB_QueryStatus
|
||||
(*get_extension_config)(void *cls,
|
||||
const char *extension_name,
|
||||
char **config,
|
||||
struct TALER_MasterSignatureP *config_sig);
|
||||
char **config);
|
||||
|
||||
};
|
||||
|
||||
|
@ -492,14 +492,14 @@ TALER_exchange_offline_wire_fee_verify (
|
||||
|
||||
void
|
||||
TALER_exchange_offline_extension_config_hash_sign (
|
||||
const struct TALER_ExtensionConfigHash h_config,
|
||||
const struct TALER_ExtensionConfigHash *h_config,
|
||||
const struct TALER_MasterPrivateKeyP *master_priv,
|
||||
struct TALER_MasterSignatureP *master_sig)
|
||||
{
|
||||
struct TALER_MasterExtensionConfigurationPS ec = {
|
||||
.purpose.purpose = htonl (TALER_SIGNATURE_MASTER_EXTENSION),
|
||||
.purpose.size = htonl (sizeof(ec)),
|
||||
.h_config = h_config
|
||||
.h_config = *h_config
|
||||
};
|
||||
GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv,
|
||||
&ec,
|
||||
@ -509,7 +509,7 @@ TALER_exchange_offline_extension_config_hash_sign (
|
||||
|
||||
enum GNUNET_GenericReturnValue
|
||||
TALER_exchange_offline_extension_config_hash_verify (
|
||||
const struct TALER_ExtensionConfigHash h_config,
|
||||
const struct TALER_ExtensionConfigHash *h_config,
|
||||
const struct TALER_MasterPublicKeyP *master_pub,
|
||||
const struct TALER_MasterSignatureP *master_sig
|
||||
)
|
||||
@ -517,7 +517,7 @@ TALER_exchange_offline_extension_config_hash_verify (
|
||||
struct TALER_MasterExtensionConfigurationPS ec = {
|
||||
.purpose.purpose = htonl (TALER_SIGNATURE_MASTER_EXTENSION),
|
||||
.purpose.size = htonl (sizeof(ec)),
|
||||
.h_config = h_config
|
||||
.h_config = *h_config
|
||||
};
|
||||
|
||||
return GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MASTER_EXTENSION,
|
||||
|
Loading…
Reference in New Issue
Block a user