gnunet-svn
[Top][All Lists]
Advanced

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

[taler-exchange] branch master updated: handle revocation requests


From: gnunet
Subject: [taler-exchange] branch master updated: handle revocation requests
Date: Sun, 15 Nov 2020 13:26:51 +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 9f60c8c0 handle revocation requests
9f60c8c0 is described below

commit 9f60c8c041d9d86ebb701a2532e4d849ca9a9d82
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Sun Nov 15 13:26:49 2020 +0100

    handle revocation requests
---
 src/util/Makefile.am                  |   3 +-
 src/util/taler-helper-crypto-rsa.c    | 478 ++++++++++++++++++++++++++--------
 src/util/taler-helper-crypto-rsa.conf |  14 +
 src/util/taler-helper-crypto-rsa.h    |  54 ++++
 4 files changed, 436 insertions(+), 113 deletions(-)

diff --git a/src/util/Makefile.am b/src/util/Makefile.am
index e8ad9c4d..4aef4cac 100644
--- a/src/util/Makefile.am
+++ b/src/util/Makefile.am
@@ -12,7 +12,8 @@ libexecdir = $(pkglibdir)/libexec/
 pkgcfgdir = $(prefix)/share/taler/config.d/
 
 pkgcfg_DATA = \
-  paths.conf
+  paths.conf \
+  taler-helper-crypto-rsa.conf
 
 EXTRA_DIST = \
   paths.conf \
diff --git a/src/util/taler-helper-crypto-rsa.c 
b/src/util/taler-helper-crypto-rsa.c
index a26ac3f4..4c35370c 100644
--- a/src/util/taler-helper-crypto-rsa.c
+++ b/src/util/taler-helper-crypto-rsa.c
@@ -249,6 +249,11 @@ static struct GNUNET_CONTAINER_MultiHashMap *keys;
  */
 static struct GNUNET_NETWORK_Handle *lsock;
 
+/**
+ * Path where we are listening.
+ */
+static char *unixpath;
+
 /**
  * Task run to accept new inbound connections.
  */
@@ -270,20 +275,75 @@ static struct Client *clients_head;
 static struct Client *clients_tail;
 
 
+/**
+ * Free @a client, releasing all (remaining) state.
+ *
+ * @param[in] client data to free
+ */
+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);
+  GNUNET_CONTAINER_DLL_remove (clients_head,
+                               clients_tail,
+                               client);
+  GNUNET_free (client);
+}
+
+
 /**
  * Function run to read incoming requests from a client.
  *
  * @param cls the `struct Client`
  */
 static void
-read_job (void *cls)
+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)
 {
-  struct Client *client = cls;
+  client->task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
+                                                client->sock,
+                                                &read_job,
+                                                client);
+}
 
-  // FIXME: DO WORK!
-  // check for:
-  // - sign requests
-  // - revocation requests!?
+
+/**
+ * Free @a dk. It must already have been removed from #keys and the
+ * denomination's DLL.
+ *
+ * @param[in] dk key to free
+ */
+static void
+free_dk (struct DenominationKey *dk)
+{
+  GNUNET_free (dk->filename);
+  GNUNET_CRYPTO_rsa_private_key_free (dk->denom_priv.rsa_private_key);
+  GNUNET_CRYPTO_rsa_public_key_free (dk->denom_pub.rsa_public_key);
+  GNUNET_free (dk);
+}
+
+
+/**
+ *
+ */
+static void
+handle_sign_request (struct Client *client,
+                     const struct TALER_CRYPTO_SignRequest *sr)
+{
+  // FIXME ...
 }
 
 
@@ -337,11 +397,7 @@ notify_client_dk_add (struct Client *client,
     GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
                          "send");
     GNUNET_free (an);
-    GNUNET_NETWORK_socket_close (client->sock);
-    GNUNET_CONTAINER_DLL_remove (clients_head,
-                                 clients_tail,
-                                 client);
-    GNUNET_free (client);
+    free_client (client);
     return GNUNET_SYSERR;
   }
   GNUNET_free (an);
