static void
zone_proc (void *cls,
           const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
           const char *label,
           unsigned int rd_count,
           const struct GNUNET_GNSRECORD_Data *rd)
{
  int failed = GNUNET_NO;
  if ((zone == NULL) && (label == NULL))
  {
    zi = NULL;
    res = 0;
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
    		"Received last result, iteration done after receing %u results\n",
    		returned_records);
    GNUNET_SCHEDULER_add_now (&end, NULL);
    return;
  }

  if (0 == memcmp (zone, privkey, sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey)))
  {
    failed = check_zone_1 (label, rd_count, rd);
    if (GNUNET_YES == failed)
      GNUNET_break (0);
  }
  else if (0 == memcmp (zone, privkey2, sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey)))
  {
    failed = check_zone_2 (label, rd_count, rd);
    if (GNUNET_YES == failed)
      GNUNET_break (0);
  }
  else
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                "Received invalid zone\n");
    failed = GNUNET_YES;
    GNUNET_break (0);
  }

  if (failed == GNUNET_NO)
  {
    returned_records ++;
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
    		"Telling namestore to send the next result\n");
    GNUNET_NAMESTORE_zone_iterator_next (zi);
  }
  else
  {
    GNUNET_break (0);
    res = 1;
    GNUNET_SCHEDULER_add_now (&end, NULL);
  }
}
/**
 * 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,
                  const char *emsg)
{
  ns_qe = NULL;
  if (GNUNET_SYSERR == success)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                "Failed to update token: %s\n",
                emsg);
    return;
  }
  GNUNET_NAMESTORE_zone_iterator_next (ns_it);
}
/**
 *
 * Update all ID_TOKEN records for an identity and store them
 *
 * @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
token_collect (void *cls,
               const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
               const char *lbl,
               unsigned int rd_count,
               const struct GNUNET_GNSRECORD_Data *rd)
{
  struct EgoEntry *ego_entry = cls;

  if (NULL == lbl)
  {
    //Done
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                ">>> Updating Ego finished\n");
    //Clear attribute map for ego
    GNUNET_CONTAINER_multihashmap_iterate (ego_entry->attr_map,
                                           &clear_ego_attrs,
                                           ego_entry);
    GNUNET_CONTAINER_multihashmap_clear (ego_entry->attr_map);
    GNUNET_SCHEDULER_add_now (&update_identities, ego_entry->next);
    return;
  }

  //There should be only a single record for a token under a label
  if ((1 != rd_count)
      || (rd->record_type != GNUNET_GNSRECORD_TYPE_ID_TOKEN)
      || (0 == (GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION & rd->flags)))
  {
    GNUNET_NAMESTORE_zone_iterator_next (ns_it);
    return;
  }
  token = GNUNET_GNSRECORD_value_to_string (rd->record_type,
                                            rd->data,
                                            rd->data_size);
  label = GNUNET_strdup (lbl); 

  GNUNET_SCHEDULER_add_now (&handle_token_update, ego_entry);
}
/**
 * Method called periodicattluy that triggers
 * iteration over root zone
 *
 * @param cls closure
 * @param tc task context
 */
static void
update_zone_dht_next(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
  zone_update_taskid = GNUNET_SCHEDULER_NO_TASK;
  GNUNET_NAMESTORE_zone_iterator_next(namestore_iter);
}
static void
zone_proc (void *cls,
					 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
					 const char *label,
					 unsigned int rd_count,
					 const struct GNUNET_GNSRECORD_Data *rd)
{
  int failed = GNUNET_NO;
  if ((zone == NULL) && (label == NULL))
  {
    GNUNET_break (2 == returned_records);
    if (2 == returned_records)
    {
      res = 0; /* Last iteraterator callback, we are done */
      zi = NULL;
    }
    else
      res = 1;

    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
    		"Received last result, iteration done after receing %u results\n",
    		returned_records );
    GNUNET_SCHEDULER_add_now (&end, NULL);
    return;
  }
  GNUNET_assert (NULL != zone);
  if (0 == memcmp (zone,
                   privkey,
                   sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey)))
  {
    if (0 == strcmp (label, s_name_1))
    {
      if (rd_count == 1)
      {
        if (GNUNET_YES != GNUNET_GNSRECORD_records_cmp (rd, s_rd_1))
        {
          failed = GNUNET_YES;
          GNUNET_break (0);
        }
      }
      else
      {
        failed = GNUNET_YES;
        GNUNET_break (0);
      }
    }
    else if (0 == strcmp (label, s_name_2))
    {
      if (rd_count == 1)
      {
        if (GNUNET_YES != GNUNET_GNSRECORD_records_cmp(rd, s_rd_2))
        {
          failed = GNUNET_YES;
          GNUNET_break (0);
        }
      }
      else
      {
        GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                    "Received invalid record count\n");
        failed = GNUNET_YES;
        GNUNET_break (0);
      }
    }
    else
    {
      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                  "Comparing result failed: got name `%s' for first zone\n",
                  label);
      failed = GNUNET_YES;
      GNUNET_break (0);
    }
  }
  else if (0 == memcmp (zone, privkey2, sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey)))
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                "Received data for not requested zone\n");
    failed = GNUNET_YES;
    GNUNET_break (0);
  }
  else
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                "Received invalid zone\n");
    failed = GNUNET_YES;
    GNUNET_break (0);
  }
  if (failed == GNUNET_NO)
  {
    returned_records ++;
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
    		"Telling namestore to send the next result\n");
    GNUNET_NAMESTORE_zone_iterator_next (zi);
  }
  else
  {
    GNUNET_break (0);
    GNUNET_SCHEDULER_add_now (&end, NULL);
  }
}
示例#6
0
/**
 * Process a record that was stored in the namestore.
 *
 * @param cls closure
 * @param zone_key private key of the zone
 * @param rname name that is being mapped (at most 255 characters long)
 * @param rd_len number of entries in @a rd array
 * @param rd array of records with data to store
 */
