aboutsummaryrefslogtreecommitdiff
path: root/src/mint/taler-mint-httpd_keystate.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mint/taler-mint-httpd_keystate.c')
-rw-r--r--src/mint/taler-mint-httpd_keystate.c116
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 */
309static struct MintKeyState * 315static int
310reload_keys () 316free_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 */
462int 472int
463TALER_MINT_key_reload_loop (void) 473TALER_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
500read_again: 509read_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