Merge branch 'master' of ssh://gnunet.org/gnunet
[oweals/gnunet.git] / src / revocation / revocation_api.c
index 55a130202ba46104d7d5b9e635c5ef87c7f5e40f..ef659baa0d609c63425d0e3424a169577b15fbe2 100644 (file)
@@ -1,6 +1,6 @@
 /*
       This file is part of GNUnet
-      (C) 2013 Christian Grothoff (and other contributing authors)
+      Copyright (C) 2013, 2016 GNUnet e.V.
 
       GNUnet is free software; you can redistribute it and/or modify
       it under the terms of the GNU General Public Licerevocation as published
@@ -14,8 +14,8 @@
 
       You should have received a copy of the GNU General Public Licerevocation
       along with GNUnet; see the file COPYING.  If not, write to the
-      Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-      Boston, MA 02111-1307, USA.
+      Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+      Boston, MA 02110-1301, USA.
  */
 /**
  * @file revocation/revocation_api.c
@@ -37,19 +37,9 @@ struct GNUNET_REVOCATION_Query
 {
 
   /**
-   * Connection to the service.
+   * Message queue to the service.
    */
-  struct GNUNET_CLIENT_Connection *client;
-  
-  /**
-   * Our configuration.
-   */
-  const struct GNUNET_CONFIGURATION_Handle *cfg;
-
-  /**
-   * Key to check.
-   */
-  struct GNUNET_CRYPTO_EccPublicSignKey key;
+  struct GNUNET_MQ_Handle *mq;
 
   /**
    * Function to call with the result.
@@ -60,9 +50,54 @@ struct GNUNET_REVOCATION_Query
    * Closure for @e func.
    */
   void *func_cls;
+
 };
 
 
+/**
+ * Generic error handler, called with the appropriate
+ * error code and the same closure specified at the creation of
+ * the message queue.
+ * Not every message queue implementation supports an error handler.
+ *
+ * @param cls closure with the `struct GNUNET_NSE_Handle *`
+ * @param error error code
+ */
+static void
+query_mq_error_handler (void *cls,
+                        enum GNUNET_MQ_Error error)
+{
+  struct GNUNET_REVOCATION_Query *q = cls;
+
+  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+              "Revocation query MQ error\n");
+  q->func (q->func_cls,
+           GNUNET_SYSERR);
+  GNUNET_REVOCATION_query_cancel (q);
+}
+
+
+/**
+ * Handle response to our revocation query.
+ *
+ * @param cls our `struct GNUNET_REVOCATION_Query` handle
+ * @param qrm response we got
+ */
+static void
+handle_revocation_query_response (void *cls,
+                                  const struct QueryResponseMessage *qrm)
+{
+  struct GNUNET_REVOCATION_Query *q = cls;
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Revocation query result: %d\n",
+              (uint32_t) ntohl (qrm->is_valid));
+  q->func (q->func_cls,
+           ntohl (qrm->is_valid));
+  GNUNET_REVOCATION_query_cancel (q);
+}
+
+
 /**
  * Check if a key was revoked.
  *
@@ -74,18 +109,40 @@ struct GNUNET_REVOCATION_Query
  */
 struct GNUNET_REVOCATION_Query *
 GNUNET_REVOCATION_query (const struct GNUNET_CONFIGURATION_Handle *cfg,
-                        const struct GNUNET_CRYPTO_EccPublicSignKey *key,
-                        GNUNET_REVOCATION_Callback func, void *func_cls)
+                        const struct GNUNET_CRYPTO_EcdsaPublicKey *key,
+                        GNUNET_REVOCATION_Callback func,
+                         void *func_cls)
 {
-  struct GNUNET_REVOCATION_Query *q;
-
-  q = GNUNET_new (struct GNUNET_REVOCATION_Query);
-  q->client = GNUNET_CLIENT_connect ("revocation", cfg);
-  q->cfg = cfg;
-  q->key = *key;
+  struct GNUNET_REVOCATION_Query *q
+    = GNUNET_new (struct GNUNET_REVOCATION_Query);
+  struct GNUNET_MQ_MessageHandler handlers[] = {
+    GNUNET_MQ_hd_fixed_size (revocation_query_response,
+                             GNUNET_MESSAGE_TYPE_REVOCATION_QUERY_RESPONSE,
+                             struct QueryResponseMessage,
+                             q),
+    GNUNET_MQ_handler_end ()
+  };
+  struct QueryMessage *qm;
+  struct GNUNET_MQ_Envelope *env;
+
+  q->mq = GNUNET_CLIENT_connect (cfg,
+                                 "revocation",
+                                 handlers,
+                                 &query_mq_error_handler,
+                                 q);
+  if (NULL == q->mq)
+  {
+    GNUNET_free (q);
+    return NULL;
+  }
   q->func = func;
   q->func_cls = func_cls;
-  GNUNET_break (0);
+  env = GNUNET_MQ_msg (qm,
+                       GNUNET_MESSAGE_TYPE_REVOCATION_QUERY);
+  qm->reserved = htonl (0);
+  qm->key = *key;
+  GNUNET_MQ_send (q->mq,
+                  env);
   return q;
 }
 
