summaryrefslogtreecommitdiff
path: root/src/reclaim
diff options
context:
space:
mode:
authorSchanzenbach, Martin <mschanzenbach@posteo.de>2019-04-12 14:31:06 +0200
committerSchanzenbach, Martin <mschanzenbach@posteo.de>2019-04-14 10:01:23 +0200
commita12b8c2c4cbf952c8c305cde193bb25c13a0912b (patch)
tree0c7f27a870ce6fc8789e1b9672156758b1c1c2e6 /src/reclaim
parent947b84dcdee19d6a4b1fcad10618a2b4f505b3b9 (diff)
RECLAIM: refactoring; cleanup
Diffstat (limited to 'src/reclaim')
-rw-r--r--src/reclaim/Makefile.am4
-rw-r--r--src/reclaim/gnunet-service-reclaim.c369
-rw-r--r--src/reclaim/gnunet-service-reclaim_tickets.c455
-rw-r--r--src/reclaim/gnunet-service-reclaim_tickets.h63
-rw-r--r--src/reclaim/plugin_gnsrecord_reclaim.c3
-rw-r--r--src/reclaim/reclaim_api.c2
6 files changed, 668 insertions, 228 deletions
diff --git a/src/reclaim/Makefile.am b/src/reclaim/Makefile.am
index 210759fce..7e8686734 100644
--- a/src/reclaim/Makefile.am
+++ b/src/reclaim/Makefile.am
@@ -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 \
diff --git a/src/reclaim/gnunet-service-reclaim.c b/src/reclaim/gnunet-service-reclaim.c
index f3a6e2073..b963b0a9b 100644
--- a/src/reclaim/gnunet-service-reclaim.c
+++ b/src/reclaim/gnunet-service-reclaim.c
@@ -30,12 +30,12 @@
#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"
/**
@@ -89,21 +89,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
*/
static struct GNUNET_SCHEDULER_Task *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,19 +528,19 @@ 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
@@ -563,26 +548,6 @@ struct TicketIssueHandle
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
*/
uint32_t r_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
index 000000000..f93e934ee
--- /dev/null
+++ b/src/reclaim/gnunet-service-reclaim_tickets.c
@@ -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
index 000000000..7ad86dba5
--- /dev/null
+++ b/src/reclaim/gnunet-service-reclaim_tickets.h
@@ -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);
diff --git a/src/reclaim/plugin_gnsrecord_reclaim.c b/src/reclaim/plugin_gnsrecord_reclaim.c
index d4d937f7e..2f075d8b9 100644
--- a/src/reclaim/plugin_gnsrecord_reclaim.c
+++ b/src/reclaim/plugin_gnsrecord_reclaim.c
@@ -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 }
};
diff --git a/src/reclaim/reclaim_api.c b/src/reclaim/reclaim_api.c
index cfa0cbbfb..c8fde121b 100644
--- a/src/reclaim/reclaim_api.c
+++ b/src/reclaim/reclaim_api.c
@@ -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/>.