From a57d476abbe857365aff157f389cc1188b5dd090 Mon Sep 17 00:00:00 2001 From: Martin Schanzenbach Date: Wed, 19 Aug 2020 23:53:02 +0200 Subject: reclaim: Attestations now called credentials. Credentials are presented to third parties as presentations. --- src/include/gnunet_gnsrecord_lib.h | 7 +- src/include/gnunet_reclaim_lib.h | 13 +- src/include/gnunet_reclaim_plugin.h | 10 + src/include/gnunet_reclaim_service.h | 18 +- src/reclaim/gnunet-reclaim.c | 5 +- src/reclaim/gnunet-service-reclaim.c | 33 +- src/reclaim/gnunet-service-reclaim_tickets.c | 197 ++++++++--- src/reclaim/gnunet-service-reclaim_tickets.h | 7 +- src/reclaim/json_reclaim.c | 12 +- src/reclaim/json_reclaim.h | 2 +- src/reclaim/oidc_helper.c | 22 +- src/reclaim/oidc_helper.h | 16 +- src/reclaim/plugin_gnsrecord_reclaim.c | 12 +- src/reclaim/plugin_reclaim_credential_jwt.c | 159 +++++++-- src/reclaim/plugin_rest_openid_connect.c | 68 ++-- src/reclaim/plugin_rest_reclaim.c | 6 +- src/reclaim/reclaim.h | 7 + src/reclaim/reclaim_api.c | 58 +++- src/reclaim/reclaim_credential.c | 501 ++++++++++++++++++++++++++- src/reclaim/reclaim_credential.h | 35 ++ 20 files changed, 1010 insertions(+), 178 deletions(-) (limited to 'src') diff --git a/src/include/gnunet_gnsrecord_lib.h b/src/include/gnunet_gnsrecord_lib.h index c976c89c5..960203fb1 100644 --- a/src/include/gnunet_gnsrecord_lib.h +++ b/src/include/gnunet_gnsrecord_lib.h @@ -143,12 +143,13 @@ extern "C" { /** * Record type for an attribute attestation */ -#define GNUNET_GNSRECORD_TYPE_RECLAIM_ATTESTATION 65554 +#define GNUNET_GNSRECORD_TYPE_RECLAIM_CREDENTIAL 65554 /** - * Record type for an attestation reference in a ticket + * Record type for a presentation of a credential (used + * in a ticket record set) */ -#define GNUNET_GNSRECORD_TYPE_RECLAIM_ATTESTATION_REF 65555 +#define GNUNET_GNSRECORD_TYPE_RECLAIM_PRESENTATION 65555 /** diff --git a/src/include/gnunet_reclaim_lib.h b/src/include/gnunet_reclaim_lib.h index f5c3d3864..bbf1c3ad3 100644 --- a/src/include/gnunet_reclaim_lib.h +++ b/src/include/gnunet_reclaim_lib.h @@ -780,6 +780,11 @@ GNUNET_RECLAIM_presentation_value_to_string (uint32_t type, const void *data, size_t data_size); +struct GNUNET_RECLAIM_Presentation * +GNUNET_RECLAIM_presentation_new (uint32_t type, + const void *data, + size_t data_size); + /** * Convert human-readable version of a 'claim' of a presentation to the binary * representation @@ -828,14 +833,16 @@ GNUNET_RECLAIM_presentation_get_expiration (const struct * * @param cred the credential to use * @param attrs the attributes to present from the credential - * @return the credential presentation presenting the attributes according + * @param presentation the credential presentation presenting the attributes according * to the presentation mechanism of the credential * or NULL on error. + * @return GNUNET_OK on success. */ -struct GNUNET_RECLAIM_Presentation* +int GNUNET_RECLAIM_credential_get_presentation ( const struct GNUNET_RECLAIM_Credential *cred, - const struct GNUNET_RECLAIM_AttributeList *attrs); + const struct GNUNET_RECLAIM_AttributeList *attrs, + struct GNUNET_RECLAIM_Presentation **presentation); #if 0 /* keep Emacsens' auto-indent happy */ diff --git a/src/include/gnunet_reclaim_plugin.h b/src/include/gnunet_reclaim_plugin.h index af6c74e0b..2ba8fc8a0 100644 --- a/src/include/gnunet_reclaim_plugin.h +++ b/src/include/gnunet_reclaim_plugin.h @@ -301,6 +301,11 @@ typedef int (*GNUNET_RECLAIM_PresentationGetExpirationFunction) ( const struct GNUNET_RECLAIM_Presentation *cred, struct GNUNET_TIME_Absolute *expiration); +typedef int (*GNUNET_RECLAIM_CredentialToPresentation) ( + void *cls, + const struct GNUNET_RECLAIM_Credential *cred, + const struct GNUNET_RECLAIM_AttributeList *attrs, + struct GNUNET_RECLAIM_Presentation **presentation); /** * Each plugin is required to return a pointer to a struct of this @@ -416,6 +421,11 @@ struct GNUNET_RECLAIM_CredentialPluginFunctions */ GNUNET_RECLAIM_PresentationGetExpirationFunction get_expiration_p; + /** + * Get presentation + */ + GNUNET_RECLAIM_CredentialToPresentation create_presentation; + }; diff --git a/src/include/gnunet_reclaim_service.h b/src/include/gnunet_reclaim_service.h index 8387c79b0..368058f56 100644 --- a/src/include/gnunet_reclaim_service.h +++ b/src/include/gnunet_reclaim_service.h @@ -92,7 +92,21 @@ struct GNUNET_RECLAIM_Ticket * @param ticket the ticket */ typedef void (*GNUNET_RECLAIM_TicketCallback) ( - void *cls, const struct GNUNET_RECLAIM_Ticket *ticket); + void *cls, + const struct GNUNET_RECLAIM_Ticket *ticket); + +/** + * Method called when a token has been issued. + * On success returns a ticket that can be given to a relying party + * in order for it retrive identity attributes + * + * @param cls closure + * @param ticket the ticket + */ +typedef void (*GNUNET_RECLAIM_IssueTicketCallback) ( + void *cls, + const struct GNUNET_RECLAIM_Ticket *ticket, + const struct GNUNET_RECLAIM_PresentationList *presentations); /** @@ -369,7 +383,7 @@ GNUNET_RECLAIM_ticket_issue ( const struct GNUNET_CRYPTO_EcdsaPrivateKey *iss, const struct GNUNET_CRYPTO_EcdsaPublicKey *rp, const struct GNUNET_RECLAIM_AttributeList *attrs, - GNUNET_RECLAIM_TicketCallback cb, void *cb_cls); + GNUNET_RECLAIM_IssueTicketCallback cb, void *cb_cls); /** diff --git a/src/reclaim/gnunet-reclaim.c b/src/reclaim/gnunet-reclaim.c index a59053f5f..ab281a645 100644 --- a/src/reclaim/gnunet-reclaim.c +++ b/src/reclaim/gnunet-reclaim.c @@ -227,7 +227,9 @@ do_cleanup (void *cls) static void -ticket_issue_cb (void *cls, const struct GNUNET_RECLAIM_Ticket *ticket) +ticket_issue_cb (void *cls, + const struct GNUNET_RECLAIM_Ticket *ticket, + const struct GNUNET_RECLAIM_PresentationList *presentations) { char *ticket_str; @@ -456,6 +458,7 @@ iter_finished (void *cls) if (NULL == attr_to_delete) { fprintf (stdout, "No such attribute ``%s''\n", attr_delete); + GNUNET_SCHEDULER_add_now (&do_cleanup, NULL); return; } reclaim_op = GNUNET_RECLAIM_attribute_delete (reclaim_handle, diff --git a/src/reclaim/gnunet-service-reclaim.c b/src/reclaim/gnunet-service-reclaim.c index 30a84b3e8..d2cdc62a2 100644 --- a/src/reclaim/gnunet-service-reclaim.c +++ b/src/reclaim/gnunet-service-reclaim.c @@ -646,19 +646,33 @@ static void send_ticket_result (const struct IdpClient *client, uint32_t r_id, const struct GNUNET_RECLAIM_Ticket *ticket, + const struct GNUNET_RECLAIM_PresentationList *presentations, uint32_t success) { struct TicketResultMessage *irm; struct GNUNET_MQ_Envelope *env; + size_t pres_len = 0; - env = GNUNET_MQ_msg (irm, - GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT); + if (NULL != presentations) + { + pres_len = + GNUNET_RECLAIM_presentation_list_serialize_get_size (presentations); + } + env = GNUNET_MQ_msg_extra (irm, + pres_len, + GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT); if (NULL != ticket) { irm->ticket = *ticket; } // TODO add success member irm->id = htonl (r_id); + irm->presentations_len = htons (pres_len); + if (NULL != presentations) + { + GNUNET_RECLAIM_presentation_list_serialize (presentations, + (char*) &irm[1]); + } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending TICKET_RESULT message\n"); GNUNET_MQ_send (client->mq, env); } @@ -669,12 +683,14 @@ send_ticket_result (const struct IdpClient *client, * * @param cls out ticket issue operation handle * @param ticket the issued ticket + * @param presentations newly created credential presentations (NULL on error) * @param success issue success status (GNUNET_OK if successful) * @param emsg error message (NULL of success is GNUNET_OK) */ static void issue_ticket_result_cb (void *cls, struct GNUNET_RECLAIM_Ticket *ticket, + struct GNUNET_RECLAIM_PresentationList *presentations, int32_t success, const char *emsg) { @@ -682,7 +698,7 @@ issue_ticket_result_cb (void *cls, if (GNUNET_OK != success) { - send_ticket_result (tio->client, tio->r_id, NULL, GNUNET_SYSERR); + send_ticket_result (tio->client, tio->r_id, NULL, NULL, GNUNET_SYSERR); GNUNET_CONTAINER_DLL_remove (tio->client->issue_op_head, tio->client->issue_op_tail, tio); @@ -690,7 +706,8 @@ issue_ticket_result_cb (void *cls, GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error issuing ticket: %s\n", emsg); return; } - send_ticket_result (tio->client, tio->r_id, ticket, GNUNET_SYSERR); + send_ticket_result (tio->client, tio->r_id, + ticket, presentations, GNUNET_SYSERR); GNUNET_CONTAINER_DLL_remove (tio->client->issue_op_head, tio->client->issue_op_tail, tio); @@ -871,7 +888,7 @@ consume_result_cb (void *cls, GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET_RESULT); crm->id = htonl (cop->r_id); crm->attrs_len = htons (attrs_len); - crm->pres_len = htons (pres_len); + crm->presentations_len = htons (pres_len); crm->identity = *identity; crm->result = htonl (success); data_tmp = (char *) &crm[1]; @@ -1152,7 +1169,7 @@ cred_add_cb (void *cls, buf_size = GNUNET_RECLAIM_credential_serialize_get_size (ash->credential); buf = GNUNET_malloc (buf_size); - GNUNET_RECLAIM_presentation_serialize (ash->credential, buf); + GNUNET_RECLAIM_credential_serialize (ash->credential, buf); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Storing new credential under `%s'.\n", label); @@ -1611,8 +1628,8 @@ cred_delete_cont (void *cls, int32_t success, const char *emsg) * @dam message to check */ static int -check_cred_delete_message (void *cls, - const struct AttributeDeleteMessage *dam) +check_credential_delete_message (void *cls, + const struct AttributeDeleteMessage *dam) { uint16_t size; diff --git a/src/reclaim/gnunet-service-reclaim_tickets.c b/src/reclaim/gnunet-service-reclaim_tickets.c index 18b173aaa..4dd8100f9 100644 --- a/src/reclaim/gnunet-service-reclaim_tickets.c +++ b/src/reclaim/gnunet-service-reclaim_tickets.c @@ -114,9 +114,9 @@ struct RECLAIM_TICKETS_ConsumeHandle struct GNUNET_RECLAIM_AttributeList *attrs; /** - * Credentials + * Presentations */ - struct GNUNET_RECLAIM_CredentialList *credentials; + struct GNUNET_RECLAIM_PresentationList *presentations; /** * Lookup time @@ -172,6 +172,11 @@ struct TicketIssueHandle */ struct GNUNET_RECLAIM_AttributeList *attrs; + /** + * Presentations to add + */ + struct GNUNET_RECLAIM_PresentationList *presentations; + /** * Issuer Key */ @@ -981,8 +986,8 @@ cleanup_cth (struct RECLAIM_TICKETS_ConsumeHandle *cth) if (NULL != cth->attrs) GNUNET_RECLAIM_attribute_list_destroy (cth->attrs); - if (NULL != cth->credentials) - GNUNET_RECLAIM_credential_list_destroy (cth->credentials); + if (NULL != cth->presentations) + GNUNET_RECLAIM_presentation_list_destroy (cth->presentations); GNUNET_free (cth); } @@ -1040,7 +1045,7 @@ process_parallel_lookup_result (void *cls, return; // Wait for more /* Else we are done */ cth->cb (cth->cb_cls, &cth->ticket.identity, - cth->attrs, cth->credentials, GNUNET_OK, NULL); + cth->attrs, cth->presentations, GNUNET_OK, NULL); cleanup_cth (cth); } @@ -1090,6 +1095,7 @@ lookup_authz_cb (void *cls, struct RECLAIM_TICKETS_ConsumeHandle *cth = cls; struct ParallelLookup *parallel_lookup; char *lbl; + struct GNUNET_RECLAIM_PresentationListEntry *ale; cth->lookup_request = NULL; @@ -1113,13 +1119,12 @@ lookup_authz_cb (void *cls, switch (rd[i].record_type) { case GNUNET_GNSRECORD_TYPE_RECLAIM_PRESENTATION: - struct GNUNET_RECLAIM_CredentialListEntry *ale; - ale = GNUNET_new (struct GNUNET_RECLAIM_CredentialListEntry); - ale->credential = - GNUNET_RECLAIM_credential_deserialize (rd[i].data, - rd[i].data_size); - GNUNET_CONTAINER_DLL_insert (cth->credentials->list_head, - cth->credentials->list_tail, + ale = GNUNET_new (struct GNUNET_RECLAIM_PresentationListEntry); + ale->presentation = + GNUNET_RECLAIM_presentation_deserialize (rd[i].data, + rd[i].data_size); + GNUNET_CONTAINER_DLL_insert (cth->presentations->list_head, + cth->presentations->list_tail, ale); break; case GNUNET_GNSRECORD_TYPE_RECLAIM_ATTRIBUTE_REF: @@ -1162,7 +1167,7 @@ lookup_authz_cb (void *cls, * No references found, return empty attribute list */ cth->cb (cth->cb_cls, &cth->ticket.identity, - cth->attrs, cth->credentials, GNUNET_OK, NULL); + cth->attrs, NULL, GNUNET_OK, NULL); cleanup_cth (cth); } @@ -1192,7 +1197,7 @@ RECLAIM_TICKETS_consume (const struct GNUNET_CRYPTO_EcdsaPrivateKey *id, cth->identity = *id; GNUNET_CRYPTO_ecdsa_key_get_public (&cth->identity, &cth->identity_pub); cth->attrs = GNUNET_new (struct GNUNET_RECLAIM_AttributeList); - cth->credentials = GNUNET_new (struct GNUNET_RECLAIM_CredentialList); + cth->presentations = GNUNET_new (struct GNUNET_RECLAIM_PresentationList); cth->ticket = *ticket; cth->cb = cb; cth->cb_cls = cb_cls; @@ -1230,8 +1235,8 @@ RECLAIM_TICKETS_consume_cancel (struct RECLAIM_TICKETS_ConsumeHandle *cth) /******************************* -* Ticket issue -*******************************/ + * Ticket issue + *******************************/ /** * Cleanup ticket consume handle @@ -1264,11 +1269,15 @@ store_ticket_issue_cont (void *cls, int32_t success, const char *emsg) { handle->cb (handle->cb_cls, &handle->ticket, + NULL, GNUNET_SYSERR, "Error storing AuthZ ticket in GNS"); return; } - handle->cb (handle->cb_cls, &handle->ticket, GNUNET_OK, NULL); + handle->cb (handle->cb_cls, + &handle->ticket, + handle->presentations, + GNUNET_OK, NULL); cleanup_issue_handle (handle); } @@ -1284,15 +1293,17 @@ static void issue_ticket (struct TicketIssueHandle *ih) { struct GNUNET_RECLAIM_AttributeListEntry *le; + struct GNUNET_RECLAIM_PresentationListEntry *ple; struct GNUNET_GNSRECORD_Data *attrs_record; char *label; int i; + int j; int attrs_count = 0; for (le = ih->attrs->list_head; NULL != le; le = le->next) attrs_count++; - // Worst case we have one credential per attribute + // Worst case we have one presentation per attribute attrs_record = GNUNET_malloc (2 * attrs_count * sizeof(struct GNUNET_GNSRECORD_Data)); i = 0; @@ -1309,31 +1320,65 @@ issue_ticket (struct TicketIssueHandle *ih) i++; if (GNUNET_NO == GNUNET_RECLAIM_id_is_zero (&le->attribute->credential)) { - struct GNUNET_RECLAIM_Presentation *pres; - int j; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Attribute is backed by credential. Adding...\n"); + struct GNUNET_RECLAIM_Presentation *pres = NULL; for (j = 0; j < i; j++) { if (attrs_record[j].record_type != GNUNET_GNSRECORD_TYPE_RECLAIM_PRESENTATION) continue; - pres = attrs_record[j].data; - if (0 == memcmp (pres->credential_id, + pres = GNUNET_RECLAIM_presentation_deserialize (attrs_record[j].data, + attrs_record[j]. + data_size); + if (NULL == pres) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Failed to deserialize presentation\n"); + continue; + } + if (0 == memcmp (&pres->credential_id, &le->attribute->credential, sizeof (le->attribute->credential))) break; + GNUNET_free (pres); + pres = NULL; } - if (j < i) + if (NULL != pres) + { + GNUNET_free (pres); continue; // Skip as we have already added this credential presentation. - /** - * FIXME: Create a new presentation from the credential. - */ - attrs_record[i].data = &le->attribute->credential; - attrs_record[i].data_size = sizeof(le->attribute->credential); - attrs_record[i].expiration_time = ticket_refresh_interval.rel_value_us; - attrs_record[i].record_type = - GNUNET_GNSRECORD_TYPE_RECLAIM_PRESENTATION; - attrs_record[i].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION; - i++; + } + for (ple = ih->presentations->list_head; NULL != ple; ple = ple->next) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Checking presentation....\n"); + + if (0 != memcmp (&le->attribute->credential, + &ple->presentation->credential_id, + sizeof (le->attribute->credential))) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Presentation does not match credential ID.\n"); + continue; + } + char *pres_buf; + size_t pres_size; + pres_size = + GNUNET_RECLAIM_presentation_serialize_get_size (ple->presentation); + pres_buf = GNUNET_malloc (pres_size); + GNUNET_RECLAIM_presentation_serialize (ple->presentation, + pres_buf); + attrs_record[i].data = pres_buf; + attrs_record[i].data_size = pres_size; + attrs_record[i].expiration_time = + ticket_refresh_interval.rel_value_us; + attrs_record[i].record_type = + GNUNET_GNSRECORD_TYPE_RECLAIM_PRESENTATION; + attrs_record[i].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION; + i++; + break; + } } } attrs_record[i].data = &ih->ticket; @@ -1355,14 +1400,23 @@ issue_ticket (struct TicketIssueHandle *ih) attrs_record, &store_ticket_issue_cont, ih); + for (j = 0; j > i; j++) + { + if (attrs_record[j].record_type + != GNUNET_GNSRECORD_TYPE_RECLAIM_PRESENTATION) + continue; + // Yes, we are allowed to do this because we allocated it above + char *ptr = (char*) attrs_record[j].data; + GNUNET_free (ptr); + } GNUNET_free (attrs_record); GNUNET_free (label); } /************************************************* -* Ticket iteration (finding a specific ticket) -*************************************************/ + * Ticket iteration (finding a specific ticket) + *************************************************/ /** @@ -1378,6 +1432,7 @@ filter_tickets_error_cb (void *cls) tih->ns_it = NULL; tih->cb (tih->cb_cls, &tih->ticket, + NULL, GNUNET_SYSERR, "Error storing AuthZ ticket in GNS"); cleanup_issue_handle (tih); @@ -1406,11 +1461,12 @@ filter_tickets_cb (void *cls, struct TicketIssueHandle *tih = cls; struct GNUNET_RECLAIM_Ticket *ticket = NULL; struct GNUNET_RECLAIM_Presentation *pres; - - // figure out the number of requested attributes + struct GNUNET_RECLAIM_PresentationList *ticket_presentations; + struct GNUNET_RECLAIM_Credential *cred; + struct GNUNET_RECLAIM_PresentationListEntry *ple; struct GNUNET_RECLAIM_AttributeListEntry *le; unsigned int attr_cnt = 0; - unsigned int cred_cnt = 0; + unsigned int pres_cnt = 0; for (le = tih->attrs->list_head; NULL != le; le = le->next) { @@ -1422,6 +1478,7 @@ filter_tickets_cb (void *cls, // ticket search unsigned int found_attrs_cnt = 0; unsigned int found_pres_cnt = 0; + ticket_presentations = GNUNET_new (struct GNUNET_RECLAIM_PresentationList); for (int i = 0; i < rd_count; i++) { @@ -1450,15 +1507,65 @@ filter_tickets_cb (void *cls, found_attrs_cnt++; } } + if (GNUNET_GNSRECORD_TYPE_RECLAIM_CREDENTIAL == rd[i].record_type) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Found credential...\n"); + + for (le = tih->attrs->list_head; NULL != le; le = le->next) + { + cred = GNUNET_RECLAIM_credential_deserialize (rd[i].data, + rd[i].data_size); + if (GNUNET_YES != GNUNET_RECLAIM_id_is_equal (&cred->id, + &le->attribute->credential)) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "No match.\n"); + GNUNET_free (cred); + continue; + } + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Match, creating presentation...\n"); + if (GNUNET_OK != GNUNET_RECLAIM_credential_get_presentation ( + cred, + tih->attrs, + &pres)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Unable to retrieve presentation from credential\n"); + GNUNET_free (cred); + continue; + } + ple = GNUNET_new (struct GNUNET_RECLAIM_PresentationListEntry); + ple->presentation = pres; + GNUNET_CONTAINER_DLL_insert (tih->presentations->list_head, + tih->presentations->list_tail, + ple); + GNUNET_free (cred); + } + } if (GNUNET_GNSRECORD_TYPE_RECLAIM_PRESENTATION == rd[i].record_type) { for (le = tih->attrs->list_head; NULL != le; le = le->next) { - pres = rd[i].data; - if (GNUNET_YES == GNUNET_RECLAIM_id_is_equal (pres->credential_id, + pres = GNUNET_RECLAIM_presentation_deserialize (rd[i].data, + rd[i].data_size); + if (NULL == pres) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Failed to deserialize presentation\n"); + continue; + } + if (GNUNET_YES == GNUNET_RECLAIM_id_is_equal (&pres->credential_id, &le->attribute->credential)) + { found_pres_cnt++; - // FIXME should we store credentials here for later use?? + ple = GNUNET_new (struct GNUNET_RECLAIM_PresentationListEntry); + ple->presentation = pres; + GNUNET_CONTAINER_DLL_insert (ticket_presentations->list_head, + ticket_presentations->list_tail, + ple); + } } } } @@ -1472,7 +1579,8 @@ filter_tickets_cb (void *cls, (NULL != ticket)) { GNUNET_NAMESTORE_zone_iteration_stop (tih->ns_it); - tih->cb (tih->cb_cls, &tih->ticket, GNUNET_OK, NULL); + tih->cb (tih->cb_cls, &tih->ticket, ticket_presentations, GNUNET_OK, NULL); + GNUNET_RECLAIM_presentation_list_destroy (ticket_presentations); cleanup_issue_handle (tih); return; } @@ -1524,6 +1632,7 @@ RECLAIM_TICKETS_issue (const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity, tih->cb = cb; tih->cb_cls = cb_cls; tih->attrs = GNUNET_RECLAIM_attribute_list_dup (attrs); + tih->presentations = GNUNET_new (struct GNUNET_RECLAIM_PresentationList); tih->identity = *identity; tih->ticket.audience = *audience; @@ -1541,8 +1650,8 @@ RECLAIM_TICKETS_issue (const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity, /************************************ -* Ticket iteration -************************************/ + * Ticket iteration + ************************************/ /** * Cleanup ticket iterator diff --git a/src/reclaim/gnunet-service-reclaim_tickets.h b/src/reclaim/gnunet-service-reclaim_tickets.h index 404b9c837..0dd790fc7 100644 --- a/src/reclaim/gnunet-service-reclaim_tickets.h +++ b/src/reclaim/gnunet-service-reclaim_tickets.h @@ -113,6 +113,7 @@ typedef void (*RECLAIM_TICKETS_TicketIter) ( * * @param cls closure * @param ticket the ticket + * @param presentations new presentations for ticket (NULL on error) * @param success #GNUNET_SYSERR on failure (including timeout/queue * drop/failure to validate) #GNUNET_OK on success * @param emsg NULL on success, otherwise an error message @@ -120,6 +121,7 @@ typedef void (*RECLAIM_TICKETS_TicketIter) ( typedef void (*RECLAIM_TICKETS_TicketResult) ( void *cls, struct GNUNET_RECLAIM_Ticket *ticket, + struct GNUNET_RECLAIM_PresentationList *presentations, int32_t success, const char *emsg); @@ -129,7 +131,8 @@ typedef void (*RECLAIM_TICKETS_TicketResult) ( * * @param cls closure * @param identity the issuer of the ticket/attributes - * @param l attribute list retrieved through ticket + * @param attributes attribute list retrieved through ticket + * @param presentations attribute presentations (may be NULL) * @param success GNUNET_OK on success * @param emsg error message (NULL on success) */ @@ -137,7 +140,7 @@ typedef void (*RECLAIM_TICKETS_ConsumeCallback) ( void *cls, const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, const struct GNUNET_RECLAIM_AttributeList *attributes, - const struct GNUNET_RECLAIM_CredentialList *credentials, + const struct GNUNET_RECLAIM_PresentationList *presentations, int32_t success, const char *emsg); diff --git a/src/reclaim/json_reclaim.c b/src/reclaim/json_reclaim.c index c8b944326..8a3479b8a 100644 --- a/src/reclaim/json_reclaim.c +++ b/src/reclaim/json_reclaim.c @@ -335,16 +335,16 @@ parse_credential (void *cls, json_t *root, struct GNUNET_JSON_Specification *spe GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Credential value invalid!\n"); return GNUNET_SYSERR; } - attr = GNUNET_RECLAIM_credential_new (name_str, type, data, data_size); + cred = GNUNET_RECLAIM_credential_new (name_str, type, data, data_size); if ((NULL == id_str) || (0 == strlen (id_str))) - memset (&attr->id, 0, sizeof (attr->id)); + memset (&cred->id, 0, sizeof (cred->id)); else GNUNET_STRINGS_string_to_data (id_str, strlen (id_str), - &attr->id, - sizeof(attr->id)); + &cred->id, + sizeof(cred->id)); - *(struct GNUNET_RECLAIM_Credential **) spec->ptr = attr; + *(struct GNUNET_RECLAIM_Credential **) spec->ptr = cred; return GNUNET_OK; } @@ -383,7 +383,7 @@ GNUNET_RECLAIM_JSON_spec_credential (struct .cleaner = &clean_credential, .cls = NULL, .field = NULL, - .ptr = attr, + .ptr = cred, .ptr_size = 0, .size_ptr = NULL }; diff --git a/src/reclaim/json_reclaim.h b/src/reclaim/json_reclaim.h index 8911cf92d..613ddf873 100644 --- a/src/reclaim/json_reclaim.h +++ b/src/reclaim/json_reclaim.h @@ -54,4 +54,4 @@ GNUNET_RECLAIM_JSON_spec_ticket (struct GNUNET_RECLAIM_Ticket **ticket); * @return JSON Specification */ struct GNUNET_JSON_Specification -GNUNET_RECLAIM_JSON_spec_credential (struct GNUNET_RECLAIM_Attestation **cred); +GNUNET_RECLAIM_JSON_spec_credential (struct GNUNET_RECLAIM_Credential **cred); diff --git a/src/reclaim/oidc_helper.c b/src/reclaim/oidc_helper.c index 9c7e79c41..b307a358c 100644 --- a/src/reclaim/oidc_helper.c +++ b/src/reclaim/oidc_helper.c @@ -156,8 +156,8 @@ fix_base64 (char *str) static json_t* generate_userinfo_json(const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key, - struct GNUNET_RECLAIM_AttributeList *attrs, - struct GNUNET_RECLAIM_PresentationList *presentations) + const struct GNUNET_RECLAIM_AttributeList *attrs, + const struct GNUNET_RECLAIM_PresentationList *presentations) { struct GNUNET_RECLAIM_AttributeListEntry *le; struct GNUNET_RECLAIM_PresentationListEntry *ple; @@ -296,8 +296,8 @@ generate_userinfo_json(const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key, */ char * OIDC_generate_userinfo (const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key, - struct GNUNET_RECLAIM_AttributeList *attrs, - struct GNUNET_RECLAIM_PresentationList *presentations) + const struct GNUNET_RECLAIM_AttributeList *attrs, + const struct GNUNET_RECLAIM_PresentationList *presentations) { char *body_str; json_t* body = generate_userinfo_json (sub_key, @@ -323,8 +323,8 @@ OIDC_generate_userinfo (const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key, char * OIDC_generate_id_token (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key, - struct GNUNET_RECLAIM_AttributeList *attrs, - struct GNUNET_RECLAIM_PresentationList *presentations, + const struct GNUNET_RECLAIM_AttributeList *attrs, + const struct GNUNET_RECLAIM_PresentationList *presentations, const struct GNUNET_TIME_Relative *expiration_time, const char *nonce, const char *secret_key) @@ -440,8 +440,8 @@ OIDC_generate_id_token (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, char * OIDC_build_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer, const struct GNUNET_RECLAIM_Ticket *ticket, - struct GNUNET_RECLAIM_AttributeList *attrs, - struct GNUNET_RECLAIM_PresentationList *presentations, + const struct GNUNET_RECLAIM_AttributeList *attrs, + const struct GNUNET_RECLAIM_PresentationList *presentations, const char *nonce_str, const char *code_challenge) { @@ -596,7 +596,7 @@ OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPublicKey *audience, struct GNUNET_CRYPTO_EcdsaSignature *signature; uint32_t code_challenge_len; uint32_t attrs_ser_len; - uint32_t presentations_ser_len; + uint32_t pres_ser_len; size_t plaintext_len; size_t code_payload_len; uint32_t nonce_len = 0; @@ -702,8 +702,8 @@ OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPublicKey *audience, presentations_ser = ((char*) attrs_ser) + attrs_ser_len; pres_ser_len = ntohl (params->pres_list_len); *presentations = - GNUNET_RECLAIM_presentations_list_deserialize (presentations_ser, - pres_ser_len); + GNUNET_RECLAIM_presentation_list_deserialize (presentations_ser, + pres_ser_len); GNUNET_free (code_payload); return GNUNET_OK; diff --git a/src/reclaim/oidc_helper.h b/src/reclaim/oidc_helper.h index 789a2acc7..10a6f3d1f 100644 --- a/src/reclaim/oidc_helper.h +++ b/src/reclaim/oidc_helper.h @@ -52,8 +52,8 @@ char* OIDC_generate_id_token (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key, - struct GNUNET_RECLAIM_AttributeList *attrs, - struct GNUNET_RECLAIM_PresentationList *presentations, + const struct GNUNET_RECLAIM_AttributeList *attrs, + const struct GNUNET_RECLAIM_PresentationList *presentations, const struct GNUNET_TIME_Relative *expiration_time, const char *nonce, const char *secret_key); @@ -73,8 +73,8 @@ OIDC_generate_id_token (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, char* OIDC_build_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer, const struct GNUNET_RECLAIM_Ticket *ticket, - struct GNUNET_RECLAIM_AttributeList *attrs, - struct GNUNET_RECLAIM_PresentationList *presentations, + const struct GNUNET_RECLAIM_AttributeList *attrs, + const struct GNUNET_RECLAIM_PresentationList *presentations, const char *nonce, const char *code_challenge); @@ -139,8 +139,8 @@ OIDC_access_token_parse (const char* token, * @return GNUNET_YES if attribute is implcitly requested */ enum GNUNET_GenericReturnValue -OIDC_check_scopes_for_claim_request (const char*scopes, - const char*attr); +OIDC_check_scopes_for_claim_request (const char *scopes, + const char *attr); /** @@ -153,7 +153,7 @@ OIDC_check_scopes_for_claim_request (const char*scopes, */ char * OIDC_generate_userinfo (const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key, - struct GNUNET_RECLAIM_AttributeList *attrs, - struct GNUNET_RECLAIM_PresentationList *presentations); + const struct GNUNET_RECLAIM_AttributeList *attrs, + const struct GNUNET_RECLAIM_PresentationList *presentations); #endif diff --git a/src/reclaim/plugin_gnsrecord_reclaim.c b/src/reclaim/plugin_gnsrecord_reclaim.c index b91e123a3..60c49fd6a 100644 --- a/src/reclaim/plugin_gnsrecord_reclaim.c +++ b/src/reclaim/plugin_gnsrecord_reclaim.c @@ -51,8 +51,8 @@ value_to_string (void *cls, uint32_t type, const void *data, size_t data_size) case GNUNET_GNSRECORD_TYPE_RECLAIM_ATTRIBUTE_REF: case GNUNET_GNSRECORD_TYPE_RECLAIM_TICKET: case GNUNET_GNSRECORD_TYPE_RECLAIM_MASTER: - case GNUNET_GNSRECORD_TYPE_RECLAIM_ATTESTATION: - case GNUNET_GNSRECORD_TYPE_RECLAIM_ATTESTATION_REF: + case GNUNET_GNSRECORD_TYPE_RECLAIM_CREDENTIAL: + case GNUNET_GNSRECORD_TYPE_RECLAIM_PRESENTATION: return GNUNET_STRINGS_data_to_string_alloc (data, data_size); default: @@ -89,8 +89,8 @@ string_to_value (void *cls, uint32_t type, const char *s, void **data, case GNUNET_GNSRECORD_TYPE_RECLAIM_ATTRIBUTE_REF: case GNUNET_GNSRECORD_TYPE_RECLAIM_MASTER: case GNUNET_GNSRECORD_TYPE_RECLAIM_TICKET: - case GNUNET_GNSRECORD_TYPE_RECLAIM_ATTESTATION: - case GNUNET_GNSRECORD_TYPE_RECLAIM_ATTESTATION_REF: + case GNUNET_GNSRECORD_TYPE_RECLAIM_CREDENTIAL: + case GNUNET_GNSRECORD_TYPE_RECLAIM_PRESENTATION: return GNUNET_STRINGS_string_to_data (s, strlen (s), *data, *data_size); default: @@ -110,8 +110,8 @@ static struct } name_map[] = { { "RECLAIM_ATTRIBUTE", GNUNET_GNSRECORD_TYPE_RECLAIM_ATTRIBUTE }, { "RECLAIM_ATTRIBUTE_REF", GNUNET_GNSRECORD_TYPE_RECLAIM_ATTRIBUTE_REF }, - { "RECLAIM_ATTESTATION", GNUNET_GNSRECORD_TYPE_RECLAIM_ATTESTATION }, - { "RECLAIM_ATTESTATION_REF", GNUNET_GNSRECORD_TYPE_RECLAIM_ATTESTATION_REF }, + { "RECLAIM_CREDENTIAL", GNUNET_GNSRECORD_TYPE_RECLAIM_CREDENTIAL }, + { "RECLAIM_PRESENTATION", GNUNET_GNSRECORD_TYPE_RECLAIM_PRESENTATION }, { "RECLAIM_MASTER", GNUNET_GNSRECORD_TYPE_RECLAIM_MASTER }, { "RECLAIM_OIDC_CLIENT", GNUNET_GNSRECORD_TYPE_RECLAIM_OIDC_CLIENT }, { "RECLAIM_OIDC_REDIRECT", GNUNET_GNSRECORD_TYPE_RECLAIM_OIDC_REDIRECT }, diff --git a/src/reclaim/plugin_reclaim_credential_jwt.c b/src/reclaim/plugin_reclaim_credential_jwt.c index 38effcf78..148865223 100644 --- a/src/reclaim/plugin_reclaim_credential_jwt.c +++ b/src/reclaim/plugin_reclaim_credential_jwt.c @@ -48,7 +48,7 @@ jwt_value_to_string (void *cls, { switch (type) { - case GNUNET_RECLAIM_credential_TYPE_JWT: + case GNUNET_RECLAIM_CREDENTIAL_TYPE_JWT: return GNUNET_strndup (data, data_size); default: @@ -79,7 +79,7 @@ jwt_string_to_value (void *cls, return GNUNET_SYSERR; switch (type) { - case GNUNET_RECLAIM_credential_TYPE_JWT: + case GNUNET_RECLAIM_CREDENTIAL_TYPE_JWT: *data = GNUNET_strdup (s); *data_size = strlen (s); return GNUNET_OK; @@ -98,8 +98,8 @@ static struct { const char *name; uint32_t number; -} jwt_cred_name_map[] = { { "JWT", GNUNET_RECLAIM_credential_TYPE_JWT }, - { NULL, UINT32_MAX } }; +} jwt_cred_name_map[] = { { "JWT", GNUNET_RECLAIM_CREDENTIAL_TYPE_JWT }, + { NULL, UINT32_MAX } }; /** * Convert a type name to the corresponding number. @@ -135,8 +135,8 @@ jwt_number_to_typename (void *cls, uint32_t type) i = 0; while ((NULL != jwt_cred_name_map[i].name) && (type != - jwt_cred_name_map[i]. - number)) + jwt_cred_name_map[i]. + number)) i++; return jwt_cred_name_map[i].name; } @@ -151,7 +151,7 @@ jwt_number_to_typename (void *cls, uint32_t type) */ struct GNUNET_RECLAIM_AttributeList * jwt_parse_attributes (void *cls, - const struct GNUNET_RECLAIM_Credential *cred) + const char *data) { char *jwt_string; struct GNUNET_RECLAIM_AttributeList *attrs; @@ -162,17 +162,14 @@ jwt_parse_attributes (void *cls, json_t *json_val; json_error_t *json_err = NULL; - /* GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "%s\n", cred->data); (not OK: 'data' is not defined as 0-terminated text, but binary) */ - if (GNUNET_RECLAIM_credential_TYPE_JWT != cred->type) - return NULL; attrs = GNUNET_new (struct GNUNET_RECLAIM_AttributeList); - jwt_string = GNUNET_strdup (cred->data); + jwt_string = GNUNET_strdup (data); const char *jwt_body = strtok (jwt_string, delim); jwt_body = strtok (NULL, delim); GNUNET_STRINGS_base64url_decode (jwt_body, strlen (jwt_body), (void **) &decoded_jwt); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n", decoded_jwt); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Decoded JWT: %s\n", decoded_jwt); GNUNET_assert (NULL != decoded_jwt); json_val = json_loads (decoded_jwt, JSON_DECODE_ANY, json_err); const char *key; @@ -202,6 +199,36 @@ jwt_parse_attributes (void *cls, } +/** + * Parse a JWT and return the respective claim value as Attribute + * + * @param cls the plugin + * @param cred the jwt credential + * @return a GNUNET_RECLAIM_Attribute, containing the new value + */ +struct GNUNET_RECLAIM_AttributeList * +jwt_parse_attributes_c (void *cls, + const struct GNUNET_RECLAIM_Credential *cred) +{ + return jwt_parse_attributes (cls, cred->data); +} + + +/** + * Parse a JWT and return the respective claim value as Attribute + * + * @param cls the plugin + * @param cred the jwt credential + * @return a GNUNET_RECLAIM_Attribute, containing the new value + */ +struct GNUNET_RECLAIM_AttributeList * +jwt_parse_attributes_p (void *cls, + const struct GNUNET_RECLAIM_Presentation *cred) +{ + return jwt_parse_attributes (cls, cred->data); +} + + /** * Parse a JWT and return the issuer * @@ -211,7 +238,7 @@ jwt_parse_attributes (void *cls, */ char * jwt_get_issuer (void *cls, - const struct GNUNET_RECLAIM_Credential *cred) + const char *data) { const char *jwt_body; char *jwt_string; @@ -223,9 +250,7 @@ jwt_get_issuer (void *cls, json_t *json_val; json_error_t *json_err = NULL; - if (GNUNET_RECLAIM_credential_TYPE_JWT != cred->type) - return NULL; - jwt_string = GNUNET_strdup (cred->data); + jwt_string = GNUNET_strdup (data); jwt_body = strtok (jwt_string, delim); jwt_body = strtok (NULL, delim); GNUNET_STRINGS_base64url_decode (jwt_body, strlen (jwt_body), @@ -240,6 +265,40 @@ jwt_get_issuer (void *cls, } +/** + * Parse a JWT and return the issuer + * + * @param cls the plugin + * @param cred the jwt credential + * @return a string, containing the isser + */ +char * +jwt_get_issuer_c (void *cls, + const struct GNUNET_RECLAIM_Credential *cred) +{ + if (GNUNET_RECLAIM_CREDENTIAL_TYPE_JWT != cred->type) + return NULL; + return jwt_get_issuer (cls, cred->data); +} + + +/** + * Parse a JWT and return the issuer + * + * @param cls the plugin + * @param cred the jwt credential + * @return a string, containing the isser + */ +char * +jwt_get_issuer_p (void *cls, + const struct GNUNET_RECLAIM_Presentation *cred) +{ + if (GNUNET_RECLAIM_CREDENTIAL_TYPE_JWT != cred->type) + return NULL; + return jwt_get_issuer (cls, cred->data); +} + + /** * Parse a JWT and return the expiration * @@ -249,7 +308,7 @@ jwt_get_issuer (void *cls, */ int jwt_get_expiration (void *cls, - const struct GNUNET_RECLAIM_Credential *cred, + const char *data, struct GNUNET_TIME_Absolute *exp) { const char *jwt_body; @@ -261,9 +320,7 @@ jwt_get_expiration (void *cls, json_t *json_val; json_error_t *json_err = NULL; - if (GNUNET_RECLAIM_credential_TYPE_JWT != cred->type) - return GNUNET_NO; - jwt_string = GNUNET_strdup (cred->data); + jwt_string = GNUNET_strdup (data); jwt_body = strtok (jwt_string, delim); jwt_body = strtok (NULL, delim); GNUNET_STRINGS_base64url_decode (jwt_body, strlen (jwt_body), @@ -278,6 +335,54 @@ jwt_get_expiration (void *cls, } +/** + * Parse a JWT and return the expiration + * + * @param cls the plugin + * @param cred the jwt credential + * @return a string, containing the isser + */ +int +jwt_get_expiration_c (void *cls, + const struct GNUNET_RECLAIM_Credential *cred, + struct GNUNET_TIME_Absolute *exp) +{ + return jwt_get_expiration (cls, cred->data, exp); +} + + +/** + * Parse a JWT and return the expiration + * + * @param cls the plugin + * @param cred the jwt credential + * @return a string, containing the isser + */ +int +jwt_get_expiration_p (void *cls, + const struct GNUNET_RECLAIM_Presentation *cred, + struct GNUNET_TIME_Absolute *exp) +{ + return jwt_get_expiration (cls, cred->data, exp); +} + + +int +jwt_create_presentation (void *cls, + const struct GNUNET_RECLAIM_Credential *cred, + const struct GNUNET_RECLAIM_AttributeList *attrs, + struct GNUNET_RECLAIM_Presentation **pres) +{ + // FIXME sanity checks?? + if (GNUNET_RECLAIM_CREDENTIAL_TYPE_JWT != cred->type) + return GNUNET_NO; + *pres = GNUNET_RECLAIM_presentation_new (GNUNET_RECLAIM_CREDENTIAL_TYPE_JWT, + cred->data, + cred->data_size); + return GNUNET_OK; +} + + /** * Entry point for the plugin. * @@ -294,9 +399,17 @@ libgnunet_plugin_reclaim_credential_jwt_init (void *cls) api->string_to_value = &jwt_string_to_value; api->typename_to_number = &jwt_typename_to_number; api->number_to_typename = &jwt_number_to_typename; - api->get_attributes = &jwt_parse_attributes; - api->get_issuer = &jwt_get_issuer; - api->get_expiration = &jwt_get_expiration; + api->get_attributes = &jwt_parse_attributes_c; + api->get_issuer = &jwt_get_issuer_c; + api->get_expiration = &jwt_get_expiration_c; + api->value_to_string_p = &jwt_value_to_string; + api->string_to_value_p = &jwt_string_to_value; + api->typename_to_number_p = &jwt_typename_to_number; + api->number_to_typename_p = &jwt_number_to_typename; + api->get_attributes_p = &jwt_parse_attributes_p; + api->get_issuer_p = &jwt_get_issuer_p; + api->get_expiration_p = &jwt_get_expiration_p; + api->create_presentation = &jwt_create_presentation; return api; } diff --git a/src/reclaim/plugin_rest_openid_connect.c b/src/reclaim/plugin_rest_openid_connect.c index 5ae6565af..5b0bb2b6f 100644 --- a/src/reclaim/plugin_rest_openid_connect.c +++ b/src/reclaim/plugin_rest_openid_connect.c @@ -439,10 +439,14 @@ struct RequestHandle struct GNUNET_RECLAIM_AttributeList *attr_userinfo_list; /** - * Credential list + * Credentials */ - struct GNUNET_RECLAIM_CredentialList *creds_list; + struct GNUNET_RECLAIM_CredentialList *credentials; + /** + * Presentations + */ + struct GNUNET_RECLAIM_PresentationList *presentations; /** * IDENTITY Operation @@ -590,8 +594,10 @@ cleanup_handle (struct RequestHandle *handle) GNUNET_RECLAIM_attribute_list_destroy (handle->attr_idtoken_list); if (NULL!=handle->attr_userinfo_list) GNUNET_RECLAIM_attribute_list_destroy (handle->attr_userinfo_list); - if (NULL!=handle->creds_list) - GNUNET_RECLAIM_credential_list_destroy (handle->creds_list); + if (NULL!=handle->credentials) + GNUNET_RECLAIM_credential_list_destroy (handle->credentials); + if (NULL!=handle->presentations) + GNUNET_RECLAIM_presentation_list_destroy (handle->presentations); GNUNET_CONTAINER_DLL_remove (requests_head, requests_tail, handle); @@ -934,7 +940,9 @@ oidc_iteration_error (void *cls) * parameter. Otherwise redirects with error */ static void -oidc_ticket_issue_cb (void *cls, const struct GNUNET_RECLAIM_Ticket *ticket) +oidc_ticket_issue_cb (void *cls, + const struct GNUNET_RECLAIM_Ticket *ticket, + const struct GNUNET_RECLAIM_PresentationList *pres) { struct RequestHandle *handle = cls; struct MHD_Response *resp; @@ -957,7 +965,7 @@ oidc_ticket_issue_cb (void *cls, const struct GNUNET_RECLAIM_Ticket *ticket) code_string = OIDC_build_authz_code (&handle->priv_key, &handle->ticket, handle->attr_idtoken_list, - handle->creds_list, + pres, handle->oidc->nonce, handle->oidc->code_challenge); if ((NULL != handle->redirect_prefix) && (NULL != handle->redirect_suffix) && @@ -1086,7 +1094,7 @@ oidc_cred_collect (void *cls, struct GNUNET_RECLAIM_AttributeListEntry *le; struct GNUNET_RECLAIM_CredentialListEntry *ale; - for (ale = handle->creds_list->list_head; NULL != ale; ale = ale->next) + for (ale = handle->credentials->list_head; NULL != ale; ale = ale->next) { if (GNUNET_NO == GNUNET_RECLAIM_id_is_equal (&ale->credential->id, &cred->id)) @@ -1107,8 +1115,8 @@ oidc_cred_collect (void *cls, cred->type, cred->data, cred->data_size); - GNUNET_CONTAINER_DLL_insert (handle->creds_list->list_head, - handle->creds_list->list_tail, + GNUNET_CONTAINER_DLL_insert (handle->credentials->list_head, + handle->credentials->list_tail, ale); } GNUNET_RECLAIM_get_credentials_next (handle->cred_it); @@ -1129,7 +1137,7 @@ oidc_attr_collect_finished_cb (void *cls) GNUNET_SCHEDULER_add_now (&do_redirect_error, handle); return; } - handle->creds_list = GNUNET_new (struct GNUNET_RECLAIM_CredentialList); + handle->credentials = GNUNET_new (struct GNUNET_RECLAIM_CredentialList); handle->cred_it = GNUNET_RECLAIM_get_credentials_start (idp, &handle->priv_key, @@ -1982,7 +1990,7 @@ token_endpoint (struct GNUNET_REST_RequestHandle *con_handle, const struct EgoEntry *ego_entry; struct GNUNET_TIME_Relative expiration_time; struct GNUNET_RECLAIM_AttributeList *cl = NULL; - struct GNUNET_RECLAIM_CredentialList *al = NULL; + struct GNUNET_RECLAIM_PresentationList *pl = NULL; struct GNUNET_RECLAIM_Ticket ticket; struct GNUNET_CRYPTO_EcdsaPublicKey cid; struct GNUNET_HashCode cache_key; @@ -2068,7 +2076,7 @@ token_endpoint (struct GNUNET_REST_RequestHandle *con_handle, // decode code if (GNUNET_OK != OIDC_parse_authz_code (&cid, code, code_verifier, &ticket, - &cl, &al, &nonce)) + &cl, &pl, &nonce)) { handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_REQUEST); handle->edesc = GNUNET_strdup ("invalid code"); @@ -2108,7 +2116,7 @@ token_endpoint (struct GNUNET_REST_RequestHandle *con_handle, id_token = OIDC_generate_id_token (&ticket.audience, &ticket.identity, cl, - al, + pl, &expiration_time, (NULL != nonce) ? nonce : NULL, jwt_secret); @@ -2124,7 +2132,7 @@ token_endpoint (struct GNUNET_REST_RequestHandle *con_handle, MHD_add_response_header (resp, "Content-Type", "application/json"); handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); GNUNET_RECLAIM_attribute_list_destroy (cl); - GNUNET_RECLAIM_credential_list_destroy (al); + GNUNET_RECLAIM_presentation_list_destroy (pl); GNUNET_free (access_token); GNUNET_free (json_response); GNUNET_free (id_token); @@ -2139,11 +2147,11 @@ static void consume_ticket (void *cls, const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, const struct GNUNET_RECLAIM_Attribute *attr, - const struct GNUNET_RECLAIM_Credential *cred) + const struct GNUNET_RECLAIM_Presentation *pres) { struct RequestHandle *handle = cls; struct GNUNET_RECLAIM_AttributeListEntry *ale; - struct GNUNET_RECLAIM_CredentialListEntry *atle; + struct GNUNET_RECLAIM_PresentationListEntry *atle; struct MHD_Response *resp; char *result_str; handle->idp_op = NULL; @@ -2152,7 +2160,7 @@ consume_ticket (void *cls, { result_str = OIDC_generate_userinfo (&handle->ticket.identity, handle->attr_userinfo_list, - handle->creds_list); + handle->presentations); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Userinfo: %s\n", result_str); resp = GNUNET_REST_create_response (result_str); handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); @@ -2172,25 +2180,25 @@ consume_ticket (void *cls, GNUNET_CONTAINER_DLL_insert (handle->attr_userinfo_list->list_head, handle->attr_userinfo_list->list_tail, ale); - if (NULL == cred) + if (NULL == pres) return; - for (atle = handle->creds_list->list_head; NULL != atle; atle = atle->next) + for (atle = handle->presentations->list_head; + NULL != atle; atle = atle->next) { - if (GNUNET_NO == GNUNET_RECLAIM_id_is_equal (&atle->credential->id, - &cred->id)) + if (GNUNET_NO == GNUNET_RECLAIM_id_is_equal (&atle->presentation->credential_id, + &pres->credential_id)) continue; break; /** already in list **/ } if (NULL == atle) { /** Credential matches for attribute, add **/ - atle = GNUNET_new (struct GNUNET_RECLAIM_CredentialListEntry); - atle->credential = GNUNET_RECLAIM_credential_new (cred->name, - cred->type, - cred->data, - cred->data_size); - GNUNET_CONTAINER_DLL_insert (handle->creds_list->list_head, - handle->creds_list->list_tail, + atle = GNUNET_new (struct GNUNET_RECLAIM_PresentationListEntry); + atle->presentation = GNUNET_RECLAIM_presentation_new (pres->type, + pres->data, + pres->data_size); + GNUNET_CONTAINER_DLL_insert (handle->presentations->list_head, + handle->presentations->list_tail, atle); } } @@ -2289,8 +2297,8 @@ userinfo_endpoint (struct GNUNET_REST_RequestHandle *con_handle, privkey = GNUNET_IDENTITY_ego_get_private_key (aud_ego->ego); handle->attr_userinfo_list = GNUNET_new (struct GNUNET_RECLAIM_AttributeList); - handle->creds_list = - GNUNET_new (struct GNUNET_RECLAIM_CredentialList); + handle->presentations = + GNUNET_new (struct GNUNET_RECLAIM_PresentationList); handle->idp_op = GNUNET_RECLAIM_ticket_consume (idp, privkey, diff --git a/src/reclaim/plugin_rest_reclaim.c b/src/reclaim/plugin_rest_reclaim.c index a51d992e1..ff11d2a56 100644 --- a/src/reclaim/plugin_rest_reclaim.c +++ b/src/reclaim/plugin_rest_reclaim.c @@ -474,7 +474,7 @@ add_credential_cont (struct GNUNET_REST_RequestHandle *con_handle, json_t *data_json; json_error_t err; struct GNUNET_JSON_Specification attrspec[] = - { GNUNET_RECLAIM_JSON_spec_claim_cred (&attribute), + { GNUNET_RECLAIM_JSON_spec_credential (&attribute), GNUNET_JSON_spec_end () }; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, @@ -811,7 +811,7 @@ add_attribute_cont (struct GNUNET_REST_RequestHandle *con_handle, json_t *data_json; json_error_t err; struct GNUNET_JSON_Specification attrspec[] = - { GNUNET_RECLAIM_JSON_spec_claim (&attribute), GNUNET_JSON_spec_end () }; + { GNUNET_RECLAIM_JSON_spec_attribute (&attribute), GNUNET_JSON_spec_end () }; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding an attribute for %s.\n", @@ -1180,7 +1180,7 @@ static void consume_cont (void *cls, const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, const struct GNUNET_RECLAIM_Attribute *attr, - const struct GNUNET_RECLAIM_Credential *cred) + const struct GNUNET_RECLAIM_Presentation *pres) { struct RequestHandle *handle = cls; char *val_str; diff --git a/src/reclaim/reclaim.h b/src/reclaim/reclaim.h index 6ba9fdcd7..bc7f34365 100644 --- a/src/reclaim/reclaim.h +++ b/src/reclaim/reclaim.h @@ -462,10 +462,17 @@ struct TicketResultMessage */ uint32_t id GNUNET_PACKED; + /** + * Length of new presentations created + */ + uint32_t presentations_len GNUNET_PACKED; + /** * The new ticket */ struct GNUNET_RECLAIM_Ticket ticket; + + /* Followed by the serialized GNUNET_RECLAIM_PresentationList */ }; /** diff --git a/src/reclaim/reclaim_api.c b/src/reclaim/reclaim_api.c index 2cfcbad09..1e0251519 100644 --- a/src/reclaim/reclaim_api.c +++ b/src/reclaim/reclaim_api.c @@ -91,6 +91,11 @@ struct GNUNET_RECLAIM_Operation */ GNUNET_RECLAIM_TicketCallback tr_cb; + /** + * Ticket issue result callback + */ + GNUNET_RECLAIM_IssueTicketCallback ti_cb; + /** * Envelope with the message for this queue entry. */ @@ -866,6 +871,30 @@ handle_credential_result (void *cls, const struct GNUNET_assert (0); } +/** + * Handle an incoming message of type + * #GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT + * + * @param cls + * @param msg the message we received + * @return #GNUNET_OK on success, #GNUNET_SYSERR on error + */ +static int +check_ticket_result (void *cls, const struct TicketResultMessage *msg) +{ + size_t msg_len; + size_t pres_len; + + msg_len = ntohs (msg->header.size); + pres_len = ntohs (msg->presentations_len); + if (msg_len != sizeof(struct TicketResultMessage) + pres_len) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + return GNUNET_OK; +} + /** * Handle an incoming message of type @@ -880,8 +909,10 @@ handle_ticket_result (void *cls, const struct TicketResultMessage *msg) struct GNUNET_RECLAIM_Handle *handle = cls; struct GNUNET_RECLAIM_Operation *op; struct GNUNET_RECLAIM_TicketIterator *it; + struct GNUNET_RECLAIM_PresentationList *pres; uint32_t r_id = ntohl (msg->id); static const struct GNUNET_RECLAIM_Ticket ticket; + uint32_t pres_len = ntohs (msg->presentations_len); for (op = handle->op_head; NULL != op; op = op->next) if (op->r_id == r_id) @@ -893,18 +924,25 @@ handle_ticket_result (void *cls, const struct TicketResultMessage *msg) return; if (NULL != op) { + if (0 < pres_len) + pres = GNUNET_RECLAIM_presentation_list_deserialize ((char*)&msg[1], + pres_len); GNUNET_CONTAINER_DLL_remove (handle->op_head, handle->op_tail, op); if (0 == memcmp (&msg->ticket, &ticket, sizeof(struct GNUNET_RECLAIM_Ticket))) { - if (NULL != op->tr_cb) - op->tr_cb (op->cls, NULL); + if (NULL != op->ti_cb) + op->ti_cb (op->cls, NULL, NULL); } else { - if (NULL != op->tr_cb) - op->tr_cb (op->cls, &msg->ticket); + if (NULL != op->ti_cb) + op->ti_cb (op->cls, + &msg->ticket, + (0 < pres_len) ? pres : NULL); } + if (0 < pres_len) + GNUNET_RECLAIM_presentation_list_destroy (pres); free_op (op); return; } @@ -989,10 +1027,10 @@ reconnect (struct GNUNET_RECLAIM_Handle *h) GNUNET_MESSAGE_TYPE_RECLAIM_CREDENTIAL_RESULT, struct CredentialResultMessage, h), - GNUNET_MQ_hd_fixed_size (ticket_result, - GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT, - struct TicketResultMessage, - h), + GNUNET_MQ_hd_var_size (ticket_result, + GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT, + struct TicketResultMessage, + h), GNUNET_MQ_hd_var_size (consume_ticket_result, GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET_RESULT, struct ConsumeTicketResultMessage, @@ -1506,7 +1544,7 @@ GNUNET_RECLAIM_ticket_issue ( const struct GNUNET_CRYPTO_EcdsaPrivateKey *iss, const struct GNUNET_CRYPTO_EcdsaPublicKey *rp, const struct GNUNET_RECLAIM_AttributeList *attrs, - GNUNET_RECLAIM_TicketCallback cb, + GNUNET_RECLAIM_IssueTicketCallback cb, void *cb_cls) { struct GNUNET_RECLAIM_Operation *op; @@ -1516,7 +1554,7 @@ GNUNET_RECLAIM_ticket_issue ( fprintf (stderr, "Issuing ticket\n"); op = GNUNET_new (struct GNUNET_RECLAIM_Operation); op->h = h; - op->tr_cb = cb; + op->ti_cb = cb; op->cls = cb_cls; op->r_id = h->r_id_gen++; GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, op); diff --git a/src/reclaim/reclaim_credential.c b/src/reclaim/reclaim_credential.c index 10b17ae96..5c8974400 100644 --- a/src/reclaim/reclaim_credential.c +++ b/src/reclaim/reclaim_credential.c @@ -165,9 +165,9 @@ GNUNET_RECLAIM_credential_number_to_typename (uint32_t type) */ int GNUNET_RECLAIM_credential_string_to_value (uint32_t type, - const char *s, - void **data, - size_t *data_size) + const char *s, + void **data, + size_t *data_size) { unsigned int i; struct Plugin *plugin; @@ -197,8 +197,8 @@ GNUNET_RECLAIM_credential_string_to_value (uint32_t type, */ char * GNUNET_RECLAIM_credential_value_to_string (uint32_t type, - const void *data, - size_t data_size) + const void *data, + size_t data_size) { unsigned int i; struct Plugin *plugin; @@ -229,9 +229,9 @@ GNUNET_RECLAIM_credential_value_to_string (uint32_t type, */ struct GNUNET_RECLAIM_Credential * GNUNET_RECLAIM_credential_new (const char *attr_name, - uint32_t type, - const void *data, - size_t data_size) + uint32_t type, + const void *data, + size_t data_size) { struct GNUNET_RECLAIM_Credential *attr; char *write_ptr; @@ -335,7 +335,7 @@ GNUNET_RECLAIM_credential_list_deserialize (const char *data, size_t data_size) ale = GNUNET_new (struct GNUNET_RECLAIM_CredentialListEntry); ale->credential = GNUNET_RECLAIM_credential_deserialize (read_ptr, - data_size - (read_ptr - data)); + data_size - (read_ptr - data)); if (NULL == ale->credential) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, @@ -371,9 +371,9 @@ GNUNET_RECLAIM_credential_list_dup ( GNUNET_assert (NULL != ale->credential); result_ale->credential = GNUNET_RECLAIM_credential_new (ale->credential->name, - ale->credential->type, - ale->credential->data, - ale->credential->data_size); + ale->credential->type, + ale->credential->data, + ale->credential->data_size); result_ale->credential->id = ale->credential->id; GNUNET_CONTAINER_DLL_insert (result->list_head, result->list_tail, @@ -490,7 +490,7 @@ GNUNET_RECLAIM_credential_deserialize (const char *data, size_t data_size) return NULL; } credential = GNUNET_malloc (sizeof(struct GNUNET_RECLAIM_Credential) - + data_len + name_len + 1); + + data_len + name_len + 1); credential->type = ntohs (atts->credential_type); credential->flag = ntohl (atts->credential_flag); credential->id = atts->credential_id; @@ -511,7 +511,7 @@ GNUNET_RECLAIM_credential_deserialize (const char *data, size_t data_size) struct GNUNET_RECLAIM_AttributeList* GNUNET_RECLAIM_credential_get_attributes (const struct - GNUNET_RECLAIM_Credential *credential) + GNUNET_RECLAIM_Credential *credential) { unsigned int i; struct Plugin *plugin; @@ -531,7 +531,7 @@ GNUNET_RECLAIM_credential_get_attributes (const struct char* GNUNET_RECLAIM_credential_get_issuer (const struct - GNUNET_RECLAIM_Credential *credential) + GNUNET_RECLAIM_Credential *credential) { unsigned int i; struct Plugin *plugin; @@ -551,8 +551,8 @@ GNUNET_RECLAIM_credential_get_issuer (const struct int GNUNET_RECLAIM_credential_get_expiration (const struct - GNUNET_RECLAIM_Credential *credential, - struct GNUNET_TIME_Absolute*exp) + GNUNET_RECLAIM_Credential *credential, + struct GNUNET_TIME_Absolute*exp) { unsigned int i; struct Plugin *plugin; @@ -568,3 +568,470 @@ GNUNET_RECLAIM_credential_get_expiration (const struct } return GNUNET_SYSERR; } + + +/** + * Convert an presentation type name to the corresponding number + * + * @param typename name to convert + * @return corresponding number, UINT32_MAX on error + */ +uint32_t +GNUNET_RECLAIM_presentation_typename_to_number (const char *typename) +{ + unsigned int i; + struct Plugin *plugin; + uint32_t ret; + init (); + for (i = 0; i < num_plugins; i++) + { + plugin = credential_plugins[i]; + if (UINT32_MAX != + (ret = plugin->api->typename_to_number_p (plugin->api->cls, + typename))) + return ret; + } + return UINT32_MAX; +} + + +/** + * Convert an presentation type number to the corresponding presentation type string + * + * @param type number of a type + * @return corresponding typestring, NULL on error + */ +const char * +GNUNET_RECLAIM_presentation_number_to_typename (uint32_t type) +{ + unsigned int i; + struct Plugin *plugin; + const char *ret; + + init (); + for (i = 0; i < num_plugins; i++) + { + plugin = credential_plugins[i]; + if (NULL != + (ret = plugin->api->number_to_typename_p (plugin->api->cls, type))) + return ret; + } + return NULL; +} + + +/** + * Convert human-readable version of a 'claim' of an presentation to the binary + * representation + * + * @param type type of the claim + * @param s human-readable string + * @param data set to value in binary encoding (will be allocated) + * @param data_size set to number of bytes in @a data + * @return #GNUNET_OK on success + */ +int +GNUNET_RECLAIM_presentation_string_to_value (uint32_t type, + const char *s, + void **data, + size_t *data_size) +{ + unsigned int i; + struct Plugin *plugin; + + init (); + for (i = 0; i < num_plugins; i++) + { + plugin = credential_plugins[i]; + if (GNUNET_OK == plugin->api->string_to_value_p (plugin->api->cls, + type, + s, + data, + data_size)) + return GNUNET_OK; + } + return GNUNET_SYSERR; +} + + +/** + * Convert the 'claim' of an presentation to a string + * + * @param type the type of presentation + * @param data claim in binary encoding + * @param data_size number of bytes in @a data + * @return NULL on error, otherwise human-readable representation of the claim + */ +char * +GNUNET_RECLAIM_presentation_value_to_string (uint32_t type, + const void *data, + size_t data_size) +{ + unsigned int i; + struct Plugin *plugin; + char *ret; + + init (); + for (i = 0; i < num_plugins; i++) + { + plugin = credential_plugins[i]; + if (NULL != (ret = plugin->api->value_to_string_p (plugin->api->cls, + type, + data, + data_size))) + return ret; + } + return NULL; +} + + +struct GNUNET_RECLAIM_Presentation * +GNUNET_RECLAIM_presentation_new (uint32_t type, + const void *data, + size_t data_size) +{ + struct GNUNET_RECLAIM_Presentation *attr; + char *write_ptr; + + attr = GNUNET_malloc (sizeof(struct GNUNET_RECLAIM_Presentation) + + data_size); + attr->type = type; + attr->data_size = data_size; + write_ptr = (char *) &attr[1]; + GNUNET_memcpy (write_ptr, data, data_size); + attr->data = write_ptr; + return attr; +} + + +/** + * Get required size for serialization buffer + * + * @param attrs the attribute list to serialize + * @return the required buffer size + */ +size_t +GNUNET_RECLAIM_presentation_list_serialize_get_size ( + const struct GNUNET_RECLAIM_PresentationList *presentations) +{ + struct GNUNET_RECLAIM_PresentationListEntry *le; + size_t len = 0; + + for (le = presentations->list_head; NULL != le; le = le->next) + { + GNUNET_assert (NULL != le->presentation); + len += GNUNET_RECLAIM_presentation_serialize_get_size (le->presentation); + len += sizeof(struct GNUNET_RECLAIM_PresentationListEntry); + } + return len; +} + + +/** + * Serialize an attribute list + * + * @param attrs the attribute list to serialize + * @param result the serialized attribute + * @return length of serialized data + */ +size_t +GNUNET_RECLAIM_presentation_list_serialize ( + const struct GNUNET_RECLAIM_PresentationList *presentations, + char *result) +{ + struct GNUNET_RECLAIM_PresentationListEntry *le; + size_t len; + size_t total_len; + char *write_ptr; + write_ptr = result; + total_len = 0; + for (le = presentations->list_head; NULL != le; le = le->next) + { + GNUNET_assert (NULL != le->presentation); + len = GNUNET_RECLAIM_presentation_serialize (le->presentation, write_ptr); + total_len += len; + write_ptr += len; + } + return total_len; +} + + +/** + * Deserialize an presentation list + * + * @param data the serialized attribute list + * @param data_size the length of the serialized data + * @return a GNUNET_IDENTITY_PROVIDER_AttributeList, must be free'd by caller + */ +struct GNUNET_RECLAIM_PresentationList * +GNUNET_RECLAIM_presentation_list_deserialize (const char *data, size_t + data_size) +{ + struct GNUNET_RECLAIM_PresentationList *al; + struct GNUNET_RECLAIM_PresentationListEntry *ale; + size_t att_len; + const char *read_ptr; + + al = GNUNET_new (struct GNUNET_RECLAIM_PresentationList); + + if ((data_size < sizeof(struct Presentation) + + sizeof(struct GNUNET_RECLAIM_PresentationListEntry))) + return al; + + read_ptr = data; + while (((data + data_size) - read_ptr) >= sizeof(struct Presentation)) + { + ale = GNUNET_new (struct GNUNET_RECLAIM_PresentationListEntry); + ale->presentation = + GNUNET_RECLAIM_presentation_deserialize (read_ptr, + data_size - (read_ptr - data)); + if (NULL == ale->presentation) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Failed to deserialize malformed presentation.\n"); + GNUNET_free (ale); + return al; + } + GNUNET_CONTAINER_DLL_insert (al->list_head, al->list_tail, ale); + att_len = GNUNET_RECLAIM_presentation_serialize_get_size ( + ale->presentation); + read_ptr += att_len; + } + return al; +} + + +/** + * Make a (deep) copy of the presentation list + * @param attrs claim list to copy + * @return copied claim list + */ +struct GNUNET_RECLAIM_PresentationList * +GNUNET_RECLAIM_presentation_list_dup ( + const struct GNUNET_RECLAIM_PresentationList *al) +{ + struct GNUNET_RECLAIM_PresentationListEntry *ale; + struct GNUNET_RECLAIM_PresentationListEntry *result_ale; + struct GNUNET_RECLAIM_PresentationList *result; + + result = GNUNET_new (struct GNUNET_RECLAIM_PresentationList); + for (ale = al->list_head; NULL != ale; ale = ale->next) + { + result_ale = GNUNET_new (struct GNUNET_RECLAIM_PresentationListEntry); + GNUNET_assert (NULL != ale->presentation); + result_ale->presentation = + GNUNET_RECLAIM_presentation_new (ale->presentation->type, + ale->presentation->data, + ale->presentation->data_size); + result_ale->presentation->credential_id = ale->presentation->credential_id; + GNUNET_CONTAINER_DLL_insert (result->list_head, + result->list_tail, + result_ale); + } + return result; +} + + +/** + * Destroy presentation list + * + * @param attrs list to destroy + */ +void +GNUNET_RECLAIM_presentation_list_destroy ( + struct GNUNET_RECLAIM_PresentationList *al) +{ + struct GNUNET_RECLAIM_PresentationListEntry *ale; + struct GNUNET_RECLAIM_PresentationListEntry *tmp_ale; + + for (ale = al->list_head; NULL != ale;) + { + if (NULL != ale->presentation) + GNUNET_free (ale->presentation); + tmp_ale = ale; + ale = ale->next; + GNUNET_free (tmp_ale); + } + GNUNET_free (al); +} + + +/** + * Get required size for serialization buffer + * + * @param attr the presentation to serialize + * @return the required buffer size + */ +size_t +GNUNET_RECLAIM_presentation_serialize_get_size ( + const struct GNUNET_RECLAIM_Presentation *presentation) +{ + return sizeof(struct Presentation) + presentation->data_size; +} + + +/** + * Serialize an presentation + * + * @param attr the presentation to serialize + * @param result the serialized presentation + * @return length of serialized data + */ +size_t +GNUNET_RECLAIM_presentation_serialize ( + const struct GNUNET_RECLAIM_Presentation *presentation, + char *result) +{ + struct Presentation *atts; + char *write_ptr; + + atts = (struct Presentation *) result; + atts->presentation_type = htons (presentation->type); + atts->credential_id = presentation->credential_id; + write_ptr = (char *) &atts[1]; + GNUNET_memcpy (write_ptr, presentation->data, presentation->data_size); + atts->data_size = htons (presentation->data_size); + + return sizeof(struct Presentation) + presentation->data_size; +} + + +/** + * Deserialize an presentation + * + * @param data the serialized presentation + * @param data_size the length of the serialized data + * + * @return a GNUNET_IDENTITY_PROVIDER_Attribute, must be free'd by caller + */ +struct GNUNET_RECLAIM_Presentation * +GNUNET_RECLAIM_presentation_deserialize (const char *data, size_t data_size) +{ + struct GNUNET_RECLAIM_Presentation *presentation; + struct Presentation *atts; + size_t data_len; + char *write_ptr; + + if (data_size < sizeof(struct Presentation)) + return NULL; + + atts = (struct Presentation *) data; + data_len = ntohs (atts->data_size); + if (data_size < sizeof(struct Presentation) + data_len) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Buffer too small to deserialize\n"); + return NULL; + } + presentation = GNUNET_malloc (sizeof(struct GNUNET_RECLAIM_Presentation) + + data_len); + presentation->type = ntohs (atts->presentation_type); + presentation->credential_id = atts->credential_id; + presentation->data_size = data_len; + + write_ptr = (char *) &presentation[1]; + GNUNET_memcpy (write_ptr, &atts[1], data_len); + presentation->data = write_ptr; + return presentation; +} + + +struct GNUNET_RECLAIM_AttributeList* +GNUNET_RECLAIM_presentation_get_attributes (const struct + GNUNET_RECLAIM_Presentation * + presentation) +{ + unsigned int i; + struct Plugin *plugin; + struct GNUNET_RECLAIM_AttributeList *ret; + init (); + for (i = 0; i < num_plugins; i++) + { + plugin = credential_plugins[i]; + if (NULL != + (ret = plugin->api->get_attributes_p (plugin->api->cls, + presentation))) + return ret; + } + return NULL; +} + + +char* +GNUNET_RECLAIM_presentation_get_issuer (const struct + GNUNET_RECLAIM_Presentation * + presentation) +{ + unsigned int i; + struct Plugin *plugin; + char *ret; + init (); + for (i = 0; i < num_plugins; i++) + { + plugin = credential_plugins[i]; + if (NULL != + (ret = plugin->api->get_issuer_p (plugin->api->cls, + presentation))) + return ret; + } + return NULL; +} + + +int +GNUNET_RECLAIM_presentation_get_expiration (const struct + GNUNET_RECLAIM_Presentation * + presentation, + struct GNUNET_TIME_Absolute*exp) +{ + unsigned int i; + struct Plugin *plugin; + init (); + for (i = 0; i < num_plugins; i++) + { + plugin = credential_plugins[i]; + if (GNUNET_OK != plugin->api->get_expiration_p (plugin->api->cls, + presentation, + exp)) + continue; + return GNUNET_OK; + } + return GNUNET_SYSERR; +} + +/** + * Create a presentation from a credential and a lift of (selected) + * attributes in the credential. + * FIXME not yet implemented + * + * @param cred the credential to use + * @param attrs the attributes to present from the credential + * @return the credential presentation presenting the attributes according + * to the presentation mechanism of the credential + * or NULL on error. + */ +int +GNUNET_RECLAIM_credential_get_presentation ( + const struct GNUNET_RECLAIM_Credential *cred, + const struct GNUNET_RECLAIM_AttributeList *attrs, + struct GNUNET_RECLAIM_Presentation **pres) +{ + unsigned int i; + struct Plugin *plugin; + init (); + for (i = 0; i < num_plugins; i++) + { + plugin = credential_plugins[i]; + if (GNUNET_OK != plugin->api->create_presentation (plugin->api->cls, + cred, + attrs, + pres)) + continue; + (*pres)->credential_id = cred->id; + return GNUNET_OK; + } + return GNUNET_SYSERR; +} + + + diff --git a/src/reclaim/reclaim_credential.h b/src/reclaim/reclaim_credential.h index cd3a9539a..7704ed968 100644 --- a/src/reclaim/reclaim_credential.h +++ b/src/reclaim/reclaim_credential.h @@ -61,4 +61,39 @@ struct Credential // followed by data_size Credential value data }; + +/** + * Serialized presentation claim + */ +struct Presentation +{ + /** + * Presentation type + */ + uint32_t presentation_type; + + /** + * Presentation flag + */ + uint32_t presentation_flag; + + /** + * Credential ID + */ + struct GNUNET_RECLAIM_Identifier credential_id; + + /** + * Name length + */ + uint32_t name_len; + + /** + * Data size + */ + uint32_t data_size; + + // followed by data_size Presentation value data +}; + + #endif -- cgit v1.2.3