@@ -98,7 +155,11 @@ GNUNET_REVOCATION_query (const struct GNUNET_CONFIGURATION_Handle *cfg,
 void
 GNUNET_REVOCATION_query_cancel (struct GNUNET_REVOCATION_Query *q)
 {
-  GNUNET_CLIENT_disconnect (q->client);
+  if (NULL != q->mq)
+  {
+    GNUNET_MQ_destroy (q->mq);
+    q->mq = NULL;
+  }
   GNUNET_free (q);
 }
 
@@ -108,31 +169,11 @@ GNUNET_REVOCATION_query_cancel (struct GNUNET_REVOCATION_Query *q)
  */
 struct GNUNET_REVOCATION_Handle
 {
-  
-  /**
-   * Connection to the service.
-   */
-  struct GNUNET_CLIENT_Connection *client;
-  
-  /**
-   * Our configuration.
-   */
-  const struct GNUNET_CONFIGURATION_Handle *cfg;
-
-  /**
-   * Key to revoke.
-   */
-  struct GNUNET_CRYPTO_EccPublicSignKey key;
-
-  /**
-   * Signature showing that we have the right to revoke.
-   */
-  struct GNUNET_CRYPTO_EccSignature sig;
 
   /**
-   * Proof of work showing that we spent enough resources to broadcast revocation.
+   * Message queue to the service.
    */
-  uint64_t pow;
+  struct GNUNET_MQ_Handle *mq;
 
   /**
    * Function to call once we are done.
@@ -147,6 +188,50 @@ struct GNUNET_REVOCATION_Handle
 };
 
 
+/**
+ * Generic error handler, called with the appropriate
+ * error code and the same closure specified at the creation of
+ * the message queue.
+ * Not every message queue implementation supports an error handler.
+ *
+ * @param cls closure with the `struct GNUNET_NSE_Handle *`
+ * @param error error code
+ */
+static void
+revocation_mq_error_handler (void *cls,
+                             enum GNUNET_MQ_Error error)
+{
+  struct GNUNET_REVOCATION_Handle *h = cls;
+
+  GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+              "Revocation MQ error\n");
+  h->func (h->func_cls,
+           GNUNET_SYSERR);
+  GNUNET_REVOCATION_revoke_cancel (h);
+}
+
+
+/**
+ * Handle response to our revocation query.
+ *
+ * @param cls our `struct GNUNET_REVOCATION_Handle` handle
+ * @param rrm response we got
+ */
+static void
+handle_revocation_response (void *cls,
+                            const struct RevocationResponseMessage *rrm)
+{
+  struct GNUNET_REVOCATION_Handle *h = cls;
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Revocation transmission result: %d\n",
+              (uint32_t) ntohl (rrm->is_valid));
+  h->func (h->func_cls,
+           ntohl (rrm->is_valid));
+  GNUNET_REVOCATION_revoke_cancel (h);
+}
+
+
 /**
  * Perform key revocation.
  *
@@ -160,26 +245,67 @@ struct GNUNET_REVOCATION_Handle
  *             (called with `is_valid` being #GNUNET_NO if
  *              the revocation worked).
  * @param func_cls closure to pass to @a func
- * @return handle to use in #GNUNET_REVOCATION_cancel to stop REVOCATION from invoking the callback
+ * @return handle to use in #GNUNET_REVOCATION_revoke_cancel to stop REVOCATION from invoking the callback
  */
 struct GNUNET_REVOCATION_Handle *
 GNUNET_REVOCATION_revoke (const struct GNUNET_CONFIGURATION_Handle *cfg,
-                         const struct GNUNET_CRYPTO_EccPublicSignKey *key,
-                         const struct GNUNET_CRYPTO_EccSignature *sig,
+                         const struct GNUNET_CRYPTO_EcdsaPublicKey *key,
+                         const struct GNUNET_CRYPTO_EcdsaSignature *sig,
                          uint64_t pow,
-                         GNUNET_REVOCATION_Callback func, void *func_cls)
+                         GNUNET_REVOCATION_Callback func,
+                          void *func_cls)
 {
-  struct GNUNET_REVOCATION_Handle *h;
-
-  h = GNUNET_new (struct GNUNET_REVOCATION_Handle);
-  h->client = GNUNET_CLIENT_connect ("revocation", cfg);
-  h->cfg = cfg;
-  h->key = *key;
-  h->sig = *sig;
-  h->pow = pow;
+  struct GNUNET_REVOCATION_Handle *h
+    = GNUNET_new (struct GNUNET_REVOCATION_Handle);
+  struct GNUNET_MQ_MessageHandler handlers[] = {
+    GNUNET_MQ_hd_fixed_size (revocation_response,
+                             GNUNET_MESSAGE_TYPE_REVOCATION_REVOKE_RESPONSE,
+                             struct RevocationResponseMessage,
+                             h),
+    GNUNET_MQ_handler_end ()
+  };
+  unsigned long long matching_bits;
+  struct RevokeMessage *rm;
+  struct GNUNET_MQ_Envelope *env;
+
+  if ( (GNUNET_OK ==
+        GNUNET_CONFIGURATION_get_value_number (cfg,
+                                               "REVOCATION",
+                                               "WORKBITS",
+                                               &matching_bits)) &&
+       (GNUNET_YES !=
+        GNUNET_REVOCATION_check_pow (key,
+                                     pow,
+                                     (unsigned int) matching_bits)) )
+  {
+    GNUNET_break (0);
+    GNUNET_free (h);
+    return NULL;
+  }
+
+  h->mq = GNUNET_CLIENT_connect (cfg,
+                                 "revocation",
+                                 handlers,
+                                 &revocation_mq_error_handler,
+                                 h);
+  if (NULL == h->mq)
+  {
+    GNUNET_free (h);
+    return NULL;
+  }
   h->func = func;
   h->func_cls = func_cls;
-  GNUNET_break (0);
+  env = GNUNET_MQ_msg (rm,
+                       GNUNET_MESSAGE_TYPE_REVOCATION_REVOKE);
+  rm->reserved = htonl (0);
+  rm->proof_of_work = pow;
+  rm->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_REVOCATION);
+  rm->purpose.size = htonl (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) +
+                            sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
+  rm->public_key = *key;
+  rm->signature = *sig;
+  GNUNET_MQ_send (h->mq,
+                  env);
   return h;
 }
 
