gnunet-svn
[Top][All Lists]
Advanced

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

[taler-exchange] branch master updated: start with testing crypto rsa he


From: gnunet
Subject: [taler-exchange] branch master updated: start with testing crypto rsa helper
Date: Sun, 22 Nov 2020 18:31:35 +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 a9fb94e9 start with testing crypto rsa helper
a9fb94e9 is described below

commit a9fb94e916ba6084997571f03fd6c2b4d557576b
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Sun Nov 22 18:31:33 2020 +0100

    start with testing crypto rsa helper
---
 src/util/.gitignore                |   1 +
 src/util/Makefile.am               |  14 +-
 src/util/crypto_helper.c           | 161 +++++++++++++---
 src/util/taler-helper-crypto-rsa.c | 368 ++++++++++++++++++-------------------
 src/util/taler-helper-crypto-rsa.h |   9 +-
 src/util/test_helper_rsa.c         | 314 +++++++++++++++++++++++++++++++
 src/util/test_helper_rsa.conf      |   9 +
 7 files changed, 657 insertions(+), 219 deletions(-)

diff --git a/src/util/.gitignore b/src/util/.gitignore
index 8409f61d..8a8cc052 100644
--- a/src/util/.gitignore
+++ b/src/util/.gitignore
@@ -1,3 +1,4 @@
 taler-config
 test_payto
 taler-helper-crypto-rsa
+test_helper_rsa
diff --git a/src/util/Makefile.am b/src/util/Makefile.am
index c74fe210..50563438 100644
--- a/src/util/Makefile.am
+++ b/src/util/Makefile.am
@@ -7,7 +7,7 @@ if USE_COVERAGE
 endif
 
 
-libexecdir = $(pkglibdir)/libexec/
+libexecdir = $(libdir)/taler/libexec
 
 pkgcfgdir = $(prefix)/share/taler/config.d/
 
@@ -17,7 +17,8 @@ pkgcfg_DATA = \
 
 EXTRA_DIST = \
   paths.conf \
-  taler-config.in
+  taler-config.in \
+  test_helper_rsa.conf
 
 libexec_PROGRAMS = \
   taler-helper-crypto-rsa
@@ -72,9 +73,12 @@ libtalerutil_la_LDFLAGS = \
   -export-dynamic -no-undefined
 
 
+AM_TESTS_ENVIRONMENT=export TALER_PREFIX=$${TALER_PREFIX:-@libdir@};export 
PATH=$${TALER_PREFIX:-@prefix@}/bin:$$PATH;
+
 check_PROGRAMS = \
  test_amount \
  test_crypto \
+ test_helper_rsa \
  test_payto \
  test_url
 
@@ -100,6 +104,12 @@ test_payto_LDADD = \
   -lgnunetutil \
   libtalerutil.la
 
+test_helper_rsa_SOURCES = \
+  test_helper_rsa.c
+test_helper_rsa_LDADD = \
+  -lgnunetutil \
+  libtalerutil.la
+
 test_url_SOURCES = \
   test_url.c
 test_url_LDADD = \
diff --git a/src/util/crypto_helper.c b/src/util/crypto_helper.c
index 2b0fbe46..c42f01fc 100644
--- a/src/util/crypto_helper.c
+++ b/src/util/crypto_helper.c
@@ -41,6 +41,16 @@ struct TALER_CRYPTO_DenominationHelper
    */
   struct sockaddr_un sa;
 
+  /**
+   * Socket address of this process.
+   */
+  struct sockaddr_un my_sa;
+
+  /**
+   * Template for @e my_sa.
+   */
+  char *template;
+
   /**
    * The UNIX domain socket, -1 if we are currently not connected.
    */
@@ -58,6 +68,10 @@ static void
 do_disconnect (struct TALER_CRYPTO_DenominationHelper *dh)
 {
   GNUNET_break (0 == close (dh->sock));
+  if (0 != unlink (dh->my_sa.sun_path))
+    GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
+                              "unlink",
+                              dh->my_sa.sun_path);
   dh->sock = -1;
 }
 
@@ -82,18 +96,73 @@ try_connect (struct TALER_CRYPTO_DenominationHelper *dh)
                          "socket");
     return;
   }
-  if (0 != connect (dh->sock,
-                    (const struct sockaddr *) &dh->sa,
-                    sizeof (dh->sa)))
   {
-    if (EINPROGRESS != dh->sock)
+    char *tmpdir;
+
+    tmpdir = GNUNET_DISK_mktemp (dh->template);
+    if (NULL == tmpdir)
     {
-      GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
-                           "connect");
       do_disconnect (dh);
       return;
     }
+    /* we use >= here because we want the sun_path to always
+       be 0-terminated */
+    if (strlen (tmpdir) >= sizeof (dh->sa.sun_path))
+    {
+      GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
+                                 "PATHS",
+                                 "TALER_RUNTIME_DIR",
+                                 "path too long");
+      GNUNET_free (tmpdir);
+      do_disconnect (dh);
+      return;
+    }
+    dh->my_sa.sun_family = AF_UNIX;
+    strncpy (dh->my_sa.sun_path,
+             tmpdir,
+             sizeof (dh->sa.sun_path));
+    if (0 != unlink (tmpdir))
+      GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
+                                "unlink",
+                                tmpdir);
+    GNUNET_free (tmpdir);
   }
