summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Schanzenbach <mschanzenbach@posteo.de>2020-08-19 23:53:02 +0200
committerMartin Schanzenbach <mschanzenbach@posteo.de>2020-08-20 17:59:02 +0200
commita57d476abbe857365aff157f389cc1188b5dd090 (patch)
treee8f7163ef7e6f5426748fed8d2eaa5183038a5d6
parente75869506cc08e08056168383bd4ab02e1f007de (diff)
reclaim: Attestations now called credentials. Credentials are presented to third parties as presentations.
-rw-r--r--src/include/gnunet_gnsrecord_lib.h7
-rw-r--r--src/include/gnunet_reclaim_lib.h13
-rw-r--r--src/include/gnunet_reclaim_plugin.h10
-rw-r--r--src/include/gnunet_reclaim_service.h18
-rw-r--r--src/reclaim/gnunet-reclaim.c5
-rw-r--r--src/reclaim/gnunet-service-reclaim.c33
-rw-r--r--src/reclaim/gnunet-service-reclaim_tickets.c197
-rw-r--r--src/reclaim/gnunet-service-reclaim_tickets.h7
-rw-r--r--src/reclaim/json_reclaim.c12
-rw-r--r--src/reclaim/json_reclaim.h2
-rw-r--r--src/reclaim/oidc_helper.c22
-rw-r--r--src/reclaim/oidc_helper.h16
-rw-r--r--src/reclaim/plugin_gnsrecord_reclaim.c12
-rw-r--r--src/reclaim/plugin_reclaim_credential_jwt.c159
-rw-r--r--src/reclaim/plugin_rest_openid_connect.c68
-rw-r--r--src/reclaim/plugin_rest_reclaim.c6
-rw-r--r--src/reclaim/reclaim.h7
-rw-r--r--src/reclaim/reclaim_api.c58
-rw-r--r--src/reclaim/reclaim_credential.c501
-rw-r--r--src/reclaim/reclaim_credential.h35
20 files changed, 1010 insertions, 178 deletions
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
@@ -173,6 +173,11 @@ struct TicketIssueHandle
struct GNUNET_RECLAIM_AttributeList *attrs;
/**
+ * Presentations to add
+ */
+ struct GNUNET_RECLAIM_PresentationList *presentations;
+
+ /**
* Issuer Key
*/
struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
@@ -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;
@@ -203,6 +200,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
*
* @param cls the plugin
@@ -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),
@@ -241,6 +266,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
*
* @param cls the plugin
@@ -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),
@@ -279,6 +336,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.
*
* @param cls NULL
@@ -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
@@ -463,9 +463,16 @@ 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
@@ -92,6 +92,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.
*/
struct GNUNET_MQ_Envelope *env;
@@ -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