fix FTBFS issues in new /keys logic

This commit is contained in:
Christian Grothoff 2020-12-07 21:39:45 +01:00
parent f256dab738
commit 3ffd605041
No known key found for this signature in database
GPG Key ID: 939E6BE1E29FC3CC
3 changed files with 130 additions and 68 deletions

View File

@ -82,6 +82,7 @@ taler_exchange_httpd_SOURCES = \
taler-exchange-httpd_db.c taler-exchange-httpd_db.h \ taler-exchange-httpd_db.c taler-exchange-httpd_db.h \
taler-exchange-httpd_deposit.c taler-exchange-httpd_deposit.h \ taler-exchange-httpd_deposit.c taler-exchange-httpd_deposit.h \
taler-exchange-httpd_deposits_get.c taler-exchange-httpd_deposits_get.h \ taler-exchange-httpd_deposits_get.c taler-exchange-httpd_deposits_get.h \
taler-exchange-httpd_keys.c taler-exchange-httpd_keys.h \
taler-exchange-httpd_keystate.c taler-exchange-httpd_keystate.h \ taler-exchange-httpd_keystate.c taler-exchange-httpd_keystate.h \
taler-exchange-httpd_link.c taler-exchange-httpd_link.h \ taler-exchange-httpd_link.c taler-exchange-httpd_link.h \
taler-exchange-httpd_management.h \ taler-exchange-httpd_management.h \

View File