+  if (0 != bind (dh->sock,
+                 (const struct sockaddr *) &dh->my_sa,
+                 sizeof (dh->my_sa)))
+  {
+    GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
+                         "bind");
+    do_disconnect (dh);
+    return;
+  }
+  {
+    struct GNUNET_MessageHeader hdr = {
+      .size = htons (sizeof (hdr)),
+      .type = htons (TALER_HELPER_RSA_MT_REQ_INIT)
+    };
+    ssize_t ret;
+
+    ret = sendto (dh->sock,
+                  &hdr,
+                  sizeof (hdr),
+                  0,
+                  (const struct sockaddr *) &dh->sa,
+                  sizeof (dh->sa));
+    if (ret < 0)
+    {
+      GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
+                                "sendto",
+                                dh->sa.sun_path);
+      do_disconnect (dh);
+      return;
+    }
+    /* We are using SOCK_DGRAM, partial writes should not be possible */
+    GNUNET_break (((size_t) ret) == sizeof (hdr));
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "Successfully sent REQ_INIT\n");
+  }
+
 }
 
 
@@ -117,7 +186,9 @@ TALER_CRYPTO_helper_denom_connect (
                                "UNIXPATH");
     return NULL;
   }
-  if (strlen (unixpath) > sizeof (dh->sa.sun_path))
+  /* we use >= here because we want the sun_path to always
+     be 0-terminated */
+  if (strlen (unixpath) >= sizeof (dh->sa.sun_path))
   {
     GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
                                "taler-helper-crypto-rsa",
@@ -129,10 +200,39 @@ TALER_CRYPTO_helper_denom_connect (
   dh = GNUNET_new (struct TALER_CRYPTO_DenominationHelper);
   dh->dkc = dkc;
   dh->dkc_cls = dkc_cls;
+  dh->sa.sun_family = AF_UNIX;
   strncpy (dh->sa.sun_path,
            unixpath,
            sizeof (dh->sa.sun_path));
   dh->sock = -1;
+  {
+    char *tmpdir;
+    char *template;
+
+    if (GNUNET_OK !=
+        GNUNET_CONFIGURATION_get_value_filename (cfg,
+                                                 "PATHS",
+                                                 "TALER_RUNTIME_DIR",
+                                                 &tmpdir))
+    {
+      GNUNET_log_config_missing (GNUNET_ERROR_TYPE_WARNING,
+                                 "PATHS",
+                                 "TALER_RUNTIME_DIR");
+      tmpdir = GNUNET_strdup ("/tmp");
+    }
+    GNUNET_asprintf (&template,
+                     "%s/crypto-rsa-client/XXXXXX",
+                     tmpdir);
+    GNUNET_free (tmpdir);
+    if (GNUNET_OK !=
+        GNUNET_DISK_directory_create_for_file (template))
+    {
+      GNUNET_free (dh);
+      GNUNET_free (template);
+      return NULL;
+    }
+    dh->template = template;
+  }
   TALER_CRYPTO_helper_poll (dh);
   return dh;
 }
@@ -157,6 +257,8 @@ TALER_CRYPTO_helper_poll (struct 
TALER_CRYPTO_DenominationHelper *dh)
                 MSG_DONTWAIT);
     if (ret < 0)
     {
+      if (EAGAIN == errno)
+        break;
       GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
                            "recv");
       do_disconnect (dh);
@@ -180,10 +282,22 @@ TALER_CRYPTO_helper_poll (struct 
TALER_CRYPTO_DenominationHelper *dh)
         struct TALER_DenominationPublicKey denom_pub;
         struct GNUNET_HashCode h_denom_pub;
 
-        if ( (sizeof (*kan) < ret) ||
-             (sizeof (*kan) + ntohs (kan->pub_size) + ntohs (
-                kan->section_name_len)) ||
-             ('\0' != buf[ret - 1]) )
+        if (sizeof (*kan) > ret)
+        {
+          GNUNET_break_op (0);
+          do_disconnect (dh);
+          return;
+        }
+        if (ret !=
+            sizeof (*kan)
+            + ntohs (kan->pub_size)
+            + ntohs (kan->section_name_len))
+        {
+          GNUNET_break_op (0);
+          do_disconnect (dh);
+          return;
+        }
+        if ('\0' != buf[ret - 1])
         {
           GNUNET_break_op (0);
           do_disconnect (dh);
@@ -267,14 +381,16 @@ TALER_CRYPTO_helper_denom_sign (
     memcpy (&sr[1],
             msg,
             msg_size);
-    ret = send (dh->sock,
-                buf,
-                sizeof (buf),
-                0);
+    ret = sendto (dh->sock,
+                  buf,
+                  sizeof (buf),
+                  0,
+                  &dh->sa,
+                  sizeof (dh->sa));
     if (ret < 0)
     {
       GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
-                           "send");
+                           "sendto");
       do_disconnect (dh);
       *ec = TALER_EC_EXCHANGE_DENOMINATION_HELPER_UNAVAILABLE;
       return ds;
@@ -378,14 +494,16 @@ TALER_CRYPTO_helper_denom_revoke (
   try_connect (dh);
   if (-1 == dh->sock)
     return; /* give up */
-  ret = send (dh->sock,
-              &rr,
-              sizeof (rr),
-              0);
+  ret = sendto (dh->sock,
+                &rr,
+                sizeof (rr),
+                0,
+                (const struct sockaddr *) &dh->sa,
+                sizeof (dh->sa));
   if (ret < 0)
   {
     GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
-                         "send");
+                         "sendto");
     do_disconnect (dh);
     return;
   }
