fix #4506: check that master key matches our master key when loading signing and denomination keys; also do not send master_pub with each signing key, that is not in the spec

This commit is contained in:
Christian Grothoff 2016-05-18 17:58:32 +02:00
parent 396f29ab9e
commit daff72b63f
2 changed files with 54 additions and 21 deletions

View File

@ -183,15 +183,15 @@ parse_json_signkey (struct TALER_EXCHANGE_SigningPublicKey *sign_key,
struct GNUNET_TIME_Absolute valid_legal; struct GNUNET_TIME_Absolute valid_legal;
struct GNUNET_JSON_Specification spec[] = { struct GNUNET_JSON_Specification spec[] = {
GNUNET_JSON_spec_fixed_auto ("master_sig", GNUNET_JSON_spec_fixed_auto ("master_sig",
&sig), &sig),
GNUNET_JSON_spec_fixed_auto ("key", GNUNET_JSON_spec_fixed_auto ("key",
&sign_key_issue.signkey_pub), &sign_key_issue.signkey_pub),
GNUNET_JSON_spec_absolute_time ("stamp_start", GNUNET_JSON_spec_absolute_time ("stamp_start",
&valid_from), &valid_from),
GNUNET_JSON_spec_absolute_time ("stamp_expire", GNUNET_JSON_spec_absolute_time ("stamp_expire",
&valid_until), &valid_until),
GNUNET_JSON_spec_absolute_time ("stamp_end", GNUNET_JSON_spec_absolute_time ("stamp_end",
&valid_legal), &valid_legal),
GNUNET_JSON_spec_end() GNUNET_JSON_spec_end()
}; };
@ -487,13 +487,13 @@ decode_keys_json (const json_t *resp_obj,
{ {
struct GNUNET_JSON_Specification spec[] = { struct GNUNET_JSON_Specification spec[] = {
GNUNET_JSON_spec_fixed_auto ("master_public_key", GNUNET_JSON_spec_fixed_auto ("master_public_key",
&key_data->master_pub), &key_data->master_pub),
GNUNET_JSON_spec_fixed_auto ("eddsa_sig", GNUNET_JSON_spec_fixed_auto ("eddsa_sig",
&sig), &sig),
GNUNET_JSON_spec_fixed_auto ("eddsa_pub", GNUNET_JSON_spec_fixed_auto ("eddsa_pub",
&pub), &pub),
GNUNET_JSON_spec_absolute_time ("list_issue_date", GNUNET_JSON_spec_absolute_time ("list_issue_date",
&list_issue_date), &list_issue_date),
GNUNET_JSON_spec_end() GNUNET_JSON_spec_end()
}; };

View File

@ -250,6 +250,18 @@ reload_keys_denom_iter (void *cls,
GNUNET_CRYPTO_hash_context_read (ctx->hash_context, GNUNET_CRYPTO_hash_context_read (ctx->hash_context,
&denom_key_hash, &denom_key_hash,
sizeof (struct GNUNET_HashCode)); sizeof (struct GNUNET_HashCode));
if (0 != memcmp (&dki->issue.properties.master,
&TMH_master_public_key,
sizeof (struct TALER_MasterPublicKeyP)))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Master key in denomination key file `%s' does not match! Skipping it.\n",
alias);
return GNUNET_OK;
}
session = TMH_plugin->get_session (TMH_plugin->cls); session = TMH_plugin->get_session (TMH_plugin->cls);
if (NULL == session) if (NULL == session)
return GNUNET_SYSERR; return GNUNET_SYSERR;
@ -345,22 +357,19 @@ static json_t *
sign_key_issue_to_json (const struct TALER_ExchangeSigningKeyValidityPS *ski) sign_key_issue_to_json (const struct TALER_ExchangeSigningKeyValidityPS *ski)
{ {
return return
json_pack ("{s:o, s:o, s:o, s:o, s:o, s:o}", json_pack ("{s:o, s:o, s:o, s:o, s:o}",
"stamp_start", "stamp_start",
GNUNET_JSON_from_time_abs (GNUNET_TIME_absolute_ntoh (ski->start)), GNUNET_JSON_from_time_abs (GNUNET_TIME_absolute_ntoh (ski->start)),
"stamp_expire", "stamp_expire",
GNUNET_JSON_from_time_abs (GNUNET_TIME_absolute_ntoh (ski->expire)), GNUNET_JSON_from_time_abs (GNUNET_TIME_absolute_ntoh (ski->expire)),
"stamp_end", "stamp_end",
GNUNET_JSON_from_time_abs (GNUNET_TIME_absolute_ntoh (ski->end)), GNUNET_JSON_from_time_abs (GNUNET_TIME_absolute_ntoh (ski->end)),
"master_pub",
GNUNET_JSON_from_data (&ski->master_public_key,
sizeof (struct TALER_MasterPublicKeyP)),
"master_sig", "master_sig",
GNUNET_JSON_from_data (&ski->signature, GNUNET_JSON_from_data (&ski->signature,
sizeof (struct TALER_MasterSignatureP)), sizeof (struct TALER_MasterSignatureP)),
"key", "key",
GNUNET_JSON_from_data (&ski->signkey_pub, GNUNET_JSON_from_data (&ski->signkey_pub,
sizeof (struct TALER_ExchangePublicKeyP))); sizeof (struct TALER_ExchangePublicKeyP)));
} }
@ -402,6 +411,16 @@ reload_keys_sign_iter (void *cls,
return GNUNET_OK; return GNUNET_OK;
} }
if (0 != memcmp (&ski->issue.master_public_key,
&TMH_master_public_key,
sizeof (struct TALER_MasterPublicKeyP)))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Master key in signing key file `%s' does not match! Skipping it.\n",
filename);
return GNUNET_OK;
}
/* The signkey is valid at this time, check if it's more recent than /* The signkey is valid at this time, check if it's more recent than
what we have so far! */ what we have so far! */
if ( (GNUNET_TIME_absolute_ntoh (ctx->current_sign_key_issue.issue.start).abs_value_us < if ( (GNUNET_TIME_absolute_ntoh (ctx->current_sign_key_issue.issue.start).abs_value_us <
@ -649,14 +668,25 @@ TMH_KS_acquire_ (const char *location)
"Loading keys from `%s'\n", "Loading keys from `%s'\n",
TMH_exchange_directory); TMH_exchange_directory);
TALER_EXCHANGEDB_denomination_keys_iterate (TMH_exchange_directory, TALER_EXCHANGEDB_denomination_keys_iterate (TMH_exchange_directory,
&reload_keys_denom_iter, &reload_keys_denom_iter,
key_state); key_state);
TALER_EXCHANGEDB_signing_keys_iterate (TMH_exchange_directory, TALER_EXCHANGEDB_signing_keys_iterate (TMH_exchange_directory,
&reload_keys_sign_iter, &reload_keys_sign_iter,
key_state); key_state);
TALER_EXCHANGEDB_auditor_iterate (cfg, TALER_EXCHANGEDB_auditor_iterate (cfg,
&reload_auditor_iter, &reload_auditor_iter,
key_state); key_state);
if (0 != memcmp (&key_state->current_sign_key_issue.issue.master_public_key,
&TMH_master_public_key,
sizeof (struct TALER_MasterPublicKeyP)))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Have no signing key. Bad configuration.\n");
return NULL;
}
ks.purpose.size = htonl (sizeof (ks)); ks.purpose.size = htonl (sizeof (ks));
ks.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_KEY_SET); ks.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_KEY_SET);
ks.list_issue_date = GNUNET_TIME_absolute_hton (key_state->reload_time); ks.list_issue_date = GNUNET_TIME_absolute_hton (key_state->reload_time);
@ -897,8 +927,11 @@ TMH_KS_loop (void)
} }
/* This will re-initialize 'internal_key_state' with /* This will re-initialize 'internal_key_state' with
an initial refcnt of 1 */ an initial refcnt of 1 */
(void) TMH_KS_acquire (); if (NULL == TMH_KS_acquire ())
{
ret = GNUNET_SYSERR;
break;
}
read_again: read_again:
errno = 0; errno = 0;
res = read (reload_pipe[0], res = read (reload_pipe[0],