@@ -375,17 +431,270 @@ notify_client_dk_del (struct Client *client,
   {
     GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
                          "send");
-    GNUNET_NETWORK_socket_close (client->sock);
-    GNUNET_CONTAINER_DLL_remove (clients_head,
-                                 clients_tail,
-                                 client);
-    GNUNET_free (client);
+    free_client (client);
+    return GNUNET_SYSERR;
+  }
+  return GNUNET_OK;
+}
+
+
+/**
+ * Initialize key material for denomination key @a dk (also on disk).
+ *
+ * @param[in,out] denomination key to compute key material for
+ * @param position where in the DLL will the @a dk go
+ * @return #GNUNET_OK on success
+ */
+static int
+setup_key (struct DenominationKey *dk,
+           struct DenominationKey *position)
+{
+  struct Denomination *denom = dk->denom;
+  struct GNUNET_CRYPTO_RsaPrivateKey *priv;
+  struct GNUNET_CRYPTO_RsaPublicKey *pub;
+  size_t buf_size;
+  void *buf;
+
+  priv = GNUNET_CRYPTO_rsa_private_key_create (denom->rsa_keysize);
+  if (NULL == priv)
+  {
+    GNUNET_break (0);
+    GNUNET_SCHEDULER_shutdown ();
+    global_ret = 40;
+    return GNUNET_SYSERR;
+  }
+  pub = GNUNET_CRYPTO_rsa_private_key_get_public (priv);
+  if (NULL == pub)
+  {
+    GNUNET_break (0);
+    GNUNET_CRYPTO_rsa_private_key_free (priv);
+    return GNUNET_SYSERR;
+  }
+  buf_size = GNUNET_CRYPTO_rsa_private_key_encode (priv,
+                                                   &buf);
+  GNUNET_CRYPTO_rsa_public_key_hash (pub,
+                                     &dk->h_pub);
+  GNUNET_asprintf (&dk->filename,
+                   "%s/%s/%llu",
+                   keydir,
+                   denom->section,
+                   (unsigned long long) (dk->anchor.abs_value_us
+                                         / 
GNUNET_TIME_UNIT_SECONDS.rel_value_us));
+  if (buf_size !=
+      GNUNET_DISK_fn_write (dk->filename,
+                            buf,
+                            buf_size,
+                            GNUNET_DISK_PERM_USER_READ))
+  {
+    GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
+                              "write",
+                              dk->filename);
+    GNUNET_free (buf);
+    GNUNET_CRYPTO_rsa_private_key_free (priv);
+    GNUNET_CRYPTO_rsa_public_key_free (pub);
+    return GNUNET_SYSERR;
+  }
+  GNUNET_free (buf);
+  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,
+        GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Duplicate private key created! Terminating.\n");
+    GNUNET_CRYPTO_rsa_private_key_free (dk->denom_priv.rsa_private_key);
+    GNUNET_CRYPTO_rsa_public_key_free (dk->denom_pub.rsa_public_key);
+    GNUNET_free (dk->filename);
+    GNUNET_free (dk);
     return GNUNET_SYSERR;
   }
+  GNUNET_CONTAINER_DLL_insert_after (denom->keys_head,
+                                     denom->keys_tail,
+                                     position,
+                                     dk);
+
+  /* tell clients about new key */
+  {
+    struct Client *nxt;
+
+    for (struct Client *client = clients_head;
+         NULL != client;
+         client = nxt)
+    {
+      nxt = client->next;
+      if (GNUNET_OK !=
+          notify_client_dk_add (client,
+                                dk))
+      {
+        GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                    "Failed to notify client about new key, client dropped\n");
+      }
+    }
+  }
   return GNUNET_OK;
 }
 
 
