RECLAIM: refactoring; cleanup
authorSchanzenbach, Martin <mschanzenbach@posteo.de>
Fri, 12 Apr 2019 12:31:06 +0000 (14:31 +0200)
committerSchanzenbach, Martin <mschanzenbach@posteo.de>
Fri, 12 Apr 2019 12:31:06 +0000 (14:31 +0200)
src/include/gnunet_gnsrecord_lib.h
src/reclaim-attribute/reclaim_attribute.c
src/reclaim/Makefile.am
src/reclaim/gnunet-service-reclaim.c
src/reclaim/gnunet-service-reclaim_tickets.c [new file with mode: 0644]
src/reclaim/gnunet-service-reclaim_tickets.h [new file with mode: 0644]
src/reclaim/plugin_gnsrecord_reclaim.c
src/reclaim/reclaim_api.c

index c76e87d12678fdd2d6bb8090c38e8fc1ecccd57a..27228c0bcf937788ac9f67ee9d4be70cf008d73f 100644 (file)
@@ -99,7 +99,12 @@ extern "C"
 #define GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR 65544
 
 /**
- * 65544-65547 deprecated
+ * Record type for local ticket references
+ */
+#define GNUNET_GNSRECORD_TYPE_RECLAIM_TICKETREF 65545
+
+/**
+ * 65546 reserved
  */
 
 /**
index 3d260f15b1483935964e4306d085b2dfda7eb0dc..86f0f8f67e5a795ee189401a4305ba578defe1e6 100644 (file)
@@ -349,6 +349,8 @@ GNUNET_RECLAIM_ATTRIBUTE_list_dup (const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimLi
                                                            le->claim->type,
                                                            le->claim->data,
                                                            le->claim->data_size);
+    result_le->claim->version = le->claim->version;
+    result_le->claim->id = le->claim->id;
     GNUNET_CONTAINER_DLL_insert (result->list_head,
                                  result->list_tail,
                                  result_le);
index 210759fcecd25a9d1604c62c1648589e9980faab..7e8686734cf23057a85d04ac10a7299a34a82a6e 100644 (file)
@@ -108,14 +108,14 @@ libgnunet_plugin_reclaim_sqlite_la_LDFLAGS = \
 
 
 gnunet_service_reclaim_SOURCES = \
- gnunet-service-reclaim.c
+ gnunet-service-reclaim.c \
+ gnunet-service-reclaim_tickets.c
 gnunet_service_reclaim_LDADD = \
  $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \
  $(top_builddir)/src/util/libgnunetutil.la \
  $(top_builddir)/src/namestore/libgnunetnamestore.la \
  $(top_builddir)/src/identity/libgnunetidentity.la \
  $(top_builddir)/src/statistics/libgnunetstatistics.la \
- $(top_builddir)/src/credential/libgnunetcredential.la \
  $(top_builddir)/src/reclaim-attribute/libgnunetreclaimattribute.la \
  libgnunetreclaim.la \
  $(top_builddir)/src/gns/libgnunetgns.la \
index f3a6e2073270ef4253221be58c22398fb281eefe..b963b0a9b0ac2f8fa9a2be6399934318678d79e4 100644 (file)
 #include "gnunet_identity_service.h"
 #include "gnunet_gnsrecord_lib.h"
 #include "gnunet_namestore_service.h"
-#include "gnunet_credential_service.h"
 #include "gnunet_statistics_service.h"
 #include "gnunet_gns_service.h"
 #include "gnunet_reclaim_plugin.h"
 #include "gnunet_reclaim_attribute_lib.h"
 #include "gnunet_signatures.h"
+#include "gnunet-service-reclaim_tickets.h"
 #include "reclaim.h"
 
 /**
@@ -88,21 +88,6 @@ static struct GNUNET_NAMESTORE_Handle *nsh;
  */
 static struct GNUNET_GNS_Handle *gns_handle;
 
-/**
- * Credential handle
- */
-static struct GNUNET_CREDENTIAL_Handle *credential_handle;
-
-/**
- * Namestore qe
- */
-static struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
-
-/**
- * Namestore iterator
- */
-static struct GNUNET_NAMESTORE_ZoneIterator *ns_it;
-
 /**
  * Timeout task
  */
@@ -268,12 +253,12 @@ struct IdpClient
   /**
    * Head of DLL of ticket issue ops
    */
-  struct TicketIssueHandle *issue_op_head;
+  struct TicketIssueOperation *issue_op_head;
 
   /**
    * Tail of DLL of ticket issue ops
    */
-  struct TicketIssueHandle *issue_op_tail;
+  struct TicketIssueOperation *issue_op_tail;
 
   /**
    * Head of DLL of ticket consume ops
@@ -543,45 +528,25 @@ struct TicketRevocationHandle
 
 
 /**
- * Ticket issue request handle
+ * Ticket issue operation handle
  */
