implement auditor's exchange signing key caching (#6052)

This commit is contained in:
Christian Grothoff 2020-02-05 21:11:57 +01:00
parent b332604325
commit 9e0a813b38
No known key found for this signature in database
GPG Key ID: 939E6BE1E29FC3CC
3 changed files with 113 additions and 37 deletions

View File

@ -594,7 +594,7 @@ main (int argc,
if (GNUNET_OK !=
auditor_serve_process_config ())
return 1;
TEAH_DEPOSIT_CONFIRMATION_init ();
/* check for systemd-style FD passing */
listen_pid = getenv ("LISTEN_PID");
listen_fds = getenv ("LISTEN_FDS");
@ -635,8 +635,11 @@ main (int argc,
fh = TALER_MHD_open_unix_path (serve_unixpath,
unixpath_mode);
if (-1 == fh)
{
TEAH_DEPOSIT_CONFIRMATION_done ();
return 1;
}
}
mhd
= MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_PIPE_FOR_SHUTDOWN
@ -659,6 +662,7 @@ main (int argc,
{
fprintf (stderr,
"Failed to start HTTP server.\n");
TEAH_DEPOSIT_CONFIRMATION_done ();
return 1;
}
@ -732,6 +736,7 @@ main (int argc,
break;
}
TALER_AUDITORDB_plugin_unload (TAH_plugin);
TEAH_DEPOSIT_CONFIRMATION_done ();
return (GNUNET_SYSERR == ret) ? 1 : 0;
}

View File

@ -32,6 +32,19 @@
#include "taler-auditor-httpd_deposit-confirmation.h"
/**
* Cache of already verified exchange signing keys. Maps the hash of the
* `struct TALER_ExchangeSigningKeyValidityPS` to the (static) string
* "verified". Access to this map is guarded by the #lock.
*/
static struct GNUNET_CONTAINER_MultiHashMap *cache;
/**
* Lock for operations on #cache.
*/
static pthread_mutex_t lock;
/**
* We have parsed the JSON information about the deposit, do some
* basic sanity checks (especially that the signature on the coin is
@ -55,6 +68,8 @@ verify_and_execute_deposit_confirmation (struct MHD_Connection *connection,
struct TALER_AUDITORDB_Session *session;
enum GNUNET_DB_QueryStatus qs;
struct GNUNET_TIME_Absolute now;
struct GNUNET_HashCode h;
int cached;
now = GNUNET_TIME_absolute_get ();
if ( (es->ep_start.abs_value_us > now.abs_value_us) ||
@ -68,10 +83,6 @@ verify_and_execute_deposit_confirmation (struct MHD_Connection *connection,
"master_sig (expired)");
}
/* TODO (#6052): consider having an in-memory cache of already
verified exchange signing keys, this could save us
a signature check AND a database transaction per
operation. */
/* check exchange signing key signature */
skv.purpose.purpose = htonl (TALER_SIGNATURE_MASTER_SIGNING_KEY_VALIDITY);
skv.purpose.size = htonl (sizeof (struct TALER_ExchangeSigningKeyValidityPS));
@ -80,6 +91,19 @@ verify_and_execute_deposit_confirmation (struct MHD_Connection *connection,
skv.expire = GNUNET_TIME_absolute_hton (es->ep_expire);
skv.end = GNUNET_TIME_absolute_hton (es->ep_end);
skv.signkey_pub = es->exchange_pub;
/* check our cache */
GNUNET_CRYPTO_hash (&skv,
sizeof (skv),
&h);
GNUNET_assert (0 == pthread_mutex_lock (&lock));
cached = GNUNET_CONTAINER_multihashmap_contains (cache,
&h);
GNUNET_assert (0 == pthread_mutex_unlock (&lock));
if (! cached)
{
/* Not in cache, need to verify the signature, persist it, and possibly cache it */
if (GNUNET_OK !=
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MASTER_SIGNING_KEY_VALIDITY,
&skv.purpose,
@ -116,6 +140,17 @@ verify_and_execute_deposit_confirmation (struct MHD_Connection *connection,
"failed to persist exchange signing key");
}
/* Cache it, due to concurreny it might already be in the cache,
so we do not cache it twice but also don't insist on the 'put' to
succeed. */
GNUNET_assert (0 == pthread_mutex_lock (&lock));
(void) GNUNET_CONTAINER_multihashmap_put (cache,
&h,
"verified",
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
GNUNET_assert (0 == pthread_mutex_unlock (&lock));
}
/* check deposit confirmation signature */
dcs.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_DEPOSIT);
dcs.purpose.size = htonl (sizeof (struct TALER_DepositConfirmationPS));
@ -237,4 +272,28 @@ TAH_DEPOSIT_CONFIRMATION_handler (struct TAH_RequestHandler *rh,
}
/**
* Initialize subsystem.
*/
void
TEAH_DEPOSIT_CONFIRMATION_init (void)
{
cache = GNUNET_CONTAINER_multihashmap_create (32,
GNUNET_NO);
GNUNET_assert (0 == pthread_mutex_init (&lock, NULL));
}
/**
* Shut down subsystem.
*/
void
TEAH_DEPOSIT_CONFIRMATION_done (void)
{
GNUNET_CONTAINER_multihashmap_destroy (cache);
cache = NULL;
GNUNET_assert (0 == pthread_mutex_destroy (&lock));
}
/* end of taler-auditor-httpd_deposit-confirmation.c */

View File

@ -25,6 +25,18 @@
#include <microhttpd.h>
#include "taler-auditor-httpd.h"
/**
* Initialize subsystem.
*/
void
TEAH_DEPOSIT_CONFIRMATION_init (void);
/**
* Shut down subsystem.
*/
void
TEAH_DEPOSIT_CONFIRMATION_done (void);
/**
* Handle a "/deposit-confirmation" request. Parses the JSON, and, if