@ -93,12 +93,12 @@ struct TEH_AuditorSignature
/** /**
* We store the signatures in a DLL. * We store the signatures in a DLL.
*/ */
struct AuditorSignature *prev; struct TEH_AuditorSignature *prev;
/** /**
* We store the signatures in a DLL. * We store the signatures in a DLL.
*/ */
struct AuditorSignature *next; struct TEH_AuditorSignature *next;
/** /**
* A signature from the auditor. * A signature from the auditor.
@ -310,6 +310,12 @@ static pthread_key_t key_state;
*/ */
static volatile uint64_t key_generation; static volatile uint64_t key_generation;
/**
* For how long should a signing key be legally retained?
* Configuration value.
*/
static struct GNUNET_TIME_Relative signkey_legal_duration;
/** /**
* RSA security module public key, all zero if not known. * RSA security module public key, all zero if not known.
*/ */
@ -339,11 +345,12 @@ clear_response_cache (struct TEH_KeyStateHandle *ksh)
{ {
struct KeysResponseData *krd = &ksh->krd_array[i]; struct KeysResponseData *krd = &ksh->krd_array[i];
MHD_destroy_response (kdr->response_compressed); MHD_destroy_response (krd->response_compressed);
MHD_destroy_response (kdr->response_uncompressed); MHD_destroy_response (krd->response_uncompressed);
} }
GNUNET_array_grow (ksh->krd_array, GNUNET_array_grow (ksh->krd_array,
ksh->krd_array_length); ksh->krd_array_length,
0);
} }
@ -456,12 +463,12 @@ free_esign_cb (void *cls,
static void static void
destroy_key_helpers (struct HelperState *hs) destroy_key_helpers (struct HelperState *hs)
{ {
GNUNET_CONTIANER_multihashmap_iterate (hs->denom_keys, GNUNET_CONTAINER_multihashmap_iterate (hs->denom_keys,
&free_denom_cb, &free_denom_cb,
hs); hs);
GNUNET_CONTAINER_multihashmap_destroy (hs->denom_keys); GNUNET_CONTAINER_multihashmap_destroy (hs->denom_keys);
hs->denom_keys = NULL; hs->denom_keys = NULL;
GNUNET_CONTIANER_multipeermap_iterate (hs->denom_keys, GNUNET_CONTAINER_multipeermap_iterate (hs->esign_keys,
&free_esign_cb, &free_esign_cb,
hs); hs);
GNUNET_CONTAINER_multipeermap_destroy (hs->esign_keys); GNUNET_CONTAINER_multipeermap_destroy (hs->esign_keys);
@ -577,12 +584,12 @@ helper_esign_cb (
check_esign_sm_pub (sm_pub); check_esign_sm_pub (sm_pub);
pid.public_key = exchange_pub->eddsa_pub; pid.public_key = exchange_pub->eddsa_pub;
hsk = GNUNET_CONTAINER_multipeermap_get (hs->denom_keys, hsk = GNUNET_CONTAINER_multipeermap_get (hs->esign_keys,
&pid); &pid);
if (NULL != hsk) if (NULL != hsk)
{ {
/* should be just an update (revocation!), so update existing entry */ /* should be just an update (revocation!), so update existing entry */
sk->validity_duration = validity_duration; hsk->validity_duration = validity_duration;
GNUNET_break (0 == GNUNET_break (0 ==
GNUNET_memcmp (sm_sig, GNUNET_memcmp (sm_sig,
&hsk->sm_sig)); &hsk->sm_sig));
@ -598,7 +605,7 @@ helper_esign_cb (
hsk->sm_sig = *sm_sig; hsk->sm_sig = *sm_sig;
GNUNET_assert ( GNUNET_assert (
GNUNET_OK == GNUNET_OK ==
GNUNET_CONTAINER_multihashmap_put ( GNUNET_CONTAINER_multipeermap_put (
hs->esign_keys, hs->esign_keys,
&pid, &pid,
hsk, hsk,
@ -621,7 +628,7 @@ setup_key_helpers (struct HelperState *hs)
hs->esign_keys hs->esign_keys
= GNUNET_CONTAINER_multipeermap_create (32, = GNUNET_CONTAINER_multipeermap_create (32,
GNUNET_NO /* MUST BE NO! */); GNUNET_NO /* MUST BE NO! */);
hs->dh = TALER_CRYPTO_helper_denom_connect (cfg, hs->dh = TALER_CRYPTO_helper_denom_connect (TEH_cfg,
&helper_denom_cb, &helper_denom_cb,
hs); hs);
if (NULL == hs->dh) if (NULL == hs->dh)
@ -629,7 +636,7 @@ setup_key_helpers (struct HelperState *hs)
destroy_key_helpers (hs); destroy_key_helpers (hs);
return GNUNET_SYSERR; return GNUNET_SYSERR;
} }
hs->esh = TALER_CRYPTO_helper_esign_connect (cfg, hs->esh = TALER_CRYPTO_helper_esign_connect (TEH_cfg,
&helper_esign_cb, &helper_esign_cb,
hs); hs);
if (NULL == hs->esh) if (NULL == hs->esh)
@ -723,10 +730,10 @@ destroy_key_state (struct TEH_KeyStateHandle *ksh,
&clear_denomination_cb, &clear_denomination_cb,
ksh); ksh);
GNUNET_CONTAINER_multihashmap_destroy (ksh->denomkey_map); GNUNET_CONTAINER_multihashmap_destroy (ksh->denomkey_map);
GNUNET_CONTAINER_multihashmap_iterate (ksh->signkey_map, GNUNET_CONTAINER_multipeermap_iterate (ksh->signkey_map,
&clear_signkey_cb, &clear_signkey_cb,
ksh); ksh);
GNUNET_CONTAINER_multihashmap_destroy (ksh->denomkey_map); GNUNET_CONTAINER_multipeermap_destroy (ksh->signkey_map);
json_decref (ksh->auditors); json_decref (ksh->auditors);
ksh->auditors = NULL; ksh->auditors = NULL;
if (NULL != ksh->management_keys_reply) if (NULL != ksh->management_keys_reply)
@ -756,6 +763,44 @@ destroy_key_state_cb (void *cls)
} }
/**
* Initialize keys submodule.
*
* @return #GNUNET_OK on success
*/
int
TEH_keys_init ()
{
if (0 !=
pthread_key_create (&key_state,
&destroy_key_state_cb))
return GNUNET_SYSERR;
if (GNUNET_OK !=
GNUNET_CONFIGURATION_get_value_time (TEH_cfg,
"exchange",
"SIGNKEY_LEGAL_DURATION",
&signkey_legal_duration))
{
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
"exchange",
"SIGNKEY_LEGAL_DURATION");
return GNUNET_SYSERR;
}
return GNUNET_OK;
}
/**
* Close down keys submodule.
*/
void
TEH_keys_done ()
{
GNUNET_assert (0 ==
pthread_key_delete (key_state));
}
/** /**
* Function called with information about the exchange's denomination keys. * Function called with information about the exchange's denomination keys.
* *
@ -783,15 +828,15 @@ denomination_info_cb (
dk->denom_pub.rsa_public_key dk->denom_pub.rsa_public_key
= GNUNET_CRYPTO_rsa_public_key_dup (denom_pub->rsa_public_key); = GNUNET_CRYPTO_rsa_public_key_dup (denom_pub->rsa_public_key);
dk->h_denom_pub = *h_denom_pub; dk->h_denom_pub = *h_denom_pub;
dk->meta = meta; dk->meta = *meta;
dk->master_sig = *master_sig; dk->master_sig = *master_sig;
dk->recoup_possible = recoup_possible; dk->recoup_possible = recoup_possible;
GNUNET_assert ( GNUNET_assert (
GNUNET_OK == GNUNET_OK ==
GNUNET_CONTAINER_multihashmap_insert (ksh->denom_map, GNUNET_CONTAINER_multihashmap_put (ksh->denomkey_map,
&dk->h_denom_pub, &dk->h_denom_pub,
dk, dk,
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
} }
@ -815,16 +860,16 @@ signkey_info_cb (
struct GNUNET_PeerIdentity pid; struct GNUNET_PeerIdentity pid;
sk = GNUNET_new (struct SigningKey); sk = GNUNET_new (struct SigningKey);
sk->exchnage_pub = *exchange_pub; sk->exchange_pub = *exchange_pub;
sk->meta = *meta; sk->meta = *meta;
sk->master_sig = *master_sig; sk->master_sig = *master_sig;
pid.public_key = exchange_pub->eddsa_pub; pid.public_key = exchange_pub->eddsa_pub;
GNUNET_assert ( GNUNET_assert (
GNUNET_OK == GNUNET_OK ==
GNUNET_CONTAINER_multihashmap_insert (ksh->signkey_map, GNUNET_CONTAINER_multipeermap_put (ksh->signkey_map,
&pid, &pid,
sk, sk,
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
} }
@ -878,7 +923,7 @@ auditor_denom_cb (
struct TEH_DenominationKey *dk; struct TEH_DenominationKey *dk;
struct TEH_AuditorSignature *as; struct TEH_AuditorSignature *as;
dk = GNUNET_CONTAINER_multihashmap_get (ksh->denom_map, dk = GNUNET_CONTAINER_multihashmap_get (ksh->denomkey_map,
h_denom_pub); h_denom_pub);
if (NULL == dk) if (NULL == dk)
{ {
@ -927,7 +972,7 @@ build_key_state (struct HelperState *hs)
} }
ksh->denomkey_map = GNUNET_CONTAINER_multihashmap_create (1024, ksh->denomkey_map = GNUNET_CONTAINER_multihashmap_create (1024,
GNUNET_YES); GNUNET_YES);
ksh->signkey_map = GNUNET_CONTAINER_multihashmap_create (32, ksh->signkey_map = GNUNET_CONTAINER_multipeermap_create (32,
GNUNET_NO /* MUST be NO! */); GNUNET_NO /* MUST be NO! */);
ksh->auditors = json_array (); ksh->auditors = json_array ();
/* NOTE: fetches master-signed signkeys, but ALSO those that were revoked! */ /* NOTE: fetches master-signed signkeys, but ALSO those that were revoked! */
@ -1036,16 +1081,15 @@ TEH_keys_get_state (void)
ksh)) ksh))
{ {
GNUNET_break (0); GNUNET_break (0);
destroy_key_state_cb (ksh, destroy_key_state (ksh,
true); true);
return NULL; return NULL;
} }
return ksh; return ksh;
} }
if (old_ksh->key_generation < key_generation) if (old_ksh->key_generation < key_generation)
{ {
ksh = build_key_state (key_generation, ksh = build_key_state (&old_ksh->helpers);
&old_ksh->helpers);
if (0 != pthread_setspecific (key_state, if (0 != pthread_setspecific (key_state,
ksh)) ksh))
{ {
@ -1101,14 +1145,15 @@ TEH_keys_denomination_sign (
enum TALER_ErrorCode *ec) enum TALER_ErrorCode *ec)
{ {
struct TEH_KeyStateHandle *ksh; struct TEH_KeyStateHandle *ksh;
struct TALER_DenominationSignature none = { NULL };
ksh = TEH_keys_get_state (); ksh = TEH_keys_get_state ();
if (NULL == ksh) if (NULL == ksh)
{ {
*ec = TALER_EC_EXCHANGE_GENERIC_KEYS_MISSING; *ec = TALER_EC_EXCHANGE_GENERIC_KEYS_MISSING;
return; return none;
} }
return TALER_CRYPTO_helper_denom_sign (ksh->dh, return TALER_CRYPTO_helper_denom_sign (ksh->helpers.dh,
h_denom_pub, h_denom_pub,
msg, msg,
msg_size, msg_size,
@ -1128,7 +1173,7 @@ TEH_keys_denomination_revoke (
GNUNET_break (0); GNUNET_break (0);
return; return;
} }
TALER_CRYPTO_helper_denom_revoke (ksh->dh, TALER_CRYPTO_helper_denom_revoke (ksh->helpers.dh,
h_denom_pub); h_denom_pub);
TEH_keys_update_states (); TEH_keys_update_states ();
} }
@ -1152,7 +1197,7 @@ TEH_keys_exchange_sign_ (const struct
"Cannot sign request, no valid signing keys available.\n"); "Cannot sign request, no valid signing keys available.\n");
return TALER_EC_EXCHANGE_GENERIC_KEYS_MISSING; return TALER_EC_EXCHANGE_GENERIC_KEYS_MISSING;
} }
ec = TALER_CRYPTO_helper_esign_sign_ (ksh->esh, ec = TALER_CRYPTO_helper_esign_sign_ (ksh->helpers.esh,
purpose, purpose,
pub, pub,
sig); sig);
@ -1177,7 +1222,7 @@ TEH_keys_exchange_sign_ (const struct
memset (sig, memset (sig,
0, 0,
sizeof (*sig)); sizeof (*sig));
return TALER_EC_EXCHANGE_KEYS_SIGNKEY_HELPER_BUG; return TALER_EC_EXCHANGE_SIGNKEY_HELPER_BUG;
} }
} }
return ec; return ec;
@ -1195,7 +1240,7 @@ TEH_keys_exchange_revoke (const struct TALER_ExchangePublicKeyP *exchange_pub)
GNUNET_break (0); GNUNET_break (0);
return; return;
} }
TALER_CRYPTO_helper_esign_revoke (ksh->esh, TALER_CRYPTO_helper_esign_revoke (ksh->helpers.esh,
exchange_pub); exchange_pub);
TEH_keys_update_states (); TEH_keys_update_states ();
} }
@ -1225,9 +1270,9 @@ krd_search_comparator (const void *key,
MHD_RESULT MHD_RESULT
TEH_handler_keys (const struct TEH_RequestHandler *rh, TEH_handler_keys_NEW (const struct TEH_RequestHandler *rh,
struct MHD_Connection *connection, struct MHD_Connection *connection,
const char *const args[]) const char *const args[])
{ {
struct GNUNET_TIME_Absolute last_issue_date; struct GNUNET_TIME_Absolute last_issue_date;
struct GNUNET_TIME_Absolute now; struct GNUNET_TIME_Absolute now;
@ -1324,22 +1369,22 @@ TEH_handler_keys (const struct TEH_RequestHandler *rh,
update_keys_response (ksh, update_keys_response (ksh,
now); now);
krd = bsearch (&last_issue_date, krd = bsearch (&last_issue_date,
key_state->krd_array, ksh->krd_array,
key_state->krd_array_length, ksh->krd_array_length,
sizeof (struct KeysResponseData), sizeof (struct KeysResponseData),
&krd_search_comparator); &krd_search_comparator);
GNUNET_log (GNUNET_ERROR_TYPE_INFO, GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Filtering /keys by cherry pick date %s found entry %u/%u\n", "Filtering /keys by cherry pick date %s found entry %u/%u\n",
GNUNET_STRINGS_absolute_time_to_string (last_issue_date), GNUNET_STRINGS_absolute_time_to_string (last_issue_date),
(unsigned int) (krd - key_state->krd_array), (unsigned int) (krd - ksh->krd_array),
key_state->krd_array_length); ksh->krd_array_length);
if ( (NULL == krd) && if ( (NULL == krd) &&
(key_state->krd_array_length > 0) ) (ksh->krd_array_length > 0) )
{ {
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Client provided invalid cherry picking timestamp %s, returning full response\n", "Client provided invalid cherry picking timestamp %s, returning full response\n",
GNUNET_STRINGS_absolute_time_to_string (last_issue_date)); GNUNET_STRINGS_absolute_time_to_string (last_issue_date));
krd = &key_state->krd_array[0]; krd = &ksh->krd_array[0];
} }
if (NULL == krd) if (NULL == krd)
{ {
@ -1348,7 +1393,6 @@ TEH_handler_keys (const struct TEH_RequestHandler *rh,
NOT_FOUND situation. But, OTOH, for 'sane' clients it is more likely NOT_FOUND situation. But, OTOH, for 'sane' clients it is more likely
to be our fault, so let's speculatively assume we are to blame ;-) */// to be our fault, so let's speculatively assume we are to blame ;-) *///
GNUNET_break (0); GNUNET_break (0);
TEH_KS_release (key_state);
return TALER_MHD_reply_with_error (connection, return TALER_MHD_reply_with_error (connection,
MHD_HTTP_INTERNAL_SERVER_ERROR, MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_EXCHANGE_GENERIC_KEYS_MISSING, TALER_EC_EXCHANGE_GENERIC_KEYS_MISSING,
@ -1364,9 +1408,9 @@ TEH_handler_keys (const struct TEH_RequestHandler *rh,
/** /**
* Load fees and expiration times (!) for the denomination type configured * Load fees and expiration times (!) for the denomination type configured in
* in section @a section_name. Before calling this function, the * section @a section_name. Before calling this function, the `start` and
* `start` time must already be initialized in @a meta. * `validity_duration` times must already be initialized in @a meta.
* *
* @param section_name section in the configuration to use * @param section_name section in the configuration to use
* @param[in,out] meta denomination type data to complete * @param[in,out] meta denomination type data to complete
@ -1379,9 +1423,9 @@ TEH_keys_load_fees (const char *section_name,
struct GNUNET_TIME_Relative deposit_duration; struct GNUNET_TIME_Relative deposit_duration;
struct GNUNET_TIME_Relative legal_duration; struct GNUNET_TIME_Relative legal_duration;
GNUNET_assert (0 != meta.start.abs_value_us); /* caller bug */ GNUNET_assert (0 != meta->start.abs_value_us); /* caller bug */
if (GNUNET_OK != if (GNUNET_OK !=
GNUNET_CONFIGURATION_get_value_time (kcfg, GNUNET_CONFIGURATION_get_value_time (TEH_cfg,
section_name, section_name,
"DURATION_SPEND", "DURATION_SPEND",
&deposit_duration)) &deposit_duration))
@ -1392,7 +1436,7 @@ TEH_keys_load_fees (const char *section_name,
return GNUNET_SYSERR; return GNUNET_SYSERR;
} }
if (GNUNET_OK != if (GNUNET_OK !=
GNUNET_CONFIGURATION_get_value_time (kcfg, GNUNET_CONFIGURATION_get_value_time (TEH_cfg,
section_name, section_name,
"DURATION_LEGAL", "DURATION_LEGAL",
&legal_duration)) &legal_duration))
@ -1402,8 +1446,6 @@ TEH_keys_load_fees (const char *section_name,
"DURATION_LEGAL"); "DURATION_LEGAL");
return GNUNET_SYSERR; return GNUNET_SYSERR;
} }
meta->expire_withdraw = GNUNET_TIME_absolute_add (meta->start,
hd->validity_duration);
/* NOTE: this is a change from the 0.8 semantics of the configuration: /* NOTE: this is a change from the 0.8 semantics of the configuration:
before duration_spend was relative to 'start', not to 'expire_withdraw'. before duration_spend was relative to 'start', not to 'expire_withdraw'.
But doing it this way avoids the error case where previously But doing it this way avoids the error case where previously
@ -1537,11 +1579,13 @@ add_future_denomkey_cb (void *cls,
struct TEH_DenominationKey *dk; struct TEH_DenominationKey *dk;
struct TALER_EXCHANGEDB_DenominationKeyMetaData meta; struct TALER_EXCHANGEDB_DenominationKeyMetaData meta;
dk = GNUNET_CONTAINER_multihashmap_get (ksh->denom_map, dk = GNUNET_CONTAINER_multihashmap_get (fbc->ksh->denomkey_map,
h_denom_pub); h_denom_pub);
if (NULL != dk) if (NULL != dk)
return GNUNET_OK; /* skip: this key is already active! */ return GNUNET_OK; /* skip: this key is already active! */
meta.start = hd->start_time; meta.start = hd->start_time;
meta.expire_withdraw = GNUNET_TIME_absolute_add (meta.start,
hd->validity_duration);
if (GNUNET_OK != if (GNUNET_OK !=
TEH_keys_load_fees (hd->section_name, TEH_keys_load_fees (hd->section_name,
&meta)) &meta))
@ -1552,6 +1596,7 @@ add_future_denomkey_cb (void *cls,
GNUNET_assert ( GNUNET_assert (
0 == 0 ==
json_array_append_new ( json_array_append_new (
fbc->denoms,
json_pack ("{s:o, s:o, s:o, s:o, s:o, s:o, s:o, s:o, s:o, s:o, s:o}", json_pack ("{s:o, s:o, s:o, s:o, s:o, s:o, s:o, s:o, s:o, s:o, s:o}",
"value", "value",
TALER_JSON_from_amount (&meta.value), TALER_JSON_from_amount (&meta.value),
@ -1564,7 +1609,7 @@ add_future_denomkey_cb (void *cls,
"stamp_expire_legal", "stamp_expire_legal",
GNUNET_JSON_from_time_abs (meta.expire_legal), GNUNET_JSON_from_time_abs (meta.expire_legal),
"denom_pub", "denom_pub",
GNUNET_JSON_from_rsa_public_key (pk->rsa_public_key), GNUNET_JSON_from_rsa_public_key (dk->denom_pub.rsa_public_key),
"fee_withdraw", "fee_withdraw",
TALER_JSON_from_amount (&meta.fee_withdraw), TALER_JSON_from_amount (&meta.fee_withdraw),
"fee_deposit", "fee_deposit",
@ -1601,16 +1646,17 @@ add_future_signkey_cb (void *cls,
struct GNUNET_TIME_Absolute stamp_expire; struct GNUNET_TIME_Absolute stamp_expire;
struct GNUNET_TIME_Absolute legal_end; struct GNUNET_TIME_Absolute legal_end;
sk = GNUNET_CONTAINER_multipeermap_get (ksh->signkey_map, sk = GNUNET_CONTAINER_multipeermap_get (fbc->ksh->signkey_map,
pid); pid);
if (NULL != sk) if (NULL != sk)
return GNUNET_OK; /* skip: this key is already active */ return GNUNET_OK; /* skip: this key is already active */
stamp_expire = GNUNET_TIME_absolute_add (hsk->start_time, stamp_expire = GNUNET_TIME_absolute_add (hsk->start_time,
hsk->validity_duration); hsk->validity_duration);
legal_end = GNUNET_TIME_absolute_add (stamp_expire, legal_end = GNUNET_TIME_absolute_add (stamp_expire,
TEH_signkey_legal_duration); signkey_legal_duration);
GNUNET_assert (0 == GNUNET_assert (0 ==
json_array_append_new ( json_array_append_new (
fbc->signkeys,
json_pack ("{s:o, s:o, s:o, s:o, s:o}", json_pack ("{s:o, s:o, s:o, s:o, s:o}",
"key", "key",
GNUNET_JSON_from_data_auto (&hsk->exchange_pub), GNUNET_JSON_from_data_auto (&hsk->exchange_pub),
@ -1655,23 +1701,23 @@ TEH_keys_management_get_handler (const struct TEH_RequestHandler *rh,
if (NULL == ksh->management_keys_reply) if (NULL == ksh->management_keys_reply)
{ {
struct FutureBuilderContext fbc = { struct FutureBuilderContext fbc = {
.ksh = ksh .ksh = ksh,
.denoms = json_array (); .denoms = json_array (),
.signkeys = json_array (); .signkeys = json_array ()
}; };
GNUNET_CONTAINER_multihashmap_iterate (ksh->helpers.denom_keys, GNUNET_CONTAINER_multihashmap_iterate (ksh->helpers.denom_keys,
&add_future_denomkey_cb, &add_future_denomkey_cb,
denoms); &fbc);
GNUNET_CONTAINER_multihashmap_iterate (ksh->helpers.esign_keys, GNUNET_CONTAINER_multipeermap_iterate (ksh->helpers.esign_keys,
&add_future_signkey_cb, &add_future_signkey_cb,
signkeys); &fbc);
reply = json_pack ( reply = json_pack (
"{s:o, s:o, s:o, s:o, s:o}", "{s:o, s:o, s:o, s:o, s:o}",
"future_denoms", "future_denoms",
denoms, fbc.denoms,
"future_signkeys", "future_signkeys",
signkeys, fbc.signkeys,
"master_pub", "master_pub",
GNUNET_JSON_from_data_auto (&TEH_master_public_key), GNUNET_JSON_from_data_auto (&TEH_master_public_key),
"denom_secmod_public_key", "denom_secmod_public_key",

View File

@ -167,7 +167,7 @@ enum TALER_ErrorCode
TEH_keys_exchange_sign_ (const struct TEH_keys_exchange_sign_ (const struct
GNUNET_CRYPTO_EccSignaturePurpose *purpose, GNUNET_CRYPTO_EccSignaturePurpose *purpose,
struct TALER_ExchangePublicKeyP *pub, struct TALER_ExchangePublicKeyP *pub,
struct TALER_ExchangeSignatureP *sig) struct TALER_ExchangeSignatureP *sig);
/** /**
@ -245,7 +245,7 @@ TEH_keys_management_get_handler (const struct TEH_RequestHandler *rh,
/** /**
* Load fees and expiration times (!) for the denomination type configured * Load fees and expiration times (!) for the denomination type configured
* in section @a section_name. Before calling this function, the * in section @a section_name. Before calling this function, the
* `start` time must already be initialized in @a meta. * `start` and `validity_duration` times must already be initialized in @a meta.
* *
* @param section_name section in the configuration to use * @param section_name section in the configuration to use
* @param[in,out] meta denomination type data to complete * @param[in,out] meta denomination type data to complete
@ -256,4 +256,19 @@ TEH_keys_load_fees (const char *section_name,
struct TALER_EXCHANGEDB_DenominationKeyMetaData *meta); struct TALER_EXCHANGEDB_DenominationKeyMetaData *meta);
/**
* Initialize keys submodule.
*
* @return #GNUNET_OK on success
*/
int
TEH_keys_init (void);
/**
* Close down keys submodule.
*/
void
TEH_keys_done (void);
#endif #endif