+/**
+ * A client informs us that a key has been revoked.
+ * 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 rr the revocation request
+ */
+static void
+handle_revoke_request (struct Client *client,
+                       const struct TALER_CRYPTO_RevokeRequest *rr)
+{
+  struct DenominationKey *dk;
+  struct DenominationKey *ndk;
+  struct Denomination *denom;
+
+  dk = GNUNET_CONTAINER_multihashmap_get (keys,
+                                          &rr->h_denom_pub);
+  if (NULL == dk)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                "Revocation request ignored, denomination key unknown\n");
+    client_next (client);
+    return;
+  }
+
+  /* kill existing key, done first to ensure this always happens */
+  if (0 != unlink (dk->filename))
+    GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
+                              "unlink",
+                              dk->filename);
+
+  /* Setup replacement key */
+  denom = dk->denom;
+  ndk = GNUNET_new (struct DenominationKey);
+  ndk->denom = denom;
+  ndk->anchor = dk->anchor;
+  if (GNUNET_OK !=
+      setup_key (ndk,
+                 dk))
+  {
+    GNUNET_break (0);
+    GNUNET_SCHEDULER_shutdown ();
+    global_ret = 44;
+    return;
+  }
+
+  /* get rid of the old key */
+  dk->purge = true;
+  GNUNET_assert (GNUNET_OK ==
+                 GNUNET_CONTAINER_multihashmap_remove (
+                   keys,
+                   &dk->h_pub,
+                   dk));
+  GNUNET_CONTAINER_DLL_remove (denom->keys_head,
+                               denom->keys_tail,
+                               dk);
+
+  /* Tell clients this key is gone */
+  {
+    struct Client *nxt;
+
+    for (struct Client *client = clients_head;
+         NULL != client;
+         client = nxt)
+    {
+      nxt = client->next;
+      if (GNUNET_OK !=
+          notify_client_dk_del (client,
+                                dk))
+        GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                    "Failed to notify client about revoked key, client 
dropped\n");
+    }
+  }
+  if (0 == dk->rc)
+    free_dk (dk);
+
+  client_next (client);
+}
+
+
+static void
+read_job (void *cls)
+{
+  struct Client *client = cls;
+  char buf[65536];
+  ssize_t buf_size;
+  struct GNUNET_MessageHeader hdr;
+
+  client->task = NULL;
+  buf_size = GNUNET_NETWORK_socket_recv (client->sock,
+                                         buf,
+                                         sizeof (buf));
+  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))
+  {
+    GNUNET_break_op (0);
+    free_client (client);
+    return;
+  }
+  memcpy (&hdr,
+          buf,
+          sizeof (hdr));
+  if (ntohs (hdr.size) != buf_size)
+  {
+    GNUNET_break_op (0);
+    free_client (client);
+    return;
+  }
+  switch (ntohs (hdr.type))
+  {
+  case TALER_HELPER_RSA_MT_REQ_SIGN:
+    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);
+    break;
+  case TALER_HELPER_RSA_MT_REQ_REVOKE:
+    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);
+    break;
+  default:
+    GNUNET_break_op (0);
+    free_client (client);
+    return;
+  }
+}
+
+
 /**
  * Function run to accept incoming connections on #sock.
  *
@@ -412,10 +721,7 @@ accept_job (void *cls)
     GNUNET_CONTAINER_DLL_insert (clients_head,
                                  clients_tail,
                                  client);
-    client->task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
-                                                  sock,
-                                                  &read_job,
-                                                  client);
+    client_next (client);
     for (struct Denomination *denom = denom_head;
          NULL != denom;
          denom = denom->next)
@@ -455,10 +761,6 @@ create_key (struct Denomination *denom)
 {
   struct DenominationKey *dk;
   struct GNUNET_TIME_Absolute anchor;
-  struct GNUNET_CRYPTO_RsaPrivateKey *priv;
-  struct GNUNET_CRYPTO_RsaPublicKey *pub;
-  size_t buf_size;
-  void *buf;
 
   if (NULL == denom->keys_tail)
   {
@@ -472,93 +774,19 @@ create_key (struct Denomination *denom)
                                          denom->duration_withdraw,
                                          overlap_duration));
   }
-  priv = GNUNET_CRYPTO_rsa_private_key_create (denom->rsa_keysize);
-  if (NULL == priv)
-  {
-    GNUNET_break (0);
-    GNUNET_SCHEDULER_shutdown ();
-    global_ret = 40;
-    return GNUNET_SYSERR;
-  }
-  pub = GNUNET_CRYPTO_rsa_private_key_get_public (priv);
-  if (NULL == pub)
-  {
-    GNUNET_break (0);
-    GNUNET_CRYPTO_rsa_private_key_free (priv);
-    GNUNET_SCHEDULER_shutdown ();
-    global_ret = 41;
-    return GNUNET_SYSERR;
-  }
-  buf_size = GNUNET_CRYPTO_rsa_private_key_encode (priv,
-                                                   &buf);
   dk = GNUNET_new (struct DenominationKey);
   dk->denom = denom;
   dk->anchor = anchor;
-  dk->denom_priv.rsa_private_key = priv;
-  GNUNET_CRYPTO_rsa_public_key_hash (pub,
-                                     &dk->h_pub);
-  dk->denom_pub.rsa_public_key = pub;
-  GNUNET_asprintf (&dk->filename,
-                   "%s/%s/%llu",
-                   keydir,
-                   denom->section,
-                   (unsigned long long) (anchor.abs_value_us
-                                         / 
GNUNET_TIME_UNIT_SECONDS.rel_value_us));
-  if (buf_size !=
-      GNUNET_DISK_fn_write (dk->filename,
-                            buf,
-                            buf_size,
-                            GNUNET_DISK_PERM_USER_READ))
-  {
-    GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
-                              "write",
-                              dk->filename);
-    GNUNET_free (buf);
-    GNUNET_CRYPTO_rsa_private_key_free (priv);
-    GNUNET_CRYPTO_rsa_public_key_free (pub);
-    GNUNET_free (dk);
-    GNUNET_SCHEDULER_shutdown ();
-    global_ret = 42;
-    return GNUNET_SYSERR;
-  }
-  GNUNET_free (buf);
-
   if (GNUNET_OK !=
-      GNUNET_CONTAINER_multihashmap_put (
-        keys,
-        &dk->h_pub,
-        dk,
-        GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
+      setup_key (dk,
+                 denom->keys_tail))
   {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Duplicate private key created! Terminating.\n");
-    GNUNET_CRYPTO_rsa_private_key_free (priv);
-    GNUNET_CRYPTO_rsa_public_key_free (pub);
     GNUNET_free (dk);
     GNUNET_SCHEDULER_shutdown ();
-    global_ret = 43;
+    global_ret = 42;
     return GNUNET_SYSERR;
   }
-  GNUNET_CONTAINER_DLL_insert_tail (denom->keys_head,
-                                    denom->keys_tail,
-                                    dk);
-  {
-    struct Client *nxt;
 
-    for (struct Client *client = clients_head;
-         NULL != client;
-         client = nxt)
-    {
-      nxt = client->next;
-      if (GNUNET_OK !=
-          notify_client_dk_add (client,
-                                dk))
-      {
-        GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-                    "Failed to notify client about new key, client dropped\n");
-      }
-    }
-  }
   return GNUNET_OK;
 }
 
@@ -833,6 +1061,9 @@ parse_key (struct Denomination *denom,
                                        denom->keys_tail,
                                        before,
                                        dk);
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "Imported key from `%s'\n",
+                filename);
   }
 }
 
@@ -983,7 +1214,7 @@ parse_denomination_cfg (const char *ct,
       denom->duration_withdraw.rel_value_us)
   {
     GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
-                               "exchangedb",
+                               "taler-helper-crypto-rsa",
                                "OVERLAP_DURATION",
                                "Value given must be smaller than value for 
DURATION_WITHDRAW!");
     return GNUNET_SYSERR;
@@ -1003,7 +1234,7 @@ parse_denomination_cfg (const char *ct,
        (rsa_keysize < 1024) )
   {
     GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
-                               "exchangedb",
+                               ct,
                                "RSA_KEYSIZE",
                                "Given RSA keysize outside of permitted range 
[1024,8192]\n");
     return GNUNET_SYSERR;
@@ -1041,6 +1272,9 @@ load_denominations (void *cls,
     GNUNET_free (denom);
     return;
   }
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Loading keys for denomination %s\n",
+              denom->section);
   {
     char *dname;
 
@@ -1070,12 +1304,12 @@ load_durations (void)
 {
   if (GNUNET_OK !=
       GNUNET_CONFIGURATION_get_value_time (kcfg,
-                                           "exchangedb",
+                                           "taler-helper-crypto-rsa",
                                            "OVERLAP_DURATION",
                                            &overlap_duration))
   {
     GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
-                               "exchangedb",
+                               "taler-helper-crypto-rsa",
                                "OVERLAP_DURATION");
     return GNUNET_SYSERR;
   }
@@ -1114,10 +1348,17 @@ do_shutdown (void *cls)
   }
   if (NULL != lsock)
   {
-    GNUNET_break (0 ==
+    GNUNET_break (GNUNET_OK ==
                   GNUNET_NETWORK_socket_close (lsock));
     lsock = NULL;
   }
+  if (0 != unlink (unixpath))
+  {
+    GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
+                              "unlink",
+                              unixpath);
+  }
+  GNUNET_free (unixpath);
   if (NULL != keygen_task)
   {
     GNUNET_SCHEDULER_cancel (keygen_task);
@@ -1164,12 +1405,12 @@ run (void *cls,
   if (GNUNET_OK !=
       GNUNET_CONFIGURATION_get_value_filename (kcfg,
                                                "taler-helper-crypto-rsa",
-                                               "KEYDIR",
+                                               "KEY_DIR",
                                                &keydir))
   {
     GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
-                               "exchange",
-                               "KEYDIR");
+                               "taler-helper-crypto-rsa",
+                               "KEY_DIR");
     global_ret = 1;
     return;
   }
@@ -1190,20 +1431,33 @@ run (void *cls,
     }
     {
       struct sockaddr_un un;
-      char *unixpath;
 
       if (GNUNET_OK !=
           GNUNET_CONFIGURATION_get_value_filename (kcfg,
-                                                   
"exchange-helper-crypto-rsa",
+                                                   "taler-helper-crypto-rsa",
                                                    "UNIXPATH",
                                                    &unixpath))
       {
         GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
-                                   "exchange-helper-crypto-rsa",
+                                   "taler-helper-crypto-rsa",
                                    "UNIXPATH");
         global_ret = 3;
         return;
       }
+      if (GNUNET_OK !=
+          GNUNET_DISK_directory_create_for_file (unixpath))
+      {
+        GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
+                                  "mkdir(dirname)",
+                                  unixpath);
+      }
+      if (0 != unlink (unixpath))
+      {
+        if (ENOENT != errno)
+          GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
+                                    "unlink",
+                                    unixpath);
+      }
       memset (&un,
               0,
               sizeof (un));
diff --git a/src/util/taler-helper-crypto-rsa.conf 
b/src/util/taler-helper-crypto-rsa.conf
new file mode 100644
index 00000000..6d7135d9
--- /dev/null
+++ b/src/util/taler-helper-crypto-rsa.conf
@@ -0,0 +1,14 @@
+[taler-helper-crypto-rsa]
+
+# How long should generated coins overlap in their validity
+# periods. Should be long enough to avoid problems with
+# wallets picking one key and then due to network latency
+# another key being valid.  The DURATION_WITHDRAW period
+# must be longer than this value.
+OVERLAP_DURATION = 5m
+
+# Where do we store the private keys.
+KEY_DIR = ${TALER_DATA_HOME}/crypto-rsa/
+
+# Where does the helper listen for requests?
+UNIXPATH = $TALER_RUNTIME_DIR/taler-helper-crypto-rsa.sock
diff --git a/src/util/taler-helper-crypto-rsa.h 
b/src/util/taler-helper-crypto-rsa.h
index 3715c17c..b5ad6775 100644
--- a/src/util/taler-helper-crypto-rsa.h
+++ b/src/util/taler-helper-crypto-rsa.h
@@ -24,6 +24,9 @@
 #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
+
 GNUNET_NETWORK_STRUCT_BEGIN
 
 /**
@@ -87,6 +90,57 @@ struct TALER_CRYPTO_RsaKeyPurgeNotification
 };
 
 
+/**
+ * Message sent if a signature is requested.
+ */
+struct TALER_CRYPTO_SignRequest
+{
+  /**
+   * Type is #TALER_HELPER_RSA_MT_SIGN.
+   */
+  struct GNUNET_MessageHeader header;
+
+  /**
+   * For now, always zero.
+   */
+  uint32_t reserved;
+
+  /**
+   * Hash of the public key of the RSA key to use for the signature.
+   */
+  struct GNUNET_HashCode h_denom_pub;
+
+  /**
+   * Hash of the value to sign (FDH still to be computed!).
+   */
+  struct GNUNET_HashCode h_message;
+
+};
+
+
+/**
+ * Message sent if a key was revoked.
+ */
+struct TALER_CRYPTO_RevokeRequest
+{
+  /**
+   * Type is #TALER_HELPER_RSA_MT_REVOKE.
+   */
+  struct GNUNET_MessageHeader header;
+
+  /**
+   * For now, always zero.
+   */
+  uint32_t reserved;
+
+  /**
+   * Hash of the public key of the revoked RSA key.
+   */
+  struct GNUNET_HashCode h_denom_pub;
+
+};
+
+
 GNUNET_NETWORK_STRUCT_END
 
 

-- 
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]