@@ -399,6 +517,7 @@ TALER_CRYPTO_helper_denom_disconnect (
   struct TALER_CRYPTO_DenominationHelper *dh)
 {
   do_disconnect (dh);
+  GNUNET_free (dh->template);
   GNUNET_free (dh);
 }
 
diff --git a/src/util/taler-helper-crypto-rsa.c 
b/src/util/taler-helper-crypto-rsa.c
index 92485571..2d57fe75 100644
--- a/src/util/taler-helper-crypto-rsa.c
+++ b/src/util/taler-helper-crypto-rsa.c
@@ -92,7 +92,7 @@ struct DenominationKey
   /**
    * Hash of this denomination's public key.
    */
-  struct GNUNET_HashCode h_pub;
+  struct GNUNET_HashCode h_denom_pub;
 
   /**
    * Time at which this key is supposed to become valid.
@@ -181,26 +181,14 @@ struct Client
   struct Client *prev;
 
   /**
-   * Work created by this client, NULL for none.
+   * Client address.
    */
-  struct WorkItem *work;
+  struct sockaddr_un addr;
 
   /**
-   * Client socket.
+   * Number of bytes used in @e addr.
    */
-  struct GNUNET_NETWORK_Handle *sock;
-
-  /**
-   * Client task to read from @e sock. NULL if we are working.
-   */
-  struct GNUNET_SCHEDULER_Task *task;
-
-  /**
-   * Flag set to true if this client has disconnected. Used
-   * by the workers to detect that they must free the client
-   * instead of returning the result.
-   */
-  bool gone;
+  socklen_t addr_size;
 
 };
 
@@ -218,11 +206,6 @@ struct WorkItem
    */
   struct WorkItem *prev;
 
-  /**
-   * The client that created the request.
-   */
-  struct Client *client;
-
   /**
    * Key to be used for this operation.
    */
@@ -244,6 +227,16 @@ struct WorkItem
    */
   size_t blinded_msg_size;
 
+  /**
+   * Client address.
+   */
+  struct sockaddr_un addr;
+
+  /**
+   * Number of bytes used in @e addr.
+   */
+  socklen_t addr_size;
+
 };
 
 
@@ -305,7 +298,7 @@ static struct GNUNET_CONTAINER_MultiHashMap *keys;
 /**
  * Our listen socket.
  */
-static struct GNUNET_NETWORK_Handle *lsock;
+static struct GNUNET_NETWORK_Handle *unix_sock;
 
 /**
  * Path where we are listening.
@@ -315,7 +308,7 @@ static char *unixpath;
 /**
  * Task run to accept new inbound connections.
  */
-static struct GNUNET_SCHEDULER_Task *accept_task;
+static struct GNUNET_SCHEDULER_Task *read_task;
 
 /**
  * Task run to generate new keys.
@@ -464,20 +457,10 @@ sign_worker (void *cls)
 static void
 free_client (struct Client *client)
 {
-  if (NULL != client->task)
-  {
-    GNUNET_SCHEDULER_cancel (client->task);
-    client->task = NULL;
-  }
-  GNUNET_NETWORK_socket_close (client->sock);
-  client->sock = NULL;
   GNUNET_CONTAINER_DLL_remove (clients_head,
                                clients_tail,
                                client);
-  if (NULL != client->work)
-    client->gone = true;
-  else
-    GNUNET_free (client);
+  GNUNET_free (client);
 }
 
 
@@ -490,21 +473,6 @@ static void
 read_job (void *cls);
 
 
-/**
- * Start reading requests from the @a client.
- *
- * @param client client to read requests from.
- */
-static void
-client_next (struct Client *client)
-{
-  client->task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
-                                                client->sock,
-                                                &read_job,
-                                                client);
-}
-
-
 /**
  * Free @a dk. It must already have been removed from #keys and the
  * denomination's DLL.
@@ -524,25 +492,27 @@ free_dk (struct DenominationKey *dk)
 /**
  * Send a message starting with @a hdr to @a client.
  *
- * @param client where to send @a hdr
+ * @param addr address where to send the message
+ * @param addr_size number of bytes in @a addr
  * @param hdr beginning of the message, length indicated in size field
  * @return #GNUNET_OK on success
  */
 static int
-transmit_to_client (struct Client *client,
-                    const struct GNUNET_MessageHeader *hdr)
+transmit (const struct sockaddr_un *addr,
+          socklen_t addr_size,
+          const struct GNUNET_MessageHeader *hdr)
 {
   ssize_t ret;
 
-  ret = send (GNUNET_NETWORK_get_fd (client->sock),
-              hdr,
-              ntohs (hdr->size),
-              0);
+  ret = GNUNET_NETWORK_socket_sendto (unix_sock,
+                                      hdr,
+                                      ntohs (hdr->size),
+                                      (const struct sockaddr *) addr,
+                                      addr_size);
   if (ret != ntohs (hdr->size))
   {
-    GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
-                         "send");
-    free_client (client);
+    GNUNET_log_strerror (GNUNET_ERROR_TYPE_INFO,
+                         "sendto");
     return GNUNET_SYSERR;
   }
   return GNUNET_OK;
@@ -598,8 +568,9 @@ handle_done (void *cls)
               buf,
               buf_size);
       GNUNET_free (buf);
-      (void) transmit_to_client (wi->client,
-                                 &sr->header);
+      (void) transmit (&wi->addr,
+                       wi->addr_size,
+                       &sr->header);
       GNUNET_free (sr);
     }
     GNUNET_free (wi);