-struct TicketIssueHandle
+struct TicketIssueOperation
 {
   /**
    * DLL
    */
-  struct TicketIssueHandle *prev;
+  struct TicketIssueOperation *prev;
 
   /**
    * DLL
    */
-  struct TicketIssueHandle *next;
+  struct TicketIssueOperation *next;
 
   /**
    * Client connection
    */
   struct IdpClient *client;
 
-  /**
-   * Attributes to issue
-   */
-  struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs;
-
-  /**
-   * Issuer Key
-   */
-  struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
-
-  /**
-   * Ticket to issue
-   */
-  struct GNUNET_RECLAIM_Ticket ticket;
-
-  /**
-   * QueueEntry
-   */
-  struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
-
   /**
    * request id
    */
@@ -644,12 +609,6 @@ cleanup()
     GNUNET_IDENTITY_disconnect (identity_handle);
   if (NULL != gns_handle)
     GNUNET_GNS_disconnect (gns_handle);
-  if (NULL != credential_handle)
-    GNUNET_CREDENTIAL_disconnect (credential_handle);
-  if (NULL != ns_it)
-    GNUNET_NAMESTORE_zone_iteration_stop (ns_it);
-  if (NULL != ns_qe)
-    GNUNET_NAMESTORE_cancel (ns_qe);
   if (NULL != nsh)
     GNUNET_NAMESTORE_disconnect (nsh);
 }
@@ -691,83 +650,136 @@ create_sym_key_from_ecdh (const struct GNUNET_HashCode *new_key_hash,
   return GNUNET_OK;
 }
 
-/**
- * Cleanup ticket consume handle
- * @param handle the handle to clean up
- */
-static void
-cleanup_ticket_issue_handle (struct TicketIssueHandle *handle)
-{
-  if (NULL != handle->attrs)
-    GNUNET_RECLAIM_ATTRIBUTE_list_destroy (handle->attrs);
-  if (NULL != handle->ns_qe)
-    GNUNET_NAMESTORE_cancel (handle->ns_qe);
-  GNUNET_free (handle);
-}
-
 
 static void
-send_ticket_result (struct IdpClient *client,
+send_ticket_result (const struct IdpClient *client,
                     uint32_t r_id,
                     const struct GNUNET_RECLAIM_Ticket *ticket,
-                    const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs)
+                    uint32_t success)
 {
   struct TicketResultMessage *irm;
   struct GNUNET_MQ_Envelope *env;
   struct GNUNET_RECLAIM_Ticket *ticket_buf;
 
-  /* store ticket in DB */
-  if (GNUNET_OK != TKT_database->store_ticket (TKT_database->cls,
-                                               ticket,
-                                               attrs))
+  if (NULL != ticket)
   {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Unable to store ticket after issue\n");
-    GNUNET_break (0);
+    env = GNUNET_MQ_msg_extra (irm,
+                               sizeof (struct GNUNET_RECLAIM_Ticket),
+                               GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT);
+    ticket_buf = (struct GNUNET_RECLAIM_Ticket *)&irm[1];
+    *ticket_buf = *ticket;
+  } else {
+    env = GNUNET_MQ_msg (irm,
+                         GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT);
   }
-
-  env = GNUNET_MQ_msg_extra (irm,
-                             sizeof (struct GNUNET_RECLAIM_Ticket),
-                             GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT);
-  ticket_buf = (struct GNUNET_RECLAIM_Ticket *)&irm[1];
-  *ticket_buf = *ticket;
+  //TODO add success member
   irm->id = htonl (r_id);
   GNUNET_MQ_send (client->mq,
                   env);
 }
 
+
 static void
-store_ticket_issue_cont (void *cls,
-                         int32_t success,
-                         const char *emsg)
+issue_ticket_result_cb (void *cls,
+                        struct GNUNET_RECLAIM_Ticket *ticket,
+                        uint32_t success,
+                        const char* emsg)
 {
-  struct TicketIssueHandle *handle = cls;
-
-  handle->ns_qe = NULL;
-  GNUNET_CONTAINER_DLL_remove (handle->client->issue_op_head,
-                               handle->client->issue_op_tail,
-                               handle);
-  if (GNUNET_SYSERR == success)
+  struct TicketIssueOperation *tio = cls;
+  if (GNUNET_OK != success)
   {
-    cleanup_ticket_issue_handle (handle);
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n",
-                "Unknown Error\n");
-    GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
+    send_ticket_result (tio->client,
+                        tio->r_id,
+                        NULL,
+                        GNUNET_SYSERR);
+    GNUNET_CONTAINER_DLL_remove (tio->client->issue_op_head,
+                                 tio->client->issue_op_tail,
+                                 tio);
+    GNUNET_free (tio);
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Error issuing ticket: %s\n",
+                emsg);
     return;
   }
-  send_ticket_result (handle->client,
-                      handle->r_id,
-                      &handle->ticket,
-                      handle->attrs);
-  cleanup_ticket_issue_handle (handle);
+  send_ticket_result (tio->client,
+                      tio->r_id,
+                      ticket,
+                      GNUNET_SYSERR);
+  GNUNET_CONTAINER_DLL_remove (tio->client->issue_op_head,
+                               tio->client->issue_op_tail,
+                               tio);
+  GNUNET_free (tio);
+}
+
+static int
+check_issue_ticket_message (void *cls,
+                            const struct IssueTicketMessage *im)
+{
+  uint16_t size;
+
+  size = ntohs (im->header.size);
+  if (size <= sizeof (struct IssueTicketMessage))
+  {
+    GNUNET_break (0);
+    return GNUNET_SYSERR;
+  }
+  return GNUNET_OK;
 }
 
