From b7389bb3a98c077bcf39cafe2f9b66db15bd0bda Mon Sep 17 00:00:00 2001 From: "Schanzenbach, Martin" Date: Sat, 7 Oct 2017 13:01:52 +0200 Subject: [PATCH] -mem fixes, revocation finish --- src/identity-provider/gnunet-idp.c | 46 ++++++- .../gnunet-service-identity-provider.c | 123 +++++++++++------- src/identity-provider/identity_provider_api.c | 8 +- .../plugin_identity_provider_sqlite.c | 1 + src/identity-provider/test_idp_revoke.sh | 37 ++++++ src/util/crypto_abe.c | 3 +- 6 files changed, 167 insertions(+), 51 deletions(-) create mode 100755 src/identity-provider/test_idp_revoke.sh diff --git a/src/identity-provider/gnunet-idp.c b/src/identity-provider/gnunet-idp.c index d6544eb3b..6940220d7 100644 --- a/src/identity-provider/gnunet-idp.c +++ b/src/identity-provider/gnunet-idp.c @@ -61,6 +61,11 @@ static char* issue_attrs; */ static char* consume_ticket; +/** + * Ticket to revoke + */ +static char* revoke_ticket; + /** * Ego name */ @@ -181,18 +186,32 @@ iter_error (void *cls) GNUNET_SCHEDULER_add_now (&do_cleanup, NULL); } +static void +process_rvk (void *cls, int success, const char* msg) +{ + if (GNUNET_OK != success) + GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, + "Revocation failed.\n"); + else + GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, + "Revocation successful.\n"); + GNUNET_SCHEDULER_add_now (&do_cleanup, NULL); +} + static void iter_finished (void *cls) { struct GNUNET_IDENTITY_PROVIDER_Attribute *attr; attr_iterator = NULL; - if (list) { + if (list) + { GNUNET_SCHEDULER_add_now (&do_cleanup, NULL); return; } - if (issue_attrs) { + if (issue_attrs) + { idp_op = GNUNET_IDENTITY_PROVIDER_ticket_issue (idp_handle, pkey, &rp_key, @@ -201,7 +220,8 @@ iter_finished (void *cls) NULL); return; } - if (consume_ticket) { + if (consume_ticket) + { idp_op = GNUNET_IDENTITY_PROVIDER_ticket_consume (idp_handle, pkey, &ticket, @@ -209,6 +229,15 @@ iter_finished (void *cls) NULL); return; } + if (revoke_ticket) + { + idp_op = GNUNET_IDENTITY_PROVIDER_ticket_revoke (idp_handle, + pkey, + &ticket, + &process_rvk, + NULL); + return; + } attr = GNUNET_IDENTITY_PROVIDER_attribute_new (attr_name, GNUNET_IDENTITY_PROVIDER_AT_STRING, attr_value, @@ -279,6 +308,12 @@ ego_cb (void *cls, strlen (consume_ticket), &ticket, sizeof (struct GNUNET_IDENTITY_PROVIDER_Ticket)); + if (NULL != revoke_ticket) + GNUNET_STRINGS_string_to_data (revoke_ticket, + strlen (revoke_ticket), + &ticket, + sizeof (struct GNUNET_IDENTITY_PROVIDER_Ticket)); + attr_list = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_AttributeList); @@ -358,6 +393,11 @@ main(int argc, char *const argv[]) NULL, gettext_noop ("Consume a ticket"), &consume_ticket), + GNUNET_GETOPT_option_string ('R', + "revoke", + NULL, + gettext_noop ("Revoke a ticket"), + &revoke_ticket), GNUNET_GETOPT_OPTION_END }; return GNUNET_PROGRAM_run (argc, argv, "ct", diff --git a/src/identity-provider/gnunet-service-identity-provider.c b/src/identity-provider/gnunet-service-identity-provider.c index f9d3f3f92..2f477370e 100644 --- a/src/identity-provider/gnunet-service-identity-provider.c +++ b/src/identity-provider/gnunet-service-identity-provider.c @@ -473,10 +473,15 @@ struct TicketRevocationHandle struct IdpClient *client; /** - * Attributes to issue + * Attributes to reissue */ struct GNUNET_IDENTITY_PROVIDER_AttributeList *attrs; + /** + * Attributes to revoke + */ + struct GNUNET_IDENTITY_PROVIDER_AttributeList *rvk_attrs; + /** * Issuer Key */ @@ -679,6 +684,7 @@ bootstrap_store_task (void *cls) rd, &bootstrap_store_cont, abh); + GNUNET_free ((void*)rd[0].data); } /** @@ -917,6 +923,7 @@ serialize_abe_keyinfo2 (const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket, enc_keyinfo, enc_size); GNUNET_free (enc_keyinfo); + GNUNET_free (buf); return sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)+enc_size; } @@ -978,6 +985,8 @@ issue_ticket_after_abe_bootstrap (void *cls, GNUNET_free (label); GNUNET_free (attrs); GNUNET_free (code_record_data); + GNUNET_CRYPTO_cpabe_delete_master_key (abe_key); + GNUNET_CRYPTO_cpabe_delete_key (rp_key); } @@ -1049,8 +1058,10 @@ cleanup_revoke_ticket_handle (struct TicketRevocationHandle *handle) { if (NULL != handle->attrs) attribute_list_destroy (handle->attrs); + if (NULL != handle->rvk_attrs) + attribute_list_destroy (handle->rvk_attrs); if (NULL != handle->abe_key) - GNUNET_free (handle->abe_key); + GNUNET_CRYPTO_cpabe_delete_master_key (handle->abe_key); if (NULL != handle->ns_qe) GNUNET_NAMESTORE_cancel (handle->ns_qe); if (NULL != handle->ns_it) @@ -1078,7 +1089,6 @@ send_revocation_finished (struct TicketRevocationHandle *rh, GNUNET_CONTAINER_DLL_remove (rh->client->revocation_list_head, rh->client->revocation_list_tail, rh); - cleanup_revoke_ticket_handle (rh); } @@ -1101,6 +1111,7 @@ reissue_ticket_cont (void *cls, const char *emsg) { struct TicketRevocationHandle *rh = cls; + int ret; rh->ns_qe = NULL; if (GNUNET_SYSERR == success) @@ -1111,14 +1122,20 @@ reissue_ticket_cont (void *cls, cleanup_revoke_ticket_handle (rh); return; } + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Continue DB iteration\n"); rh->offset++; - GNUNET_assert (GNUNET_SYSERR != + GNUNET_assert (GNUNET_SYSERR != (ret = TKT_database->iterate_tickets (TKT_database->cls, &rh->ticket.identity, GNUNET_NO, rh->offset, &ticket_reissue_proc, - rh)); + rh))); + if (GNUNET_NO == ret) + { + send_revocation_finished (rh, GNUNET_OK); + cleanup_revoke_ticket_handle (rh); + } } @@ -1136,7 +1153,6 @@ ticket_reissue_proc (void *cls, const struct GNUNET_IDENTITY_PROVIDER_AttributeList *attrs) { struct TicketRevocationHandle *rh = cls; - const struct GNUNET_IDENTITY_PROVIDER_AttributeList *attrs_to_reissue; struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry *le; struct GNUNET_CRYPTO_EcdhePrivateKey *ecdhe_privkey; struct GNUNET_GNSRECORD_Data code_record[1]; @@ -1159,19 +1175,16 @@ ticket_reissue_proc (void *cls, } //Create new ABE key for RP attrs_len = 0; - attrs_to_reissue = attrs; /* If this is the RP we want to revoke attributes of, the do so */ - if (0 == memcmp (&ticket->audience, - &rh->ticket.audience, - sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey))) - attrs_to_reissue = rh->attrs; - for (le = attrs_to_reissue->list_head; NULL != le; le = le->next) + 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_to_reissue->list_head; NULL != le; le = le->next) { + for (le = attrs->list_head; NULL != le; le = le->next) { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Recreating key with %s\n", (char*) le->attribute->name); attr_arr[i] = (char*) le->attribute->name; i++; } @@ -1181,7 +1194,7 @@ ticket_reissue_proc (void *cls, //TODO review this wireformat code_record_len = serialize_abe_keyinfo2 (&rh->ticket, - rh->attrs, + attrs, rp_key, &ecdhe_privkey, &code_record_data); @@ -1205,18 +1218,40 @@ ticket_reissue_proc (void *cls, GNUNET_free (label); GNUNET_free (attr_arr); GNUNET_free (code_record_data); - + GNUNET_CRYPTO_cpabe_delete_key (rp_key); } - - /* Prototype for below function */ static void attr_reenc_cont (void *cls, int32_t success, const char *emsg); +static void +revocation_reissue_tickets (struct TicketRevocationHandle *rh) +{ + int ret; + /* Done, issue new keys */ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "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); + } + if (GNUNET_NO == ret) + { + send_revocation_finished (rh, GNUNET_OK); + cleanup_revoke_ticket_handle (rh); + } + +} + /** * Revoke next attribte by reencryption with * new ABE master @@ -1226,8 +1261,15 @@ reenc_next_attribute (struct TicketRevocationHandle *rh) { struct GNUNET_GNSRECORD_Data rd[1]; char* buf; + char* enc_buf; size_t buf_size; + if (NULL == rh->attrs->list_head) + { + revocation_reissue_tickets (rh); + return; + } + buf_size = attribute_serialize_get_size (rh->attrs->list_head->attribute); buf = GNUNET_malloc (buf_size); @@ -1241,8 +1283,9 @@ reenc_next_attribute (struct TicketRevocationHandle *rh) buf_size, rh->attrs->list_head->attribute->name, //Policy rh->abe_key, - (void**)&rd[0].data); + (void**)&enc_buf); GNUNET_free (buf); + rd[0].data = enc_buf; rd[0].record_type = GNUNET_GNSRECORD_TYPE_ID_ATTR; rd[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION; rd[0].expiration_time = GNUNET_TIME_UNIT_HOURS.rel_value_us; //TODO sane? @@ -1253,7 +1296,7 @@ reenc_next_attribute (struct TicketRevocationHandle *rh) rd, &attr_reenc_cont, rh); - GNUNET_free ((void*)rd[0].data); + GNUNET_free (enc_buf); } @@ -1268,7 +1311,6 @@ attr_reenc_cont (void *cls, { struct TicketRevocationHandle *rh = cls; struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry *le; - int ret; if (GNUNET_SYSERR == success) { @@ -1278,30 +1320,19 @@ attr_reenc_cont (void *cls, GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); return; } + if (NULL == rh->attrs->list_head) + { + revocation_reissue_tickets (rh); + return; + } le = rh->attrs->list_head; GNUNET_CONTAINER_DLL_remove (rh->attrs->list_head, rh->attrs->list_tail, - rh->attrs->list_head); + le); GNUNET_free (le->attribute); GNUNET_free (le); - if (NULL == rh->attrs->list_head) - { - /* Done, issue new keys */ - 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, "Re-encrypting next attribute\n"); reenc_next_attribute (rh); @@ -1327,7 +1358,7 @@ reenc_after_abe_bootstrap (void *cls, cleanup_revoke_ticket_handle (rh); return; } else { - GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Revocation Phase III: Re-encrypting attributes\n"); reenc_next_attribute (rh); } @@ -1357,7 +1388,7 @@ revoke_collect_iter_finished (void *cls) { struct TicketRevocationHandle *rh = cls; rh->ns_it = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Revocation Phase II: Invalidating old ABE Master\n"); /* Bootstrap new abe key */ bootstrap_abe (&rh->identity, &reenc_after_abe_bootstrap, rh, GNUNET_YES); @@ -1404,6 +1435,7 @@ revoke_collect_iter_cb (void *cls, "Attribute to reencrypt: %s\n", label); le = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry); le->attribute = attribute_deserialize (attr_ser, attr_len); + GNUNET_free (attr_ser); GNUNET_CONTAINER_DLL_insert_tail (rh->attrs->list_head, rh->attrs->list_tail, le); @@ -1419,9 +1451,9 @@ collect_after_abe_bootstrap (void *cls, { struct TicketRevocationHandle *rh = cls; - rh->abe_key = cls; + rh->abe_key = abe_key; GNUNET_assert (NULL != abe_key); - GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Revocation Phase I: Collecting attributes\n"); /* Reencrypt all attributes with new key */ rh->ns_it = GNUNET_NAMESTORE_zone_iteration_start (ns_handle, @@ -1480,7 +1512,8 @@ handle_revoke_ticket_message (void *cls, attrs_len = ntohs (rm->attrs_len); ticket = (struct GNUNET_IDENTITY_PROVIDER_Ticket*)&rm[1]; if (0 < attrs_len) - rh->attrs = attribute_list_deserialize ((char*)&ticket[1], attrs_len); + rh->rvk_attrs = attribute_list_deserialize ((char*)&ticket[1], attrs_len); + rh->attrs = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_AttributeList); rh->ticket = *ticket; rh->r_id = ntohl (rm->id); rh->client = idp; @@ -1502,7 +1535,7 @@ cleanup_as_handle (struct AttributeStoreHandle *handle) if (NULL != handle->attribute) GNUNET_free (handle->attribute); if (NULL != handle->abe_key) - GNUNET_free (handle->abe_key); + GNUNET_CRYPTO_cpabe_delete_master_key (handle->abe_key); GNUNET_free (handle); } @@ -1625,7 +1658,7 @@ static void cleanup_consume_ticket_handle (struct ConsumeTicketHandle *handle) { if (NULL != handle->key) - GNUNET_free (handle->key); + GNUNET_CRYPTO_cpabe_delete_key (handle->key); GNUNET_free (handle); } diff --git a/src/identity-provider/identity_provider_api.c b/src/identity-provider/identity_provider_api.c index fb9926a2c..1dec43b16 100644 --- a/src/identity-provider/identity_provider_api.c +++ b/src/identity-provider/identity_provider_api.c @@ -1363,10 +1363,14 @@ GNUNET_IDENTITY_PROVIDER_ticket_revoke (struct GNUNET_IDENTITY_PROVIDER_Handle * GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, op); - env = GNUNET_MQ_msg (msg, - GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_REVOKE_TICKET); + env = GNUNET_MQ_msg_extra (msg, + sizeof (struct GNUNET_IDENTITY_PROVIDER_Ticket), + GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_REVOKE_TICKET); msg->id = htonl (rid); msg->identity = *identity; + memcpy (&msg[1], + ticket, + sizeof (struct GNUNET_IDENTITY_PROVIDER_Ticket)); if (NULL == h->mq) op->env = env; else diff --git a/src/identity-provider/plugin_identity_provider_sqlite.c b/src/identity-provider/plugin_identity_provider_sqlite.c index ac4e3c686..c55366214 100644 --- a/src/identity-provider/plugin_identity_provider_sqlite.c +++ b/src/identity-provider/plugin_identity_provider_sqlite.c @@ -547,6 +547,7 @@ get_ticket_and_call_iterator (struct Plugin *plugin, iter (iter_cls, &ticket, attrs); + attribute_list_destroy (attrs); ret = GNUNET_YES; } GNUNET_SQ_cleanup_result (rs); diff --git a/src/identity-provider/test_idp_revoke.sh b/src/identity-provider/test_idp_revoke.sh new file mode 100755 index 000000000..57872c5b9 --- /dev/null +++ b/src/identity-provider/test_idp_revoke.sh @@ -0,0 +1,37 @@ +#!/bin/bash +trap "gnunet-arm -e -c test_idp.conf" SIGINT + +LOCATION=$(which gnunet-config) +if [ -z $LOCATION ] +then + LOCATION="gnunet-config" +fi +$LOCATION --version 1> /dev/null +if test $? != 0 +then + echo "GNUnet command line tools cannot be found, check environmental variables PATH and GNUNET_PREFIX" + exit 77 +fi + +rm -rf `gnunet-config -c test_idp.conf -s PATHS -o GNUNET_HOME -f` + +# (1) PKEY1.user -> PKEY2.resu.user +# (2) PKEY2.resu -> PKEY3 +# (3) PKEY3.user -> PKEY4 + + +which timeout &> /dev/null && DO_TIMEOUT="timeout 30" + +TEST_ATTR="test" +gnunet-arm -s -c test_idp.conf +gnunet-identity -C testego -c test_idp.conf +gnunet-identity -C rpego -c test_idp.conf +SUBJECT_KEY=$(gnunet-identity -d -c test_idp.conf | grep rpego | awk '{print $3}') +TEST_KEY=$(gnunet-identity -d -c test_idp.conf | grep testego | awk '{print $3}') +gnunet-idp -e testego -a email -V john@doe.gnu -c test_idp.conf +gnunet-idp -e testego -a name -V John -c test_idp.conf +#gnunet-idp -e testego -D -c test_idp.conf +TICKET=$(gnunet-idp -e testego -i "email,name" -r $SUBJECT_KEY -c test_idp.conf | awk '{print $1}') +#echo "Consuming $TICKET" +gnunet-idp -e testego -R $TICKET -c test_idp.conf +gnunet-arm -e -c test_idp.conf diff --git a/src/util/crypto_abe.c b/src/util/crypto_abe.c index 899965159..f52cd5213 100644 --- a/src/util/crypto_abe.c +++ b/src/util/crypto_abe.c @@ -108,7 +108,7 @@ aes_128_cbc_encrypt( char* pt, GNUNET_assert (0 == gcry_cipher_encrypt (handle, *ct, buf_size, buf, buf_size)); gcry_cipher_close (handle); //AES_cbc_encrypt(pt->data, ct->data, pt->len, &key, iv, AES_ENCRYPT); - + GNUNET_free (buf); return buf_size; } @@ -300,6 +300,7 @@ GNUNET_CRYPTO_cpabe_decrypt (const void *block, } gabe_cph_free(cph); plt_len = aes_128_cbc_decrypt(aes_buf, aes_buf_size, m, (char**)result); + GNUNET_free (aes_buf); //freeing is buggy in gabe //gabe_prv_free (prv); //gabe_pub_free (pub); -- 2.25.1