@@ -615,11 +586,13 @@ handle_done (void *cls)
  * signature using the respective key and return the result to
  * the client.
  *
- * @param client the client making the request
+ * @param addr address of the client making the request
+ * @param addr_size number of bytes in @a addr
  * @param sr the request details
  */
 static void
-handle_sign_request (struct Client *client,
+handle_sign_request (const struct sockaddr_un *addr,
+                     socklen_t addr_size,
                      const struct TALER_CRYPTO_SignRequest *sr)
 {
   struct DenominationKey *dk;
@@ -638,15 +611,17 @@ handle_sign_request (struct Client *client,
     };
 
     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-                "Signing request failed, denomination key unknown\n");
-    transmit_to_client (client,
-                        &sf.header);
-    client_next (client);
+                "Signing request failed, denomination key %s unknown\n",
+                GNUNET_h2s (&sr->h_denom_pub));
+    (void) transmit (addr,
+                     addr_size,
+                     &sf.header);
     return;
   }
 
   wi = GNUNET_new (struct WorkItem);
-  wi->client = client;
+  wi->addr = *addr;
+  wi->addr_size = addr_size;
   wi->dk = dk;
   dk->rc++;
   wi->blinded_msg = GNUNET_memdup (blinded_msg,
@@ -680,7 +655,6 @@ notify_client_dk_add (struct Client *client,
   void *buf;
   void *p;
   size_t tlen;
-  int ret;
 
   buf_len = GNUNET_CRYPTO_rsa_public_key_encode (dk->denom_pub.rsa_public_key,
                                                  &buf);
@@ -703,10 +677,23 @@ notify_client_dk_add (struct Client *client,
   memcpy (p + buf_len,
           denom->section,
           nlen);
-  ret = transmit_to_client (client,
-                            &an->header);
-  GNUNET_free (an);
-  return ret;
+  {
+    int ret = GNUNET_OK;
+
+    if (GNUNET_OK !=
+        transmit (&client->addr,
+                  client->addr_size,
+                  &an->header))
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                  "Client %s must have disconnected\n",
+                  client->addr.sun_path);
+      free_client (client);
+      ret = GNUNET_SYSERR;
+    }
+    GNUNET_free (an);
+    return ret;
+  }
 }
 
 
@@ -724,11 +711,21 @@ notify_client_dk_del (struct Client *client,
   struct TALER_CRYPTO_RsaKeyPurgeNotification pn = {
     .header.type = htons (TALER_HELPER_RSA_MT_PURGE),
     .header.size = htons (sizeof (pn)),
-    .h_denom_pub = dk->h_pub
+    .h_denom_pub = dk->h_denom_pub
   };
 
-  return transmit_to_client (client,
-                             &pn.header);
+  if (GNUNET_OK !=
+      transmit (&client->addr,
+                client->addr_size,
+                &pn.header))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                "Client %s must have disconnected\n",
+                client->addr.sun_path);
+    free_client (client);
+    return GNUNET_SYSERR;
+  }
+  return GNUNET_OK;
 }
 
 
