From 0b3e4109250e96515d7ea5964f50aa32b4cccbd2 Mon Sep 17 00:00:00 2001 From: Markus Voggenreiter Date: Wed, 27 Nov 2019 12:30:49 +0100 Subject: [PATCH] Basic Functionality Implemented --- src/include/gnunet_gnsrecord_lib.h | 9 - src/include/gnunet_reclaim_attribute_lib.h | 22 ++ src/reclaim-attribute/reclaim_attribute.c | 214 +++++++++++++-- src/reclaim/gnunet-service-reclaim.c | 71 ++++- src/reclaim/gnunet-service-reclaim_tickets.c | 260 +++++++++++++++---- src/reclaim/json_reclaim.c | 7 +- src/reclaim/oidc_helper.c | 126 ++++++++- src/reclaim/oidc_helper.h | 2 +- src/reclaim/plugin_gnsrecord_reclaim.c | 2 - src/reclaim/plugin_rest_openid_connect.c | 167 +++++++++--- src/reclaim/plugin_rest_reclaim.c | 5 + src/reclaim/reclaim_api.c | 18 +- 12 files changed, 750 insertions(+), 153 deletions(-) diff --git a/src/include/gnunet_gnsrecord_lib.h b/src/include/gnunet_gnsrecord_lib.h index b49e39b76..797c71380 100644 --- a/src/include/gnunet_gnsrecord_lib.h +++ b/src/include/gnunet_gnsrecord_lib.h @@ -150,15 +150,6 @@ extern "C" { */ #define GNUNET_GNSRECORD_TYPE_RECLAIM_REFERENCE 65555 -/** - * Record type for reclaim attestation records - */ -#define GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_REF 65556 - -/** - * Record type for reclaim reference records - */ -#define GNUNET_GNSRECORD_TYPE_RECLAIM_REFERENCE_REF 65557 /** * Flags that can be set for a record. diff --git a/src/include/gnunet_reclaim_attribute_lib.h b/src/include/gnunet_reclaim_attribute_lib.h index c761d20ed..004f2bd10 100644 --- a/src/include/gnunet_reclaim_attribute_lib.h +++ b/src/include/gnunet_reclaim_attribute_lib.h @@ -198,6 +198,20 @@ struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry * The attribute claim */ struct GNUNET_RECLAIM_ATTRIBUTE_Claim *claim; + /** + * The attestation claim + */ + struct GNUNET_RECLAIM_ATTESTATION_Claim *attest; + + /** + * The reference + */ + struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *reference; +}; + +struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType +{ + uint32_t type; }; @@ -278,6 +292,14 @@ GNUNET_RECLAIM_ATTRIBUTE_list_serialize ( struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList * GNUNET_RECLAIM_ATTRIBUTE_list_deserialize (const char *data, size_t data_size); +/** + * Count attestations in claim list + * + * @param attrs list + */ +int +GNUNET_RECLAIM_ATTRIBUTE_list_count_attest ( + const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs); /** * Get required size for serialization buffer diff --git a/src/reclaim-attribute/reclaim_attribute.c b/src/reclaim-attribute/reclaim_attribute.c index 207bfb617..43199c108 100644 --- a/src/reclaim-attribute/reclaim_attribute.c +++ b/src/reclaim-attribute/reclaim_attribute.c @@ -476,7 +476,30 @@ GNUNET_RECLAIM_ATTRIBUTE_list_serialize_get_size ( size_t len = 0; for (le = attrs->list_head; NULL != le; le = le->next) - len += GNUNET_RECLAIM_ATTRIBUTE_serialize_get_size (le->claim); + { + if (NULL != le->claim) + { + len += sizeof(struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType); + len += GNUNET_RECLAIM_ATTRIBUTE_serialize_get_size (le->claim); + } + else if (NULL != le->attest ) + { + len += sizeof(struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType); + len += GNUNET_RECLAIM_ATTESTATION_serialize_get_size (le->attest); + } + else if (NULL != le->reference) + { + len += sizeof(struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType); + len += GNUNET_RECLAIM_ATTESTATION_REF_serialize_get_size (le->reference); + } + else + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Unserialized Claim List Entry Type for size not known.\n"); + break; + } + len += sizeof(struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry); + } return len; } @@ -497,14 +520,50 @@ GNUNET_RECLAIM_ATTRIBUTE_list_serialize ( size_t len; size_t total_len; char *write_ptr; - write_ptr = result; total_len = 0; for (le = attrs->list_head; NULL != le; le = le->next) { - len = GNUNET_RECLAIM_ATTRIBUTE_serialize (le->claim, write_ptr); - total_len += len; - write_ptr += len; + struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType *list_type; + if (NULL != le->claim) + { + list_type = (struct + GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType *) write_ptr; + list_type->type = htons (1); + total_len += sizeof(struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType); + write_ptr += sizeof(struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType); + len = GNUNET_RECLAIM_ATTRIBUTE_serialize (le->claim, write_ptr); + total_len += len; + write_ptr += len; + } + else if (NULL != le->attest ) + { + list_type = (struct + GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType *) write_ptr; + list_type->type = htons (2); + total_len += sizeof(struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType); + write_ptr += sizeof(struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType); + len = GNUNET_RECLAIM_ATTESTATION_serialize (le->attest, write_ptr); + total_len += len; + write_ptr += len; + } + else if (NULL != le->reference) + { + list_type = (struct + GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType *) write_ptr; + list_type->type = htons (3); + total_len += sizeof(struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType); + write_ptr += sizeof(struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType); + len = GNUNET_RECLAIM_ATTESTATION_REF_serialize (le->reference, write_ptr); + total_len += len; + write_ptr += len; + } + else + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Unserialized Claim List Entry Type not known.\n"); + continue; + } } return total_len; } @@ -525,23 +584,75 @@ GNUNET_RECLAIM_ATTRIBUTE_list_deserialize (const char *data, size_t data_size) size_t attr_len; const char *read_ptr; - if (data_size < sizeof(struct Attribute)) + if ((data_size < sizeof(struct Attribute) + sizeof(struct + GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry)) + && (data_size < sizeof(struct + Attestation) + + sizeof(struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry)) && + (data_size < sizeof(struct Attestation_Reference) + sizeof(struct + GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry)) ) return NULL; attrs = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList); read_ptr = data; while (((data + data_size) - read_ptr) >= sizeof(struct Attribute)) { - le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry); - le->claim = - GNUNET_RECLAIM_ATTRIBUTE_deserialize (read_ptr, - data_size - (read_ptr - data)); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Deserialized attribute %s\n", - le->claim->name); - GNUNET_CONTAINER_DLL_insert (attrs->list_head, attrs->list_tail, le); - attr_len = GNUNET_RECLAIM_ATTRIBUTE_serialize_get_size (le->claim); - read_ptr += attr_len; + struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType *list_type; + list_type = (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType *) read_ptr; + if (1 == ntohs (list_type->type)) + { + le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry); + read_ptr += sizeof(struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType); + if (((data + data_size) - read_ptr) < sizeof(struct Attribute)) + break; + le->attest = NULL; + le->reference = NULL; + le->claim = + GNUNET_RECLAIM_ATTRIBUTE_deserialize (read_ptr, + data_size - (read_ptr - data)); + GNUNET_CONTAINER_DLL_insert (attrs->list_head, attrs->list_tail, le); + attr_len = GNUNET_RECLAIM_ATTRIBUTE_serialize_get_size (le->claim); + read_ptr += attr_len; + } + else if (2 == ntohs (list_type->type)) + { + le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry); + read_ptr += sizeof(struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType); + if (((data + data_size) - read_ptr) < sizeof(struct Attestation)) + break; + le->claim = NULL; + le->reference = NULL; + le->attest = + GNUNET_RECLAIM_ATTESTATION_deserialize (read_ptr, + data_size - (read_ptr - data)); + GNUNET_CONTAINER_DLL_insert (attrs->list_head, attrs->list_tail, le); + attr_len = GNUNET_RECLAIM_ATTESTATION_serialize_get_size (le->attest); + read_ptr += attr_len; + } + else if (3 == ntohs (list_type->type)) + { + le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry); + read_ptr += sizeof(struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntryType); + if (((data + data_size) - read_ptr) < sizeof(struct + Attestation_Reference)) + break; + le->claim = NULL; + le->attest = NULL; + le->reference = + GNUNET_RECLAIM_ATTESTATION_REF_deserialize (read_ptr, + data_size - (read_ptr + - data)); + GNUNET_CONTAINER_DLL_insert (attrs->list_head, attrs->list_tail, le); + attr_len = GNUNET_RECLAIM_ATTESTATION_REF_serialize_get_size ( + le->reference); + read_ptr += attr_len; + } + else + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Serialized Claim List Entry Type not known.\n"); + break; + } } return attrs; } @@ -561,16 +672,45 @@ GNUNET_RECLAIM_ATTRIBUTE_list_dup ( struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *result; result = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList); + if (NULL == attrs->list_head) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Duplicating empty List\n"); + } for (le = attrs->list_head; NULL != le; le = le->next) { result_le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry); - result_le->claim = - GNUNET_RECLAIM_ATTRIBUTE_claim_new (le->claim->name, - le->claim->type, - le->claim->data, - le->claim->data_size); - result_le->claim->id = le->claim->id; - result_le->claim->flag = le->claim->flag; + result_le->claim = NULL; + result_le->attest = NULL; + result_le->reference = NULL; + if (NULL != le->claim) + { + result_le->claim = + GNUNET_RECLAIM_ATTRIBUTE_claim_new (le->claim->name, + le->claim->type, + le->claim->data, + le->claim->data_size); + + result_le->claim->id = le->claim->id; + result_le->claim->flag = le->claim->flag; + } + if ( NULL != le->attest) + { + result_le->attest = GNUNET_RECLAIM_ATTESTATION_claim_new ( + le->attest->name, + le->attest->type, + le->attest->data, + le->attest-> + data_size); + result_le->attest->id = le->attest->id; + } + if (NULL !=le->reference) + { + result_le->reference = GNUNET_RECLAIM_ATTESTATION_reference_new ( + le->reference->name, + le->reference->reference_value); + result_le->reference->id = le->reference->id; + result_le->reference->id_attest = le->reference->id_attest; + } GNUNET_CONTAINER_DLL_insert (result->list_head, result->list_tail, result_le); @@ -591,9 +731,14 @@ GNUNET_RECLAIM_ATTRIBUTE_list_destroy ( struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le; struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *tmp_le; - for (le = attrs->list_head; NULL != le;) + for (le = attrs->list_head; NULL != le; le = le->next) { - GNUNET_free (le->claim); + if (NULL != le->claim) + GNUNET_free (le->claim); + if (NULL != le->attest) + GNUNET_free (le->attest); + if (NULL != le->reference) + GNUNET_free (le->reference); tmp_le = le; le = le->next; GNUNET_free (tmp_le); @@ -601,7 +746,24 @@ GNUNET_RECLAIM_ATTRIBUTE_list_destroy ( GNUNET_free (attrs); } - +/** + * Count attestations in claim list + * + * @param attrs list + */ +int +GNUNET_RECLAIM_ATTRIBUTE_list_count_attest ( + const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs) +{ + struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le; + int i = 0; + for (le = attrs->list_head; NULL != le; le = le->next) + { + if (NULL != le->attest) + i++; + } + return i; +} /** * Get required size for serialization buffer * diff --git a/src/reclaim/gnunet-service-reclaim.c b/src/reclaim/gnunet-service-reclaim.c index fcbd9413f..8b7557090 100644 --- a/src/reclaim/gnunet-service-reclaim.c +++ b/src/reclaim/gnunet-service-reclaim.c @@ -1250,6 +1250,31 @@ reference_store_cont (void *cls, int32_t success, const char *emsg) cleanup_as_handle (ash); } +/** + * Send a reference error response + * + * @param ash our attribute store handle + * @param success the success status + */ +static void +send_ref_error (struct AttributeStoreHandle *ash) +{ + struct GNUNET_MQ_Envelope *env; + struct SuccessResultMessage *acr_msg; + + ash->ns_qe = NULL; + GNUNET_CONTAINER_DLL_remove (ash->client->store_op_head, + ash->client->store_op_tail, + ash); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending SUCCESS_RESPONSE message\n"); + env = GNUNET_MQ_msg (acr_msg, GNUNET_MESSAGE_TYPE_RECLAIM_SUCCESS_RESPONSE); + acr_msg->id = htonl (ash->r_id); + acr_msg->op_result = htonl (GNUNET_SYSERR); + GNUNET_MQ_send (ash->client->mq, env); + cleanup_as_handle (ash); +} + /** * Check for existing record before storing reference * @@ -1272,33 +1297,46 @@ ref_add_cb (void *cls, buf_size = GNUNET_RECLAIM_ATTESTATION_REF_serialize_get_size (ash->reference); buf = GNUNET_malloc (buf_size); GNUNET_RECLAIM_ATTESTATION_REF_serialize (ash->reference, buf); + struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *ref; + char *data_tmp; if (0 == rd_count ) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to find Attestation entry for Attestation reference\n"); - cleanup_as_handle (ash); - GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); + send_ref_error (ash); return; } if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR != rd[0].record_type) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Intended Reference storage location is not an attestation\n"); - cleanup_as_handle (ash); - GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); + send_ref_error (ash); return; } struct GNUNET_GNSRECORD_Data rd_new[rd_count + 1]; int i; for (i = 0; ireference->name,ref->name) == 0)&& + (strcmp (ash->reference->reference_value,ref->reference_value)==0) ) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Reference already stored\n"); + reference_store_cont (ash,GNUNET_OK, NULL); + return; + } } rd_new[rd_count].data_size = buf_size; rd_new[rd_count].data = buf; rd_new[rd_count].record_type = GNUNET_GNSRECORD_TYPE_RECLAIM_REFERENCE; rd_new[rd_count].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION; rd_new[rd_count].expiration_time = ash->exp.rel_value_us; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Encrypting with label %s\n", label); ash->ns_qe = GNUNET_NAMESTORE_records_store (nsh, &ash->identity, label, @@ -1339,7 +1377,8 @@ reference_store_task (void *cls) label = GNUNET_STRINGS_data_to_string_alloc (&ash->reference->id, sizeof(uint64_t)); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Encrypting with label %s\n", label); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Looking up existing data under label %s\n", label); // Test for the content of the existing ID ash->ns_qe = GNUNET_NAMESTORE_records_lookup (nsh, @@ -1452,9 +1491,7 @@ ticket_iter (void *cls, int has_changed = GNUNET_NO; for (int i = 0; i < rd_count; i++) { - if ((GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF != rd[i].record_type) && - (GNUNET_GNSRECORD_TYPE_RECLAIM_REFERENCE_REF != rd[i].record_type) && - (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_REF != rd[i].record_type)) + if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF != rd[i].record_type) continue; if (&adh->claim != NULL) if (0 != memcmp (rd[i].data, &adh->claim->id, sizeof(uint64_t))) @@ -1559,10 +1596,10 @@ update_tickets (void *cls) if ((GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF == rd[i].record_type) && (0 == memcmp (rd[i].data, &adh->claim->id, sizeof(uint64_t)))) continue; - if ((GNUNET_GNSRECORD_TYPE_RECLAIM_REFERENCE_REF == rd[i].record_type) + if ((GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF == rd[i].record_type) && (0 == memcmp (rd[i].data, &adh->attest->id, sizeof(uint64_t)))) continue; - if ((GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_REF == rd[i].record_type) + if ((GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF == rd[i].record_type) && (0 == memcmp (rd[i].data, &adh->reference->id, sizeof(uint64_t)))) continue; rd_new[j] = rd[i]; @@ -1879,7 +1916,7 @@ ref_del_cb (void *cls, { data_tmp = GNUNET_malloc (rd[i].data_size); GNUNET_memcpy (data_tmp, rd[i].data, rd[i].data_size); - attr_len = htons (rd->data_size); + attr_len = htons (rd[i].data_size); ref = GNUNET_RECLAIM_ATTESTATION_REF_deserialize (data_tmp, attr_len); if (NULL == ref ) { @@ -2045,10 +2082,18 @@ attr_iter_cb (void *cls, } if (rd_count > 1) { - if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR != rd[0].record_type) + if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF == rd[0].record_type) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Found Ticket. Ignoring.\n"); + GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it, 1); + return; + } + else if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR != rd[0].record_type) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Non-Attestation record with multiple entries found\n"); + "Non-Attestation record with multiple entries found: %u\n", + rd[0].record_type); GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it, 1); return; } diff --git a/src/reclaim/gnunet-service-reclaim_tickets.c b/src/reclaim/gnunet-service-reclaim_tickets.c index 4d1a26333..b022225b8 100644 --- a/src/reclaim/gnunet-service-reclaim_tickets.c +++ b/src/reclaim/gnunet-service-reclaim_tickets.c @@ -667,8 +667,7 @@ rvk_move_attr_cb (void *cls, const struct GNUNET_GNSRECORD_Data *rd) { struct RECLAIM_TICKETS_RevokeHandle *rvk = cls; - struct GNUNET_RECLAIM_ATTRIBUTE_Claim *claim; - struct GNUNET_GNSRECORD_Data new_rd; + struct GNUNET_GNSRECORD_Data new_rd[rd_count]; struct RevokedAttributeEntry *le; char *new_label; char *attr_data; @@ -677,7 +676,7 @@ rvk_move_attr_cb (void *cls, if (0 == rd_count) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "The attribute %s no longer exists!\n", + "The claim %s no longer exists!\n", label); le = rvk->move_attr; rvk->move_attr = le->next; @@ -686,32 +685,82 @@ rvk_move_attr_cb (void *cls, GNUNET_SCHEDULER_add_now (&move_attrs_cont, rvk); return; } - /** find a new place for this attribute **/ - rvk->move_attr->new_id = - GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG, UINT64_MAX); - new_rd = *rd; - claim = GNUNET_RECLAIM_ATTRIBUTE_deserialize (rd->data, rd->data_size); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Attribute to update: Name=%s, ID=%" PRIu64 "\n", - claim->name, - claim->id); - claim->id = rvk->move_attr->new_id; - new_rd.data_size = GNUNET_RECLAIM_ATTRIBUTE_serialize_get_size (claim); - attr_data = GNUNET_malloc (rd->data_size); - new_rd.data_size = GNUNET_RECLAIM_ATTRIBUTE_serialize (claim, attr_data); - new_rd.data = attr_data; - new_label = GNUNET_STRINGS_data_to_string_alloc (&rvk->move_attr->new_id, - sizeof(uint64_t)); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding attribute %s\n", new_label); + rvk->move_attr->new_id =GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG, UINT64_MAX); + new_label=NULL; + attr_data=NULL; + //new_rd = *rd; + for (int i = 0; i < rd_count; i++) + { + if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR == rd[i].record_type) + { + /** find a new place for this attribute **/ + struct GNUNET_RECLAIM_ATTRIBUTE_Claim *claim; + claim = GNUNET_RECLAIM_ATTRIBUTE_deserialize (rd[i].data, rd[i].data_size); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Attribute to update: Name=%s, ID=%" PRIu64 "\n", + claim->name, + claim->id); + claim->id = rvk->move_attr->new_id; + new_rd[i].data_size = GNUNET_RECLAIM_ATTRIBUTE_serialize_get_size (claim); + attr_data = GNUNET_malloc (rd[i].data_size); + new_rd[i].data_size = GNUNET_RECLAIM_ATTRIBUTE_serialize (claim, attr_data); + new_rd[i].data = attr_data; + new_rd[i].record_type = rd[i].record_type; + new_rd[i].flags = rd[i].flags; + new_rd[i].expiration_time = rd[i].expiration_time; + new_label = GNUNET_STRINGS_data_to_string_alloc (&rvk->move_attr->new_id, + sizeof(uint64_t)); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding attribute %s\n", new_label); + GNUNET_free (claim); + } else if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR == rd[i].record_type) + { + struct GNUNET_RECLAIM_ATTESTATION_Claim *attest; + attest=GNUNET_RECLAIM_ATTESTATION_deserialize(rd[i].data, rd[i].data_size); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Attestation to update: Name=%s, ID=%" PRIu64 "\n", + attest->name, + attest->id); + attest->id = rvk->move_attr->new_id; + new_rd[i].data_size = GNUNET_RECLAIM_ATTESTATION_serialize_get_size (attest); + attr_data = GNUNET_malloc (rd[i].data_size); + new_rd[i].data_size = GNUNET_RECLAIM_ATTESTATION_serialize (attest, attr_data); + new_rd[i].data = attr_data; + new_rd[i].record_type = rd[i].record_type; + new_rd[i].flags = rd[i].flags; + new_rd[i].expiration_time = rd[i].expiration_time; + new_label = GNUNET_STRINGS_data_to_string_alloc (&rvk->move_attr->new_id, sizeof(uint64_t)); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding attestation %s\n", new_label); + GNUNET_free (attest); + } else if (GNUNET_GNSRECORD_TYPE_RECLAIM_REFERENCE == rd[i].record_type) + { + struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *reference; + reference=GNUNET_RECLAIM_ATTESTATION_REF_deserialize(rd[i].data, rd[i].data_size); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Reference to update: Name=%s, ID=%" PRIu64 "\n", + reference->name, + reference->id); + reference->id = rvk->move_attr->new_id; + reference->id_attest = rvk->move_attr->new_id; + new_rd[i].data_size = GNUNET_RECLAIM_ATTESTATION_REF_serialize_get_size (reference); + attr_data = GNUNET_malloc (rd[i].data_size); + new_rd[i].data_size = GNUNET_RECLAIM_ATTESTATION_REF_serialize (reference, attr_data); + new_rd[i].data = attr_data; + new_label = GNUNET_STRINGS_data_to_string_alloc (&rvk->move_attr->new_id, sizeof(uint64_t)); + new_rd[i].record_type = rd[i].record_type; + new_rd[i].flags = rd[i].flags; + new_rd[i].expiration_time = rd[i].expiration_time; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding reference %s\n", new_label); + GNUNET_free (reference); + } + } rvk->ns_qe = GNUNET_NAMESTORE_records_store (nsh, - &rvk->identity, - new_label, - 1, - &new_rd, - &move_attr_finished, - rvk); + &rvk->identity, + new_label, + rd_count, + new_rd, + &move_attr_finished, + rvk); GNUNET_free (new_label); - GNUNET_free (claim); GNUNET_free (attr_data); } @@ -745,7 +794,7 @@ move_attrs (struct RECLAIM_TICKETS_RevokeHandle *rvk) } label = GNUNET_STRINGS_data_to_string_alloc (&rvk->move_attr->old_id, sizeof(uint64_t)); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Moving attribute %s\n", label); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Moving claim %s\n", label); rvk->ns_qe = GNUNET_NAMESTORE_records_lookup (nsh, &rvk->identity, @@ -982,21 +1031,70 @@ process_parallel_lookup_result (void *cls, GNUNET_free (parallel_lookup); - if (1 != rd_count) - GNUNET_break (0); // FIXME: We should never find this. - if (rd->record_type == GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR) + if (0 == rd_count) + GNUNET_break (0); + // REMARK: It is possible now to find rd_count > 1 + for (int i = 0; i < rd_count; i++) { - attr_le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry); - attr_le->claim = - GNUNET_RECLAIM_ATTRIBUTE_deserialize (rd->data, rd->data_size); - GNUNET_CONTAINER_DLL_insert (cth->attrs->list_head, - cth->attrs->list_tail, - attr_le); - } + if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR == rd[i].record_type) + { + attr_le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry); + attr_le->claim = + GNUNET_RECLAIM_ATTRIBUTE_deserialize (rd[i].data, rd[i].data_size); + GNUNET_CONTAINER_DLL_insert (cth->attrs->list_head, + cth->attrs->list_tail, + attr_le); + attr_le->reference = NULL; + attr_le->attest = NULL; + } + else if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR == rd[i].record_type) + { + /**Ignore all plain attestations + *attr_le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry); + *attr_le->attest = + * GNUNET_RECLAIM_ATTESTATION_deserialize (rd[i].data, rd[i].data_size); + *GNUNET_CONTAINER_DLL_insert (cth->attrs->list_head, + * cth->attrs->list_tail, + * attr_le); + */ + continue; + } + else if (GNUNET_GNSRECORD_TYPE_RECLAIM_REFERENCE == rd[i].record_type) + { + struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *attr_le2; + attr_le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry); + attr_le2 = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry); + if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR == rd[0].record_type) + { + attr_le->attest = GNUNET_RECLAIM_ATTESTATION_deserialize (rd[0].data, + rd[0]. + data_size); + attr_le2->reference = + GNUNET_RECLAIM_ATTESTATION_REF_deserialize (rd[i].data, + rd[i].data_size); + attr_le->claim = NULL; + attr_le->reference = NULL; + attr_le2->claim = NULL; + attr_le2->attest = NULL; + GNUNET_CONTAINER_DLL_insert (cth->attrs->list_head, + cth->attrs->list_tail, + attr_le); + GNUNET_CONTAINER_DLL_insert (cth->attrs->list_head, + cth->attrs->list_tail, + attr_le2); + } + else + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Parallel Lookup of Reference without Attestation"); + continue; + } + + } + } if (NULL != cth->parallel_lookups_head) return; // Wait for more - /* Else we are done */ cth->cb (cth->cb_cls, &cth->ticket.identity, cth->attrs, GNUNET_OK, NULL); cleanup_cth (cth); @@ -1076,7 +1174,7 @@ lookup_authz_cb (void *cls, GNUNET_GNS_lookup (gns, lbl, &cth->ticket.identity, - GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR, + GNUNET_GNSRECORD_TYPE_ANY, GNUNET_GNS_LO_DEFAULT, &process_parallel_lookup_result, parallel_lookup); @@ -1223,6 +1321,7 @@ issue_ticket (struct TicketIssueHandle *ih) char *label; size_t list_len = 1; int i; + char *attest_string; for (le = ih->attrs->list_head; NULL != le; le = le->next) list_len++; @@ -1232,8 +1331,51 @@ issue_ticket (struct TicketIssueHandle *ih) i = 0; for (le = ih->attrs->list_head; NULL != le; le = le->next) { - attrs_record[i].data = &le->claim->id; - attrs_record[i].data_size = sizeof(le->claim->id); + if (NULL != le->claim) + { + attrs_record[i].data = &le->claim->id; + attrs_record[i].data_size = sizeof(le->claim->id); + } + else if (NULL != le->attest) + { + // REMARK: Since we only store IDs, the references are irrelevant + int j = 0; + GNUNET_asprintf (&attest_string,"%d",le->attest->id); + while (jattest->id; + attrs_record[i].data_size = sizeof(le->attest->id); + } + else if (NULL != le->reference) + { + list_len--; + continue; + /* + int j = 0; + GNUNET_asprintf (&attest_string,"%d",le->attest->id); + while (jreference->id; + attrs_record[i].data_size = sizeof(le->reference->id); + */ + } /** * FIXME: Should this be the attribute expiration time or ticket * refresh interval? Probably min(attrs.expiration) @@ -1344,14 +1486,34 @@ filter_tickets_cb (void *cls, for (le = tih->attrs->list_head; NULL != le; le = le->next) { // cmp attr_ref id with requested attr id - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - " %" PRIu64 "\n %" PRIu64 "\n", - *((uint64_t *) rd[i].data), - le->claim->id); - + if (NULL !=le->claim) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + " %" PRIu64 "\n %" PRIu64 "\n", + *((uint64_t *) rd[i].data), + le->claim->id); + if (0 == memcmp (rd[i].data, &le->claim->id, sizeof(uint64_t))) + found_attrs_cnt++; + } + else if (NULL !=le->attest) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + " %" PRIu64 "\n %" PRIu64 "\n", + *((uint64_t *) rd[i].data), + le->attest->id); + if (0 == memcmp (rd[i].data, &le->attest->id, sizeof(uint64_t))) + found_attrs_cnt++; + } + else if (NULL != le->reference) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + " %" PRIu64 "\n %" PRIu64 "\n", + *((uint64_t *) rd[i].data), + le->reference->id); + if (0 == memcmp (rd[i].data, &le->reference->id, sizeof(uint64_t))) + found_attrs_cnt++; + } - if (0 == memcmp (rd[i].data, &le->claim->id, sizeof(uint64_t))) - found_attrs_cnt++; } } diff --git a/src/reclaim/json_reclaim.c b/src/reclaim/json_reclaim.c index 552ca0e69..775ab58d6 100644 --- a/src/reclaim/json_reclaim.c +++ b/src/reclaim/json_reclaim.c @@ -48,6 +48,7 @@ parse_attr (void *cls, json_t *root, struct GNUNET_JSON_Specification *spec) const char *val_str = NULL; const char *type_str = NULL; const char *id_str = NULL; + const char *flag_str = NULL; char *data; int unpack_state; uint32_t type; @@ -63,7 +64,7 @@ parse_attr (void *cls, json_t *root, struct GNUNET_JSON_Specification *spec) } // interpret single attribute unpack_state = json_unpack (root, - "{s:s, s?s, s:s, s:s!}", + "{s:s, s?s, s:s, s:s, s?s!}", "name", &name_str, "id", @@ -71,7 +72,9 @@ parse_attr (void *cls, json_t *root, struct GNUNET_JSON_Specification *spec) "type", &type_str, "value", - &val_str); + &val_str, + "flag", + &flag_str); if ((0 != unpack_state) || (NULL == name_str) || (NULL == val_str) || (NULL == type_str)) { diff --git a/src/reclaim/oidc_helper.c b/src/reclaim/oidc_helper.c index 1c3d65f35..2ce462854 100644 --- a/src/reclaim/oidc_helper.c +++ b/src/reclaim/oidc_helper.c @@ -118,7 +118,7 @@ fix_base64 (char *str) char * OIDC_id_token_new (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key, - const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs, + struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs, const struct GNUNET_TIME_Relative *expiration_time, const char *nonce, const char *secret_key) @@ -131,13 +131,22 @@ OIDC_id_token_new (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, char *subject; char *header; char *body_str; + char *aggr_names_str; + char *aggr_sources_str; + char *aggr_sources_jwt_str; + char *source_name; char *result; char *header_base64; char *body_base64; char *signature_target; char *signature_base64; char *attr_val_str; + char *attest_val_str; json_t *body; + json_t *aggr_names; + json_t *aggr_sources; + json_t *aggr_sources_jwt; + uint64_t attest_arr[GNUNET_RECLAIM_ATTRIBUTE_list_count_attest (attrs)]; // iat REQUIRED time now time_now = GNUNET_TIME_absolute_get (); @@ -156,6 +165,8 @@ OIDC_id_token_new (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, GNUNET_CRYPTO_EcdsaPublicKey)); header = create_jwt_header (); body = json_object (); + aggr_names = json_object (); + aggr_sources = json_object (); // iss REQUIRED case sensitive server uri with https // The issuer is the local reclaim instance (e.g. @@ -180,18 +191,111 @@ OIDC_id_token_new (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, // nonce if (NULL != nonce) json_object_set_new (body, "nonce", json_string (nonce)); - + int i = 0; + attest_val_str = NULL; + aggr_names_str = NULL; + aggr_sources_str = NULL; + aggr_sources_jwt_str = NULL; + source_name = NULL; for (le = attrs->list_head; NULL != le; le = le->next) { - attr_val_str = - GNUNET_RECLAIM_ATTRIBUTE_value_to_string (le->claim->type, - le->claim->data, - le->claim->data_size); - json_object_set_new (body, le->claim->name, json_string (attr_val_str)); - GNUNET_free (attr_val_str); + + if (le->claim != NULL) + { + + attr_val_str = + GNUNET_RECLAIM_ATTRIBUTE_value_to_string (le->claim->type, + le->claim->data, + le->claim->data_size); + json_object_set_new (body, le->claim->name, json_string (attr_val_str)); + GNUNET_free (attr_val_str); + } + else if (NULL != le->reference) + { + // Check if attest is there + int j = 0; + while (jreference->id_attest) + break; + j++; + } + if (j==i) + { + // Attest not yet existent. Append to the end of the list + GNUNET_CONTAINER_DLL_remove (attrs->list_head, attrs->list_tail, le); + GNUNET_CONTAINER_DLL_insert_tail (attrs->list_head, attrs->list_tail, + le); + continue; + } + else + { + // Attestation is existing, hence take the respective source str + GNUNET_asprintf (&source_name, + "src%d", + j); + json_object_set_new (aggr_names, le->reference->name, json_string ( + source_name)); + } + + } + else if (NULL != le->attest) + { + // We assume that at max 99 different attestations + int j = 0; + while (jattest->id) + break; + j++; + } + if (j==i) + { + // New Attestation + attest_arr[i] = le->attest->id; + GNUNET_asprintf (&source_name, + "src%d", + i); + aggr_sources_jwt = json_object (); + attest_val_str = GNUNET_RECLAIM_ATTESTATION_value_to_string ( + le->attest->type, le->attest->data, le->attest->data_size); + json_object_set_new (aggr_sources_jwt, "JWT",json_string ( + attest_val_str) ); + aggr_sources_jwt_str = json_dumps (aggr_sources_jwt, JSON_INDENT (0) + | JSON_COMPACT); + json_object_set_new (aggr_sources, source_name,json_string ( + aggr_sources_jwt_str)); + i++; + } + else + { + // Attestation already existent. Ignore + continue; + } + + } + } + if (NULL != attest_val_str) + GNUNET_free (attest_val_str); + if (NULL != source_name) + GNUNET_free (source_name); + if (0!=i) + { + aggr_names_str = json_dumps (aggr_names, JSON_INDENT (0) | JSON_COMPACT); + aggr_sources_str = json_dumps (aggr_sources, JSON_INDENT (0) + | JSON_COMPACT); + json_object_set_new (body, "_claim_names", json_string (aggr_names_str)); + json_object_set_new (body, "_claim_sources", json_string ( + aggr_sources_str)); } + + json_decref (aggr_names); + json_decref (aggr_sources); + json_decref (aggr_sources_jwt); + body_str = json_dumps (body, JSON_INDENT (0) | JSON_COMPACT); json_decref (body); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"ID-Token: %s\n", body_str); GNUNET_STRINGS_base64_encode (header, strlen (header), &header_base64); fix_base64 (header_base64); @@ -226,6 +330,12 @@ OIDC_id_token_new (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, GNUNET_free (signature_target); GNUNET_free (header); GNUNET_free (body_str); + if (NULL != aggr_sources_str) + GNUNET_free (aggr_sources_str); + if (NULL != aggr_names_str) + GNUNET_free (aggr_names_str); + if (NULL != aggr_sources_jwt_str) + GNUNET_free (aggr_sources_jwt_str); GNUNET_free (signature_base64); GNUNET_free (body_base64); GNUNET_free (header_base64); diff --git a/src/reclaim/oidc_helper.h b/src/reclaim/oidc_helper.h index 1774618e8..a7072755b 100644 --- a/src/reclaim/oidc_helper.h +++ b/src/reclaim/oidc_helper.h @@ -51,7 +51,7 @@ char* OIDC_id_token_new (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key, - const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs, + struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs, const struct GNUNET_TIME_Relative *expiration_time, const char *nonce, const char *secret_key); diff --git a/src/reclaim/plugin_gnsrecord_reclaim.c b/src/reclaim/plugin_gnsrecord_reclaim.c index 0f59082dc..f7145a272 100644 --- a/src/reclaim/plugin_gnsrecord_reclaim.c +++ b/src/reclaim/plugin_gnsrecord_reclaim.c @@ -122,8 +122,6 @@ static struct { "RECLAIM_OIDC_REDIRECT", GNUNET_GNSRECORD_TYPE_RECLAIM_OIDC_REDIRECT }, { "RECLAIM_TICKET", GNUNET_GNSRECORD_TYPE_RECLAIM_TICKET }, { "RECLAIM_REFERENCE", GNUNET_GNSRECORD_TYPE_RECLAIM_REFERENCE }, - { "RECLAIM_REFERENCE_REF", GNUNET_GNSRECORD_TYPE_RECLAIM_REFERENCE_REF }, - { "RECLAIM_ATTEST_REF", GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_REF }, { NULL, UINT32_MAX } }; diff --git a/src/reclaim/plugin_rest_openid_connect.c b/src/reclaim/plugin_rest_openid_connect.c index 2c4b75c3f..741094f21 100644 --- a/src/reclaim/plugin_rest_openid_connect.c +++ b/src/reclaim/plugin_rest_openid_connect.c @@ -119,6 +119,11 @@ */ #define OIDC_NONCE_KEY "nonce" +/** + * OIDC claims key + */ +#define OIDC_CLAIMS_KEY "claims" + /** * OIDC PKCE code challenge */ @@ -290,6 +295,11 @@ struct OIDC_Variables */ char *nonce; + /** + * The OIDC claims + */ + char *claims; + /** * The OIDC response type */ @@ -560,7 +570,12 @@ cleanup_handle (struct RequestHandle *handle) { claim_tmp = claim_entry; claim_entry = claim_entry->next; - GNUNET_free (claim_tmp->claim); + if (NULL != claim_tmp->claim) + GNUNET_free (claim_tmp->claim); + if (NULL != claim_tmp->attest) + GNUNET_free (claim_tmp->attest); + if (NULL != claim_tmp->reference) + GNUNET_free (claim_tmp->reference); GNUNET_free (claim_tmp); } GNUNET_free (handle->attr_list); @@ -697,7 +712,7 @@ return_userinfo_response (void *cls) struct MHD_Response *resp; result_str = json_dumps (handle->oidc->response, 0); - + GNUNET_log (GNUNET_ERROR_TYPE_ERROR,"ID-Token: %s\n",result_str); resp = GNUNET_REST_create_response (result_str); handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); GNUNET_free (result_str); @@ -838,7 +853,7 @@ login_redirect (void *cls) &login_base_url)) { GNUNET_asprintf (&new_redirect, - "%s?%s=%s&%s=%s&%s=%s&%s=%s&%s=%s&%s=%s&%s=%s", + "%s?%s=%s&%s=%s&%s=%s&%s=%s&%s=%s&%s=%s&%s=%s&%s=%s", login_base_url, OIDC_RESPONSE_TYPE_KEY, handle->oidc->response_type, @@ -854,7 +869,10 @@ login_redirect (void *cls) (NULL != handle->oidc->code_challenge) ? handle->oidc->code_challenge : "", OIDC_NONCE_KEY, - (NULL != handle->oidc->nonce) ? handle->oidc->nonce : ""); + (NULL != handle->oidc->nonce) ? handle->oidc->nonce : "", + OIDC_CLAIMS_KEY, + (NULL != handle->oidc->claims) ? handle->oidc->claims : + ""); resp = GNUNET_REST_create_response (""); MHD_add_response_header (resp, "Location", new_redirect); GNUNET_free (login_base_url); @@ -993,7 +1011,7 @@ oidc_attr_collect (void *cls, GNUNET_RECLAIM_get_attributes_next (handle->attr_it); return; } - if (NULL == attr) + if (NULL != reference) { if ((NULL == reference->name) || (NULL == reference->reference_value)) { @@ -1013,35 +1031,31 @@ oidc_attr_collect (void *cls, return; } GNUNET_free (scope_variables); - // Store references as attributes as they only use the ID later - const char *type_str = NULL; - char *data; - size_t data_size; - uint32_t type; + struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le2; + le2 = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry); le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry); - type_str = "String"; - type = GNUNET_RECLAIM_ATTRIBUTE_typename_to_number (type_str); - if (GNUNET_SYSERR ==(GNUNET_RECLAIM_ATTRIBUTE_string_to_value (type, - reference-> - reference_value, - (void **) & - data, - &data_size))) - { - return; - } - le->claim = GNUNET_RECLAIM_ATTRIBUTE_claim_new (reference->name, - type, - data, - data_size); - le->claim->id = reference->id; - le->claim->flag = 1; - + le->claim = NULL; + le->reference = NULL; + le->attest = GNUNET_RECLAIM_ATTESTATION_claim_new (attest->name, + attest->type, + attest->data, + attest->data_size); + le->attest->id = attest->id; + le2->attest = NULL; + le2->claim = NULL; + le2->reference = GNUNET_RECLAIM_ATTESTATION_reference_new (reference->name, + reference-> + reference_value); + le2->reference->id = reference->id; + le2->reference->id_attest = reference->id_attest; GNUNET_CONTAINER_DLL_insert (handle->attr_list->list_head, handle->attr_list->list_tail, le); + GNUNET_CONTAINER_DLL_insert (handle->attr_list->list_head, + handle->attr_list->list_tail, + le2); } - else + else if (NULL != attr) { if ((NULL == attr->name) || (NULL == attr->data)) { @@ -1063,8 +1077,9 @@ oidc_attr_collect (void *cls, return; } GNUNET_free (scope_variables); - le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry); + le->reference = NULL; + le->attest = NULL; le->claim = GNUNET_RECLAIM_ATTRIBUTE_claim_new (attr->name, attr->type, attr->data, @@ -1362,6 +1377,9 @@ build_authz_response (void *cls) // OPTIONAL value: nonce handle->oidc->nonce = get_url_parameter_copy (handle, OIDC_NONCE_KEY); + // OPTIONAL value: claims + handle->oidc->claims = get_url_parameter_copy (handle, OIDC_CLAIMS_KEY); + // TODO check other values if needed number_of_ignored_parameter = sizeof(OIDC_ignored_parameter_array) / sizeof(char *); @@ -1918,8 +1936,8 @@ token_endpoint (struct GNUNET_REST_RequestHandle *con_handle, /** - * Collects claims and stores them in handle - */ + * Collects claims and stores them in handle + */ static void consume_ticket (void *cls, const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, @@ -1928,20 +1946,87 @@ consume_ticket (void *cls, const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *reference) { struct RequestHandle *handle = cls; - char *tmp_value; - json_t *value; - if (NULL == identity) { GNUNET_SCHEDULER_add_now (&return_userinfo_response, handle); return; } - tmp_value = GNUNET_RECLAIM_ATTRIBUTE_value_to_string (attr->type, - attr->data, - attr->data_size); - value = json_string (tmp_value); - json_object_set_new (handle->oidc->response, attr->name, value); - GNUNET_free (tmp_value); + if (NULL != attr) + { + char *tmp_value; + json_t *value; + tmp_value = GNUNET_RECLAIM_ATTRIBUTE_value_to_string (attr->type, + attr->data, + attr->data_size); + value = json_string (tmp_value); + json_object_set_new (handle->oidc->response, attr->name, value); + GNUNET_free (tmp_value); + } + else if ((NULL != attest) && (NULL != reference)) + { + json_t *claim_sources; + json_t *claim_sources_jwt; + json_t *claim_names; + char *attest_val_str; + claim_sources=json_object_get(handle->oidc->response,"_claim_sources"); + claim_names=json_object_get(handle->oidc->response,"_claim_names"); + attest_val_str = GNUNET_RECLAIM_ATTESTATION_value_to_string (attest->type, + attest->data, + attest-> + data_size); + if ((NULL == claim_sources) && (NULL == claim_names) ) + { + claim_sources = json_object (); + claim_names = json_object (); + } + char *source_name; + int i = 0; + GNUNET_asprintf (&source_name,"src%d",i); + while (NULL != (claim_sources_jwt = json_object_get (claim_sources, + source_name))) + { + if (0 == strcmp (json_string_value (json_object_get (claim_sources_jwt, + "JWT")), + attest_val_str)) + { + // Adapt only the claim names + json_object_set_new (claim_names, reference->name, json_string ( + source_name)); + json_object_set (handle->oidc->response, "_claim_names",claim_names); + handle->oidc->response = json_deep_copy(handle->oidc->response); + break; + } + i++; + GNUNET_asprintf (&source_name,"src%d",i); + } + + // Create new one + if (NULL == claim_sources_jwt) + { + claim_sources_jwt = json_object (); + // Set the JWT for names + json_object_set_new (claim_names, reference->name, json_string ( + source_name)); + // Set the JWT for the inner source + json_object_set_new (claim_sources_jwt, "JWT", json_string ( + attest_val_str)); + // Set the JWT for the source + json_object_set_new (claim_sources, source_name,claim_sources_jwt); + // Set as claims + json_object_set (handle->oidc->response, "_claim_names", claim_names); + json_object_set (handle->oidc->response, "_claim_sources",claim_sources); + handle->oidc->response = json_deep_copy(handle->oidc->response); + } + + json_decref (claim_sources); + json_decref (claim_names); + json_decref (claim_sources_jwt); + GNUNET_free (attest_val_str); + } + else + { + // REMARK: We should not find any claim, one of attest/ref is NULL + } } diff --git a/src/reclaim/plugin_rest_reclaim.c b/src/reclaim/plugin_rest_reclaim.c index 16286444a..70defae3d 100644 --- a/src/reclaim/plugin_rest_reclaim.c +++ b/src/reclaim/plugin_rest_reclaim.c @@ -276,6 +276,8 @@ cleanup_handle (struct RequestHandle *handle) claim_tmp = claim_entry; claim_entry = claim_entry->next; GNUNET_free (claim_tmp->claim); + GNUNET_free (claim_tmp->attest); + GNUNET_free (claim_tmp->reference); GNUNET_free (claim_tmp); } GNUNET_free (handle->attr_list); @@ -1286,6 +1288,7 @@ attr_collect (void *cls, return; } char *tmp_value; + char *flag_str; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding attribute: %s\n", attr->name); tmp_value = GNUNET_RECLAIM_ATTRIBUTE_value_to_string (attr->type, @@ -1295,6 +1298,8 @@ attr_collect (void *cls, attr_obj = json_object (); json_object_set_new (attr_obj, "value", json_string (tmp_value)); json_object_set_new (attr_obj, "name", json_string (attr->name)); + GNUNET_asprintf (&flag_str,"%d",attr->flag); + json_object_set_new (attr_obj, "flag", json_string (flag_str)); type = GNUNET_RECLAIM_ATTRIBUTE_number_to_typename (attr->type); json_object_set_new (attr_obj, "type", json_string (type)); id_str = GNUNET_STRINGS_data_to_string_alloc (&attr->id, sizeof(uint64_t)); diff --git a/src/reclaim/reclaim_api.c b/src/reclaim/reclaim_api.c index 75ef22c8c..847abb58a 100644 --- a/src/reclaim/reclaim_api.c +++ b/src/reclaim/reclaim_api.c @@ -486,7 +486,7 @@ handle_consume_ticket_result (void *cls, uint32_t r_id = ntohl (msg->id); attrs_len = ntohs (msg->attrs_len); - LOG (GNUNET_ERROR_TYPE_DEBUG, "Processing attribute result.\n"); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Processing ticket result.\n"); for (op = h->op_head; NULL != op; op = op->next) @@ -498,6 +498,7 @@ handle_consume_ticket_result (void *cls, { struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs; struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le; + struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le2; attrs = GNUNET_RECLAIM_ATTRIBUTE_list_deserialize ((char *) &msg[1], attrs_len); if (NULL != op->ar_cb) @@ -509,7 +510,20 @@ handle_consume_ticket_result (void *cls, else { for (le = attrs->list_head; NULL != le; le = le->next) - op->ar_cb (op->cls, &msg->identity, le->claim, NULL, NULL); + { + if (le->reference != NULL && le->attest == NULL) + { + for (le2 = attrs->list_head; NULL != le2; le2 = le2->next) + { + if (le2->attest != NULL && le2->attest->id == le->reference->id_attest) + { + op->ar_cb (op->cls, &msg->identity, le->claim, le2->attest, le->reference); + break; + } + + } + } + } GNUNET_RECLAIM_ATTRIBUTE_list_destroy (attrs); attrs = NULL; } -- 2.25.1