/*
This file is part of GNUnet.
- Copyright (C) 2012-2015 Christian Grothoff (and other contributing authors)
+ Copyright (C) 2012-2015 GNUnet e.V.
GNUnet is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published
*/
/**
* @author Martin Schanzenbach
- * @file src/identity/gnunet-service-identity-provider.c
+ * @file src/identity-provider/gnunet-service-identity-provider.c
* @brief Identity Token Service
*
*/
#include "gnunet_namestore_service.h"
#include "gnunet_statistics_service.h"
#include "gnunet_gns_service.h"
-#include <jansson.h>
#include "gnunet_signatures.h"
#include "identity_provider.h"
#include "identity_token.h"
+#include <inttypes.h>
/**
* First pass state
*/
#define MIN_WAIT_TIME GNUNET_TIME_UNIT_MINUTES
+/**
+ * Standard token expiration time
+ */
+#define DEFAULT_TOKEN_EXPIRATION_INTERVAL GNUNET_TIME_UNIT_HOURS
+
/**
* Service state (to detect initial update pass)
*/
*/
static struct GNUNET_IDENTITY_Handle *identity_handle;
+/**
+ * Token expiration interval
+ */
+static struct GNUNET_TIME_Relative token_expiration_interval;
+
/**
* Namestore handle
*/
*/
static struct GNUNET_SERVER_NotificationContext *nc;
+/**
+ * Our configuration.
+ */
+static const struct GNUNET_CONFIGURATION_Handle *cfg;
+
+
struct ExchangeHandle
{
* QueueEntry
*/
struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
+
+ /**
+ * The label the token is stored under
+ */
+ char *label;
};
/**
};
/**
- * Our configuration.
+ * Continuation for token store call
+ *
+ * @param cls NULL
+ * @param success error code
+ * @param emsg error message
*/
- static const struct GNUNET_CONFIGURATION_Handle *cfg;
-
-
- /**
- * Continuation for token store call
- *
- * @param cls NULL
- * @param success error code
- * @param emsg error message
- */
static void
store_token_cont (void *cls,
int32_t success,
char *token_metadata;
char *write_ptr;
char *enc_token_str;
- const char *key;
const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key;
struct GNUNET_CRYPTO_EcdsaPublicKey pub_key;
struct GNUNET_CRYPTO_EcdhePrivateKey *new_ecdhe_privkey;
struct GNUNET_TIME_Absolute new_iat;
struct GNUNET_TIME_Absolute new_nbf;
struct IdentityToken *new_token;
- json_t *payload_json;
- json_t *value;
- json_t *cur_value;
- json_t *token_nbf_json;
- json_t *token_exp_json;
+ struct TokenAttr *cur_value;
+ struct TokenAttr *attr;
size_t token_metadata_len;
priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
//but this service will reissue new tokens that can be retrieved from GNS
//automatically.
- payload_json = token->payload;
-
- token_exp_json = json_object_get (payload_json, "exp");
- token_nbf_json = json_object_get (payload_json, "nbf");
- token_exp.abs_value_us = json_integer_value(token_exp_json);
- token_nbf.abs_value_us = json_integer_value(token_nbf_json);
+ for (attr = token->attr_head; NULL != attr; attr = attr->next)
+ {
+ if (0 == strcmp (attr->name, "exp"))
+ {
+ sscanf (attr->val_head->value,
+ "%"SCNu64,
+ &token_exp.abs_value_us);
+ } else if (0 == strcmp (attr->name, "nbf")) {
+ sscanf (attr->val_head->value,
+ "%"SCNu64,
+ &token_nbf.abs_value_us);
+ }
+ }
token_rel_exp = GNUNET_TIME_absolute_get_difference (token_nbf, token_exp);
token_ttl = GNUNET_TIME_absolute_get_remaining (token_exp);
{
min_rel_exp = token_ttl;
}
- json_decref (payload_json);
GNUNET_free (token);
token = NULL;
GNUNET_free (label);
new_exp = GNUNET_TIME_relative_to_absolute (token_rel_exp);
new_nbf = GNUNET_TIME_absolute_get ();
new_iat = new_nbf;
-
- json_object_foreach(payload_json, key, value) {
- if (0 == strcmp (key, "exp"))
+ for (attr = token->attr_head; NULL != attr; attr = attr->next)
+ {
+ if (0 == strcmp (attr->name, "exp"))
{
- token_add_json (new_token, key, json_integer (new_exp.abs_value_us));
+ token_add_attr_int (new_token, attr->name, new_exp.abs_value_us);
}
- else if (0 == strcmp (key, "nbf"))
+ else if (0 == strcmp (attr->name, "nbf"))
{
- token_add_json (new_token, key, json_integer (new_nbf.abs_value_us));
+ token_add_attr_int (new_token, attr->name, new_nbf.abs_value_us);
}
- else if (0 == strcmp (key, "iat"))
+ else if (0 == strcmp (attr->name, "iat"))
{
- token_add_json (new_token, key, json_integer (new_iat.abs_value_us));
+ token_add_attr_int (new_token, attr->name, new_iat.abs_value_us);
}
- else if ((0 == strcmp (key, "iss"))
- || (0 == strcmp (key, "aud")))
+ else if ((0 == strcmp (attr->name, "iss"))
+ || (0 == strcmp (attr->name, "aud")))
{
//Omit
}
- else if ((0 == strcmp (key, "sub"))
- || (0 == strcmp (key, "rnl")))
+ else if (0 == strcmp (attr->name, "sub"))
{
- token_add_json (new_token, key, value);
+ token_add_attr (new_token,
+ attr->name,
+ attr->val_head->value);
}
- else {
- GNUNET_CRYPTO_hash (key,
- strlen (key),
+ else
+ {
+ GNUNET_CRYPTO_hash (attr->name,
+ strlen (attr->name),
&key_hash);
//Check if attr still exists. omit of not
- if (GNUNET_NO != GNUNET_CONTAINER_multihashmap_contains (ego_entry->attr_map,
- &key_hash))
+ if (GNUNET_NO !=
+ GNUNET_CONTAINER_multihashmap_contains (ego_entry->attr_map,
+ &key_hash))
{
cur_value = GNUNET_CONTAINER_multihashmap_get (ego_entry->attr_map,
&key_hash);
- token_add_json (new_token, key, cur_value);
+ GNUNET_CONTAINER_DLL_insert (new_token->attr_head,
+ new_token->attr_tail,
+ cur_value);
}
}
}
&new_ecdhe_privkey,
&enc_token_str));
- json_decref (payload_json);
-
token_record[0].data = enc_token_str;
token_record[0].data_size = strlen (enc_token_str) + 1;
token_record[0].expiration_time = rd_exp; //Old expiration time
const struct GNUNET_HashCode *key,
void *value)
{
- json_t *attr_value = value;
-
- json_decref (attr_value);
+ struct TokenAttr *attr = value;
+ struct TokenAttrValue *val;
+ struct TokenAttrValue *tmp_val;
+ for (val = attr->val_head; NULL != val;)
+ {
+ tmp_val = val->next;
+ GNUNET_CONTAINER_DLL_remove (attr->val_head,
+ attr->val_tail,
+ val);
+ GNUNET_free (val->value);
+ GNUNET_free (val);
+ val = tmp_val;
+ }
+ GNUNET_free (attr->name);
+ GNUNET_free (attr);
return GNUNET_YES;
}
-
/**
*
* Update all ID_TOKEN records for an identity and store them
aud_key,
&token);
- //token = GNUNET_GNSRECORD_value_to_string (rd->record_type,
- // rd->data,
- // rd->data_size);
label = GNUNET_strdup (lbl);
rd_exp = token_record->expiration_time;
const struct GNUNET_GNSRECORD_Data *rd)
{
struct EgoEntry *ego_entry = cls;
- json_t *attr_value;
struct GNUNET_HashCode key;
- char* attr;
+ struct TokenAttr *attr;
+ struct TokenAttrValue *val;
+ char *val_str;
int i;
if (NULL == lbl)
{
if (rd->record_type == GNUNET_GNSRECORD_TYPE_ID_ATTR)
{
- attr = GNUNET_GNSRECORD_value_to_string (rd->record_type,
- rd->data,
- rd->data_size);
- attr_value = json_string (attr);
+ val_str = GNUNET_GNSRECORD_value_to_string (rd->record_type,
+ rd->data,
+ rd->data_size);
+ attr = GNUNET_malloc (sizeof (struct TokenAttr));
+ attr->name = GNUNET_strdup (lbl);
+ val = GNUNET_malloc (sizeof (struct TokenAttrValue));
+ val->value = val_str;
+ GNUNET_CONTAINER_DLL_insert (attr->val_head,
+ attr->val_tail,
+ val);
GNUNET_CONTAINER_multihashmap_put (ego_entry->attr_map,
&key,
- attr_value,
+ attr,
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
- GNUNET_free (attr);
}
GNUNET_NAMESTORE_zone_iterator_next (ns_it);
return;
}
- attr_value = json_array();
+ attr = GNUNET_malloc (sizeof (struct TokenAttr));
+ attr->name = GNUNET_strdup (lbl);
for (i = 0; i < rd_count; i++)
{
if (rd[i].record_type == GNUNET_GNSRECORD_TYPE_ID_ATTR)
{
- attr = GNUNET_GNSRECORD_value_to_string (rd[i].record_type,
- rd[i].data,
- rd[i].data_size);
- json_array_append_new (attr_value, json_string (attr));
- GNUNET_free (attr);
+ val_str = GNUNET_GNSRECORD_value_to_string (rd[i].record_type,
+ rd[i].data,
+ rd[i].data_size);
+ val = GNUNET_malloc (sizeof (struct TokenAttrValue));
+ val->value = val_str;
+ GNUNET_CONTAINER_DLL_insert (attr->val_head,
+ attr->val_tail,
+ val);
}
-
}
GNUNET_CONTAINER_multihashmap_put (ego_entry->attr_map,
&key,
- attr_value,
+ attr,
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
GNUNET_NAMESTORE_zone_iterator_next (ns_it);
return;
">>> Finished. Rescheduling in %d\n",
min_rel_exp.rel_value_us);
ns_it = NULL;
- //finished -> TODO reschedule
+ //finished -> reschedule
update_task = GNUNET_SCHEDULER_add_delayed (min_rel_exp,
&update_identities,
ego_head);
static struct GNUNET_IDENTITY_PROVIDER_ExchangeResultMessage*
create_exchange_result_message (const char* token,
- const char* label)
+ const char* label,
+ uint64_t ticket_nonce)
{
struct GNUNET_IDENTITY_PROVIDER_ExchangeResultMessage *erm;
uint16_t token_len = strlen (token) + 1;
erm->header.type = htons (GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_EXCHANGE_RESULT);
erm->header.size = htons (sizeof (struct GNUNET_IDENTITY_PROVIDER_ExchangeResultMessage)
+ token_len);
+ erm->ticket_nonce = htonl (ticket_nonce);
memcpy (&erm[1], token, token_len);
return erm;
}
static struct GNUNET_IDENTITY_PROVIDER_IssueResultMessage*
-create_issue_result_message (const char* ticket)
+create_issue_result_message (const char* label,
+ const char* ticket,
+ const char* token)
{
struct GNUNET_IDENTITY_PROVIDER_IssueResultMessage *irm;
+ char *tmp_str;
- irm = GNUNET_malloc (sizeof (struct GNUNET_IDENTITY_PROVIDER_IssueResultMessage) + strlen(ticket) + 1);
+ irm = GNUNET_malloc (sizeof (struct GNUNET_IDENTITY_PROVIDER_IssueResultMessage)
+ + strlen (label) + 1
+ + strlen (ticket) + 1
+ + strlen (token) + 1);
irm->header.type = htons (GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ISSUE_RESULT);
- irm->header.size = htons (sizeof (struct GNUNET_IDENTITY_PROVIDER_IssueResultMessage) + strlen (ticket) + 1);
- memcpy (&irm[1], ticket, strlen (ticket) + 1);
+ irm->header.size = htons (sizeof (struct GNUNET_IDENTITY_PROVIDER_IssueResultMessage)
+ + strlen (label) + 1
+ + strlen (ticket) + 1
+ + strlen (token) + 1);
+ GNUNET_asprintf (&tmp_str, "%s,%s,%s", label, ticket, token);
+ memcpy (&irm[1], tmp_str, strlen (tmp_str) + 1);
+ GNUNET_free (tmp_str);
return irm;
}
-void
+static void
+cleanup_issue_handle (struct IssueHandle *handle)
+{
+ if (NULL != handle->attr_map)
+ GNUNET_CONTAINER_multihashmap_destroy (handle->attr_map);
+ if (NULL != handle->scopes)
+ GNUNET_free (handle->scopes);
+ if (NULL != handle->token)
+ token_destroy (handle->token);
+ if (NULL != handle->ticket)
+ ticket_destroy (handle->ticket);
+ if (NULL != handle->label)
+ GNUNET_free (handle->label);
+ GNUNET_free (handle);
+}
+
+static void
store_token_issue_cont (void *cls,
int32_t success,
const char *emsg)
{
struct IssueHandle *handle = cls;
struct GNUNET_IDENTITY_PROVIDER_IssueResultMessage *irm;
- char* token_ticket_str;
+ char *ticket_str;
+ char *token_str;
handle->ns_qe = NULL;
if (GNUNET_SYSERR == success)
{
- //TODO err msg
+ cleanup_issue_handle (handle);
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n",
+ "Unknown Error\n");
+ GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
return;
}
if (GNUNET_OK != ticket_serialize (handle->ticket,
&handle->iss_key,
- &token_ticket_str))
+ &ticket_str))
{
- GNUNET_CONTAINER_multihashmap_destroy (handle->attr_map);
- ticket_destroy (handle->ticket);
- GNUNET_free (handle);
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n",
+ "Error serializing ticket\n");
+ cleanup_issue_handle (handle);
GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
return;
}
- irm = create_issue_result_message (token_ticket_str);
+ if (GNUNET_OK != token_to_string (handle->token,
+ &handle->iss_key,
+ &token_str))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n",
+ "Error serializing token\n");
+ GNUNET_free (ticket_str);
+ cleanup_issue_handle (handle);
+ GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
+ return;
+ }
+ irm = create_issue_result_message (handle->label, ticket_str, token_str);
GNUNET_SERVER_notification_context_unicast (nc,
handle->client,
&irm->header,
GNUNET_NO);
GNUNET_SERVER_client_set_user_context (handle->client, NULL);
- GNUNET_CONTAINER_multihashmap_destroy (handle->attr_map);
- GNUNET_free (handle->scopes);
- token_destroy (handle->token);
- ticket_destroy (handle->ticket);
- GNUNET_free (handle);
+ cleanup_issue_handle (handle);
GNUNET_free (irm);
- GNUNET_free (token_ticket_str);
+ GNUNET_free (ticket_str);
+ GNUNET_free (token_str);
}
/**
struct GNUNET_CRYPTO_EcdhePrivateKey *ecdhe_privkey;
struct IssueHandle *handle = cls;
struct GNUNET_GNSRECORD_Data token_record[2];
- struct GNUNET_TIME_Relative etime_rel;
- char *lbl_str;
char *nonce_str;
char *enc_token_str;
char *token_metadata;
char* write_ptr;
uint64_t time;
uint64_t exp_time;
- uint64_t rnd_key;
size_t token_metadata_len;
//Remote nonce
nonce_str = NULL;
- GNUNET_asprintf (&nonce_str, "%d", handle->nonce);
+ GNUNET_asprintf (&nonce_str, "%lu", handle->nonce);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Request nonce: %s\n", nonce_str);
- //Label
- rnd_key = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG,
- UINT64_MAX);
- GNUNET_STRINGS_base64_encode ((char*)&rnd_key,
- sizeof (uint64_t),
- &lbl_str);
GNUNET_CRYPTO_ecdsa_key_get_public (&handle->iss_key,
&pub_key);
-
- handle->ticket = ticket_create (nonce_str,
+ handle->ticket = ticket_create (handle->nonce,
&pub_key,
- lbl_str,
+ handle->label,
&handle->aud_key);
-
- if (GNUNET_OK !=
- GNUNET_STRINGS_fancy_time_to_relative ("1d", //TODO
- &etime_rel))
- {
- ticket_destroy (handle->ticket);
- GNUNET_free (handle);
- GNUNET_SCHEDULER_add_now (&do_shutdown, handle);
- return;
- }
time = GNUNET_TIME_absolute_get().abs_value_us;
- exp_time = time + etime_rel.rel_value_us;
+ exp_time = time + token_expiration_interval.rel_value_us;
- token_add_json (handle->token, "nbf", json_integer (time));
- token_add_json (handle->token, "iat", json_integer (time));
- token_add_json (handle->token, "exp", json_integer (exp_time));
+ token_add_attr_int (handle->token, "nbf", time);
+ token_add_attr_int (handle->token, "iat", time);
+ token_add_attr_int (handle->token, "exp", exp_time);
token_add_attr (handle->token, "nonce", nonce_str);
-
//Token in a serialized encrypted format
GNUNET_assert (token_serialize (handle->token,
&handle->iss_key,
write_ptr += sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey);
memcpy (write_ptr, handle->scopes, strlen (handle->scopes) + 1); //with 0-Terminator;
- GNUNET_free (ecdhe_privkey);
-
token_record[1].data = token_metadata;
token_record[1].data_size = token_metadata_len;
token_record[1].expiration_time = exp_time;
//Persist token
handle->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
&handle->iss_key,
- lbl_str,
+ handle->label,
2,
token_record,
- &store_token_issue_cont,
+ &store_token_issue_cont,
handle);
- GNUNET_free (lbl_str);
+ GNUNET_free (ecdhe_privkey);
GNUNET_free (nonce_str);
GNUNET_free (enc_token_str);
GNUNET_free (token_metadata);
{
int i;
char* data;
- json_t *attr_arr;
struct IssueHandle *handle = cls;
struct GNUNET_HashCode key;
rd->data,
rd->data_size);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding value: %s\n", data);
- token_add_json (handle->token,
+ token_add_attr (handle->token,
label,
- json_string (data));
+ data);
GNUNET_free (data);
}
GNUNET_NAMESTORE_zone_iterator_next (handle->ns_it);
}
i = 0;
- attr_arr = json_array();
for (; i < rd_count; i++)
{
if (rd->record_type == GNUNET_GNSRECORD_TYPE_ID_ATTR)
rd[i].data,
rd[i].data_size);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding value: %s\n", data);
- json_array_append_new (attr_arr, json_string (data));
+ token_add_attr (handle->token, label, data);
GNUNET_free (data);
}
}
- if (0 < json_array_size (attr_arr))
- {
- token_add_json (handle->token, label, attr_arr);
- }
- json_decref (attr_arr);
GNUNET_NAMESTORE_zone_iterator_next (handle->ns_it);
}
+static void
+cleanup_exchange_handle (struct ExchangeHandle *handle)
+{
+ if (NULL != handle->ticket)
+ ticket_destroy (handle->ticket);
+ if (NULL != handle->token)
+ token_destroy (handle->token);
+ GNUNET_free (handle);
+}
+
static void
process_lookup_result (void *cls, uint32_t rd_count,
const struct GNUNET_GNSRECORD_Data *rd)
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Number of tokens %d != 2.",
rd_count);
- GNUNET_free (handle->label);
- GNUNET_free (handle);
+ cleanup_exchange_handle (handle);
GNUNET_SCHEDULER_add_now (&do_shutdown, handle);
return;
}
&token_str));
erm = create_exchange_result_message (token_str,
- handle->label);
+ handle->label,
+ handle->ticket->payload->nonce);
GNUNET_SERVER_notification_context_unicast (nc,
handle->client,
&erm->header,
GNUNET_NO);
GNUNET_SERVER_client_set_user_context (handle->client, NULL);
- ticket_destroy (handle->ticket);
- token_destroy (handle->token);
+
+ cleanup_exchange_handle (handle);
GNUNET_free (record_str);
GNUNET_free (token_str);
- GNUNET_free (handle);
GNUNET_free (erm);
}
+
+
/**
*
* Handler for exchange message
ticket);
xchange_handle = GNUNET_malloc (sizeof (struct ExchangeHandle));
xchange_handle->aud_privkey = em->aud_privkey;
-
+
if (GNUNET_SYSERR == ticket_parse (ticket,
&xchange_handle->aud_privkey,
&xchange_handle->ticket))
GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
return;
}
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Looking for token under %s\n",
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Looking for token under %s\n",
xchange_handle->ticket->payload->label);
GNUNET_asprintf (&lookup_query,
"%s.gnu",
}
+
+/**
+ *
+ * Look for existing token
+ *
+ * @param cls the identity entry
+ * @param zone the identity
+ * @param lbl the name of the record
+ * @param rd_count number of records
+ * @param rd record data
+ *
+ */
+static void
+find_existing_token (void *cls,
+ const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
+ const char *lbl,
+ unsigned int rd_count,
+ const struct GNUNET_GNSRECORD_Data *rd)
+{
+ struct IssueHandle *handle = cls;
+ const struct GNUNET_GNSRECORD_Data *token_metadata_record;
+ struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key;
+ struct GNUNET_HashCode key;
+ int scope_count_token;
+ uint64_t rnd_key;
+ char *scope;
+ char *tmp_scopes;
+
+ if (NULL == lbl)
+ {
+ //Done
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ ">>> No existing token found\n");
+ //Label
+ rnd_key =
+ GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG,
+ UINT64_MAX);
+ GNUNET_STRINGS_base64_encode ((char*)&rnd_key,
+ sizeof (uint64_t),
+ &handle->label);
+ handle->ns_it = NULL;
+ handle->ns_it = GNUNET_NAMESTORE_zone_iteration_start (ns_handle,
+ &handle->iss_key,
+ &attr_collect,
+ handle);
+ return;
+ }
+
+ //There should be only a single record for a token under a label
+ if (2 != rd_count)
+ {
+ GNUNET_NAMESTORE_zone_iterator_next (handle->ns_it);
+ return;
+ }
+
+ if (rd[0].record_type == GNUNET_GNSRECORD_TYPE_ID_TOKEN_METADATA)
+ {
+ token_metadata_record = &rd[0];
+ } else {
+ token_metadata_record = &rd[1];
+ }
+ if (token_metadata_record->record_type != GNUNET_GNSRECORD_TYPE_ID_TOKEN_METADATA)
+ {
+ GNUNET_NAMESTORE_zone_iterator_next (handle->ns_it);
+ return;
+ }
+ ecdhe_privkey = *((struct GNUNET_CRYPTO_EcdhePrivateKey *)token_metadata_record->data);
+ aud_key =
+ (struct GNUNET_CRYPTO_EcdsaPublicKey *)(token_metadata_record->data+sizeof(struct GNUNET_CRYPTO_EcdhePrivateKey));
+ tmp_scopes = GNUNET_strdup ((char*) aud_key+sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
+
+ if (0 != memcmp (aud_key, &handle->aud_key,
+ sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)))
+ {
+ char *tmp2 = GNUNET_STRINGS_data_to_string_alloc (aud_key,
+ sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
+ //Audience does not match!
+ char *tmp = GNUNET_GNSRECORD_value_to_string (GNUNET_GNSRECORD_TYPE_ID_TOKEN_METADATA,
+ token_metadata_record->data,
+ token_metadata_record->data_size);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Token does not match audience %s vs %s. Moving on\n",
+ tmp2,
+ tmp);
+ GNUNET_free (tmp_scopes);
+ GNUNET_NAMESTORE_zone_iterator_next (handle->ns_it);
+ return;
+ }
+
+ scope = strtok (tmp_scopes, ",");
+ scope_count_token = 0;
+ while (NULL != scope)
+ {
+ GNUNET_CRYPTO_hash (scope,
+ strlen (scope),
+ &key);
+
+ if ((NULL != handle->attr_map) &&
+ (GNUNET_YES != GNUNET_CONTAINER_multihashmap_contains (handle->attr_map, &key)))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Issued token does not include `%s'. Moving on\n", scope);
+ GNUNET_free (tmp_scopes);
+ GNUNET_NAMESTORE_zone_iterator_next (handle->ns_it);
+ return;
+ }
+ scope_count_token++;
+ scope = strtok (NULL, ",");
+ }
+ GNUNET_free (tmp_scopes);
+ //All scopes in token are also in request. Now
+ //Check length
+ if (GNUNET_CONTAINER_multihashmap_size (handle->attr_map) == scope_count_token)
+ {
+ //We have an existing token
+ handle->label = GNUNET_strdup (lbl);
+ handle->ns_it = NULL;
+ handle->ns_it = GNUNET_NAMESTORE_zone_iteration_start (ns_handle,
+ &handle->iss_key,
+ &attr_collect,
+ handle);
+
+ return;
+ }
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Nuber of attributes in token do not match request\n");
+ //No luck
+ GNUNET_NAMESTORE_zone_iterator_next (handle->ns_it);
+}
+
+
/**
*
* Handler for issue message
const struct GNUNET_MessageHeader *message)
{
const struct GNUNET_IDENTITY_PROVIDER_IssueMessage *im;
- uint16_t size;
const char *scopes;
+
+ uint16_t size;
char *scopes_tmp;
char *scope;
struct GNUNET_HashCode key;
issue_handle->aud_key = im->aud_key;
issue_handle->iss_key = im->iss_key;
+ GNUNET_CRYPTO_ecdsa_key_get_public (&im->iss_key,
+ &issue_handle->iss_pkey);
issue_handle->expiration = GNUNET_TIME_absolute_ntoh (im->expiration);
- issue_handle->nonce = im->nonce;
+ issue_handle->nonce = ntohl (im->nonce);
GNUNET_SERVER_receive_done (client, GNUNET_OK);
GNUNET_SERVER_notification_context_add (nc, client);
GNUNET_SERVER_client_set_user_context (client, issue_handle);
issue_handle->client = client;
issue_handle->scopes = GNUNET_strdup (scopes);
- GNUNET_CRYPTO_ecdsa_key_get_public (&im->iss_key,
- &issue_handle->iss_pkey);
issue_handle->token = token_create (&issue_handle->iss_pkey,
- &im->aud_key);
+ &issue_handle->aud_key);
issue_handle->ns_it = GNUNET_NAMESTORE_zone_iteration_start (ns_handle,
&im->iss_key,
- &attr_collect,
+ &find_existing_token,
issue_handle);
-
-
}
/**
&list_ego,
NULL);
+ if (GNUNET_OK ==
+ GNUNET_CONFIGURATION_get_value_time (cfg,
+ "identity-provider",
+ "TOKEN_EXPIRATION_INTERVAL",
+ &token_expiration_interval))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Time window for zone iteration: %s\n",
+ GNUNET_STRINGS_relative_time_to_string (token_expiration_interval,
+ GNUNET_YES));
+ } else {
+ token_expiration_interval = DEFAULT_TOKEN_EXPIRATION_INTERVAL;
+ }
+
GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL,
&do_shutdown, NULL);
}