@@ -767,7 +764,7 @@ setup_key (struct DenominationKey *dk,
   buf_size = GNUNET_CRYPTO_rsa_private_key_encode (priv,
                                                    &buf);
   GNUNET_CRYPTO_rsa_public_key_hash (pub,
-                                     &dk->h_pub);
+                                     &dk->h_denom_pub);
   GNUNET_asprintf (&dk->filename,
                    "%s/%s/%llu",
                    keydir,
@@ -789,13 +786,17 @@ setup_key (struct DenominationKey *dk,
     return GNUNET_SYSERR;
   }
   GNUNET_free (buf);
+  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+              "Setup fresh private key %s in `%s'\n",
+              GNUNET_h2s (&dk->h_denom_pub),
+              dk->filename);
   dk->denom_priv.rsa_private_key = priv;
   dk->denom_pub.rsa_public_key = pub;
 
   if (GNUNET_OK !=
       GNUNET_CONTAINER_multihashmap_put (
         keys,
-        &dk->h_pub,
+        &dk->h_denom_pub,
         dk,
         GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
   {
@@ -839,11 +840,13 @@ setup_key (struct DenominationKey *dk,
  * Check if the key is still in use, and if so replace (!)
  * it with a fresh key.
  *
- * @param client the client sending the request
+ * @param addr address of the client making the request
+ * @param addr_size number of bytes in @a addr
  * @param rr the revocation request
  */
 static void
-handle_revoke_request (struct Client *client,
+handle_revoke_request (const struct sockaddr_un *addr,
+                       socklen_t addr_size,
                        const struct TALER_CRYPTO_RevokeRequest *rr)
 {
   struct DenominationKey *dk;
@@ -854,9 +857,9 @@ handle_revoke_request (struct Client *client,
                                           &rr->h_denom_pub);
   if (NULL == dk)
   {
-    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-                "Revocation request ignored, denomination key unknown\n");
-    client_next (client);
+    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                "Revocation request ignored, denomination key %s unknown\n",
+                GNUNET_h2s (&rr->h_denom_pub));
     return;
   }
 
@@ -886,11 +889,13 @@ handle_revoke_request (struct Client *client,
   GNUNET_assert (GNUNET_OK ==
                  GNUNET_CONTAINER_multihashmap_remove (
                    keys,
-                   &dk->h_pub,
+                   &dk->h_denom_pub,
                    dk));
   GNUNET_CONTAINER_DLL_remove (denom->keys_head,
                                denom->keys_tail,
                                dk);
+  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+              "Revocation complete\n");
 
   /* Tell clients this key is gone */
   {
@@ -910,8 +915,6 @@ handle_revoke_request (struct Client *client,
   }
   if (0 == dk->rc)
     free_dk (dk);
-
-  client_next (client);
 }
 
 
@@ -921,129 +924,107 @@ read_job (void *cls)
   struct Client *client = cls;
   char buf[65536];
   ssize_t buf_size;
-  struct GNUNET_MessageHeader hdr;
+  const struct GNUNET_MessageHeader *hdr;
+  struct sockaddr_un addr;
+  socklen_t addr_size = sizeof (addr);
 
-  client->task = NULL;
-  buf_size = GNUNET_NETWORK_socket_recv (client->sock,
-                                         buf,
-                                         sizeof (buf));
+  read_task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
+                                             unix_sock,
+                                             &read_job,
+                                             NULL);
+  buf_size = GNUNET_NETWORK_socket_recvfrom (unix_sock,
+                                             buf,
+                                             sizeof (buf),
+                                             (struct sockaddr *) &addr,
+                                             &addr_size);
   if (-1 == buf_size)
   {
-    if (EAGAIN == errno)
-    {
-      client_next (client);
-      return;
-    }
     GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
                          "recv");
-    free_client (client);
     return;
   }
   if (0 == buf_size)
   {
-    free_client (client);
     return;
   }
-  if (buf_size < sizeof (hdr))
+  if (buf_size < sizeof (struct GNUNET_MessageHeader))
   {
     GNUNET_break_op (0);
-    free_client (client);
     return;
   }
-  memcpy (&hdr,
-          buf,
-          sizeof (hdr));
-  if (ntohs (hdr.size) != buf_size)
+  hdr = (const struct GNUNET_MessageHeader *) buf;
+  if (ntohs (hdr->size) != buf_size)
   {
     GNUNET_break_op (0);
     free_client (client);
     return;
   }
-  switch (ntohs (hdr.type))
+  switch (ntohs (hdr->type))
   {
+  case TALER_HELPER_RSA_MT_REQ_INIT:
+    if (ntohs (hdr->size) != sizeof (struct GNUNET_MessageHeader))
+    {
+      GNUNET_break_op (0);
+      return;
+    }
+    {
+      struct Client *client;
+
+      client = GNUNET_new (struct Client);
+      client->addr = addr;
+      client->addr_size = addr_size;
+      GNUNET_CONTAINER_DLL_insert (clients_head,
+                                   clients_tail,
+                                   client);
+      for (struct Denomination *denom = denom_head;
+           NULL != denom;
+           denom = denom->next)
+      {
+        for (struct DenominationKey *dk = denom->keys_head;
+             NULL != dk;
+             dk = dk->next)
+        {
+          if (GNUNET_OK !=
+              notify_client_dk_add (client,
+                                    dk))
+          {
+            /* client died, skip the rest */
+            client = NULL;
+            break;
+          }
+        }
+        if (NULL == client)
+          break;
+      }
+    }
+    break;
   case TALER_HELPER_RSA_MT_REQ_SIGN:
-    if (ntohs (hdr.size) <= sizeof (struct TALER_CRYPTO_SignRequest))
+    if (ntohs (hdr->size) <= sizeof (struct TALER_CRYPTO_SignRequest))
     {
       GNUNET_break_op (0);
-      free_client (client);
       return;
     }
-    handle_sign_request (client,
-                         (const struct TALER_CRYPTO_SignRequest *) &hdr);
+    handle_sign_request (&addr,
+                         addr_size,
+                         (const struct TALER_CRYPTO_SignRequest *) buf);
     break;
   case TALER_HELPER_RSA_MT_REQ_REVOKE:
-    if (ntohs (hdr.size) != sizeof (struct TALER_CRYPTO_RevokeRequest))
+    if (ntohs (hdr->size) != sizeof (struct TALER_CRYPTO_RevokeRequest))
     {
       GNUNET_break_op (0);
-      free_client (client);
       return;
     }
-    handle_revoke_request (client,
-                           (const struct TALER_CRYPTO_RevokeRequest *) &hdr);
+    handle_revoke_request (&addr,
+                           addr_size,
+                           (const struct TALER_CRYPTO_RevokeRequest *) buf);
     break;
   default:
     GNUNET_break_op (0);
-    free_client (client);
     return;
   }
 }
 
 
-/**
- * Function run to accept incoming connections on #sock.
- *
- * @param cls NULL
- */
-static void
-accept_job (void *cls)
-{
-  struct GNUNET_NETWORK_Handle *sock;
-  struct sockaddr_storage addr;
-  socklen_t alen;
-
-  accept_task = NULL;
-  alen = sizeof (addr);
-  sock = GNUNET_NETWORK_socket_accept (lsock,
-                                       (struct sockaddr *) &addr,
-                                       &alen);
-  if (NULL != sock)
-  {
-    struct Client *client;
-
-    client = GNUNET_new (struct Client);
-    client->sock = sock;
-    GNUNET_CONTAINER_DLL_insert (clients_head,
-                                 clients_tail,
-                                 client);
-    client_next (client);
-    for (struct Denomination *denom = denom_head;
-         NULL != denom;
-         denom = denom->next)
-    {
-      for (struct DenominationKey *dk = denom->keys_head;
-           NULL != dk;
-           dk = dk->next)
-      {
-        if (GNUNET_OK !=
-            notify_client_dk_add (client,
-                                  dk))
-        {
-          /* client died, skip the rest */
-          client = NULL;
-          break;
-        }
-      }
-      if (NULL == client)
-        break;
-    }
-  }
-  accept_task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
-                                               lsock,
-                                               &accept_job,
-                                               NULL);
-}
-
-
 /**
  * Create a new denomination key (we do not have enough).
  *
@@ -1137,7 +1118,7 @@ purge_key (struct DenominationKey *dk)
                                dk);
   GNUNET_assert (GNUNET_OK ==
                  GNUNET_CONTAINER_multihashmap_remove (keys,
-                                                       &dk->h_pub,
+                                                       &dk->h_denom_pub,
                                                        dk));
   if (0 != unlink (dk->filename))
   {
@@ -1325,17 +1306,18 @@ parse_key (struct Denomination *denom,
     dk->anchor = anchor;
     dk->filename = GNUNET_strdup (filename);
     GNUNET_CRYPTO_rsa_public_key_hash (pub,
-                                       &dk->h_pub);
+                                       &dk->h_denom_pub);
     dk->denom_pub.rsa_public_key = pub;
     if (GNUNET_OK !=
         GNUNET_CONTAINER_multihashmap_put (
           keys,
-          &dk->h_pub,
+          &dk->h_denom_pub,
           dk,
           GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
     {
       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  "Duplicate private key detected in file `%s'. Skipping.\n",
+                  "Duplicate private key %s detected in file `%s'. 
Skipping.\n",
+                  GNUNET_h2s (&dk->h_denom_pub),
                   filename);
       GNUNET_CRYPTO_rsa_private_key_free (priv);
       GNUNET_CRYPTO_rsa_public_key_free (pub);
@@ -1355,8 +1337,9 @@ parse_key (struct Denomination *denom,
                                        denom->keys_tail,
                                        before,
                                        dk);
-    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                "Imported key from `%s'\n",
+    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                "Imported key %s from `%s'\n",
+                GNUNET_h2s (&dk->h_denom_pub),
                 filename);
   }
 }
@@ -1566,7 +1549,7 @@ load_denominations (void *cls,
     GNUNET_free (denom);
     return;
   }
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
               "Loading keys for denomination %s\n",
               denom->section);
   {
@@ -1576,6 +1559,8 @@ load_denominations (void *cls,
                      "%s/%s",
                      keydir,
                      denom->section);
+    GNUNET_break (GNUNET_OK ==
+                  GNUNET_DISK_directory_create (dname));
     GNUNET_DISK_directory_scan (dname,
                                 &import_key,
                                 denom);
@@ -1611,17 +1596,16 @@ load_durations (void)
 
   if (GNUNET_OK !=
       GNUNET_CONFIGURATION_get_value_time (kcfg,
-                                           "exchange",
+                                           "taler-helper-crypto-rsa",
                                            "LOOKAHEAD_SIGN",
                                            &lookahead_sign))
   {
     GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
-                               "exchange",
+                               "taler-helper-crypto-rsa",
                                "LOOKAHEAD_SIGN");
     return GNUNET_SYSERR;
   }
   GNUNET_TIME_round_rel (&lookahead_sign);
-
   return GNUNET_OK;
 }
 
@@ -1635,16 +1619,16 @@ static void
 do_shutdown (void *cls)
 {
   (void) cls;
-  if (NULL != accept_task)
+  if (NULL != read_task)
   {
-    GNUNET_SCHEDULER_cancel (accept_task);
-    accept_task = NULL;
+    GNUNET_SCHEDULER_cancel (read_task);
+    read_task = NULL;
   }
-  if (NULL != lsock)
+  if (NULL != unix_sock)
   {
     GNUNET_break (GNUNET_OK ==
-                  GNUNET_NETWORK_socket_close (lsock));
-    lsock = NULL;
+                  GNUNET_NETWORK_socket_close (unix_sock));
+    unix_sock = NULL;
   }
   if (0 != unlink (unixpath))
   {
@@ -1790,7 +1774,7 @@ run (void *cls,
         return;
       }
     }
-    lsock = GNUNET_NETWORK_socket_box_native (sock);
+    unix_sock = GNUNET_NETWORK_socket_box_native (sock);
   }
 
   GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
@@ -1823,10 +1807,10 @@ run (void *cls,
   }
 
   /* start job to accept incoming requests on 'sock' */