+static void
+handle_issue_ticket_message (void *cls,
+                             const struct IssueTicketMessage *im)
+{
+  struct TicketIssueOperation *tio;
+  struct IdpClient *idp = cls;
+  struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs;
+  size_t attrs_len;
+
+  tio = GNUNET_new (struct TicketIssueOperation);
+  attrs_len = ntohs (im->attr_len);
+  attrs = GNUNET_RECLAIM_ATTRIBUTE_list_deserialize ((char*)&im[1], attrs_len);
+  tio->r_id = ntohl (im->id);
+  tio->client = idp;
+  GNUNET_CONTAINER_DLL_insert (idp->issue_op_head,
+                               idp->issue_op_tail,
+                               tio);
+  RECLAIM_TICKETS_issue_ticket (&im->identity,
+                                attrs,
+                                &im->rp,
+                                &issue_ticket_result_cb,
+                                tio);
+  GNUNET_SERVICE_client_continue (idp->client);
+  GNUNET_RECLAIM_ATTRIBUTE_list_destroy (attrs);
+}
+
+/**********************************************************
+ * Revocation
+ **********************************************************/
+
+/**
+ * Cleanup revoke handle
+ *
+ * @param rh the ticket revocation handle
+ */
+static void
+cleanup_revoke_ticket_handle (struct TicketRevocationHandle *rh)
+{
+  if (NULL != rh->attrs)
+    GNUNET_RECLAIM_ATTRIBUTE_list_destroy (rh->attrs);
+  if (NULL != rh->rvk_attrs)
+    GNUNET_RECLAIM_ATTRIBUTE_list_destroy (rh->rvk_attrs);
+  if (NULL != rh->ns_qe)
+    GNUNET_NAMESTORE_cancel (rh->ns_qe);
+  if (NULL != rh->ns_it)
+    GNUNET_NAMESTORE_zone_iteration_stop (rh->ns_it);
+  GNUNET_free (rh);
+}
 
 static int
 serialize_authz_record (const struct GNUNET_RECLAIM_Ticket *ticket,
-                         const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs,
-                         struct GNUNET_CRYPTO_EcdhePrivateKey **ecdh_privkey,
-                         char **result)
+                        const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs,
+                        struct GNUNET_CRYPTO_EcdhePrivateKey **ecdh_privkey,
+                        char **result)
 {
   struct GNUNET_CRYPTO_EcdhePublicKey ecdh_pubkey;
   struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le;
@@ -833,111 +845,6 @@ serialize_authz_record (const struct GNUNET_RECLAIM_Ticket *ticket,
 }
 
 
-
-static void
-issue_ticket (struct TicketIssueHandle *ih)
-{
-  struct GNUNET_CRYPTO_EcdhePrivateKey *ecdhe_privkey;
-  struct GNUNET_GNSRECORD_Data code_record[1];
-  char *authz_record_data;
-  size_t authz_record_len;
-  char *label;
-
-  //TODO rename function
-  authz_record_len = serialize_authz_record (&ih->ticket,
-                                             ih->attrs,
-                                             &ecdhe_privkey,
-                                             &authz_record_data);
-  code_record[0].data = authz_record_data;
-  code_record[0].data_size = authz_record_len;
-  code_record[0].expiration_time = GNUNET_TIME_UNIT_DAYS.rel_value_us;
-  code_record[0].record_type = GNUNET_GNSRECORD_TYPE_RECLAIM_AUTHZ;
-  code_record[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
-
-  label = GNUNET_STRINGS_data_to_string_alloc (&ih->ticket.rnd,
-                                               sizeof (uint64_t));
-  //Publish record
-  ih->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
-                                              &ih->identity,
-                                              label,
-                                              1,
-                                              code_record,
-                                              &store_ticket_issue_cont,
-                                              ih);
-  GNUNET_free (ecdhe_privkey);
-  GNUNET_free (label);
-  GNUNET_free (authz_record_data);
-}
-
-
-static int
-check_issue_ticket_message(void *cls,
-                           const struct IssueTicketMessage *im)
-{
-  uint16_t size;
-
-  size = ntohs (im->header.size);
-  if (size <= sizeof (struct IssueTicketMessage))
-  {
-    GNUNET_break (0);
-    return GNUNET_SYSERR;
-  }
-  return GNUNET_OK;
-}
-
-
-static void
-handle_issue_ticket_message (void *cls,
-                             const struct IssueTicketMessage *im)
-{
-  struct TicketIssueHandle *ih;
-  struct IdpClient *idp = cls;
-  size_t attrs_len;
-
-  ih = GNUNET_new (struct TicketIssueHandle);
-  attrs_len = ntohs (im->attr_len);
-  ih->attrs = GNUNET_RECLAIM_ATTRIBUTE_list_deserialize ((char*)&im[1], attrs_len);
-  ih->r_id = ntohl (im->id);
-  ih->client = idp;
-  ih->identity = im->identity;
-  GNUNET_CRYPTO_ecdsa_key_get_public (&ih->identity,
-                                      &ih->ticket.identity);
-  ih->ticket.audience = im->rp;
-  ih->ticket.rnd =
-    GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG,
-                              UINT64_MAX);
-  GNUNET_CONTAINER_DLL_insert (idp->issue_op_head,
-                               idp->issue_op_tail,
-                               ih);
-  issue_ticket (ih);
-  GNUNET_SERVICE_client_continue (idp->client);
-
-}
-
-/**********************************************************
- * Revocation
- **********************************************************/
-
-/**
- * Cleanup revoke handle
- *
- * @param rh the ticket revocation handle
- */
-static void
-cleanup_revoke_ticket_handle (struct TicketRevocationHandle *rh)
-{
-  if (NULL != rh->attrs)
-    GNUNET_RECLAIM_ATTRIBUTE_list_destroy (rh->attrs);
-  if (NULL != rh->rvk_attrs)
-    GNUNET_RECLAIM_ATTRIBUTE_list_destroy (rh->rvk_attrs);
-  if (NULL != rh->ns_qe)
-    GNUNET_NAMESTORE_cancel (rh->ns_qe);
-  if (NULL != rh->ns_it)
-    GNUNET_NAMESTORE_zone_iteration_stop (rh->ns_it);
-  GNUNET_free (rh);
-}
-
-
 /**
  * Send revocation result
  *
@@ -1086,8 +993,6 @@ ticket_reissue_proc (void *cls,
 
     rh->offset++;
     GNUNET_SCHEDULER_add_now (&reissue_next, rh);
-
-
     return;
   }
 
@@ -1186,6 +1091,7 @@ check_attr_cb (void *cls,
 {
   struct TicketRevocationHandle *rh = cls;
   struct TicketAttributeUpdateEntry *tue;
+  struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le;
   struct GNUNET_GNSRECORD_Data rd[1];
   char* buf;
   size_t buf_size;
@@ -1193,6 +1099,16 @@ check_attr_cb (void *cls,
 
   rh->ns_qe = NULL;
   if (1 != rd_count) {
+    le = rh->attrs->list_head;
+    GNUNET_CONTAINER_DLL_remove (rh->attrs->list_head,
+                                 rh->attrs->list_tail,
+                                 le);
+    GNUNET_assert (NULL != rh->rvk_attrs);
+    GNUNET_CONTAINER_DLL_insert (rh->rvk_attrs->list_head,
+                                 rh->rvk_attrs->list_tail,
+                                 le);
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "Re-encrypting next attribute\n");
     GNUNET_SCHEDULER_add_now (&reenc_next_attribute,
                               rh);
     return;
@@ -1213,7 +1129,7 @@ check_attr_cb (void *cls,
   rh->attrs->list_head->claim->id = tue->new_id;
   new_label = GNUNET_STRINGS_data_to_string_alloc (&tue->new_id,
                                                    sizeof (uint64_t));
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+  GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
               "New attr id %s\n", new_label);
   rd[0].data_size = buf_size;
   rd[0].data = buf;
@@ -1247,6 +1163,7 @@ reenc_next_attribute (void *cls)
   /* First check if attribute still exists */
   label = GNUNET_STRINGS_data_to_string_alloc (&rh->attrs->list_head->claim->id,
                                                sizeof (uint64_t));
