gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-exchange] branch master updated: implement auditor's exchange sig


From: gnunet
Subject: [taler-exchange] branch master updated: implement auditor's exchange signing key caching (#6052)
Date: Wed, 05 Feb 2020 21:12:06 +0100

This is an automated email from the git hooks/post-receive script.

grothoff pushed a commit to branch master
in repository exchange.

The following commit(s) were added to refs/heads/master by this push:
     new 9e0a813b implement auditor's exchange signing key caching (#6052)
9e0a813b is described below

commit 9e0a813b38b791a0bc020b8f1ee16d2b5d8712c6
Author: Christian Grothoff <address@hidden>
AuthorDate: Wed Feb 5 21:11:57 2020 +0100

    implement auditor's exchange signing key caching (#6052)
---
 src/auditor/taler-auditor-httpd.c                  |   7 +-
 .../taler-auditor-httpd_deposit-confirmation.c     | 131 +++++++++++++++------
 .../taler-auditor-httpd_deposit-confirmation.h     |  12 ++
 3 files changed, 113 insertions(+), 37 deletions(-)

diff --git a/src/auditor/taler-auditor-httpd.c 
b/src/auditor/taler-auditor-httpd.c
index 4d5537e5..043d5b14 100644
--- a/src/auditor/taler-auditor-httpd.c
+++ b/src/auditor/taler-auditor-httpd.c
@@ -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,7 +635,10 @@ main (int argc,
     fh = TALER_MHD_open_unix_path (serve_unixpath,
                                    unixpath_mode);
     if (-1 == fh)
+    {
+      TEAH_DEPOSIT_CONFIRMATION_done ();
       return 1;
+    }
   }
 
   mhd
@@ -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;
 }
 
diff --git a/src/auditor/taler-auditor-httpd_deposit-confirmation.c 
b/src/auditor/taler-auditor-httpd_deposit-confirmation.c
index 7759b553..87b1a26f 100644
--- a/src/auditor/taler-auditor-httpd_deposit-confirmation.c
+++ b/src/auditor/taler-auditor-httpd_deposit-confirmation.c
@@ -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,40 +91,64 @@ 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;
-  if (GNUNET_OK !=
-      GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MASTER_SIGNING_KEY_VALIDITY,
-                                  &skv.purpose,
-                                  &es->master_sig.eddsa_signature,
-                                  &es->master_public_key.eddsa_pub))
-  {
-    TALER_LOG_WARNING ("Invalid signature on exchange signing key\n");
-    return TALER_MHD_reply_with_error (connection,
-                                       MHD_HTTP_FORBIDDEN,
-                                       
TALER_EC_DEPOSIT_CONFIRMATION_SIGNATURE_INVALID,
-                                       "master_sig");
-  }
 
-  session = TAH_plugin->get_session (TAH_plugin->cls);
-  if (NULL == session)
-  {
-    GNUNET_break (0);
-    return TALER_MHD_reply_with_error (connection,
-                                       MHD_HTTP_INTERNAL_SERVER_ERROR,
-                                       TALER_EC_DB_SETUP_FAILED,
-                                       "failed to establish session with 
database");
-  }
-  /* execute transaction */
-  qs = TAH_plugin->insert_exchange_signkey (TAH_plugin->cls,
-                                            session,
-                                            es);
-  if (0 > qs)
+  /* 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)
   {
-    GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs);
-    TALER_LOG_WARNING ("Failed to store exchange signing key in database\n");
-    return TALER_MHD_reply_with_error (connection,
-                                       MHD_HTTP_INTERNAL_SERVER_ERROR,
-                                       
TALER_EC_AUDITOR_EXCHANGE_STORE_DB_ERROR,
-                                       "failed to persist exchange signing 
key");
+    /* 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,
+                                    &es->master_sig.eddsa_signature,
+                                    &es->master_public_key.eddsa_pub))
+    {
+      TALER_LOG_WARNING ("Invalid signature on exchange signing key\n");
+      return TALER_MHD_reply_with_error (connection,
+                                         MHD_HTTP_FORBIDDEN,
+                                         
TALER_EC_DEPOSIT_CONFIRMATION_SIGNATURE_INVALID,
+                                         "master_sig");
+    }
+
+    session = TAH_plugin->get_session (TAH_plugin->cls);
+    if (NULL == session)
+    {
+      GNUNET_break (0);
+      return TALER_MHD_reply_with_error (connection,
+                                         MHD_HTTP_INTERNAL_SERVER_ERROR,
+                                         TALER_EC_DB_SETUP_FAILED,
+                                         "failed to establish session with 
database");
+    }
+    /* execute transaction */
+    qs = TAH_plugin->insert_exchange_signkey (TAH_plugin->cls,
+                                              session,
+                                              es);
+    if (0 > qs)
+    {
+      GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs);
+      TALER_LOG_WARNING ("Failed to store exchange signing key in database\n");
+      return TALER_MHD_reply_with_error (connection,
+                                         MHD_HTTP_INTERNAL_SERVER_ERROR,
+                                         
TALER_EC_AUDITOR_EXCHANGE_STORE_DB_ERROR,
+                                         "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 */
@@ -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 */
diff --git a/src/auditor/taler-auditor-httpd_deposit-confirmation.h 
b/src/auditor/taler-auditor-httpd_deposit-confirmation.h
index 842eb356..531f3c93 100644
--- a/src/auditor/taler-auditor-httpd_deposit-confirmation.h
+++ b/src/auditor/taler-auditor-httpd_deposit-confirmation.h
@@ -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

-- 
To stop receiving notification emails like this one, please contact
address@hidden.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]