From 44f8117be5a2aca8b303943ff016927a35621ed9 Mon Sep 17 00:00:00 2001 From: "Schanzenbach, Martin" Date: Mon, 9 Oct 2017 14:45:42 +0200 Subject: [PATCH] -improve revocation handling --- .../gnunet-service-identity-provider.c | 283 ++++++++---------- src/identity-provider/identity_attribute.c | 25 ++ src/identity-provider/identity_attribute.h | 2 + .../plugin_identity_provider_sqlite.c | 54 ++++ src/identity-provider/test_idp_attribute.sh | 5 +- src/identity-provider/test_idp_issue.sh | 4 +- src/include/gnunet_identity_provider_plugin.h | 5 +- .../gnunet_identity_provider_service.h | 5 + 8 files changed, 228 insertions(+), 155 deletions(-) diff --git a/src/identity-provider/gnunet-service-identity-provider.c b/src/identity-provider/gnunet-service-identity-provider.c index 2f477370e..364c097b5 100644 --- a/src/identity-provider/gnunet-service-identity-provider.c +++ b/src/identity-provider/gnunet-service-identity-provider.c @@ -424,7 +424,8 @@ struct ConsumeTicketHandle * Attributes */ struct GNUNET_IDENTITY_PROVIDER_AttributeList *attrs; - + + /** * request id */ @@ -671,9 +672,11 @@ bootstrap_store_task (void *cls) { struct AbeBootstrapHandle *abh = cls; struct GNUNET_GNSRECORD_Data rd[1]; + char *key; rd[0].data_size = GNUNET_CRYPTO_cpabe_serialize_master_key (abh->abe_key, - (void**)&rd[0].data); + (void**)&key); + rd[0].data = key; rd[0].record_type = GNUNET_GNSRECORD_TYPE_ABE_MASTER; rd[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION | GNUNET_GNSRECORD_RF_PRIVATE; rd[0].expiration_time = GNUNET_TIME_UNIT_HOURS.rel_value_us; //TODO sane? @@ -684,7 +687,7 @@ bootstrap_store_task (void *cls) rd, &bootstrap_store_cont, abh); - GNUNET_free ((void*)rd[0].data); + GNUNET_free (key); } /** @@ -717,7 +720,7 @@ bootstrap_abe_result (void *cls, for (i=0;iproc (abh->proc_cls, abe_key); GNUNET_free (abh); @@ -1125,12 +1128,12 @@ reissue_ticket_cont (void *cls, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Continue DB iteration\n"); rh->offset++; GNUNET_assert (GNUNET_SYSERR != (ret = - TKT_database->iterate_tickets (TKT_database->cls, - &rh->ticket.identity, - GNUNET_NO, - rh->offset, - &ticket_reissue_proc, - rh))); + TKT_database->iterate_tickets (TKT_database->cls, + &rh->ticket.identity, + GNUNET_NO, + rh->offset, + &ticket_reissue_proc, + rh))); if (GNUNET_NO == ret) { send_revocation_finished (rh, GNUNET_OK); @@ -1138,6 +1141,8 @@ reissue_ticket_cont (void *cls, } } +static void +revocation_reissue_tickets (struct TicketRevocationHandle *rh); /** @@ -1154,14 +1159,17 @@ ticket_reissue_proc (void *cls, { struct TicketRevocationHandle *rh = cls; struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry *le; + struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry *le_rollover; 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; + char *policy; int attrs_len; int i; + int reissue_ticket; size_t code_record_len; @@ -1173,6 +1181,37 @@ ticket_reissue_proc (void *cls, cleanup_revoke_ticket_handle (rh); return; } + + /* + * Check if any attribute of this ticket intersects with a rollover attribute + */ + reissue_ticket = GNUNET_NO; + for (le = attrs->list_head; NULL != le; le = le->next) + { + for (le_rollover = rh->rvk_attrs->list_head; + NULL != le_rollover; + le_rollover = le_rollover->next) + { + if (0 == strcmp (le_rollover->attribute->name, + le->attribute->name)) + { + reissue_ticket = GNUNET_YES; + break; + } + } + if (GNUNET_YES == reissue_ticket) + break; + } + + if (GNUNET_NO == reissue_ticket) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Skipping ticket.\n"); + rh->offset++; + revocation_reissue_tickets (rh); + return; + } + //Create new ABE key for RP attrs_len = 0; @@ -1183,9 +1222,12 @@ ticket_reissue_proc (void *cls, attr_arr = GNUNET_malloc ((attrs_len + 1)*sizeof (char*)); i = 0; for (le = attrs->list_head; NULL != le; le = le->next) { + GNUNET_asprintf (&policy, "%s:%lu", + le->attribute->name, + le->attribute->attribute_version); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Recreating key with %s\n", (char*) le->attribute->name); - attr_arr[i] = (char*) le->attribute->name; + "Recreating key with %s\n", policy); + attr_arr[i] = policy; i++; } attr_arr[i] = NULL; @@ -1214,6 +1256,8 @@ ticket_reissue_proc (void *cls, code_record, &reissue_ticket_cont, rh); + for (; i > 0; i--) + GNUNET_free (attr_arr[i]); GNUNET_free (ecdhe_privkey); GNUNET_free (label); GNUNET_free (attr_arr); @@ -1262,30 +1306,43 @@ reenc_next_attribute (struct TicketRevocationHandle *rh) struct GNUNET_GNSRECORD_Data rd[1]; char* buf; char* enc_buf; + size_t enc_size; + char* rd_buf; size_t buf_size; + char* policy; + uint32_t attr_ver; 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); - attribute_serialize (rh->attrs->list_head->attribute, buf); - + rh->attrs->list_head->attribute->attribute_version++; + GNUNET_asprintf (&policy, "%s:%lu", rh->attrs->list_head->attribute->name, rh->attrs->list_head->attribute->attribute_version); /** * Encrypt the attribute value and store in namestore */ - rd[0].data_size = GNUNET_CRYPTO_cpabe_encrypt (buf, - buf_size, - rh->attrs->list_head->attribute->name, //Policy - rh->abe_key, - (void**)&enc_buf); + enc_size = GNUNET_CRYPTO_cpabe_encrypt (buf, + buf_size, + policy, //Policy + rh->abe_key, + (void**)&enc_buf); GNUNET_free (buf); - rd[0].data = enc_buf; + GNUNET_free (policy); + rd[0].data_size = enc_size + sizeof (uint32_t); + rd_buf = GNUNET_malloc (rd[0].data_size); + attr_ver = htonl (rh->attrs->list_head->attribute->attribute_version); + GNUNET_memcpy (rd_buf, + &attr_ver, + sizeof (uint32_t)); + GNUNET_memcpy (rd_buf+sizeof (uint32_t), + enc_buf, + enc_size); + rd[0].data = rd_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? @@ -1297,7 +1354,7 @@ reenc_next_attribute (struct TicketRevocationHandle *rh) &attr_reenc_cont, rh); GNUNET_free (enc_buf); - + GNUNET_free (rd_buf); } /** @@ -1329,8 +1386,9 @@ attr_reenc_cont (void *cls, GNUNET_CONTAINER_DLL_remove (rh->attrs->list_head, rh->attrs->list_tail, le); - GNUNET_free (le->attribute); - GNUNET_free (le); + GNUNET_CONTAINER_DLL_insert (rh->rvk_attrs->list_head, + rh->rvk_attrs->list_tail, + le); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, @@ -1339,18 +1397,17 @@ attr_reenc_cont (void *cls, } -/** - * Start reencryption with newly generated ABE master - */ static void -reenc_after_abe_bootstrap (void *cls, - struct GNUNET_CRYPTO_AbeMasterKey *abe_key) +process_attributes_to_update (void *cls, + const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket, + const struct GNUNET_IDENTITY_PROVIDER_AttributeList *attrs) { struct TicketRevocationHandle *rh = cls; - GNUNET_free (rh->abe_key); - GNUNET_assert (NULL != abe_key); - rh->abe_key = abe_key; + rh->attrs = attribute_list_dup (attrs); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Revocation Phase I: Collecting attributes\n"); + /* Reencrypt all attributes with new key */ if (NULL == rh->attrs->list_head) { /* No attributes to reencrypt */ @@ -1359,111 +1416,9 @@ reenc_after_abe_bootstrap (void *cls, return; } else { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Revocation Phase III: Re-encrypting attributes\n"); + "Revocation Phase II: Re-encrypting attributes\n"); reenc_next_attribute (rh); } -} - - -/** - * Collecting attributes failed... abort. - */ -static void -revoke_collect_iter_error (void *cls) -{ - struct TicketRevocationHandle *rh = cls; - - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Failed to iterate over attributes\n"); - rh->ns_it = NULL; - send_revocation_finished (rh, GNUNET_SYSERR); - cleanup_revoke_ticket_handle (rh); -} - -/** - * Done decrypting existing attributes. - */ -static void -revoke_collect_iter_finished (void *cls) -{ - struct TicketRevocationHandle *rh = cls; - rh->ns_it = NULL; - 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); -} - -/** - * Decrypt existing attribute and store it - * We will revoke it by reencrypting it with a new ABE master key. - */ -static void -revoke_collect_iter_cb (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, - const char *label, - unsigned int rd_count, - const struct GNUNET_GNSRECORD_Data *rd) -{ - struct TicketRevocationHandle *rh = cls; - struct GNUNET_CRYPTO_AbeKey *key; - struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry *le; - ssize_t attr_len; - char* attr_ser; - char* attrs[2]; - - if (rd_count != 1) - { - GNUNET_NAMESTORE_zone_iterator_next (rh->ns_it); - return; - } - - if (GNUNET_GNSRECORD_TYPE_ID_ATTR != rd->record_type) { - GNUNET_NAMESTORE_zone_iterator_next (rh->ns_it); - return; - } - attrs[0] = (char*)label; - attrs[1] = 0; - key = GNUNET_CRYPTO_cpabe_create_key (rh->abe_key, - attrs); - attr_len = GNUNET_CRYPTO_cpabe_decrypt (rd->data, - rd->data_size, - key, - (void**)&attr_ser); - GNUNET_CRYPTO_cpabe_delete_key (key); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "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); - GNUNET_NAMESTORE_zone_iterator_next (rh->ns_it); -} - -/** - * Start attribute collection for revocation - */ -static void -collect_after_abe_bootstrap (void *cls, - struct GNUNET_CRYPTO_AbeMasterKey *abe_key) -{ - struct TicketRevocationHandle *rh = cls; - - rh->abe_key = abe_key; - GNUNET_assert (NULL != abe_key); - 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, - &rh->identity, - &revoke_collect_iter_error, - rh, - &revoke_collect_iter_cb, - rh, - &revoke_collect_iter_finished, - rh); } @@ -1490,7 +1445,6 @@ check_revoke_ticket_message(void *cls, return GNUNET_OK; } - /** * * Handler for ticket revocation message @@ -1513,7 +1467,7 @@ handle_revoke_ticket_message (void *cls, ticket = (struct GNUNET_IDENTITY_PROVIDER_Ticket*)&rm[1]; if (0 < attrs_len) rh->rvk_attrs = attribute_list_deserialize ((char*)&ticket[1], attrs_len); - rh->attrs = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_AttributeList); + rh->rvk_attrs = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_AttributeList); rh->ticket = *ticket; rh->r_id = ntohl (rm->id); rh->client = idp; @@ -1523,7 +1477,11 @@ handle_revoke_ticket_message (void *cls, GNUNET_CONTAINER_DLL_insert (idp->revocation_list_head, idp->revocation_list_tail, rh); - bootstrap_abe (&rh->identity, &collect_after_abe_bootstrap, rh, GNUNET_NO); + TKT_database->get_ticket_attributes (TKT_database->cls, + &rh->ticket, + &process_attributes_to_update, + rh); + //bootstrap_abe (&rh->identity, &collect_after_abe_bootstrap, rh, GNUNET_NO); GNUNET_SERVICE_client_continue (idp->client); } @@ -1586,13 +1544,14 @@ process_parallel_lookup2 (void *cls, uint32_t rd_count, GNUNET_break(0);//TODO if (rd->record_type == GNUNET_GNSRECORD_TYPE_ID_ATTR) { - attr_len = GNUNET_CRYPTO_cpabe_decrypt (rd->data, - rd->data_size, + attr_len = GNUNET_CRYPTO_cpabe_decrypt (rd->data + sizeof (uint32_t), + rd->data_size - sizeof (uint32_t), handle->key, (void**)&data); attr_le = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry); attr_le->attribute = attribute_deserialize (data, attr_len); + attr_le->attribute->attribute_version = ntohl(*(uint32_t*)rd->data); GNUNET_CONTAINER_DLL_insert (handle->attrs->list_head, handle->attrs->list_tail, attr_le); @@ -1829,7 +1788,12 @@ attr_store_task (void *cls) struct AttributeStoreHandle *as_handle = cls; struct GNUNET_GNSRECORD_Data rd[1]; char* buf; + char* policy; + char* enc_buf; + char* rd_buf; + size_t enc_size; size_t buf_size; + uint32_t attr_ver; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Storing attribute\n"); @@ -1839,15 +1803,30 @@ attr_store_task (void *cls) attribute_serialize (as_handle->attribute, buf); + GNUNET_asprintf (&policy, + "%s:%lu", + as_handle->attribute->name, + as_handle->attribute->attribute_version); /** * Encrypt the attribute value and store in namestore */ - rd[0].data_size = GNUNET_CRYPTO_cpabe_encrypt (buf, - buf_size, - as_handle->attribute->name, //Policy - as_handle->abe_key, - (void**)&rd[0].data); + enc_size = GNUNET_CRYPTO_cpabe_encrypt (buf, + buf_size, + policy, //Policy + as_handle->abe_key, + (void**)&enc_buf); GNUNET_free (buf); + GNUNET_free (policy); + rd[0].data_size = enc_size + sizeof (uint32_t); + rd_buf = GNUNET_malloc (rd[0].data_size); + attr_ver = htonl (as_handle->attribute->attribute_version); + GNUNET_memcpy (rd_buf, + &attr_ver, + sizeof (uint32_t)); + GNUNET_memcpy (rd_buf+sizeof (uint32_t), + enc_buf, + enc_size); + rd[0].data = rd_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? @@ -1858,8 +1837,8 @@ attr_store_task (void *cls) rd, &attr_store_cont, as_handle); - GNUNET_free ((void*)rd[0].data); - + GNUNET_free (enc_buf); + GNUNET_free (rd_buf); } @@ -1982,6 +1961,7 @@ attr_iter_cb (void *cls, char* attr_ser; char* attrs[2]; char* data_tmp; + char* policy; if (rd_count != 1) { @@ -1993,15 +1973,18 @@ attr_iter_cb (void *cls, GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it); return; } - attrs[0] = (char*)label; + GNUNET_asprintf (&policy, "%s:%lu", + label, *(uint32_t*)rd->data); + attrs[0] = policy; attrs[1] = 0; key = GNUNET_CRYPTO_cpabe_create_key (ai->abe_key, attrs); - msg_extra_len = GNUNET_CRYPTO_cpabe_decrypt (rd->data, - rd->data_size, + msg_extra_len = GNUNET_CRYPTO_cpabe_decrypt (rd->data+sizeof (uint32_t), + rd->data_size-sizeof (uint32_t), key, (void**)&attr_ser); GNUNET_CRYPTO_cpabe_delete_key (key); + GNUNET_free (policy); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found attribute: %s\n", label); env = GNUNET_MQ_msg_extra (arm, diff --git a/src/identity-provider/identity_attribute.c b/src/identity-provider/identity_attribute.c index b90a08e3e..a8d2b27e6 100644 --- a/src/identity-provider/identity_attribute.c +++ b/src/identity-provider/identity_attribute.c @@ -125,6 +125,31 @@ attribute_list_deserialize (const char* data, return attrs; } +struct GNUNET_IDENTITY_PROVIDER_AttributeList* +attribute_list_dup (const struct GNUNET_IDENTITY_PROVIDER_AttributeList *attrs) +{ + struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry *le; + struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry *result_le; + struct GNUNET_IDENTITY_PROVIDER_AttributeList *result; + size_t len; + + result = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_AttributeList); + for (le = attrs->list_head; NULL != le; le = le->next) + { + result_le = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry); + len = sizeof (struct GNUNET_IDENTITY_PROVIDER_Attribute) + le->attribute->data_size; + result_le->attribute = GNUNET_malloc (len); + GNUNET_memcpy (result_le->attribute, + le->attribute, + len); + GNUNET_CONTAINER_DLL_insert (result->list_head, + result->list_tail, + result_le); + } + return result; +} + + void attribute_list_destroy (struct GNUNET_IDENTITY_PROVIDER_AttributeList *attrs) { diff --git a/src/identity-provider/identity_attribute.h b/src/identity-provider/identity_attribute.h index d44f4c17f..8a8da12f1 100644 --- a/src/identity-provider/identity_attribute.h +++ b/src/identity-provider/identity_attribute.h @@ -138,5 +138,7 @@ attribute_new (const char* attr_name, const void* data, size_t data_size); +struct GNUNET_IDENTITY_PROVIDER_AttributeList* +attribute_list_dup (const struct GNUNET_IDENTITY_PROVIDER_AttributeList *attrs); #endif diff --git a/src/identity-provider/plugin_identity_provider_sqlite.c b/src/identity-provider/plugin_identity_provider_sqlite.c index c55366214..c87f30e1c 100644 --- a/src/identity-provider/plugin_identity_provider_sqlite.c +++ b/src/identity-provider/plugin_identity_provider_sqlite.c @@ -87,6 +87,11 @@ struct Plugin */ sqlite3_stmt *iterate_tickets; + /** + * Precompiled SQL to get ticket attributes. + */ + sqlite3_stmt *get_ticket_attrs; + /** * Precompiled SQL to iterate tickets by audience. */ @@ -276,6 +281,11 @@ database_setup (struct Plugin *plugin) sq_prepare (plugin->dbh, "DELETE FROM identity001tickets WHERE identity=? AND rnd=?", &plugin->delete_ticket)) || + (SQLITE_OK != + sq_prepare (plugin->dbh, + "SELECT identity,audience,rnd,attributes" + " FROM identity001tickets WHERE identity=? AND rnd=?", + &plugin->get_ticket_attrs)) || (SQLITE_OK != sq_prepare (plugin->dbh, "SELECT identity,audience,rnd,attributes" @@ -317,6 +327,8 @@ database_shutdown (struct Plugin *plugin) sqlite3_finalize (plugin->iterate_tickets); if (NULL != plugin->iterate_tickets_by_audience) sqlite3_finalize (plugin->iterate_tickets_by_audience); + if (NULL != plugin->get_ticket_attrs) + sqlite3_finalize (plugin->get_ticket_attrs); result = sqlite3_close (plugin->dbh); if (result == SQLITE_BUSY) { @@ -564,6 +576,47 @@ get_ticket_and_call_iterator (struct Plugin *plugin, return ret; } + +/** + * Lookup tickets in the datastore. + * + * @param cls closure (internal context for the plugin) + * @param zone private key of the zone + * @param label name of the record in the zone + * @param iter function to call with the result + * @param iter_cls closure for @a iter + * @return #GNUNET_OK on success, else #GNUNET_SYSERR + */ +static int +identity_provider_sqlite_ticket_get_attrs (void *cls, + const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket, + GNUNET_IDENTITY_PROVIDER_TicketIterator iter, + void *iter_cls) +{ + struct Plugin *plugin = cls; + struct GNUNET_SQ_QueryParam params[] = { + GNUNET_SQ_query_param_auto_from_type (&ticket->identity), + GNUNET_SQ_query_param_uint64 (&ticket->rnd), + GNUNET_SQ_query_param_end + }; + + if (GNUNET_OK != + GNUNET_SQ_bind (plugin->get_ticket_attrs, + params)) + { + LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, + "sqlite3_bind_XXXX"); + GNUNET_SQ_reset (plugin->dbh, + plugin->get_ticket_attrs); + return GNUNET_SYSERR; + } + return get_ticket_and_call_iterator (plugin, + plugin->get_ticket_attrs, + iter, + iter_cls); +} + + /** * Iterate over the results for a particular key and zone in the * datastore. Will return at most one result to the iterator. @@ -653,6 +706,7 @@ libgnunet_plugin_identity_provider_sqlite_init (void *cls) api->store_ticket = &identity_provider_sqlite_store_ticket; api->delete_ticket = &identity_provider_sqlite_delete_ticket; api->iterate_tickets = &identity_provider_sqlite_iterate_tickets; + api->get_ticket_attributes = &identity_provider_sqlite_ticket_get_attrs; LOG (GNUNET_ERROR_TYPE_INFO, _("Sqlite database running\n")); return api; diff --git a/src/identity-provider/test_idp_attribute.sh b/src/identity-provider/test_idp_attribute.sh index 0b0436ede..7e86ae532 100755 --- a/src/identity-provider/test_idp_attribute.sh +++ b/src/identity-provider/test_idp_attribute.sh @@ -24,11 +24,12 @@ which timeout &> /dev/null && DO_TIMEOUT="timeout 30" TEST_ATTR="test" gnunet-arm -s -c test_idp.conf -gnunet-arm -i rest -c test_idp.conf +#gnunet-arm -i rest -c test_idp.conf gnunet-identity -C testego -c test_idp.conf gnunet-identity -C rpego -c test_idp.conf 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 -curl localhost:7776/idp/attributes/testego +gnunet-idp -e testego -D -c test_idp.conf +#curl localhost:7776/idp/attributes/testego gnunet-arm -e -c test_idp.conf diff --git a/src/identity-provider/test_idp_issue.sh b/src/identity-provider/test_idp_issue.sh index bf5783c9d..26c490c76 100755 --- a/src/identity-provider/test_idp_issue.sh +++ b/src/identity-provider/test_idp_issue.sh @@ -24,7 +24,7 @@ which timeout &> /dev/null && DO_TIMEOUT="timeout 30" TEST_ATTR="test" gnunet-arm -s -c test_idp.conf -#gnunet-arm -i rest -c test_idp.conf +gnunet-arm -i rest -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}') @@ -35,4 +35,4 @@ gnunet-idp -e testego -a name -V John -c test_idp.conf > /dev/null 2>&1 TICKET=$(gnunet-idp -e testego -i "email,name" -r $SUBJECT_KEY -c test_idp.conf | awk '{print $1}') #curl http://localhost:7776/idp/attributes/testego echo "Ticket: $TICKET" -gnunet-arm -e -c test_idp.conf +#gnunet-arm -e -c test_idp.conf diff --git a/src/include/gnunet_identity_provider_plugin.h b/src/include/gnunet_identity_provider_plugin.h index e34ed3f1a..c0a258ab6 100644 --- a/src/include/gnunet_identity_provider_plugin.h +++ b/src/include/gnunet_identity_provider_plugin.h @@ -105,7 +105,10 @@ struct GNUNET_IDENTITY_PROVIDER_PluginFunctions uint64_t offset, GNUNET_IDENTITY_PROVIDER_TicketIterator iter, void *iter_cls); - + int (*get_ticket_attributes) (void* cls, + const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket, + GNUNET_IDENTITY_PROVIDER_TicketIterator iter, + void *iter_cls); }; diff --git a/src/include/gnunet_identity_provider_service.h b/src/include/gnunet_identity_provider_service.h index fa4d4536c..d17a1cc9c 100644 --- a/src/include/gnunet_identity_provider_service.h +++ b/src/include/gnunet_identity_provider_service.h @@ -113,6 +113,11 @@ struct GNUNET_IDENTITY_PROVIDER_Attribute */ uint32_t attribute_type; + /** + * Attribute version + */ + uint32_t attribute_version; + /** * Number of bytes in @e data. */ -- 2.25.1