-  accept_task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
-                                               lsock,
-                                               &accept_job,
-                                               NULL);
+  read_task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
+                                             unix_sock,
+                                             &read_job,
+                                             NULL);
 
   /* start job to keep keys up-to-date */
   keygen_task = GNUNET_SCHEDULER_add_now (&update_denominations,
@@ -1893,7 +1877,7 @@ main (int argc,
   /* force linker to link against libtalerutil; if we do
    not do this, the linker may "optimize" libtalerutil
    away and skip #TALER_OS_init(), which we do need */
-  (void) TALER_project_data_default ();
+  GNUNET_OS_init (TALER_project_data_default ());
   GNUNET_assert (GNUNET_OK ==
                  GNUNET_log_setup ("taler-helper-crypto-rsa",
                                    "WARNING",
diff --git a/src/util/taler-helper-crypto-rsa.h 
b/src/util/taler-helper-crypto-rsa.h
index a80c32e6..d2bc07f7 100644
--- a/src/util/taler-helper-crypto-rsa.h
+++ b/src/util/taler-helper-crypto-rsa.h
@@ -24,11 +24,12 @@
 #define TALER_HELPER_RSA_MT_PURGE 1
 #define TALER_HELPER_RSA_MT_AVAIL 2
 
-#define TALER_HELPER_RSA_MT_REQ_SIGN 3
-#define TALER_HELPER_RSA_MT_REQ_REVOKE 4
+#define TALER_HELPER_RSA_MT_REQ_INIT 4
+#define TALER_HELPER_RSA_MT_REQ_SIGN 5
+#define TALER_HELPER_RSA_MT_REQ_REVOKE 6
 
-#define TALER_HELPER_RSA_MT_RES_SIGNATURE 5
-#define TALER_HELPER_RSA_MT_RES_SIGN_FAILURE 6
+#define TALER_HELPER_RSA_MT_RES_SIGNATURE 7
+#define TALER_HELPER_RSA_MT_RES_SIGN_FAILURE 8
 
 GNUNET_NETWORK_STRUCT_BEGIN
 
diff --git a/src/util/test_helper_rsa.c b/src/util/test_helper_rsa.c
new file mode 100644
index 00000000..4cb4a5f1
--- /dev/null
+++ b/src/util/test_helper_rsa.c
@@ -0,0 +1,314 @@
+/*
+  This file is part of TALER
+  (C) 2020 Taler Systems SA
+
+  TALER is free software; you can redistribute it and/or modify it under the
+  terms of the GNU General Public License as published by the Free Software
+  Foundation; either version 3, or (at your option) any later version.
+
+  TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+  A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License along with
+  TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+*/
+/**
+ * @file util/test_helper_rsa.c
+ * @brief Tests for RSA crypto helper
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include "taler_util.h"
+
+/**
+ * Configuration has 1 minute duration and 5 minutes lookahead, so
+ * we should never have more than 6 active keys, plus for during
+ * key expiration / revocation.
+ */
+#define MAX_KEYS 7
+
+/**
+ * How many random key revocations should we test?
+ */
+#define NUM_REVOKES 10
+
+
+/**
+ * Number of keys currently in #keys.
+ */
+static unsigned int num_keys;
+
+/**
+ * Keys currently managed by the helper.
+ */
+struct KeyData
+{
+  /**
+   * Validity start point.
+   */
+  struct GNUNET_TIME_Absolute start_time;
+
+  /**
+   * Key expires for signing at @e start_time plus this value.
+   */
+  struct GNUNET_TIME_Relative validity_duration;
+
+  /**
+   * Hash of the public key.
+   */
+  struct GNUNET_HashCode h_denom_pub;
+
+  /**
+   * Full public key.
+   */
+  struct TALER_DenominationPublicKey denom_pub;
+
+  /**
+   * Is this key currently valid?
+   */
+  bool valid;
+
+  /**
+   * Did the test driver revoke this key?
+   */
+  bool revoked;
+};
+
+static struct KeyData keys[MAX_KEYS];
+
+
+static void
+key_cb (void *cls,
+        const char *section_name,
+        struct GNUNET_TIME_Absolute start_time,
+        struct GNUNET_TIME_Relative validity_duration,
+        const struct GNUNET_HashCode *h_denom_pub,
+        const struct TALER_DenominationPublicKey *denom_pub)
+{
+  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+              "Key notification about key %s in `%s'\n",
+              GNUNET_h2s (h_denom_pub),
+              section_name);
+  if (0 == validity_duration.rel_value_us)
+  {
+    bool found = false;
+
+    GNUNET_break (NULL == denom_pub);
+    GNUNET_break (NULL == section_name);
+    for (unsigned int i = 0; i<MAX_KEYS; i++)
+      if (0 == GNUNET_memcmp (h_denom_pub,
+                              &keys[i].h_denom_pub))
+      {
+        keys[i].valid = false;
+        keys[i].revoked = false;
+        GNUNET_CRYPTO_rsa_public_key_free (keys[i].denom_pub.rsa_public_key);
+        keys[i].denom_pub.rsa_public_key = NULL;
+        GNUNET_assert (num_keys > 0);
+        num_keys--;
+        found = true;
+        break;
+      }
+    if (! found)
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                  "Error: helper announced expiration of unknown key!\n");
+
+    return;
+  }
+  GNUNET_break (NULL != denom_pub);
+  for (unsigned int i = 0; i<MAX_KEYS; i++)
+    if (! keys[i].valid)
+    {
+      keys[i].valid = true;
+      keys[i].h_denom_pub = *h_denom_pub;
+      keys[i].start_time = start_time;
+      keys[i].validity_duration = validity_duration;
+      keys[i].denom_pub.rsa_public_key
+        = GNUNET_CRYPTO_rsa_public_key_dup (denom_pub->rsa_public_key);
+      num_keys++;
+      return;
+    }
+  /* too many keys! */
+  GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+              "Error: received %d live keys from the service!\n",
+              MAX_KEYS + 1);
+}
+
+
+/**
+ * Main entry point into the test logic with the helper already running.
+ */
+static int
+run_test (void)
+{
+  struct GNUNET_CONFIGURATION_Handle *cfg;
+  struct TALER_CRYPTO_DenominationHelper *dh;
+  struct timespec req = {
+    .tv_nsec = 250000000
+  };
+
+  cfg = GNUNET_CONFIGURATION_create ();
+  if (GNUNET_OK !=
+      GNUNET_CONFIGURATION_load (cfg,
+                                 "test_helper_rsa.conf"))
+  {
+    GNUNET_break (0);
+    return 77;
+  }
+  dh = TALER_CRYPTO_helper_denom_connect (cfg,
+                                          &key_cb,
+                                          NULL);
+  GNUNET_CONFIGURATION_destroy (cfg);
+  if (NULL == dh)
+  {
+    GNUNET_break (0);
+    return 1;
+  }
+  /* wait for helper to start and give us keys */
+  fprintf (stderr, "Waiting for helper to start ");
+  for (unsigned int i = 0; i<80; i++)
+  {
+    TALER_CRYPTO_helper_poll (dh);
+    if (0 != num_keys)
+      break;
+    nanosleep (&req, NULL);
+    fprintf (stderr, ".");
+  }
+  if (0 == num_keys)
+  {
+    fprintf (stderr,
+             "\nFAILED: timeout trying to connect to helper\n");
+    TALER_CRYPTO_helper_denom_disconnect (dh);
+    return 1;
+  }
+  fprintf (stderr,
+           "\nOK: Helper ready (%u keys)\n",
+           num_keys);
+  for (unsigned int i = 0; i<NUM_REVOKES; i++)
+  {
+    uint32_t off;
+
+    off = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
+                                    num_keys);
+    /* find index of key to revoke */
+    for (unsigned int j = 0; j < MAX_KEYS; j++)
+    {
+      if (! keys[j].valid)
+        continue;
+      if (0 != off)
+      {
+        off--;
+        continue;
+      }
+      keys[j].revoked = true;
+      fprintf (stderr,
+               "Revoking key %s ...",
+               GNUNET_h2s (&keys[j].h_denom_pub));
+      TALER_CRYPTO_helper_denom_revoke (dh,
+                                        &keys[j].h_denom_pub);
+      for (unsigned int k = 0; k<80; k++)
+      {
+        TALER_CRYPTO_helper_poll (dh);
+        if (! keys[j].revoked)
+          break;
+        nanosleep (&req, NULL);
+        fprintf (stderr, ".");
+      }
+      if (keys[j].revoked)
+      {
+        fprintf (stderr,
+                 "\nFAILED: timeout trying to revoke key %u\n",
+                 j);
+        TALER_CRYPTO_helper_denom_disconnect (dh);
+        return 2;
+      }
+      break;
+    }
+  }
+
+
+  TALER_CRYPTO_helper_denom_disconnect (dh);
+  /* clean up our state */
+  for (unsigned int i = 0; i<MAX_KEYS; i++)
+    if (keys[i].valid)
+    {
+      GNUNET_CRYPTO_rsa_public_key_free (keys[i].denom_pub.rsa_public_key);
+      keys[i].denom_pub.rsa_public_key = NULL;
+      GNUNET_assert (num_keys > 0);
+      num_keys--;
+    }
+  return 0;
+}
+
+
+int
+main (int argc,
+      const char *const argv[])
+{
+  struct GNUNET_OS_Process *helper;
+  char *libexec_dir;
+  char *binary_name;
+  int ret;
+  enum GNUNET_OS_ProcessStatusType type;
+  unsigned long code;
+
+  (void) argc;
+  (void) argv;
+  GNUNET_log_setup ("test-helper-rsa",
+                    "INFO",
+                    NULL);
+  GNUNET_OS_init (TALER_project_data_default ());
+  libexec_dir = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_LIBEXECDIR);
+  GNUNET_asprintf (&binary_name,
+                   "%s/%s",
+                   libexec_dir,
+                   "taler-helper-crypto-rsa");
+  GNUNET_free (libexec_dir);
+  helper = GNUNET_OS_start_process (GNUNET_OS_INHERIT_STD_ERR,
+                                    NULL, NULL, NULL,
+                                    binary_name,
+                                    binary_name,
+                                    "-c",
+                                    "test_helper_rsa.conf",
+                                    "-L",
+                                    "INFO",
+                                    NULL);
+  if (NULL == helper)
+  {
+    GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
+                              "exec",
+                              binary_name);
+    GNUNET_free (binary_name);
+    return 77;
+  }
+  GNUNET_free (binary_name);
+  ret = run_test ();
+
+  GNUNET_OS_process_kill (helper,
+                          SIGTERM);
+  if (GNUNET_OK !=
+      GNUNET_OS_process_wait_status (helper,
+                                     &type,
+                                     &code))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Helper process did not die voluntarily, killing hard\n");
+    GNUNET_OS_process_kill (helper,
+                            SIGKILL);
+    ret = 4;
+  }
+  else if ( (GNUNET_OS_PROCESS_EXITED != type) ||
+            (0 != code) )
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Helper died with unexpected status %d/%d\n",
+                (int) type,
+                (int) code);
+    ret = 5;
+  }
+  GNUNET_OS_process_destroy (helper);
+  return ret;
+}
+
+
+/* end of test_helper_rsa.c */
diff --git a/src/util/test_helper_rsa.conf b/src/util/test_helper_rsa.conf
new file mode 100644
index 00000000..9880ae15
--- /dev/null
+++ b/src/util/test_helper_rsa.conf
@@ -0,0 +1,9 @@
+[coin_1]
+duration_withdraw = 1 minute
+rsa_keysize = 2048
+
+[taler-helper-crypto-rsa]
+lookahead_sign = 5 minutes
+overlap_duration = 1 s
+KEY_DIR = ${TALER_RUNTIME_DIR}/test_helper_rsa/
+UNIXPATH = ${TALER_RUNTIME_DIR}test_helper_rsa.unix

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

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