+  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "ID: %lu\n", rh->attrs->list_head->claim->id);
   rh->ns_qe = GNUNET_NAMESTORE_records_lookup (nsh,
                                                &rh->identity,
                                                label,
@@ -1308,7 +1225,7 @@ process_attributes_to_update (void *cls,
   struct TicketRevocationHandle *rh = cls;
 
   rh->attrs = GNUNET_RECLAIM_ATTRIBUTE_list_dup (attrs);
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+  GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
               "Revocation Phase I: Collecting attributes\n");
   /* Reencrypt all attributes with new key */
   if (NULL == rh->attrs->list_head)
@@ -1318,7 +1235,7 @@ process_attributes_to_update (void *cls,
     cleanup_revoke_ticket_handle (rh);
     return;
   } else {
-    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                 "Revocation Phase II: Re-encrypting attributes\n");
     reenc_next_attribute (rh);
   }
@@ -1463,16 +1380,16 @@ process_parallel_lookup2 (void *cls, uint32_t rd_count,
   /* Else we are done */
 
   /** Store ticket in DB
-   * TODO: Store in GNS
+   * TODO: Store in GNS?
    */
-  if (GNUNET_OK != TKT_database->store_ticket (TKT_database->cls,
-                                               &handle->ticket,
-                                               handle->attrs))
-  {
+  /**if (GNUNET_OK != TKT_database->store_ticket (TKT_database->cls,
+    &handle->ticket,
+    handle->attrs))
+    {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Unable to store ticket after consume\n");
+    "Unable to store ticket after consume\n");
     GNUNET_break (0);
-  }
+    }*/
 
   GNUNET_SCHEDULER_cancel (handle->kill_task);
   attrs_len = GNUNET_RECLAIM_ATTRIBUTE_list_serialize_get_size (handle->attrs);
@@ -1775,7 +1692,7 @@ handle_attribute_store_message (void *cls,
 
   ash = GNUNET_new (struct AttributeStoreHandle);
   ash->claim = GNUNET_RECLAIM_ATTRIBUTE_deserialize ((char*)&sam[1],
-                                                           data_len);
+                                                     data_len);
 
   ash->r_id = ntohl (sam->id);
   ash->identity = sam->identity;
@@ -2028,7 +1945,7 @@ ticket_iterate_proc (void *cls,
   send_ticket_result (proc->ti->client,
                       proc->ti->r_id,
                       ticket,
-                      attrs);
+                      GNUNET_OK);
 
 }
 
@@ -2180,6 +2097,13 @@ run (void *cls,
 
   stats = GNUNET_STATISTICS_create ("reclaim", cfg);
 
+  if (GNUNET_OK != RECLAIM_TICKETS_init (cfg))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Unable to initialized TICKETS subsystem.\n");
+    GNUNET_SCHEDULER_shutdown ();
+    return;
+  }
   //Connect to identity and namestore services
   nsh = GNUNET_NAMESTORE_connect (cfg);
   if (NULL == nsh)
@@ -2192,11 +2116,6 @@ run (void *cls,
   {
     GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "error connecting to gns");
   }
-  credential_handle = GNUNET_CREDENTIAL_connect (cfg);
-  if (NULL == credential_handle)
-  {
-    GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "error connecting to credential");
-  }
   identity_handle = GNUNET_IDENTITY_connect (cfg,
                                              NULL,
                                              NULL);
