From 58d4e0f0447ae4efc6b3f4ba8a3d612c22f7cbb4 Mon Sep 17 00:00:00 2001 From: "Schanzenbach, Martin" Date: Fri, 6 Oct 2017 22:31:12 +0200 Subject: [PATCH] -more revocation --- .../gnunet-service-identity-provider.c | 177 ++++++++++++++++-- .../plugin_identity_provider_sqlite.c | 41 ++-- src/include/gnunet_identity_provider_plugin.h | 6 +- 3 files changed, 195 insertions(+), 29 deletions(-) diff --git a/src/identity-provider/gnunet-service-identity-provider.c b/src/identity-provider/gnunet-service-identity-provider.c index 95d8b93b2..dd78dd9aa 100644 --- a/src/identity-provider/gnunet-service-identity-provider.c +++ b/src/identity-provider/gnunet-service-identity-provider.c @@ -482,6 +482,10 @@ struct TicketRevocationHandle */ struct GNUNET_CRYPTO_AbeMasterKey *abe_key; + /** + * Offset + */ + uint32_t offset; /** * request id @@ -770,7 +774,8 @@ cleanup_ticket_issue_handle (struct TicketIssueHandle *handle) static void send_ticket_result (struct IdpClient *client, uint32_t r_id, - const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket) + const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket, + const struct GNUNET_IDENTITY_PROVIDER_AttributeList *attrs) { struct TicketResultMessage *irm; struct GNUNET_MQ_Envelope *env; @@ -778,7 +783,8 @@ send_ticket_result (struct IdpClient *client, /* store ticket in DB */ if (GNUNET_OK != TKT_database->store_ticket (TKT_database->cls, - ticket)) + ticket, + attrs)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unable to store ticket after issue\n"); @@ -813,14 +819,16 @@ store_ticket_issue_cont (void *cls, } send_ticket_result (handle->client, handle->r_id, - &handle->ticket); + &handle->ticket, + handle->attrs); cleanup_ticket_issue_handle (handle); } int -serialize_abe_keyinfo2 (const struct TicketIssueHandle *handle, +serialize_abe_keyinfo2 (const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket, + const struct GNUNET_IDENTITY_PROVIDER_AttributeList *attrs, const struct GNUNET_CRYPTO_AbeKey *rp_key, struct GNUNET_CRYPTO_EcdhePrivateKey **ecdh_privkey, char **result) @@ -842,14 +850,14 @@ serialize_abe_keyinfo2 (const struct TicketIssueHandle *handle, size = GNUNET_CRYPTO_cpabe_serialize_key (rp_key, (void**)&serialized_key); attrs_str_len = 0; - for (le = handle->attrs->list_head; NULL != le; le = le->next) { + for (le = attrs->list_head; NULL != le; le = le->next) { attrs_str_len += strlen (le->attribute->name) + 1; } buf = GNUNET_malloc (attrs_str_len + size); write_ptr = buf; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Writing attributes\n"); - for (le = handle->attrs->list_head; NULL != le; le = le->next) { + for (le = attrs->list_head; NULL != le; le = le->next) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "%s\n", le->attribute->name); @@ -873,7 +881,7 @@ serialize_abe_keyinfo2 (const struct TicketIssueHandle *handle, enc_keyinfo = GNUNET_malloc (size + attrs_str_len); // Derived key K = H(eB) GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecdh_ecdsa (*ecdh_privkey, - &handle->ticket.audience, + &ticket->audience, &new_key_hash)); create_sym_key_from_ecdh(&new_key_hash, &skey, &iv); enc_size = GNUNET_CRYPTO_symmetric_encrypt (buf, @@ -925,7 +933,8 @@ issue_ticket_after_abe_bootstrap (void *cls, attrs); //TODO review this wireformat - code_record_len = serialize_abe_keyinfo2 (ih, + code_record_len = serialize_abe_keyinfo2 (&ih->ticket, + ih->attrs, rp_key, &ecdhe_privkey, &code_record_data); @@ -1008,6 +1017,124 @@ handle_issue_ticket_message (void *cls, } +/** + * Process ticket from database + * + * @param cls struct TicketIterationProcResult + * @param ticket the ticket + * @param attrs the attributes + */ +static void +ticket_reissue_proc (void *cls, + const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket, + const struct GNUNET_IDENTITY_PROVIDER_AttributeList *attrs); + + +static void +reissue_ticket_cont (void *cls, + int32_t success, + const char *emsg) +{ + struct TicketRevocationHandle *rh = cls; + + rh->ns_qe = NULL; + if (GNUNET_SYSERR == success) + { + //TODO cleanup_ticket_revocation_handle (handle); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n", + "Unknown Error\n"); + GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); + return; + } + rh->offset++; + GNUNET_assert (GNUNET_SYSERR != + TKT_database->iterate_tickets (TKT_database->cls, + &rh->ticket.identity, + GNUNET_NO, + rh->offset, + &ticket_reissue_proc, + rh)); +} + + + +/** + * Process ticket from database + * + * @param cls struct TicketIterationProcResult + * @param ticket the ticket + * @param attrs the attributes + */ +static void +ticket_reissue_proc (void *cls, + const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket, + const struct GNUNET_IDENTITY_PROVIDER_AttributeList *attrs) +{ + struct TicketRevocationHandle *rh = cls; + struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry *le; + struct GNUNET_CRYPTO_EcdhePrivateKey *ecdhe_privkey; + struct GNUNET_GNSRECORD_Data code_record[1]; + struct GNUNET_CRYPTO_AbeKey *rp_key; + char *code_record_data; + char **attr_arr; + char *label; + int attrs_len; + int i; + size_t code_record_len; + + + if (NULL == ticket) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Iteration done\n"); + /* Send reply ? */ + GNUNET_break (0); + return; + } + //Create new ABE key for RP + attrs_len = 0; + for (le = attrs->list_head; NULL != le; le = le->next) + attrs_len++; + attr_arr = GNUNET_malloc ((attrs_len + 1)*sizeof (char*)); + i = 0; + for (le = attrs->list_head; NULL != le; le = le->next) { + attr_arr[i] = (char*) le->attribute->name; + i++; + } + attr_arr[i] = NULL; + rp_key = GNUNET_CRYPTO_cpabe_create_key (rh->abe_key, + attr_arr); + + //TODO review this wireformat + code_record_len = serialize_abe_keyinfo2 (&rh->ticket, + rh->attrs, + rp_key, + &ecdhe_privkey, + &code_record_data); + code_record[0].data = code_record_data; + code_record[0].data_size = code_record_len; + code_record[0].expiration_time = GNUNET_TIME_UNIT_DAYS.rel_value_us; + code_record[0].record_type = GNUNET_GNSRECORD_TYPE_ABE_KEY; + code_record[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION; + + label = GNUNET_STRINGS_data_to_string_alloc (&ticket->rnd, + sizeof (uint64_t)); + //Publish record + rh->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle, + &rh->identity, + label, + 1, + code_record, + &reissue_ticket_cont, + rh); + GNUNET_free (ecdhe_privkey); + GNUNET_free (label); + GNUNET_free (attr_arr); + GNUNET_free (code_record_data); + +} + + static void attr_reenc_cont (void *cls, int32_t success, @@ -1017,6 +1144,7 @@ attr_reenc_cont (void *cls, struct GNUNET_GNSRECORD_Data rd[1]; size_t buf_size; char *buf; + int ret; if (GNUNET_SYSERR == success) { @@ -1032,7 +1160,18 @@ attr_reenc_cont (void *cls, if (NULL == rh->attrs->list_head) { /* Done, issue new keys */ - GNUNET_break (0); //TODO + GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, + "Revocation Phase IV: Reissuing Tickets\n"); + if (GNUNET_SYSERR == + (ret = TKT_database->iterate_tickets (TKT_database->cls, + &rh->ticket.identity, + GNUNET_NO, + rh->offset, + &ticket_reissue_proc, + rh))) + { + GNUNET_break (0); + } return; } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, @@ -1083,9 +1222,10 @@ reenc_after_abe_bootstrap (void *cls, if (NULL == rh->attrs->list_head) { /* No attributes to reencrypt, this is odd... */ + GNUNET_break (0); } else { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Re-encrypting attribute\n"); + GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, + "Revocation Phase III: Re-encrypting attributes\n"); buf_size = attribute_serialize_get_size (rh->attrs->list_head->attribute); buf = GNUNET_malloc (buf_size); @@ -1131,7 +1271,8 @@ static void revoke_collect_iter_finished (void *cls) { struct TicketRevocationHandle *rh = cls; - + GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, + "Revocation Phase II: Invalidating old ABE Master\n"); /* Bootstrap new abe key */ bootstrap_abe (&rh->identity, &reenc_after_abe_bootstrap, rh, GNUNET_YES); } @@ -1188,7 +1329,8 @@ collect_after_abe_bootstrap (void *cls, rh->abe_key = cls; GNUNET_assert (NULL != abe_key); - + GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, + "Revocation Phase I: Collecting attributes\n"); /* Reencrypt all attributes with new key */ rh->ns_it = GNUNET_NAMESTORE_zone_iteration_start (ns_handle, &rh->identity, @@ -1334,7 +1476,8 @@ process_parallel_lookup2 (void *cls, uint32_t rd_count, /* Store ticket in DB */ if (GNUNET_OK != TKT_database->store_ticket (TKT_database->cls, - &handle->ticket)) + &handle->ticket, + handle->attrs)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unable to store ticket after consume\n"); @@ -1914,7 +2057,8 @@ struct TicketIterationProcResult */ static void ticket_iterate_proc (void *cls, - const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket) + const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket, + const struct GNUNET_IDENTITY_PROVIDER_AttributeList *attrs) { struct TicketIterationProcResult *proc = cls; @@ -1928,7 +2072,8 @@ ticket_iterate_proc (void *cls, proc->res_iteration_finished = IT_SUCCESS_MORE_AVAILABLE; send_ticket_result (proc->ti->client, proc->ti->r_id, - ticket); + ticket, + attrs); } diff --git a/src/identity-provider/plugin_identity_provider_sqlite.c b/src/identity-provider/plugin_identity_provider_sqlite.c index ff2d3a22e..ac4e3c686 100644 --- a/src/identity-provider/plugin_identity_provider_sqlite.c +++ b/src/identity-provider/plugin_identity_provider_sqlite.c @@ -27,6 +27,7 @@ #include "platform.h" #include "gnunet_identity_provider_service.h" #include "gnunet_identity_provider_plugin.h" +#include "identity_attribute.h" #include "gnunet_sq_lib.h" #include @@ -252,7 +253,8 @@ database_setup (struct Plugin *plugin) "CREATE TABLE identity001tickets (" " identity BLOB NOT NULL DEFAULT ''," " audience BLOB NOT NULL DEFAULT ''," - " rnd INT8 NOT NULL DEFAULT ''" + " rnd INT8 NOT NULL DEFAULT ''," + " attributes BLOB NOT NULL DEFAULT ''" ")", NULL, NULL, NULL) != SQLITE_OK)) { @@ -267,8 +269,8 @@ database_setup (struct Plugin *plugin) if ( (SQLITE_OK != sq_prepare (plugin->dbh, - "INSERT INTO identity001tickets (identity, audience, rnd)" - " VALUES (?, ?, ?)", + "INSERT INTO identity001tickets (identity, audience, rnd, attributes)" + " VALUES (?, ?, ?, ?)", &plugin->store_ticket)) || (SQLITE_OK != sq_prepare (plugin->dbh, @@ -276,13 +278,13 @@ database_setup (struct Plugin *plugin) &plugin->delete_ticket)) || (SQLITE_OK != sq_prepare (plugin->dbh, - "SELECT identity,audience,rnd" + "SELECT identity,audience,rnd,attributes" " FROM identity001tickets WHERE identity=?" " ORDER BY rnd LIMIT 1 OFFSET ?", &plugin->iterate_tickets)) || (SQLITE_OK != sq_prepare (plugin->dbh, - "SELECT identity,audience,rnd" + "SELECT identity,audience,rnd,attributes" " FROM identity001tickets WHERE audience=?" " ORDER BY rnd LIMIT 1 OFFSET ?", &plugin->iterate_tickets_by_audience)) ) @@ -358,9 +360,12 @@ database_shutdown (struct Plugin *plugin) */ static int identity_provider_sqlite_store_ticket (void *cls, - const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket) + const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket, + const struct GNUNET_IDENTITY_PROVIDER_AttributeList *attrs) { struct Plugin *plugin = cls; + size_t attrs_len; + char *attrs_ser; int n; { @@ -384,11 +389,16 @@ identity_provider_sqlite_store_ticket (void *cls, n = sqlite3_step (plugin->delete_ticket); GNUNET_SQ_reset (plugin->dbh, plugin->delete_ticket); - + + attrs_len = attribute_list_serialize_get_size (attrs); + attrs_ser = GNUNET_malloc (attrs_len); + attribute_list_serialize (attrs, + attrs_ser); struct GNUNET_SQ_QueryParam sparams[] = { GNUNET_SQ_query_param_auto_from_type (&ticket->identity), GNUNET_SQ_query_param_auto_from_type (&ticket->audience), GNUNET_SQ_query_param_uint64 (&ticket->rnd), + GNUNET_SQ_query_param_fixed_size (attrs_ser, attrs_len), GNUNET_SQ_query_param_end }; @@ -406,6 +416,7 @@ identity_provider_sqlite_store_ticket (void *cls, n = sqlite3_step (plugin->store_ticket); GNUNET_SQ_reset (plugin->dbh, plugin->store_ticket); + GNUNET_free (attrs_ser); } switch (n) { @@ -503,8 +514,11 @@ get_ticket_and_call_iterator (struct Plugin *plugin, void *iter_cls) { struct GNUNET_IDENTITY_PROVIDER_Ticket ticket; + struct GNUNET_IDENTITY_PROVIDER_AttributeList *attrs; int ret; int sret; + size_t attrs_len; + char *attrs_ser; ret = GNUNET_NO; if (SQLITE_ROW == (sret = sqlite3_step (stmt))) @@ -513,6 +527,8 @@ get_ticket_and_call_iterator (struct Plugin *plugin, GNUNET_SQ_result_spec_auto_from_type (&ticket.identity), GNUNET_SQ_result_spec_auto_from_type (&ticket.audience), GNUNET_SQ_result_spec_uint64 (&ticket.rnd), + GNUNET_SQ_result_spec_variable_size ((void**)&attrs_ser, + &attrs_len), GNUNET_SQ_result_spec_end }; @@ -525,10 +541,13 @@ get_ticket_and_call_iterator (struct Plugin *plugin, } else { - if (NULL != iter) - iter (iter_cls, - &ticket); - ret = GNUNET_YES; + attrs = attribute_list_deserialize (attrs_ser, + attrs_len); + if (NULL != iter) + iter (iter_cls, + &ticket, + attrs); + ret = GNUNET_YES; } GNUNET_SQ_cleanup_result (rs); } diff --git a/src/include/gnunet_identity_provider_plugin.h b/src/include/gnunet_identity_provider_plugin.h index 27d7eb44f..e34ed3f1a 100644 --- a/src/include/gnunet_identity_provider_plugin.h +++ b/src/include/gnunet_identity_provider_plugin.h @@ -50,7 +50,8 @@ extern "C" * @param ticket the ticket */ typedef void (*GNUNET_IDENTITY_PROVIDER_TicketIterator) (void *cls, - const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket); + const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket, + const struct GNUNET_IDENTITY_PROVIDER_AttributeList *attrs); /** @@ -72,7 +73,8 @@ struct GNUNET_IDENTITY_PROVIDER_PluginFunctions * @return #GNUNET_OK on success, else #GNUNET_SYSERR */ int (*store_ticket) (void *cls, - const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket); + const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket, + const struct GNUNET_IDENTITY_PROVIDER_AttributeList *attrs); /** * Delete a ticket from the database. -- 2.25.1