static void
display_record (void *cls,
		const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key,
		const char *rname,
		unsigned int rd_len,
		const struct GNUNET_GNSRECORD_Data *rd)
{
  const char *typestring;
  char *s;
  unsigned int i;
  const char *ets;
  struct GNUNET_TIME_Absolute at;
  struct GNUNET_TIME_Relative rt;

  if (NULL == rname)
  {
    list_it = NULL;
    test_finished ();
    return;
  }
  if ( (NULL != name) &&
       (0 != strcmp (name, rname)) )
  {
    GNUNET_NAMESTORE_zone_iterator_next (list_it);
    return;
  }
  FPRINTF (stdout,
	   "%s:\n",
	   rname);
  for (i=0;i<rd_len;i++)
  {
    if ( (GNUNET_GNSRECORD_TYPE_NICK == rd[i].record_type) &&
         (0 != strcmp (rname,
                       "+")) )
      continue;
    typestring = GNUNET_GNSRECORD_number_to_typename (rd[i].record_type);
    s = GNUNET_GNSRECORD_value_to_string (rd[i].record_type,
					  rd[i].data,
					  rd[i].data_size);
    if (NULL == s)
    {
      FPRINTF (stdout, _("\tCorrupt or unsupported record of type %u\n"),
	       (unsigned int) rd[i].record_type);
      continue;
    }
    if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION))
    {
      rt.rel_value_us = rd[i].expiration_time;
      ets = GNUNET_STRINGS_relative_time_to_string (rt, GNUNET_YES);
    }
    else
    {
      at.abs_value_us = rd[i].expiration_time;
      ets = GNUNET_STRINGS_absolute_time_to_string (at);
    }
    FPRINTF (stdout,
	     "\t%s: %s (%s)\t%s\t%s\n",
	     typestring,
	     s,
             ets,
             (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_PRIVATE)) ? "PRIVATE" : "PUBLIC",
             (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_SHADOW_RECORD)) ? "SHADOW" : "");
    GNUNET_free (s);
  }
  FPRINTF (stdout, "%s", "\n");
  GNUNET_NAMESTORE_zone_iterator_next (list_it);
}
static void
zone_proc (void *cls,
	   const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key,
	   struct GNUNET_TIME_Absolute expire,
	   const char *name,
	   unsigned int rd_count,
	   const struct GNUNET_NAMESTORE_RecordData *rd,
	   const struct GNUNET_CRYPTO_RsaSignature *signature)
{
  int failed = GNUNET_NO;

  if ((zone_key == NULL) &&  (name == NULL))
  {
    GNUNET_break (3 == returned_records);
    if (3 == returned_records)
      res = 0;
    else
      res = 1;

    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received last result, iteration done after receing %u results\n",returned_records );
    GNUNET_SCHEDULER_add_now (&end, NULL);
  }
  else
  {

    /* verify signature returned from name store */
    if (GNUNET_OK != GNUNET_NAMESTORE_verify_signature(zone_key, expire, name, rd_count, rd, signature))
    {
      failed = GNUNET_YES;
      GNUNET_break (0);
    }


    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Comparing results name %s \n", name);
    if (0 == strcmp (name, s_name_1))
    { /* name_1 */
      if (rd_count == 1)
      {
        if (GNUNET_YES != GNUNET_NAMESTORE_records_cmp(rd, s_rd_1))
        {
          failed = GNUNET_YES;
          GNUNET_break (0);
        }
      }
      else
      {
        failed = GNUNET_YES;
        GNUNET_break (0);
      }
      if (GNUNET_OK != GNUNET_NAMESTORE_verify_signature(&pubkey, expire, s_name_1, 1, s_rd_1, signature))
      {
        failed = GNUNET_YES;
        GNUNET_break (0);
      }
    }
    else if (0 == strcmp (name, s_name_2))
    { /* name_2 */
      if (rd_count == 1)
      {
        if (GNUNET_YES != GNUNET_NAMESTORE_records_cmp(rd, s_rd_2))
        {
          failed = GNUNET_YES;
          GNUNET_break (0);
        }
      }
      else
      {
        failed = GNUNET_YES;
        GNUNET_break (0);
      }

      if (GNUNET_OK != GNUNET_NAMESTORE_verify_signature(&pubkey, expire, s_name_2, 1, s_rd_2, signature))
      {
        failed = GNUNET_YES;
        GNUNET_break (0);
      }
    }
    else if (0 == strcmp (name, s_name_3))
    { /* name_3 */
      if (rd_count == 1)
      {
        if (GNUNET_YES != GNUNET_NAMESTORE_records_cmp(rd, s_rd_3))
        {
          failed = GNUNET_YES;
          GNUNET_break (0);
        }
      }
      else
      {
        failed = GNUNET_YES;
        GNUNET_break (0);
      }
      if (GNUNET_OK != GNUNET_NAMESTORE_verify_signature(&pubkey2, expire, s_name_3, 1, s_rd_3, signature))
      {
        failed = GNUNET_YES;
        GNUNET_break (0);
      }
    }
    else
    {
      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Comparing result failed: got name `%s'\n", name);
      res = 1;
      GNUNET_break (0);
      GNUNET_SCHEDULER_add_now (&end, NULL);
    }

    if (failed == GNUNET_NO)
    {
      returned_records ++;

      if (1 == returned_records)
      {
        GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stopping zone iteration after %u received record \n",returned_records );
        GNUNET_NAMESTORE_zone_iteration_stop (zi);
        if (endbadly_task != GNUNET_SCHEDULER_NO_TASK)
        {
          GNUNET_SCHEDULER_cancel (endbadly_task);
          endbadly_task = GNUNET_SCHEDULER_NO_TASK;
        }
        GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 3), &end , NULL);
        return;
      }
      else
      {
        GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Telling namestore to send the next result\n");
        GNUNET_NAMESTORE_zone_iterator_next (zi);
      }
    }
    else
    {
      GNUNET_break (0);
      GNUNET_SCHEDULER_add_now (&end, NULL);
    }
  }
}
示例#8
0
/**
 * Process a record that was stored in the namestore, adding
 * the information to the HTML.
 *
 * @param cls closure with the `struct ZoneinfoRequest *`
 * @param zone_key private key of the zone; NULL on disconnect
 * @param name label of the records; NULL on disconnect
 * @param rd_len number of entries in @a rd array, 0 if label was deleted
 * @param rd array of records with data to store
 */
static void
iterate_cb (void *cls,
	    const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key,
	    const char *name,
	    unsigned int rd_len,
	    const struct GNUNET_GNSRECORD_Data *rd)
{
  struct ZoneinfoRequest *zr = cls;
  struct MHD_Response *response;
  char* full_page;
  size_t bytes_free;
  char* pkey;
  char* new_buf;


  if (NULL == name)
  {
    zr->list_it = NULL;

    /* return static form */
    GNUNET_asprintf (&full_page,
                     ZONEINFO_PAGE,
                     zr->zoneinfo,
                     zr->zoneinfo);
    response = MHD_create_response_from_buffer (strlen (full_page),
					      (void *) full_page,
					      MHD_RESPMEM_MUST_FREE);
    MHD_add_response_header (response,
			   MHD_HTTP_HEADER_CONTENT_TYPE,
			   MIME_HTML);
    MHD_queue_response (zr->connection,
			    MHD_HTTP_OK,
			    response);
    MHD_destroy_response (response);
    GNUNET_free (zr->zoneinfo);
    GNUNET_free (zr);
    run_httpd_now ();
    return;
  }

  if (1 != rd_len)
  {
    GNUNET_NAMESTORE_zone_iterator_next (zr->list_it);
    return;
  }

  if (GNUNET_GNSRECORD_TYPE_PKEY != rd->record_type)
  {
    GNUNET_NAMESTORE_zone_iterator_next (zr->list_it);
    return;
  }

  bytes_free = zr->buf_len - zr->write_offset;
  pkey = GNUNET_GNSRECORD_value_to_string (rd->record_type,
                                           rd->data,
                                           rd->data_size);
  if (NULL == pkey)
  {
    GNUNET_break (0);
    GNUNET_NAMESTORE_zone_iterator_next (zr->list_it);
    return;
  }
  if (bytes_free < (strlen (name) + strlen (pkey) + 40))
  {
    new_buf = GNUNET_malloc (zr->buf_len * 2);
    memcpy (new_buf, zr->zoneinfo, zr->write_offset);
    GNUNET_free (zr->zoneinfo);
    zr->zoneinfo = new_buf;
    zr->buf_len *= 2;
  }
  sprintf (zr->zoneinfo + zr->write_offset,
	   "<tr><td>%s</td><td>%s</td></tr>",
	   name,
	   pkey);
  zr->write_offset = strlen (zr->zoneinfo);
  GNUNET_NAMESTORE_zone_iterator_next (zr->list_it);
  GNUNET_free (pkey);
}
/**
 *
 * Collect all ID_ATTR records for an identity and store them
 *
 * @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
attribute_collect (void *cls,
                   const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
                   const char *lbl,
                   unsigned int rd_count,
                   const struct GNUNET_GNSRECORD_Data *rd)
{
  struct EgoEntry *ego_entry = cls;
  json_t *attr_value;
  struct GNUNET_HashCode key;
  char* attr;
  int i;

  if (NULL == lbl)
  {
    //Done
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                ">>> Updating Attributes finished\n");
    ego_entry->attributes_dirty = GNUNET_NO;
    GNUNET_SCHEDULER_add_now (&update_identities, ego_entry);
    return;
  }

  if (0 == rd_count)
  {
    GNUNET_NAMESTORE_zone_iterator_next (ns_it);
    return;
  }
  GNUNET_CRYPTO_hash (lbl,
                      strlen (lbl),
                      &key);
  if (1 == rd_count)
  {
    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);
      GNUNET_CONTAINER_multihashmap_put (ego_entry->attr_map,
                                         &key,
                                         attr_value,
                                         GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
      GNUNET_free (attr);
    }

    GNUNET_NAMESTORE_zone_iterator_next (ns_it);
    return;
  }

  attr_value = json_array();
  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);
    }

  }
  GNUNET_CONTAINER_multihashmap_put (ego_entry->attr_map,
                                     &key,
                                     attr_value,
                                     GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
  GNUNET_NAMESTORE_zone_iterator_next (ns_it);
  return;
}
/**
 * This function updates the old token with new attributes,
 * removes deleted attributes and expiration times.
 *
 * @param cls the ego entry
 * @param tc task context
 */
static void
handle_token_update (void *cls,
                     const struct GNUNET_SCHEDULER_TaskContext *tc)
{
  char *token_header;
  char *token_payload;
  char *token_payload_json;
  char *new_token;
  char *new_payload_str;
  char *new_payload_base64;
  char *sig_str;
  char *key;
  char *padding;
  const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key;
  struct EgoEntry *ego_entry = cls;
  struct GNUNET_GNSRECORD_Data token_record;
  struct GNUNET_CRYPTO_EccSignaturePurpose *purpose;
  struct GNUNET_CRYPTO_EcdsaSignature sig;
  struct GNUNET_HashCode key_hash;
  struct GNUNET_TIME_Relative token_rel_exp;
  struct GNUNET_TIME_Relative token_ttl;
  struct GNUNET_TIME_Absolute token_exp;
  struct GNUNET_TIME_Absolute token_nbf;
  struct GNUNET_TIME_Absolute new_exp;
  struct GNUNET_TIME_Absolute new_iat;
  struct GNUNET_TIME_Absolute new_nbf;
  json_t *payload_json;
  json_t *value;
  json_t *cur_value;
  json_t *new_payload_json;
  json_t *token_nbf_json;
  json_t *token_exp_json;
  json_error_t json_err;

  priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);

  //Note: We need the token expiration time here. Not the record expiration
  //time.
  //There are two types of tokens: Token that expire on GNS level with
  //an absolute expiration time. Those are basically tokens that will
  //be automatically revoked on (record)expiration.
  //Tokens stored with relative expiration times will expire on the token level (token expiration)
  //but this service will reissue new tokens that can be retrieved from GNS
  //automatically.

  token_header = strtok (token, ".");

  token_payload = strtok (NULL, ".");

  GNUNET_STRINGS_base64_decode (token_payload,
                                strlen (token_payload),
                                &token_payload_json);

  payload_json = json_loads (token_payload_json, JSON_DECODE_ANY, &json_err);
  GNUNET_free (token_payload_json);

  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);
  token_rel_exp = GNUNET_TIME_absolute_get_difference (token_nbf, token_exp);

  token_ttl = GNUNET_TIME_absolute_get_remaining (token_exp);
  if (0 != GNUNET_TIME_absolute_get_remaining (token_exp).rel_value_us)
  {
    //This token is not yet expired! Save and skip
    if (min_rel_exp.rel_value_us > token_ttl.rel_value_us)
    {
      min_rel_exp = token_ttl;
    }
    json_decref (payload_json);
    GNUNET_free (token);
    token = NULL;
    GNUNET_free (label);
    label = NULL;
    GNUNET_NAMESTORE_zone_iterator_next (ns_it);
    return;
  }
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Token is expired. Create a new one\n");
  new_exp = GNUNET_TIME_relative_to_absolute (token_rel_exp);
  new_nbf = GNUNET_TIME_absolute_get ();
  new_iat = new_nbf;
  new_payload_json = json_object();
  json_object_foreach(payload_json, key, value) {
    if (0 == strcmp (key, "exp"))
    {
      json_object_set_new (new_payload_json, key, json_integer (new_exp.abs_value_us));
    }
    else if (0 == strcmp (key, "nbf"))
    {
      json_object_set_new (new_payload_json, key, json_integer (new_nbf.abs_value_us));
    }
    else if (0 == strcmp (key, "iat"))
    {
      json_object_set_new (new_payload_json, key, json_integer (new_iat.abs_value_us));
    }
    else if ((0 == strcmp (key, "iss"))
             || (0 == strcmp (key, "aud"))
             || (0 == strcmp (key, "sub"))
             || (0 == strcmp (key, "rnl")))
    {
      json_object_set (new_payload_json, key, value);
    }
    else {
      GNUNET_CRYPTO_hash (key,
                          strlen (key),
                          &key_hash);
      //Check if attr still exists. omit of not
      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);
        json_object_set (new_payload_json, key, cur_value);
      }
    }
  }

  // reassemble and set
  new_payload_str = json_dumps (new_payload_json, JSON_COMPACT);
  json_decref (payload_json);
  json_decref (new_payload_json);
  GNUNET_STRINGS_base64_encode (new_payload_str,
                                strlen (new_payload_str),
                                &new_payload_base64);
  //Remove padding
  padding = strtok(new_payload_base64, "=");
  while (NULL != padding)
    padding = strtok(NULL, "=");

  GNUNET_asprintf (&new_token, "%s,%s", token_header, new_payload_base64);
  purpose =
    GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) +
                   strlen (new_token));
  purpose->size =
    htonl (strlen (new_token) + sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose));
  purpose->purpose = htonl(GNUNET_SIGNATURE_PURPOSE_GNUID_TOKEN);
  memcpy (&purpose[1], new_token, strlen (new_token));
  if (GNUNET_OK != GNUNET_CRYPTO_ecdsa_sign (priv_key,
                                             purpose,
                                             &sig))
    GNUNET_break(0);
  GNUNET_free (new_token);
  sig_str = GNUNET_STRINGS_data_to_string_alloc (&sig,
                                                 sizeof (struct GNUNET_CRYPTO_EcdsaSignature));
  GNUNET_asprintf (&new_token, "%s.%s.%s",
                   token_header, new_payload_base64, sig_str);
  GNUNET_free (sig_str);
  GNUNET_free (new_payload_str);
  GNUNET_free (new_payload_base64);
  GNUNET_free (purpose);

  token_record.data = new_token;
  token_record.data_size = strlen (new_token);
  token_record.expiration_time = new_exp.abs_value_us;
  token_record.record_type = GNUNET_GNSRECORD_TYPE_ID_TOKEN;
  token_record.flags = GNUNET_GNSRECORD_RF_NONE | GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
  ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
                                          priv_key,
                                          label,
                                          1,
                                          &token_record,
                                          &store_token_cont,
                                          ego_entry);
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, ">>> Updating Token w/ %s\n", new_token);
  GNUNET_free (new_token);
  GNUNET_free (token);
  token = NULL;
  GNUNET_free (label);
  label = NULL;
}