@@ -192,12 +318,15 @@ GNUNET_REVOCATION_revoke (const struct GNUNET_CONFIGURATION_Handle *cfg,
 void
 GNUNET_REVOCATION_revoke_cancel (struct GNUNET_REVOCATION_Handle *h)
 {
-  GNUNET_CLIENT_disconnect (h->client);
+  if (NULL != h->mq)
+  {
+    GNUNET_MQ_destroy (h->mq);
+    h->mq = NULL;
+  }
   GNUNET_free (h);
 }
 
 
-
 /**
  * Calculate the 'proof-of-work' hash (an expensive hash).
  *
@@ -210,11 +339,11 @@ pow_hash (const void *buf,
          size_t buf_len,
          struct GNUNET_HashCode *result)
 {
-  GNUNET_break (0 == 
+  GNUNET_break (0 ==
                gcry_kdf_derive (buf, buf_len,
                                 GCRY_KDF_SCRYPT,
                                 1 /* subalgo */,
-                                "gnunet-revocation-proof-of-work", 
+                                "gnunet-revocation-proof-of-work",
                                 strlen ("gnunet-revocation-proof-of-work"),
                                 2 /* iterations; keep cost of individual op small */,
                                 sizeof (struct GNUNET_HashCode), result));
@@ -249,17 +378,17 @@ count_leading_zeroes (const struct GNUNET_HashCode *hash)
  * @return #GNUNET_YES if the @a pow is acceptable, #GNUNET_NO if not
  */
 int
-GNUNET_REVOCATION_check_pow (const struct GNUNET_CRYPTO_EccPublicSignKey *key,
+GNUNET_REVOCATION_check_pow (const struct GNUNET_CRYPTO_EcdsaPublicKey *key,
                             uint64_t pow,
                             unsigned int matching_bits)
 {
-  char buf[sizeof (struct GNUNET_CRYPTO_EccPublicSignKey) +
+  char buf[sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey) +
            sizeof (pow)] GNUNET_ALIGN;
   struct GNUNET_HashCode result;
 
-  memcpy (buf, &pow, sizeof (pow));
-  memcpy (&buf[sizeof (pow)], key,
-          sizeof (struct GNUNET_CRYPTO_EccPublicSignKey));
+  GNUNET_memcpy (buf, &pow, sizeof (pow));
+  GNUNET_memcpy (&buf[sizeof (pow)], key,
+          sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
   pow_hash (buf, sizeof (buf), &result);
   return (count_leading_zeroes (&result) >=
           matching_bits) ? GNUNET_YES : GNUNET_NO;
@@ -273,21 +402,20 @@ GNUNET_REVOCATION_check_pow (const struct GNUNET_CRYPTO_EccPublicSignKey *key,
  * @param sig where to write the revocation signature
  */
 void
-GNUNET_REVOCATION_sign_revocation (const struct GNUNET_CRYPTO_EccPrivateKey *key,
-                                  struct GNUNET_CRYPTO_EccSignature *sig)
+GNUNET_REVOCATION_sign_revocation (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key,
+                                  struct GNUNET_CRYPTO_EcdsaSignature *sig)
 {
-  struct GNUNET_REVOCATION_RevokeMessage rm;
+  struct RevokeMessage rm;
 
   rm.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_REVOCATION);
   rm.purpose.size = htonl (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) +
-                          sizeof (struct GNUNET_CRYPTO_EccPublicSignKey));
-  GNUNET_CRYPTO_ecc_key_get_public_for_signature (key, &rm.public_key);
+                          sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
+  GNUNET_CRYPTO_ecdsa_key_get_public (key, &rm.public_key);
   GNUNET_assert (GNUNET_OK ==
-                GNUNET_CRYPTO_ecc_sign (key,
+                GNUNET_CRYPTO_ecdsa_sign (key,
                                         &rm.purpose,
                                         sig));
 }
 
 
 /* end of revocation_api.c */
-