From: Schanzenbach, Martin Date: Fri, 12 Apr 2019 12:31:06 +0000 (+0200) Subject: RECLAIM: refactoring; cleanup X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=d966a8fc091b1e34b1e4dfe975bccd7b26a80d45;p=oweals%2Fgnunet.git RECLAIM: refactoring; cleanup --- diff --git a/src/include/gnunet_gnsrecord_lib.h b/src/include/gnunet_gnsrecord_lib.h index c76e87d12..27228c0bc 100644 --- a/src/include/gnunet_gnsrecord_lib.h +++ b/src/include/gnunet_gnsrecord_lib.h @@ -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 */ /** diff --git a/src/reclaim-attribute/reclaim_attribute.c b/src/reclaim-attribute/reclaim_attribute.c index 3d260f15b..86f0f8f67 100644 --- a/src/reclaim-attribute/reclaim_attribute.c +++ b/src/reclaim-attribute/reclaim_attribute.c @@ -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); 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" /** @@ -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 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 . + + 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 . + + 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 .