summaryrefslogtreecommitdiff
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.c530
1 files changed, 342 insertions, 188 deletions
diff --git a/src/mint/taler-mint-httpd_keystate.c b/src/mint/taler-mint-httpd_keystate.c
index 7edae9f7b..c29c5c516 100644
--- a/src/mint/taler-mint-httpd_keystate.c
+++ b/src/mint/taler-mint-httpd_keystate.c
@@ -1,6 +1,6 @@
/*
This file is part of TALER
- Copyright (C) 2014 GNUnet e.V.
+ Copyright (C) 2014, 2015 GNUnet e.V.
TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU Affero General Public License as published by the Free Software
@@ -21,17 +21,73 @@
* @author Christian Grothoff
*/
#include "platform.h"
-#include <gnunet/gnunet_util_lib.h>
#include <pthread.h>
-#include "taler_signatures.h"
#include "taler-mint-httpd_keystate.h"
-#include "taler_util.h"
-#include "taler-mint-httpd_parsing.h"
+
+
+/**
+ * Snapshot of the (coin and signing) keys (including private keys) of
+ * the mint. There can be multiple instances of this struct, as it is
+ * reference counted and only destroyed once the last user is done
+ * with it. The current instance is acquired using
+ * #TALER_MINT_key_state_acquire(). Using this function increases the
+ * reference count. The contents of this structure (except for the
+ * reference counter) should be considered READ-ONLY until it is
+ * ultimately destroyed (as there can be many concurrent users).
+ */
+struct MintKeyState
+{
+ /**
+ * JSON array with denomination keys. (Currently not really used
+ * after initialization.)
+ */
+ json_t *denom_keys_array;
+
+ /**
+ * JSON array with signing keys. (Currently not really used
+ * after initialization.)
+ */
+ json_t *sign_keys_array;
+
+ /**
+ * Cached JSON text that the mint will send for a "/keys" request.
+ * Includes our @e master_pub public key, the signing and
+ * denomination keys as well as the @e reload_time.
+ */
+ char *keys_json;
+
+ /**
+ * Mapping from denomination keys to denomination key issue struct.
+ * Used to lookup the key by hash.
+ */
+ struct GNUNET_CONTAINER_MultiHashMap *denomkey_map;
+
+ /**
+ * When did we initiate the key reloading?
+ */
+ struct GNUNET_TIME_Absolute reload_time;
+
+ /**
+ * When is the next key invalid and we have to reload? (We also
+ * reload on SIGUSR1.)
+ */
+ struct GNUNET_TIME_Absolute next_reload;
+
+ /**
+ * Mint signing key that should be used currently.
+ */
+ struct TALER_MINT_SignKeyIssuePriv current_sign_key_issue;
+
+ /**
+ * Reference count. The struct is released when the RC hits zero.
+ */
+ unsigned int refcnt;
+};
/**
* Mint key state. Never use directly, instead access via
- * #TALER_MINT_key_state_acquire and #TALER_MINT_key_state_release.
+ * #TALER_MINT_key_state_acquire() and #TALER_MINT_key_state_release().
*/
static struct MintKeyState *internal_key_state;
@@ -50,79 +106,48 @@ static int reload_pipe[2];
* Convert the public part of a denomination key issue to a JSON
* object.
*
+ * @param pk public key of the denomination key
* @param dki the denomination key issue
* @return a JSON object describing the denomination key isue (public part)
*/
static json_t *
-denom_key_issue_to_json (const struct TALER_MINT_DenomKeyIssue *dki)
-{
- char *buf;
- size_t buf_len;
- json_t *dk_json = json_object ();
-
- json_object_set_new (dk_json,
- "master_sig",
- TALER_JSON_from_data (&dki->signature,
- sizeof (struct GNUNET_CRYPTO_EddsaSignature)));
- json_object_set_new (dk_json,
- "stamp_start",
- TALER_JSON_from_abs (GNUNET_TIME_absolute_ntoh (dki->start)));
- json_object_set_new (dk_json,
- "stamp_expire_withdraw",
- TALER_JSON_from_abs (GNUNET_TIME_absolute_ntoh (dki->expire_withdraw)));
- json_object_set_new (dk_json,
- "stamp_expire_deposit",
- TALER_JSON_from_abs (GNUNET_TIME_absolute_ntoh (dki->expire_spend)));
-
- buf_len = GNUNET_CRYPTO_rsa_public_key_encode (dki->denom_pub,
- &buf);
- json_object_set_new (dk_json,
- "denom_pub",
- TALER_JSON_from_data (buf,
- buf_len));
- GNUNET_free (buf);
- json_object_set_new (dk_json,
- "value",
- TALER_JSON_from_amount (TALER_amount_ntoh (dki->value)));
- json_object_set_new (dk_json,
- "fee_withdraw",
- TALER_JSON_from_amount (TALER_amount_ntoh (dki->fee_withdraw)));
- json_object_set_new (dk_json,
- "fee_deposit",
- TALER_JSON_from_amount (TALER_amount_ntoh (dki->fee_deposit)));
- json_object_set_new (dk_json,
- "fee_refresh",
- TALER_JSON_from_amount (TALER_amount_ntoh (dki->fee_refresh)));
- return dk_json;
-}
-
-
-/**
- * Convert the public part of a sign key issue to a JSON object.
- *
- * @param ski the sign key issue
- * @return a JSON object describing the sign key isue (public part)
- */
-static json_t *
-sign_key_issue_to_json (const struct TALER_MINT_SignKeyIssue *ski)
+denom_key_issue_to_json (const struct TALER_DenominationPublicKey *pk,
+ const struct TALER_MINT_DenomKeyIssue *dki)
{
- json_t *sk_json = json_object ();
-
- json_object_set_new (sk_json,
- "stamp_start",
- TALER_JSON_from_abs (GNUNET_TIME_absolute_ntoh (ski->start)));
- json_object_set_new (sk_json,
- "stamp_expire",
- TALER_JSON_from_abs (GNUNET_TIME_absolute_ntoh (ski->expire)));
- json_object_set_new (sk_json,
- "master_sig",
- TALER_JSON_from_data (&ski->signature,
- sizeof (struct GNUNET_CRYPTO_EddsaSignature)));
- json_object_set_new (sk_json,
- "key",
- TALER_JSON_from_data (&ski->signkey_pub,
- sizeof (struct GNUNET_CRYPTO_EddsaPublicKey)));
- return sk_json;
+ struct TALER_Amount value;
+ struct TALER_Amount fee_withdraw;
+ struct TALER_Amount fee_deposit;
+ struct TALER_Amount fee_refresh;
+
+ TALER_amount_ntoh (&value,
+ &dki->value);
+ TALER_amount_ntoh (&fee_withdraw,
+ &dki->fee_withdraw);
+ TALER_amount_ntoh (&fee_deposit,
+ &dki->fee_deposit);
+ TALER_amount_ntoh (&fee_refresh,
+ &dki->fee_refresh);
+ return
+ json_pack ("{s:o, s:o, s:o, s:o, s:o, s:o, s:o, s:o, s:o}",
+ "master_sig",
+ TALER_JSON_from_data (&dki->signature,
+ sizeof (struct GNUNET_CRYPTO_EddsaSignature)),
+ "stamp_start",
+ TALER_JSON_from_abs (GNUNET_TIME_absolute_ntoh (dki->start)),
+ "stamp_expire_withdraw",
+ TALER_JSON_from_abs (GNUNET_TIME_absolute_ntoh (dki->expire_withdraw)),
+ "stamp_expire_deposit",
+ TALER_JSON_from_abs (GNUNET_TIME_absolute_ntoh (dki->expire_spend)),
+ "denom_pub",
+ TALER_JSON_from_rsa_public_key (pk->rsa_public_key),
+ "value",
+ TALER_JSON_from_amount (&value),
+ "fee_withdraw",
+ TALER_JSON_from_amount (&fee_withdraw),
+ "fee_deposit",
+ TALER_JSON_from_amount (&fee_deposit),
+ "fee_refresh",
+ TALER_JSON_from_amount (&fee_refresh));
}
@@ -152,7 +177,7 @@ TALER_MINT_conf_duration_provide ()
/**
- * Iterator for denomination keys.
+ * Iterator for (re)loading/initializing denomination keys.
*
* @param cls closure
* @param dki the denomination key issue
@@ -167,47 +192,83 @@ reload_keys_denom_iter (void *cls,
const struct TALER_MINT_DenomKeyIssuePriv *dki)
{
struct MintKeyState *ctx = cls;
- struct GNUNET_TIME_Absolute stamp_provide;
+ struct GNUNET_TIME_Absolute now;
+ struct GNUNET_TIME_Absolute horizon;
struct GNUNET_HashCode denom_key_hash;
+ struct TALER_MINT_DenomKeyIssuePriv *d2;
int res;
- stamp_provide = GNUNET_TIME_absolute_add (ctx->reload_time,
- TALER_MINT_conf_duration_provide ());
-
- if (GNUNET_TIME_absolute_ntoh (dki->issue.expire_spend).abs_value_us < ctx->reload_time.abs_value_us)
+ horizon = GNUNET_TIME_relative_to_absolute (TALER_MINT_conf_duration_provide ());
+ if (GNUNET_TIME_absolute_ntoh (dki->issue.expire_spend).abs_value_us >
+ horizon.abs_value_us)
{
- // this key is expired
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Skipping future denomination key `%s'\n",
+ alias);
return GNUNET_OK;
}
- if (GNUNET_TIME_absolute_ntoh (dki->issue.start).abs_value_us > stamp_provide.abs_value_us)
+ now = GNUNET_TIME_absolute_get ();
+ if (GNUNET_TIME_absolute_ntoh (dki->issue.expire_spend).abs_value_us <
+ now.abs_value_us)
{
- // we are to early for this key
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Skipping expired denomination key `%s'\n",
+ alias);
return GNUNET_OK;
}
- GNUNET_CRYPTO_hash (&dki->issue.denom_pub,
- sizeof (struct GNUNET_CRYPTO_EddsaPublicKey),
- &denom_key_hash);
-
+ GNUNET_CRYPTO_rsa_public_key_hash (dki->denom_pub.rsa_public_key,
+ &denom_key_hash);
+ d2 = GNUNET_memdup (dki,
+ sizeof (struct TALER_MINT_DenomKeyIssuePriv));
res = GNUNET_CONTAINER_multihashmap_put (ctx->denomkey_map,
&denom_key_hash,
- GNUNET_memdup (dki, sizeof (struct TALER_MINT_DenomKeyIssuePriv)),
+ d2,
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
if (GNUNET_OK != res)
+ {
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "Duplicate denomination key\n");
-
+ "Duplicate denomination key `%s'\n",
+ alias);
+ GNUNET_free (d2);
+ return GNUNET_OK;
+ }
json_array_append_new (ctx->denom_keys_array,
- denom_key_issue_to_json (&dki->issue));
-
+ denom_key_issue_to_json (&dki->denom_pub,
+ &dki->issue));
return GNUNET_OK;
}
/**
+ * Convert the public part of a sign key issue to a JSON object.
+ *
+ * @param ski the sign key issue
+ * @return a JSON object describing the sign key isue (public part)
+ */
+static json_t *
+sign_key_issue_to_json (const struct TALER_MINT_SignKeyIssue *ski)
+{
+ return
+ json_pack ("{s:o, s:o, s:o, s:o}",
+ "stamp_start",
+ TALER_JSON_from_abs (GNUNET_TIME_absolute_ntoh (ski->start)),
+ "stamp_expire",
+ TALER_JSON_from_abs (GNUNET_TIME_absolute_ntoh (ski->expire)),
+ "master_sig",
+ TALER_JSON_from_data (&ski->signature,
+ sizeof (struct GNUNET_CRYPTO_EddsaSignature)),
+ "key",
+ TALER_JSON_from_data (&ski->signkey_pub,
+ sizeof (struct GNUNET_CRYPTO_EddsaPublicKey)));
+}
+
+
+/**
* Iterator for sign keys.
*
* @param cls closure
+ * @param filename name of the file the key came from
* @param ski the sign key issue
* @return #GNUNET_OK to continue to iterate,
* #GNUNET_NO to stop iteration with no error,
@@ -215,36 +276,40 @@ reload_keys_denom_iter (void *cls,
*/
static int
reload_keys_sign_iter (void *cls,
+ const char *filename,
const struct TALER_MINT_SignKeyIssuePriv *ski)
{
struct MintKeyState *ctx = cls;
- struct GNUNET_TIME_Absolute stamp_provide;
-
- stamp_provide = GNUNET_TIME_absolute_add (ctx->reload_time,
- TALER_MINT_conf_duration_provide (cfg));
+ struct GNUNET_TIME_Absolute now;
+ struct GNUNET_TIME_Absolute horizon;
- if (GNUNET_TIME_absolute_ntoh (ski->issue.expire).abs_value_us < ctx->reload_time.abs_value_us)
+ horizon = GNUNET_TIME_relative_to_absolute (TALER_MINT_conf_duration_provide ());
+ if (GNUNET_TIME_absolute_ntoh (ski->issue.start).abs_value_us >
+ horizon.abs_value_us)
{
- // this key is expired
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Skipping future signing key `%s'\n",
+ filename);
return GNUNET_OK;
}
-
- if (GNUNET_TIME_absolute_ntoh (ski->issue.start).abs_value_us > stamp_provide.abs_value_us)
+ now = GNUNET_TIME_absolute_get ();
+ if (GNUNET_TIME_absolute_ntoh (ski->issue.expire).abs_value_us <
+ now.abs_value_us)
{
- // we are to early for this key
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Skipping expired signing key `%s'\n",
+ filename);
return GNUNET_OK;
}
- // the signkey is valid for now, check
- // if it's more recent than the current one!
- if (GNUNET_TIME_absolute_ntoh (ctx->current_sign_key_issue.issue.start).abs_value_us >
+ /* The signkey is valid at this time, check if it's more recent than
+ what we have so far! */
+ if (GNUNET_TIME_absolute_ntoh (ctx->current_sign_key_issue.issue.start).abs_value_us <
GNUNET_TIME_absolute_ntoh (ski->issue.start).abs_value_us)
+ {
+ /* We keep the most recent one around */
ctx->current_sign_key_issue = *ski;
-
-
- ctx->next_reload = GNUNET_TIME_absolute_min (ctx->next_reload,
- GNUNET_TIME_absolute_ntoh (ski->issue.expire));
-
+ }
json_array_append_new (ctx->sign_keys_array,
sign_key_issue_to_json (&ski->issue));
@@ -253,46 +318,24 @@ reload_keys_sign_iter (void *cls,
/**
- * Load the mint's key state from disk.
+ * Iterator for freeing denomination keys.
*
- * @return fresh key state (with reference count 1)
+ * @param cls closure with the `struct MintKeyState`
+ * @param key key for the denomination key
+ * @param alias coin alias
+ * @return #GNUNET_OK to continue to iterate,
+ * #GNUNET_NO to stop iteration with no error,
+ * #GNUNET_SYSERR to abort iteration with error!
*/
-static struct MintKeyState *
-reload_keys ()
+static int
+free_denom_key (void *cls,
+ const struct GNUNET_HashCode *key,
+ void *value)
{
- struct MintKeyState *key_state;
- json_t *keys;
-
- key_state = GNUNET_new (struct MintKeyState);
- key_state->refcnt = 1;
-
- key_state->next_reload = GNUNET_TIME_UNIT_FOREVER_ABS;
-
- key_state->denom_keys_array = json_array ();
- GNUNET_assert (NULL != key_state->denom_keys_array);
-
- key_state->sign_keys_array = json_array ();
- GNUNET_assert (NULL != key_state->sign_keys_array);
-
- key_state->denomkey_map = GNUNET_CONTAINER_multihashmap_create (32,
- GNUNET_NO);
- GNUNET_assert (NULL != key_state->denomkey_map);
+ struct TALER_MINT_DenomKeyIssuePriv *dki = value;
- key_state->reload_time = GNUNET_TIME_absolute_get ();
-
- TALER_MINT_denomkeys_iterate (mintdir, &reload_keys_denom_iter, key_state);
- TALER_MINT_signkeys_iterate (mintdir, &reload_keys_sign_iter, key_state);
-
- keys = json_pack ("{s:o, s:o, s:o, s:o}",
- "master_pub", TALER_JSON_from_data (&master_pub,
- sizeof (struct GNUNET_CRYPTO_EddsaPublicKey)),
- "signkeys", key_state->sign_keys_array,
- "denoms", key_state->denom_keys_array,
- "list_issue_date", TALER_JSON_from_abs (key_state->reload_time));
-
- key_state->keys_json = json_dumps (keys, JSON_INDENT(2));
-
- return key_state;
+ GNUNET_free (dki);
+ return GNUNET_OK;
}
@@ -309,6 +352,13 @@ TALER_MINT_key_state_release (struct MintKeyState *key_state)
key_state->refcnt--;
if (0 == key_state->refcnt)
{
+ json_decref (key_state->denom_keys_array);
+ json_decref (key_state->sign_keys_array);
+ GNUNET_CONTAINER_multihashmap_iterate (key_state->denomkey_map,
+ &free_denom_key,
+ key_state);
+ GNUNET_CONTAINER_multihashmap_destroy (key_state->denomkey_map);
+ GNUNET_free (key_state->keys_json);
GNUNET_free (key_state);
}
GNUNET_assert (0 == pthread_mutex_unlock (&internal_key_state_mutex));
@@ -317,8 +367,8 @@ TALER_MINT_key_state_release (struct MintKeyState *key_state)
/**
* Acquire the key state of the mint. Updates keys if necessary.
- * For every call to #TALER_MINT_key_state_acquire, a matching call
- * to #TALER_MINT_key_state_release must be made.
+ * For every call to #TALER_MINT_key_state_acquire(), a matching call
+ * to #TALER_MINT_key_state_release() must be made.
*
* @return the key state
*/
@@ -327,19 +377,64 @@ TALER_MINT_key_state_acquire (void)
{
struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ();
struct MintKeyState *key_state;
+ json_t *keys;
+ char *inner;
+ struct TALER_MINT_KeySetSignature ks;
+ struct TALER_MintSignature sig;
GNUNET_assert (0 == pthread_mutex_lock (&internal_key_state_mutex));
- if (NULL == internal_key_state)
+ if (internal_key_state->next_reload.abs_value_us <= now.abs_value_us)
{
- internal_key_state = reload_keys ();
+ TALER_MINT_key_state_release (internal_key_state);
+ internal_key_state = NULL;
}
- else if (internal_key_state->next_reload.abs_value_us <= now.abs_value_us)
+ if (NULL == internal_key_state)
{
- GNUNET_assert (0 < internal_key_state->refcnt);
- internal_key_state->refcnt--;
- if (0 == internal_key_state->refcnt)
- GNUNET_free (internal_key_state);
- internal_key_state = reload_keys ();
+ key_state = GNUNET_new (struct MintKeyState);
+ key_state->denom_keys_array = json_array ();
+ GNUNET_assert (NULL != key_state->denom_keys_array);
+ key_state->sign_keys_array = json_array ();
+ GNUNET_assert (NULL != key_state->sign_keys_array);
+ key_state->denomkey_map = GNUNET_CONTAINER_multihashmap_create (32,
+ GNUNET_NO);
+ key_state->reload_time = GNUNET_TIME_absolute_get ();
+ TALER_MINT_denomkeys_iterate (mintdir,
+ &reload_keys_denom_iter,
+ key_state);
+ TALER_MINT_signkeys_iterate (mintdir,
+ &reload_keys_sign_iter,
+ key_state);
+ key_state->next_reload = GNUNET_TIME_absolute_ntoh (key_state->current_sign_key_issue.issue.expire);
+ if (0 == key_state->next_reload.abs_value_us)
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "No valid signing key found!\n");
+
+ keys = json_pack ("{s:o, s:o, s:o, s:o}",
+ "master_pub",
+ TALER_JSON_from_data (&master_pub,
+ sizeof (struct GNUNET_CRYPTO_EddsaPublicKey)),
+ "signkeys", key_state->sign_keys_array,
+ "denoms", key_state->denom_keys_array,
+ "list_issue_date", TALER_JSON_from_abs (key_state->reload_time));
+ inner = json_dumps (keys,
+ JSON_INDENT(2));
+ ks.purpose.size = htonl (sizeof (ks));
+ ks.purpose.purpose = htonl (TALER_SIGNATURE_KEYS_SET);
+ ks.list_issue_date = GNUNET_TIME_absolute_hton (key_state->reload_time);
+ GNUNET_CRYPTO_hash (inner,
+ strlen (inner),
+ &ks.hc);
+ GNUNET_free (inner);
+ TALER_MINT_keys_sign (&ks.purpose,
+ &sig);
+ keys = json_pack ("{s:o, s:o}",
+ "keys", keys,
+ "eddsa-signature", TALER_JSON_from_eddsa_sig (&ks.purpose,
+ &sig.eddsa_signature));
+ key_state->keys_json = json_dumps (keys,
+ JSON_INDENT (2));
+ json_decref (keys);
+ internal_key_state = key_state;
}
key_state = internal_key_state;
key_state->refcnt++;
@@ -359,20 +454,14 @@ TALER_MINT_key_state_acquire (void)
*/
struct TALER_MINT_DenomKeyIssuePriv *
TALER_MINT_get_denom_key (const struct MintKeyState *key_state,
- const struct GNUNET_CRYPTO_rsa_PublicKey *denom_pub)
+ const struct TALER_DenominationPublicKey *denom_pub)
{
- struct GNUNET_HashCode hash;
- char *buf;
- size_t buf_len;
-
- buf_len = GNUNET_CRYPTO_rsa_public_key_encode (denom_pub,
- &buf);
- GNUNET_CRYPTO_hash (buf,
- buf_len,
- &hash);
- GNUNET_free (buf);
+ struct GNUNET_HashCode hc;
+
+ GNUNET_CRYPTO_rsa_public_key_hash (denom_pub->rsa_public_key,
+ &hc);
return GNUNET_CONTAINER_multihashmap_get (key_state->denomkey_map,
- &hash);
+ &hc);
}
@@ -390,9 +479,11 @@ handle_signal (int signal_number)
if (SIGUSR1 == signal_number)
{
- errno = 0;
- res = write (reload_pipe[1], &c, 1);
- if ((res < 0) && (EINTR != errno))
+ res = write (reload_pipe[1],
+ &c,
+ 1);
+ if ( (res < 0) &&
+ (EINTR != errno) )
{
GNUNET_break (0);
return;
@@ -409,11 +500,16 @@ handle_signal (int signal_number)
/**
* Read signals from a pipe in a loop, and reload keys from disk if
* SIGUSR1 is read from the pipe.
+ *
+ * @return #GNUNET_SYSERR on errors, otherwise does not return
+ * (FIXME: #3474)
*/
int
TALER_MINT_key_reload_loop (void)
{
struct sigaction act;
+ struct sigaction rec;
+ int ret;
if (0 != pipe (reload_pipe))
{
@@ -421,16 +517,21 @@ TALER_MINT_key_reload_loop (void)
"Failed to create pipe.\n");
return GNUNET_SYSERR;
}
- memset (&act, 0, sizeof (struct sigaction));
+ memset (&act,
+ 0,
+ sizeof (struct sigaction));
act.sa_handler = &handle_signal;
-
- if (0 != sigaction (SIGUSR1, &act, NULL))
+ if (0 != sigaction (SIGUSR1,
+ &act,
+ &rec))
{
fprintf (stderr,
"Failed to set signal handler.\n");
return GNUNET_SYSERR;
}
+ ret = GNUNET_OK;
+ /* FIXME: allow for 'clean' termination or restart (#3474) */
while (1)
{
char c;
@@ -438,52 +539,105 @@ TALER_MINT_key_reload_loop (void)
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"(re-)loading keys\n");
- GNUNET_assert (0 == pthread_mutex_lock (&internal_key_state_mutex));
if (NULL != internal_key_state)
{
- GNUNET_assert (0 != internal_key_state->refcnt);
- internal_key_state->refcnt -= 1;
- if (0 == internal_key_state->refcnt)
- GNUNET_free (internal_key_state);
+ TALER_MINT_key_state_release (internal_key_state);
+ internal_key_state = NULL;
}
- internal_key_state = reload_keys ();
- GNUNET_assert (0 == pthread_mutex_unlock (&internal_key_state_mutex));
+ /* This will re-initialize 'internal_key_state' with
+ an initial refcnt of 1 */
+ (void) TALER_MINT_key_state_acquire ();
+
read_again:
errno = 0;
- res = read (reload_pipe[0], &c, 1);
+ res = read (reload_pipe[0],
+ &c,
+ 1);
if ((res < 0) && (EINTR != errno))
{
GNUNET_break (0);
- return GNUNET_SYSERR;
+ ret = GNUNET_SYSERR;
+ break;
}
if (EINTR == errno)
goto read_again;
}
- return GNUNET_OK;
+
+ if (0 != sigaction (SIGUSR1,
+ &rec,
+ &act))
+ {
+ fprintf (stderr,
+ "Failed to restore signal handler.\n");
+ return GNUNET_SYSERR;
+ }
+ return ret;
}
/**
- * Sign the message in @a purpose with the mint's signing
- * key.
+ * Sign the message in @a purpose with the mint's signing key.
*
* @param purpose the message to sign
* @param[OUT] sig signature over purpose using current signing key
*/
void
TALER_MINT_keys_sign (const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose,
- struct GNUNET_CRYPTO_EddsaSignature *sig)
+ struct TALER_MintSignature *sig)
{
struct MintKeyState *key_state;
key_state = TALER_MINT_key_state_acquire ();
GNUNET_assert (GNUNET_OK ==
- GNUNET_CRYPTO_eddsa_sign (&key_state->current_sign_key_issue.signkey_priv,
+ GNUNET_CRYPTO_eddsa_sign (&key_state->current_sign_key_issue.signkey_priv.eddsa_priv,
purpose,
- sig));
+ &sig->eddsa_signature));
TALER_MINT_key_state_release (key_state);
}
+/**
+ * Function to call to handle the request by sending
+ * back static data from the @a rh.
+ *
+ * @param rh context of the handler
+ * @param connection the MHD connection to handle
+ * @param[IN|OUT] connection_cls the connection's closure (can be updated)
+ * @param upload_data upload data
+ * @param[IN|OUT] upload_data_size number of bytes (left) in @a upload_data
+ * @return MHD result code
+ */
+int
+TALER_MINT_handler_keys (struct RequestHandler *rh,
+ struct MHD_Connection *connection,
+ void **connection_cls,
+ const char *upload_data,
+ size_t *upload_data_size)
+{
+ struct MintKeyState *key_state;
+ struct MHD_Response *response;
+ int ret;
+
+ key_state = TALER_MINT_key_state_acquire ();
+ response = MHD_create_response_from_buffer (strlen (key_state->keys_json),
+ key_state->keys_json,
+ MHD_RESPMEM_MUST_COPY);
+ TALER_MINT_key_state_release (key_state);
+ if (NULL == response)
+ {
+ GNUNET_break (0);
+ return MHD_NO;
+ }
+ (void) MHD_add_response_header (response,
+ "Content-Type",
+ rh->mime_type);
+ ret = MHD_queue_response (connection,
+ rh->response_code,
+ response);
+ MHD_destroy_response (response);
+ return ret;
+}
+
+
/* end of taler-mint-httpd_keystate.c */