@@ -2256,7 +2175,7 @@ client_disconnect_cb (void *cls,
   struct AttributeIterator *ai;
   struct TicketIteration *ti;
   struct TicketRevocationHandle *rh;
-  struct TicketIssueHandle *iss;
+  struct TicketIssueOperation *iss;
   struct ConsumeTicketHandle *ct;
   struct AttributeStoreHandle *as;
 
@@ -2271,7 +2190,7 @@ client_disconnect_cb (void *cls,
     GNUNET_CONTAINER_DLL_remove (idp->issue_op_head,
                                  idp->issue_op_tail,
                                  iss);
-    cleanup_ticket_issue_handle (iss);
+    GNUNET_free (iss);
   }
   while (NULL != (ct = idp->consume_op_head))
   {
diff --git a/src/reclaim/gnunet-service-reclaim_tickets.c b/src/reclaim/gnunet-service-reclaim_tickets.c
new file mode 100644 (file)
index 0000000..f93e934
--- /dev/null
@@ -0,0 +1,455 @@
+/*
+   This file is part of GNUnet.
+   Copyright (C) 2012-2015 GNUnet e.V.
+
+   GNUnet is free software: you can redistribute it and/or modify it
+   under the terms of the GNU Affero General Public License as published
+   by the Free Software Foundation, either version 3 of the License,
+   or (at your option) any later version.
+
+   GNUnet 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
+   Affero General Public License for more details.
+
+   You should have received a copy of the GNU Affero General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+   SPDX-License-Identifier: AGPL3.0-or-later
+   */
+
+/**
+ * @author Martin Schanzenbach
+ * @file src/reclaim/gnunet-service-reclaim_tickets.c
+ * @brief reclaim tickets
+ *
+ */
+#include "gnunet-service-reclaim_tickets.h"
+
+/**
+ * A reference to a ticket stored in GNS
+ */
+struct TicketReference
+{
+  /**
+   * DLL
+   */
+  struct TicketReference *next;
+
+  /**
+   * DLL
+   */
+  struct TicketReference *prev;
+
+  /**
+   * Attributes
+   */
+  struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs;
+
+  /**
+   * Tickets
+   */
+  struct GNUNET_RECLAIM_Ticket ticket;
+};
+
+
+/**
+ * Ticket issue request handle
+ */
+struct TicketIssueHandle
+{
+  /**
+   * Attributes to issue
+   */
+  struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs;
+
+  /**
+   * Issuer Key
+   */
+  struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
+
+  /**
+   * Ticket to issue
+   */
+  struct GNUNET_RECLAIM_Ticket ticket;
+
+  /**
+   * QueueEntry
+   */
+  struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
+
+  /**
+   * Ticket reference list
+   */
+  struct TicketReference *ticket_refs_head;
+
+  /**
+   * Ticket reference list
+   */
+  struct TicketReference *ticket_refs_tail;
+
+  /**
+   * Number of references
+   */
+  uint32_t ticket_ref_num;
+
+  /**
+   * Callback
+   */
+  RECLAIM_TICKETS_TicketResult cb;
+
+  /**
+   * Callback cls
+   */
+  void *cb_cls;
+
+};
+
+static struct GNUNET_NAMESTORE_Handle *nsh;
+
+/**
+ * Cleanup ticket consume handle
+ * @param handle the handle to clean up
+ */
+static void
+cleanup_issue_handle (struct TicketIssueHandle *handle)
+{
+  struct TicketReference *tr;
+  struct TicketReference *tr_tmp;
+  if (NULL != handle->attrs)
+    GNUNET_RECLAIM_ATTRIBUTE_list_destroy (handle->attrs);
+  if (NULL != handle->ns_qe)
+    GNUNET_NAMESTORE_cancel (handle->ns_qe);
+  for (tr = handle->ticket_refs_head; NULL != tr;)
+  {
+    if (NULL != tr->attrs)
+      GNUNET_RECLAIM_ATTRIBUTE_list_destroy (tr->attrs);
+    tr_tmp = tr;
+    tr = tr->next;
+    GNUNET_free (tr_tmp);
+  }
+  GNUNET_free (handle);
+}
+
+
+
+static void
+store_ticket_refs_cont (void *cls,
+                        int32_t success,
+                        const char *emsg)
+{
+  struct TicketIssueHandle *handle = cls;
+  handle->ns_qe = NULL;
+  if (GNUNET_OK != success)
+  {
+    handle->cb (handle->cb_cls,
+                NULL,
+                GNUNET_SYSERR,
+                "Error storing updated ticket refs in GNS");
+    cleanup_issue_handle (handle);
+    return;
+  }
+  handle->cb (handle->cb_cls,
+              &handle->ticket,
+              GNUNET_OK,
+              NULL);
+  cleanup_issue_handle (handle);
+}
+
+
+
+static void
+update_ticket_refs (void* cls)
+{
+  struct TicketIssueHandle *handle = cls;
+  struct GNUNET_GNSRECORD_Data refs_rd[handle->ticket_ref_num];
+  struct TicketReference *tr;
+  char* buf;
+  size_t buf_size;
+
+  tr = handle->ticket_refs_head;
+  for (int i = 0; i < handle->ticket_ref_num; i++)
+  {
+    buf_size = GNUNET_RECLAIM_ATTRIBUTE_list_serialize_get_size (tr->attrs);
+    buf_size += sizeof (struct GNUNET_RECLAIM_Ticket);
+    buf = GNUNET_malloc (buf_size);
+    memcpy (buf, &tr->ticket, sizeof (struct GNUNET_RECLAIM_Ticket));
+    GNUNET_RECLAIM_ATTRIBUTE_list_serialize (tr->attrs,
+                                             buf + sizeof (struct GNUNET_RECLAIM_Ticket));
+    refs_rd[i].data = buf;
+    refs_rd[i].data_size = buf_size;
+    refs_rd[i].expiration_time = GNUNET_TIME_UNIT_DAYS.rel_value_us;
+    refs_rd[i].record_type = GNUNET_GNSRECORD_TYPE_RECLAIM_TICKETREF;
+    refs_rd[i].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION |
+      GNUNET_GNSRECORD_RF_PRIVATE;
+    tr = tr->next;
+  }
+
+  handle->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
+                                                  &handle->identity,
+                                                  GNUNET_GNS_EMPTY_LABEL_AT,
+                                                  handle->ticket_ref_num,
+                                                  refs_rd,
+                                                  &store_ticket_refs_cont,
+                                                  handle);
+  for (int i = 0; i < handle->ticket_ref_num; i++)
+    GNUNET_free ((char*)refs_rd[i].data);
+}
+
+
+
+static void
+ticket_lookup_cb (void *cls,
+                  const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
+                  const char *label,
+                  unsigned int rd_count,
+                  const struct GNUNET_GNSRECORD_Data *rd)
+{
+  struct TicketIssueHandle *handle = cls;
+  struct TicketReference *tr;
+  const char* attr_data;
+  size_t attr_data_len;
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Received tickets from local namestore.\n");
+  handle->ns_qe = NULL;
+  for (int i = 0; i < rd_count; i++)
+  {
+    if (GNUNET_GNSRECORD_TYPE_RECLAIM_TICKETREF != rd[i].record_type)
+      continue;
+    tr = GNUNET_new (struct TicketReference);
+    memcpy (&tr->ticket, rd[i].data,
+            sizeof (struct GNUNET_RECLAIM_Ticket));
+    if (0 != memcmp (&tr->ticket.identity,
+                     &handle->ticket.identity,
+                     sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)))
+    {
+      //Not our ticket
+      GNUNET_free (tr);
+      continue;
+    }
+    attr_data = rd[i].data + sizeof (struct GNUNET_RECLAIM_Ticket);
+    attr_data_len = rd[i].data_size - sizeof (struct GNUNET_RECLAIM_Ticket);
+    tr->attrs = GNUNET_RECLAIM_ATTRIBUTE_list_deserialize (attr_data,
+                                                           attr_data_len);
+    GNUNET_CONTAINER_DLL_insert (handle->ticket_refs_head,
+                                 handle->ticket_refs_tail,
+                                 tr);
+    handle->ticket_ref_num++;
+  }
+  tr = GNUNET_new (struct TicketReference);
+  tr->ticket = handle->ticket;
+  tr->attrs = GNUNET_RECLAIM_ATTRIBUTE_list_dup (handle->attrs);
+  GNUNET_CONTAINER_DLL_insert (handle->ticket_refs_head,
+                               handle->ticket_refs_tail,
+                               tr);
+  handle->ticket_ref_num++;
+  GNUNET_SCHEDULER_add_now (&update_ticket_refs, handle);
+}
+
+static void
+ticket_lookup_error_cb (void *cls)
+{
+  struct TicketIssueHandle *handle = cls;
+  handle->ns_qe = NULL;
+  handle->cb (handle->cb_cls,
+              &handle->ticket,
+              GNUNET_SYSERR,
+              "Error checking for ticketsin GNS\n");
+  cleanup_issue_handle (handle);
+}
+
+static void
+store_ticket_issue_cont (void *cls,
+                         int32_t success,
+                         const char *emsg)
+{
+  struct TicketIssueHandle *handle = cls;
+
+  handle->ns_qe = NULL;
+  if (GNUNET_SYSERR == success)
+  {
+    handle->cb (handle->cb_cls,
+                &handle->ticket,
+                GNUNET_SYSERR,
+                "Error storing AuthZ ticket in GNS");
+    return;
+  }
+  /* First, local references to tickets */
+  handle->ns_qe = GNUNET_NAMESTORE_records_lookup (nsh,
+                                                   &handle->identity,
+                                                   GNUNET_GNS_EMPTY_LABEL_AT,
+                                                   &ticket_lookup_error_cb,
+                                                   handle,
+                                                   &ticket_lookup_cb,
+                                                   handle);
+}
+
+static int
+create_sym_key_from_ecdh (const struct GNUNET_HashCode *new_key_hash,
+                          struct GNUNET_CRYPTO_SymmetricSessionKey *skey,
+                          struct GNUNET_CRYPTO_SymmetricInitializationVector *iv)
+{
+  struct GNUNET_CRYPTO_HashAsciiEncoded new_key_hash_str;
+
+  GNUNET_CRYPTO_hash_to_enc (new_key_hash,
+                             &new_key_hash_str);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating symmetric rsa key from %s\n", (char*)&new_key_hash_str);
+  static const char ctx_key[] = "gnuid-aes-ctx-key";
+  GNUNET_CRYPTO_kdf (skey, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
+                     new_key_hash, sizeof (struct GNUNET_HashCode),
+                     ctx_key, strlen (ctx_key),
+                     NULL, 0);
+  static const char ctx_iv[] = "gnuid-aes-ctx-iv";
+  GNUNET_CRYPTO_kdf (iv, sizeof (struct GNUNET_CRYPTO_SymmetricInitializationVector),
+                     new_key_hash, sizeof (struct GNUNET_HashCode),
+                     ctx_iv, strlen (ctx_iv),
+                     NULL, 0);
+  return GNUNET_OK;
+}
+
+
+static int
+serialize_authz_record (const struct GNUNET_RECLAIM_Ticket *ticket,
+                        const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs,
+                        struct GNUNET_CRYPTO_EcdhePrivateKey **ecdh_privkey,
+                        char **result)
+{
+  struct GNUNET_CRYPTO_EcdhePublicKey ecdh_pubkey;
+  struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le;
+  struct GNUNET_CRYPTO_SymmetricSessionKey skey;
+  struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
+  struct GNUNET_HashCode new_key_hash;
+  ssize_t enc_size;
+  char *enc_keyinfo;
+  char *buf;
+  char *write_ptr;
+  char attrs_str_len;
+  char* label;
+
+  GNUNET_assert (NULL != attrs->list_head);
+  attrs_str_len = 0;
+  for (le = attrs->list_head; NULL != le; le = le->next) {
+    attrs_str_len += 15 + 1; //TODO propery calculate
+  }
+  buf = GNUNET_malloc (attrs_str_len);
+  write_ptr = buf;
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Writing attributes\n");
+  for (le = attrs->list_head; NULL != le; le = le->next) {
+    label = GNUNET_STRINGS_data_to_string_alloc (&le->claim->id,
+                                                 sizeof (uint64_t));
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Adding attribute to record: %s\n", label);
+
+    GNUNET_memcpy (write_ptr,
+                   label,
+                   strlen (label));
+    write_ptr[strlen (label)] = ',';
+    write_ptr += strlen (label) + 1;
+    GNUNET_free (label);
+  }
+  write_ptr--;
+  write_ptr[0] = '\0'; //replace last , with a 0-terminator
+  // ECDH keypair E = eG
+  *ecdh_privkey = GNUNET_CRYPTO_ecdhe_key_create();
+  GNUNET_CRYPTO_ecdhe_key_get_public (*ecdh_privkey,
+                                      &ecdh_pubkey);
+  enc_keyinfo = GNUNET_malloc (attrs_str_len);
+  // Derived key K = H(eB)
+  GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecdh_ecdsa (*ecdh_privkey,
+                                                        &ticket->audience,
+                                                        &new_key_hash));
+  create_sym_key_from_ecdh (&new_key_hash, &skey, &iv);
+  enc_size = GNUNET_CRYPTO_symmetric_encrypt (buf,
+                                              attrs_str_len,
+                                              &skey, &iv,
+                                              enc_keyinfo);
+  *result = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)+
+                           enc_size);
+  GNUNET_memcpy (*result,
+                 &ecdh_pubkey,
+                 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
+  GNUNET_memcpy (*result + sizeof (struct GNUNET_CRYPTO_EcdhePublicKey),
+                 enc_keyinfo,
+                 enc_size);
+  GNUNET_free (enc_keyinfo);
+  GNUNET_free (buf);
+  return sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)+enc_size;
+}
+
+
+
+static void
+issue_ticket (struct TicketIssueHandle *ih)
+{
+  struct GNUNET_CRYPTO_EcdhePrivateKey *ecdhe_privkey;
+  struct GNUNET_GNSRECORD_Data code_record[1];
+  char *authz_record_data;
+  size_t authz_record_len;
+  char *label;
+
+  //TODO rename function
+  authz_record_len = serialize_authz_record (&ih->ticket,
+                                             ih->attrs,
+                                             &ecdhe_privkey,
+                                             &authz_record_data);
+  code_record[0].data = authz_record_data;
+  code_record[0].data_size = authz_record_len;
+  code_record[0].expiration_time = GNUNET_TIME_UNIT_DAYS.rel_value_us;
+  code_record[0].record_type = GNUNET_GNSRECORD_TYPE_RECLAIM_AUTHZ;
+  code_record[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
+
+  label = GNUNET_STRINGS_data_to_string_alloc (&ih->ticket.rnd,
+                                               sizeof (uint64_t));
+  //Publish record
+  ih->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
+                                              &ih->identity,
+                                              label,
+                                              1,
+                                              code_record,
+                                              &store_ticket_issue_cont,
+                                              ih);
+  GNUNET_free (ecdhe_privkey);
+  GNUNET_free (label);
+  GNUNET_free (authz_record_data);
+}
+
+
+
+
+void
+RECLAIM_TICKETS_issue_ticket (const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
+                              const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs,
+                              const struct GNUNET_CRYPTO_EcdsaPublicKey *audience,
+                              RECLAIM_TICKETS_TicketResult cb,
+                              void* cb_cls)
+{
+  struct TicketIssueHandle *tih;
+  tih = GNUNET_new (struct TicketIssueHandle);
+  tih->cb = cb;
+  tih->cb_cls = cb_cls;
+  tih->attrs = GNUNET_RECLAIM_ATTRIBUTE_list_dup (attrs);
+  tih->identity = *identity;
+  GNUNET_CRYPTO_ecdsa_key_get_public (identity,
+                                      &tih->ticket.identity);
+  tih->ticket.rnd =
+    GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG,
+                              UINT64_MAX);
+  tih->ticket.audience = *audience;
+  issue_ticket (tih);
+}
+
+
+int
+RECLAIM_TICKETS_init (const struct GNUNET_CONFIGURATION_Handle *c)
+{
+  //Connect to identity and namestore services
+  nsh = GNUNET_NAMESTORE_connect (c);
+  if (NULL == nsh)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Error connecting to namestore\n");
+    return GNUNET_SYSERR;
+  }
+  return GNUNET_OK;
+}
diff --git a/src/reclaim/gnunet-service-reclaim_tickets.h b/src/reclaim/gnunet-service-reclaim_tickets.h
new file mode 100644 (file)
index 0000000..7ad86db
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+   This file is part of GNUnet.
+   Copyright (C) 2012-2015 GNUnet e.V.
+
+   GNUnet is free software: you can redistribute it and/or modify it
+   under the terms of the GNU Affero General Public License as published
+   by the Free Software Foundation, either version 3 of the License,
+   or (at your option) any later version.
+
+   GNUnet 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
+   Affero General Public License for more details.
+
+   You should have received a copy of the GNU Affero General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+   SPDX-License-Identifier: AGPL3.0-or-later
+   */
+#include "platform.h"
+#include "gnunet_util_lib.h"
+#include "gnunet_constants.h"
+#include "gnunet_protocols.h"
+#include "gnunet_gnsrecord_lib.h"
+#include "gnunet_gns_service.h"
+#include "gnunet_namestore_service.h"
+#include "gnunet_statistics_service.h"
+#include "gnunet_reclaim_plugin.h"
+#include "gnunet_reclaim_attribute_lib.h"
+#include "gnunet_signatures.h"
+#include "reclaim.h"
+
+/**
+ * Continuation called with ticket.
+ *
+ * @param cls closure
+ * @param ticket the ticket
+ * @param success #GNUNET_SYSERR on failure (including timeout/queue drop/failure to validate)
+ *                #GNUNET_OK on success
+ * @param emsg NULL on success, otherwise an error message
+ */
+typedef void
+(*RECLAIM_TICKETS_TicketResult) (void *cls,
+                                 struct GNUNET_RECLAIM_Ticket *ticket,
+                                 uint32_t success,
+                                 const char *emsg);
+
+
+/**
+ * @author Martin Schanzenbach
+ * @file src/reclaim/gnunet-service-reclaim_tickets.h
+ * @brief reclaim tickets
+ *
+ */
+void
+RECLAIM_TICKETS_issue_ticket (const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
+                              const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs,
+                              const struct GNUNET_CRYPTO_EcdsaPublicKey *audience,
+                              RECLAIM_TICKETS_TicketResult cb,
+                              void* cb_cls);
+
+int
+RECLAIM_TICKETS_init (const struct GNUNET_CONFIGURATION_Handle *c);
index d4d937f7e518d2a952235481399a6b3336cc2ffc..2f075d8b90f46cf623a69ef92ed1269250835581 100644 (file)
@@ -52,6 +52,7 @@ value_to_string (void *cls,
     case GNUNET_GNSRECORD_TYPE_RECLAIM_OIDC_CLIENT:
       return GNUNET_strndup (data, data_size);
     case GNUNET_GNSRECORD_TYPE_RECLAIM_AUTHZ:
+    case GNUNET_GNSRECORD_TYPE_RECLAIM_TICKETREF:
     case GNUNET_GNSRECORD_TYPE_RECLAIM_MASTER:
       return GNUNET_STRINGS_data_to_string_alloc (data, data_size);
     default:
@@ -94,6 +95,7 @@ string_to_value (void *cls,
       return GNUNET_OK;
     case GNUNET_GNSRECORD_TYPE_RECLAIM_AUTHZ:
     case GNUNET_GNSRECORD_TYPE_RECLAIM_MASTER:
+    case GNUNET_GNSRECORD_TYPE_RECLAIM_TICKETREF:
       return GNUNET_STRINGS_string_to_data (s,
                                             strlen (s),
                                             *data,
@@ -117,6 +119,7 @@ static struct {
   { "RECLAIM_MASTER", GNUNET_GNSRECORD_TYPE_RECLAIM_MASTER },
   { "RECLAIM_OIDC_CLIENT", GNUNET_GNSRECORD_TYPE_RECLAIM_OIDC_CLIENT },
   { "RECLAIM_OIDC_REDIRECT", GNUNET_GNSRECORD_TYPE_RECLAIM_OIDC_REDIRECT },
+  { "RECLAIM_TICKETREF", GNUNET_GNSRECORD_TYPE_RECLAIM_TICKETREF },
   { NULL, UINT32_MAX }
 };
 
index cfa0cbbfb0b9cfad18f6092dc3df7f9af238b849..c8fde121b7cc2b31bc875c1413a0a5368dd0a847 100644 (file)
@@ -11,7 +11,7 @@
      WITHOUT ANY WARRANTY; without even the implied warranty of
      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      Affero General Public License for more details.
-    
+
      You should have received a copy of the GNU Affero General Public License
      along with this program.  If not, see <http://www.gnu.org/licenses/>.