diff options
Diffstat (limited to 'src/mint/taler-mint-httpd_keystate.c')
-rw-r--r-- | src/mint/taler-mint-httpd_keystate.c | 116 |
1 files changed, 62 insertions, 54 deletions
diff --git a/src/mint/taler-mint-httpd_keystate.c b/src/mint/taler-mint-httpd_keystate.c index a26e30b90..a66802010 100644 --- a/src/mint/taler-mint-httpd_keystate.c +++ b/src/mint/taler-mint-httpd_keystate.c | |||
@@ -201,7 +201,7 @@ TALER_MINT_conf_duration_provide () | |||
201 | 201 | ||
202 | 202 | ||
203 | /** | 203 | /** |
204 | * Iterator for denomination keys. | 204 | * Iterator for (re)loading/initializing denomination keys. |
205 | * | 205 | * |
206 | * @param cls closure | 206 | * @param cls closure |
207 | * @param dki the denomination key issue | 207 | * @param dki the denomination key issue |
@@ -240,7 +240,8 @@ reload_keys_denom_iter (void *cls, | |||
240 | 240 | ||
241 | res = GNUNET_CONTAINER_multihashmap_put (ctx->denomkey_map, | 241 | res = GNUNET_CONTAINER_multihashmap_put (ctx->denomkey_map, |
242 | &denom_key_hash, | 242 | &denom_key_hash, |
243 | GNUNET_memdup (dki, sizeof (struct TALER_MINT_DenomKeyIssuePriv)), | 243 | GNUNET_memdup (dki, |
244 | sizeof (struct TALER_MINT_DenomKeyIssuePriv)), | ||
244 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); | 245 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); |
245 | if (GNUNET_OK != res) | 246 | if (GNUNET_OK != res) |
246 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 247 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
@@ -302,46 +303,24 @@ reload_keys_sign_iter (void *cls, | |||
302 | 303 | ||
303 | 304 | ||
304 | /** | 305 | /** |
305 | * Load the mint's key state from disk. | 306 | * Iterator for freeing denomination keys. |
306 | * | 307 | * |
307 | * @return fresh key state (with reference count 1) | 308 | * @param cls closure with the `struct MintKeyState` |
309 | * @param key key for the denomination key | ||
310 | * @param alias coin alias | ||
311 | * @return #GNUNET_OK to continue to iterate, | ||
312 | * #GNUNET_NO to stop iteration with no error, | ||
313 | * #GNUNET_SYSERR to abort iteration with error! | ||
308 | */ | 314 | */ |
309 | static struct MintKeyState * | 315 | static int |
310 | reload_keys () | 316 | free_denom_key (void *cls, |
317 | const struct GNUNET_HashCode *key, | ||
318 | void *value) | ||
311 | { | 319 | { |
312 | struct MintKeyState *key_state; | 320 | struct TALER_MINT_DenomKeyIssuePriv *dki = value; |
313 | json_t *keys; | ||
314 | |||
315 | key_state = GNUNET_new (struct MintKeyState); | ||
316 | key_state->refcnt = 1; | ||
317 | |||
318 | key_state->next_reload = GNUNET_TIME_UNIT_FOREVER_ABS; | ||
319 | |||
320 | key_state->denom_keys_array = json_array (); | ||
321 | GNUNET_assert (NULL != key_state->denom_keys_array); | ||
322 | |||
323 | key_state->sign_keys_array = json_array (); | ||
324 | GNUNET_assert (NULL != key_state->sign_keys_array); | ||
325 | |||
326 | key_state->denomkey_map = GNUNET_CONTAINER_multihashmap_create (32, | ||
327 | GNUNET_NO); | ||
328 | GNUNET_assert (NULL != key_state->denomkey_map); | ||
329 | 321 | ||
330 | key_state->reload_time = GNUNET_TIME_absolute_get (); | 322 | GNUNET_free (dki); |
331 | 323 | return GNUNET_OK; | |
332 | TALER_MINT_denomkeys_iterate (mintdir, &reload_keys_denom_iter, key_state); | ||
333 | TALER_MINT_signkeys_iterate (mintdir, &reload_keys_sign_iter, key_state); | ||
334 | |||
335 | keys = json_pack ("{s:o, s:o, s:o, s:o}", | ||
336 | "master_pub", TALER_JSON_from_data (&master_pub, | ||
337 | sizeof (struct GNUNET_CRYPTO_EddsaPublicKey)), | ||
338 | "signkeys", key_state->sign_keys_array, | ||
339 | "denoms", key_state->denom_keys_array, | ||
340 | "list_issue_date", TALER_JSON_from_abs (key_state->reload_time)); | ||
341 | |||
342 | key_state->keys_json = json_dumps (keys, JSON_INDENT(2)); | ||
343 | |||
344 | return key_state; | ||
345 | } | 324 | } |
346 | 325 | ||
347 | 326 | ||
@@ -358,6 +337,12 @@ TALER_MINT_key_state_release (struct MintKeyState *key_state) | |||
358 | key_state->refcnt--; | 337 | key_state->refcnt--; |
359 | if (0 == key_state->refcnt) | 338 | if (0 == key_state->refcnt) |
360 | { | 339 | { |
340 | json_decref (key_state->denom_keys_array); | ||
341 | json_decref (key_state->sign_keys_array); | ||
342 | GNUNET_CONTAINER_multihashmap_iterate (key_state->denomkey_map, | ||
343 | &free_denom_key, | ||
344 | key_state); | ||
345 | GNUNET_CONTAINER_multihashmap_destroy (key_state->denomkey_map); | ||
361 | GNUNET_free (key_state); | 346 | GNUNET_free (key_state); |
362 | } | 347 | } |
363 | GNUNET_assert (0 == pthread_mutex_unlock (&internal_key_state_mutex)); | 348 | GNUNET_assert (0 == pthread_mutex_unlock (&internal_key_state_mutex)); |
@@ -376,19 +361,41 @@ TALER_MINT_key_state_acquire (void) | |||
376 | { | 361 | { |
377 | struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get (); | 362 | struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get (); |
378 | struct MintKeyState *key_state; | 363 | struct MintKeyState *key_state; |
364 | json_t *keys; | ||
379 | 365 | ||
380 | GNUNET_assert (0 == pthread_mutex_lock (&internal_key_state_mutex)); | 366 | GNUNET_assert (0 == pthread_mutex_lock (&internal_key_state_mutex)); |
381 | if (NULL == internal_key_state) | 367 | if (internal_key_state->next_reload.abs_value_us <= now.abs_value_us) |
382 | { | 368 | { |
383 | internal_key_state = reload_keys (); | 369 | TALER_MINT_key_state_release (internal_key_state); |
370 | internal_key_state = NULL; | ||
384 | } | 371 | } |
385 | else if (internal_key_state->next_reload.abs_value_us <= now.abs_value_us) | 372 | if (NULL == internal_key_state) |
386 | { | 373 | { |
387 | GNUNET_assert (0 < internal_key_state->refcnt); | 374 | key_state = GNUNET_new (struct MintKeyState); |
388 | internal_key_state->refcnt--; | 375 | key_state->next_reload = GNUNET_TIME_UNIT_FOREVER_ABS; |
389 | if (0 == internal_key_state->refcnt) | 376 | key_state->denom_keys_array = json_array (); |
390 | GNUNET_free (internal_key_state); | 377 | GNUNET_assert (NULL != key_state->denom_keys_array); |
391 | internal_key_state = reload_keys (); | 378 | key_state->sign_keys_array = json_array (); |
379 | GNUNET_assert (NULL != key_state->sign_keys_array); | ||
380 | key_state->denomkey_map = GNUNET_CONTAINER_multihashmap_create (32, | ||
381 | GNUNET_NO); | ||
382 | key_state->reload_time = GNUNET_TIME_absolute_get (); | ||
383 | TALER_MINT_denomkeys_iterate (mintdir, | ||
384 | &reload_keys_denom_iter, | ||
385 | key_state); | ||
386 | TALER_MINT_signkeys_iterate (mintdir, | ||
387 | &reload_keys_sign_iter, | ||
388 | key_state); | ||
389 | keys = json_pack ("{s:o, s:o, s:o, s:o}", | ||
390 | "master_pub", | ||
391 | TALER_JSON_from_data (&master_pub, | ||
392 | sizeof (struct GNUNET_CRYPTO_EddsaPublicKey)), | ||
393 | "signkeys", key_state->sign_keys_array, | ||
394 | "denoms", key_state->denom_keys_array, | ||
395 | "list_issue_date", TALER_JSON_from_abs (key_state->reload_time)); | ||
396 | key_state->keys_json = json_dumps (keys, | ||
397 | JSON_INDENT(2)); | ||
398 | internal_key_state = key_state; | ||
392 | } | 399 | } |
393 | key_state = internal_key_state; | 400 | key_state = internal_key_state; |
394 | key_state->refcnt++; | 401 | key_state->refcnt++; |
@@ -458,6 +465,9 @@ handle_signal (int signal_number) | |||
458 | /** | 465 | /** |
459 | * Read signals from a pipe in a loop, and reload keys from disk if | 466 | * Read signals from a pipe in a loop, and reload keys from disk if |
460 | * SIGUSR1 is read from the pipe. | 467 | * SIGUSR1 is read from the pipe. |
468 | * | ||
469 | * @return #GNUNET_SYSERR on errors, otherwise does not return | ||
470 | * (FIXME: #3474) | ||
461 | */ | 471 | */ |
462 | int | 472 | int |
463 | TALER_MINT_key_reload_loop (void) | 473 | TALER_MINT_key_reload_loop (void) |
@@ -487,16 +497,15 @@ TALER_MINT_key_reload_loop (void) | |||
487 | 497 | ||
488 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 498 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
489 | "(re-)loading keys\n"); | 499 | "(re-)loading keys\n"); |
490 | GNUNET_assert (0 == pthread_mutex_lock (&internal_key_state_mutex)); | ||
491 | if (NULL != internal_key_state) | 500 | if (NULL != internal_key_state) |
492 | { | 501 | { |
493 | GNUNET_assert (0 != internal_key_state->refcnt); | 502 | GNUNET_assert (0 != internal_key_state->refcnt); |
494 | internal_key_state->refcnt -= 1; | 503 | TALER_MINT_key_state_release (internal_key_state); |
495 | if (0 == internal_key_state->refcnt) | ||
496 | GNUNET_free (internal_key_state); | ||
497 | } | 504 | } |
498 | internal_key_state = reload_keys (); | 505 | /* This will re-initialize 'internal_key_state' with |
499 | GNUNET_assert (0 == pthread_mutex_unlock (&internal_key_state_mutex)); | 506 | an initial refcnt of 1 */ |
507 | (void) TALER_MINT_key_state_acquire (); | ||
508 | |||
500 | read_again: | 509 | read_again: |
501 | errno = 0; | 510 | errno = 0; |
502 | res = read (reload_pipe[0], &c, 1); | 511 | res = read (reload_pipe[0], &c, 1); |
@@ -513,8 +522,7 @@ read_again: | |||
513 | 522 | ||
514 | 523 | ||
515 | /** | 524 | /** |
516 | * Sign the message in @a purpose with the mint's signing | 525 | * Sign the message in @a purpose with the mint's signing key. |
517 | * key. | ||
518 | * | 526 | * |
519 | * @param purpose the message to sign | 527 | * @param purpose the message to sign |
520 | * @param[OUT] sig signature over purpose using current signing key | 528 | * @param[OUT] sig signature over purpose using current signing key |