#include "gnunet_gnsrecord_lib.h"
#include "gnunet_identity_service.h"
#include "gnunet_namestore_service.h"
-#include "gnunet_reclaim_attribute_lib.h"
+#include "gnunet_reclaim_lib.h"
#include "gnunet_reclaim_service.h"
#include "gnunet_rest_lib.h"
#include "gnunet_rest_plugin.h"
*/
#define OIDC_NONCE_KEY "nonce"
+/**
+ * OIDC claims key
+ */
+#define OIDC_CLAIMS_KEY "claims"
+
/**
* OIDC PKCE code challenge
*/
*/
char *nonce;
+ /**
+ * The OIDC claims
+ */
+ char *claims;
+
/**
* The OIDC response type
*/
/**
* Attribute claim list
*/
- struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attr_list;
+ struct GNUNET_RECLAIM_AttributeList *attr_list;
+
+ /**
+ * Attestation list
+ */
+ struct GNUNET_RECLAIM_AttestationList *attests_list;
+
/**
* IDENTITY Operation
*/
struct GNUNET_RECLAIM_AttributeIterator *attr_it;
+ /**
+ * Attestation iterator
+ */
+ struct GNUNET_RECLAIM_AttestationIterator *attest_it;
+
+
/**
* Ticket iterator
*/
static void
cleanup_handle (struct RequestHandle *handle)
{
- struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *claim_entry;
- struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *claim_tmp;
struct EgoEntry *ego_entry;
struct EgoEntry *ego_tmp;
GNUNET_IDENTITY_disconnect (handle->identity_handle);
if (NULL != handle->attr_it)
GNUNET_RECLAIM_get_attributes_stop (handle->attr_it);
+ if (NULL != handle->attest_it)
+ GNUNET_RECLAIM_get_attestations_stop (handle->attest_it);
if (NULL != handle->ticket_it)
GNUNET_RECLAIM_ticket_iteration_stop (handle->ticket_it);
if (NULL != handle->idp)
json_decref (handle->oidc->response);
GNUNET_free (handle->oidc);
}
- if (NULL != handle->attr_list)
- {
- for (claim_entry = handle->attr_list->list_head; NULL != claim_entry;)
- {
- claim_tmp = claim_entry;
- claim_entry = claim_entry->next;
- GNUNET_free (claim_tmp->claim);
- GNUNET_free (claim_tmp);
- }
- GNUNET_free (handle->attr_list);
- }
+ GNUNET_RECLAIM_attribute_list_destroy (handle->attr_list);
+ GNUNET_RECLAIM_attestation_list_destroy (handle->attests_list);
+
for (ego_entry = handle->ego_head; NULL != ego_entry;)
{
ego_tmp = ego_entry;
struct MHD_Response *resp;
result_str = json_dumps (handle->oidc->response, 0);
-
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,"ID-Token: %s\n",result_str);
resp = GNUNET_REST_create_response (result_str);
handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
GNUNET_free (result_str);
&login_base_url))
{
GNUNET_asprintf (&new_redirect,
- "%s?%s=%s&%s=%s&%s=%s&%s=%s&%s=%s&%s=%s&%s=%s",
+ "%s?%s=%s&%s=%s&%s=%s&%s=%s&%s=%s&%s=%s&%s=%s&%s=%s",
login_base_url,
OIDC_RESPONSE_TYPE_KEY,
handle->oidc->response_type,
(NULL != handle->oidc->code_challenge) ?
handle->oidc->code_challenge : "",
OIDC_NONCE_KEY,
- (NULL != handle->oidc->nonce) ? handle->oidc->nonce : "");
+ (NULL != handle->oidc->nonce) ? handle->oidc->nonce : "",
+ OIDC_CLAIMS_KEY,
+ (NULL != handle->oidc->claims) ? handle->oidc->claims :
+ "");
resp = GNUNET_REST_create_response ("");
MHD_add_response_header (resp, "Location", new_redirect);
GNUNET_free (login_base_url);
code_string = OIDC_build_authz_code (&handle->priv_key,
&handle->ticket,
handle->attr_list,
+ handle->attests_list,
handle->oidc->nonce,
handle->oidc->code_challenge);
if ((NULL != handle->redirect_prefix) && (NULL != handle->redirect_suffix) &&
static void
-oidc_collect_finished_cb (void *cls)
+oidc_attest_collect_finished_cb (void *cls)
+{
+ struct RequestHandle *handle = cls;
+
+ handle->attest_it = NULL;
+ handle->idp_op = GNUNET_RECLAIM_ticket_issue (handle->idp,
+ &handle->priv_key,
+ &handle->oidc->client_pkey,
+ handle->attr_list,
+ &oidc_ticket_issue_cb,
+ handle);
+}
+
+
+/**
+ * Collects all attributes for an ego if in scope parameter
+ */
+static void
+oidc_attest_collect (void *cls,
+ const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
+ const struct GNUNET_RECLAIM_Attestation *attest)
+{
+ struct RequestHandle *handle = cls;
+ struct GNUNET_RECLAIM_AttributeListEntry *le;
+
+ for (le = handle->attr_list->list_head; NULL != le; le = le->next)
+ {
+ if (GNUNET_NO == GNUNET_RECLAIM_id_is_equal (&le->attribute->attestation,
+ &attest->id))
+ {
+ struct GNUNET_RECLAIM_AttestationListEntry *ale;
+ ale = GNUNET_new (struct GNUNET_RECLAIM_AttestationListEntry);
+ ale->attestation = GNUNET_RECLAIM_attestation_new (attest->name,
+ attest->type,
+ attest->data,
+ attest->data_size);
+ GNUNET_CONTAINER_DLL_insert (handle->attests_list->list_head,
+ handle->attests_list->list_tail,
+ ale);
+ }
+ }
+ GNUNET_RECLAIM_get_attestations_next (handle->attest_it);
+}
+
+
+static void
+oidc_attr_collect_finished_cb (void *cls)
{
struct RequestHandle *handle = cls;
GNUNET_SCHEDULER_add_now (&do_redirect_error, handle);
return;
}
+ handle->attests_list = GNUNET_new (struct GNUNET_RECLAIM_AttestationList);
+ handle->attest_it =
+ GNUNET_RECLAIM_get_attestations_start (handle->idp,
+ &handle->priv_key,
+ &oidc_iteration_error,
+ handle,
+ &oidc_attest_collect,
+ handle,
+ &oidc_attest_collect_finished_cb,
+ handle);
+
handle->idp_op = GNUNET_RECLAIM_ticket_issue (handle->idp,
&handle->priv_key,
&handle->oidc->client_pkey,
/**
- * Collects all attributes/references for an ego if in scope parameter
+ * Collects all attributes for an ego if in scope parameter
*/
static void
oidc_attr_collect (void *cls,
const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
- const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr,
- const struct GNUNET_RECLAIM_ATTESTATION_Claim *attest,
- const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *reference)
+ const struct GNUNET_RECLAIM_Attribute *attr)
{
struct RequestHandle *handle = cls;
- struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le;
+ struct GNUNET_RECLAIM_AttributeListEntry *le;
char *scope_variables;
char *scope_variable;
char delimiter[] = " ";
- if ((NULL == attr) && (NULL == reference))
+ scope_variables = GNUNET_strdup (handle->oidc->scope);
+ scope_variable = strtok (scope_variables, delimiter);
+ while (NULL != scope_variable)
{
- GNUNET_RECLAIM_get_attributes_next (handle->attr_it);
- return;
- }
- if (NULL == attr)
- {
- if ((NULL == reference->name) || (NULL == reference->reference_value))
- {
- return;
- }
- scope_variables = GNUNET_strdup (handle->oidc->scope);
- scope_variable = strtok (scope_variables, delimiter);
- while (NULL != scope_variable)
- {
- if (0 == strcmp (reference->name, scope_variable))
- break;
- scope_variable = strtok (NULL, delimiter);
- }
- if (NULL == scope_variable)
- {
- GNUNET_free (scope_variables);
- return;
- }
- GNUNET_free (scope_variables);
- // Store references as attributes as they only use the ID later
- const char *type_str = NULL;
- char *data;
- size_t data_size;
- uint32_t type;
- le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry);
- type_str = "String";
- type = GNUNET_RECLAIM_ATTRIBUTE_typename_to_number (type_str);
- if (GNUNET_SYSERR ==(GNUNET_RECLAIM_ATTRIBUTE_string_to_value (type,
- reference->
- reference_value,
- (void **) &
- data,
- &data_size)))
- {
- return;
- }
- le->claim = GNUNET_RECLAIM_ATTRIBUTE_claim_new (reference->name,
- type,
- data,
- data_size);
- le->claim->id = reference->id;
- le->claim->flag = 1;
-
- GNUNET_CONTAINER_DLL_insert (handle->attr_list->list_head,
- handle->attr_list->list_tail,
- le);
+ if (0 == strcmp (attr->name, scope_variable))
+ break;
+ scope_variable = strtok (NULL, delimiter);
}
- else
+ if (NULL == scope_variable)
{
- if ((NULL == attr->name) || (NULL == attr->data))
- {
- GNUNET_RECLAIM_get_attributes_next (handle->attr_it);
- return;
- }
- scope_variables = GNUNET_strdup (handle->oidc->scope);
- scope_variable = strtok (scope_variables, delimiter);
- while (NULL != scope_variable)
- {
- if (0 == strcmp (attr->name, scope_variable))
- break;
- scope_variable = strtok (NULL, delimiter);
- }
- if (NULL == scope_variable)
- {
- GNUNET_RECLAIM_get_attributes_next (handle->attr_it);
- GNUNET_free (scope_variables);
- return;
- }
- GNUNET_free (scope_variables);
-
- le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry);
- le->claim = GNUNET_RECLAIM_ATTRIBUTE_claim_new (attr->name,
- attr->type,
- attr->data,
- attr->data_size);
- le->claim->id = attr->id;
- le->claim->flag = attr->flag;
-
- GNUNET_CONTAINER_DLL_insert (handle->attr_list->list_head,
- handle->attr_list->list_tail,
- le);
GNUNET_RECLAIM_get_attributes_next (handle->attr_it);
+ GNUNET_free (scope_variables);
+ // We can ignore this
+ return;
}
+ GNUNET_free (scope_variables);
+ le = GNUNET_new (struct GNUNET_RECLAIM_AttributeListEntry);
+ le->attribute = GNUNET_RECLAIM_attribute_new (attr->name,
+ &attr->attestation,
+ attr->type,
+ attr->data,
+ attr->data_size);
+ le->attribute->id = attr->id;
+ le->attribute->flag = attr->flag;
+ le->attribute->attestation = attr->attestation;
+ GNUNET_CONTAINER_DLL_insert (handle->attr_list->list_head,
+ handle->attr_list->list_tail,
+ le);
+ GNUNET_RECLAIM_get_attributes_next (handle->attr_it);
}
*GNUNET_IDENTITY_ego_get_private_key (handle->ego_entry->ego);
handle->idp = GNUNET_RECLAIM_connect (cfg);
handle->attr_list =
- GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList);
+ GNUNET_new (struct GNUNET_RECLAIM_AttributeList);
handle->attr_it =
GNUNET_RECLAIM_get_attributes_start (handle->idp,
&handle->priv_key,
handle,
&oidc_attr_collect,
handle,
- &oidc_collect_finished_cb,
+ &oidc_attr_collect_finished_cb,
handle);
return;
}
// OPTIONAL value: nonce
handle->oidc->nonce = get_url_parameter_copy (handle, OIDC_NONCE_KEY);
+ // OPTIONAL value: claims
+ handle->oidc->claims = get_url_parameter_copy (handle, OIDC_CLAIMS_KEY);
+
// TODO check other values if needed
number_of_ignored_parameter =
sizeof(OIDC_ignored_parameter_array) / sizeof(char *);
struct RequestHandle *handle = cls;
const struct EgoEntry *ego_entry;
struct GNUNET_TIME_Relative expiration_time;
- struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *cl;
+ struct GNUNET_RECLAIM_AttributeList *cl;
+ struct GNUNET_RECLAIM_AttestationList *al;
struct GNUNET_RECLAIM_Ticket ticket;
struct GNUNET_CRYPTO_EcdsaPublicKey cid;
const struct GNUNET_CRYPTO_EcdsaPrivateKey *privkey;
// decode code
if (GNUNET_OK != OIDC_parse_authz_code (privkey, code, code_verifier, &ticket,
- &cl, &nonce))
+ &cl, &al, &nonce))
{
handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_REQUEST);
handle->edesc = GNUNET_strdup ("invalid code");
id_token = OIDC_id_token_new (&ticket.audience,
&ticket.identity,
cl,
+ al,
&expiration_time,
(NULL != nonce) ? nonce : NULL,
jwt_secret);
MHD_add_response_header (resp, "Pragma", "no-cache");
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_attribute_list_destroy (cl);
+ GNUNET_RECLAIM_attestation_list_destroy (al);
GNUNET_free (access_token);
GNUNET_free (json_response);
GNUNET_free (id_token);
static void
consume_ticket (void *cls,
const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
- const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr,
- const struct GNUNET_RECLAIM_ATTESTATION_Claim *attest,
- const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *reference)
+ const struct GNUNET_RECLAIM_Attribute *attr,
+ const struct GNUNET_RECLAIM_Attestation *attest)
{
struct RequestHandle *handle = cls;
- char *tmp_value;
- json_t *value;
-
if (NULL == identity)
{
GNUNET_SCHEDULER_add_now (&return_userinfo_response, handle);
return;
}
- tmp_value = GNUNET_RECLAIM_ATTRIBUTE_value_to_string (attr->type,
- attr->data,
- attr->data_size);
- value = json_string (tmp_value);
- json_object_set_new (handle->oidc->response, attr->name, value);
- GNUNET_free (tmp_value);
+ if (GNUNET_YES == GNUNET_RECLAIM_id_is_zero (&attr->attestation))
+ {
+ char *tmp_value;
+ json_t *value;
+ tmp_value = GNUNET_RECLAIM_attribute_value_to_string (attr->type,
+ attr->data,
+ attr->data_size);
+ value = json_string (tmp_value);
+ json_object_set_new (handle->oidc->response, attr->name, value);
+ GNUNET_free (tmp_value);
+ return;
+ }
+ json_t *claim_sources;
+ json_t *claim_sources_jwt;
+ json_t *claim_names;
+ char *attest_val_str;
+ claim_sources = json_object_get (handle->oidc->response,"_claim_sources");
+ claim_names = json_object_get (handle->oidc->response,"_claim_names");
+ attest_val_str =
+ GNUNET_RECLAIM_attestation_value_to_string (attest->type,
+ attest->data,
+ attest->data_size);
+ if ((NULL == claim_sources) && (NULL == claim_names) )
+ {
+ claim_sources = json_object ();
+ claim_names = json_object ();
+ }
+ char *source_name;
+ int i = 0;
+ GNUNET_asprintf (&source_name, "src%d", i);
+ while (NULL != (claim_sources_jwt = json_object_get (claim_sources,
+ source_name)))
+ {
+ if (0 == strcmp (json_string_value (json_object_get (claim_sources_jwt,
+ "JWT")),
+ attest_val_str))
+ {
+ // Adapt only the claim names
+ json_object_set_new (claim_names, attr->data,
+ json_string (source_name));
+ json_object_set (handle->oidc->response,
+ "_claim_names", claim_names);
+ break;
+ }
+ i++;
+ GNUNET_free (source_name);
+ GNUNET_asprintf (&source_name, "src%d", i);
+ }
+
+ // Create new one
+ if (NULL == claim_sources_jwt)
+ {
+ claim_sources_jwt = json_object ();
+ // Set the JWT for names
+ json_object_set_new (claim_names, attr->data,
+ json_string (source_name));
+ // Set the JWT for the inner source
+ json_object_set_new (claim_sources_jwt, "JWT",
+ json_string (attest_val_str));
+ // Set the JWT for the source
+ json_object_set_new (claim_sources, source_name, claim_sources_jwt);
+ // Set as claims
+ json_object_set (handle->oidc->response, "_claim_names", claim_names);
+ json_object_set (handle->oidc->response, "_claim_sources",claim_sources);
+ }
+
+ json_decref (claim_sources);
+ json_decref (claim_names);
+ json_decref (claim_sources_jwt);
+ GNUNET_free (attest_val_str);
}