* QueueEntry
*/
struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
+
+ /**
+ * The label the token is stored under
+ */
+ char *label;
};
/**
char *token_metadata;
char *write_ptr;
char *enc_token_str;
- char *val_str;
const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key;
struct GNUNET_CRYPTO_EcdsaPublicKey pub_key;
struct GNUNET_CRYPTO_EcdhePrivateKey *new_ecdhe_privkey;
{
if (0 == strcmp (attr->name, "exp"))
{
- GNUNET_asprintf (&val_str, "%ul", new_exp.abs_value_us);
- token_add_attr (new_token, attr->name, val_str);
- GNUNET_free (val_str);
+ token_add_attr_int (new_token, attr->name, new_exp.abs_value_us);
}
else if (0 == strcmp (attr->name, "nbf"))
{
- GNUNET_asprintf (&val_str, "%ul", new_nbf.abs_value_us);
- token_add_attr (new_token, attr->name, val_str);
- GNUNET_free (val_str);
+ token_add_attr_int (new_token, attr->name, new_nbf.abs_value_us);
}
else if (0 == strcmp (attr->name, "iat"))
{
- GNUNET_asprintf (&val_str, "%ul", new_iat.abs_value_us);
- token_add_attr (new_token, attr->name, val_str);
- GNUNET_free (val_str);
+ token_add_attr_int (new_token, attr->name, new_iat.abs_value_us);
}
else if ((0 == strcmp (attr->name, "iss"))
|| (0 == strcmp (attr->name, "aud")))
return GNUNET_YES;
}
-
/**
*
* Update all ID_TOKEN records for an identity and store them
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;
}
if (NULL != handle->scopes)
GNUNET_free (handle->scopes);
if (NULL != handle->token)
- token_destroy (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);
}
{
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)
{
}
if (GNUNET_OK != ticket_serialize (handle->ticket,
&handle->iss_key,
- &token_ticket_str))
+ &ticket_str))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n",
"Error serializing ticket\n");
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_SERVER_client_set_user_context (handle->client, NULL);
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];
- char *lbl_str;
char *nonce_str;
char *enc_token_str;
char *token_metadata;
char* write_ptr;
- char* attr_val;
uint64_t time;
uint64_t exp_time;
- uint64_t rnd_key;
size_t token_metadata_len;
//Remote nonce
GNUNET_asprintf (&nonce_str, "%d", 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,
&pub_key,
- lbl_str,
+ handle->label,
&handle->aud_key);
time = GNUNET_TIME_absolute_get().abs_value_us;
exp_time = time + token_expiration_interval.rel_value_us;
- GNUNET_asprintf (&attr_val, "%ul", time);
- token_add_attr (handle->token, "nbf", attr_val);
- token_add_attr (handle->token, "iat", attr_val);
- GNUNET_free (attr_val);
- GNUNET_asprintf (&attr_val, "%ul", exp_time);
- token_add_attr (handle->token, "exp", attr_val);
- GNUNET_free (attr_val);
+ 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
//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,
handle);
GNUNET_free (ecdhe_privkey);
- GNUNET_free (lbl_str);
GNUNET_free (nonce_str);
GNUNET_free (enc_token_str);
GNUNET_free (token_metadata);
}
+
+
/**
*
* Handler for exchange message
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
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);
}