struct GNUNET_DATASTORE_Handle *dsh;
/**
- * URI that was created.
+ * Our scheduler.
+ */
+ struct GNUNET_SCHEDULER_Handle *sched;
+
+ /**
+ * Our KSK URI.
*/
- struct GNUNET_FS_Uri *uri;
+ struct GNUNET_FS_Uri *ksk_uri;
+
+ /**
+ * Plaintext.
+ */
+ char *pt;
+
+ /**
+ * NBlock to sign and store.
+ */
+ struct NBlock *nb;
+
+ /**
+ * The namespace.
+ */
+ struct GNUNET_FS_Namespace *ns;
+
+ /**
+ * Expiration time.
+ */
+ struct GNUNET_TIME_Absolute expiration;
+
+ /**
+ * Number of bytes of plaintext.
+ */
+ size_t pt_size;
+
+ /**
+ * Anonymity level.
+ */
+ uint32_t anonymity;
+
+ /**
+ * Content priority.
+ */
+ uint32_t priority;
+
+ /**
+ * Current keyword offset.
+ */
+ unsigned int pos;
};
+/**
+ * Disconnect from the datastore.
+ *
+ * @param cls datastore handle
+ * @param tc scheduler context
+ */
+static void
+do_disconnect (void *cls,
+ const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ struct GNUNET_DATASTORE_Handle *dsh = cls;
+
+ GNUNET_DATASTORE_disconnect (dsh,
+ GNUNET_NO);
+}
+
+
/**
* Continuation called to notify client about result of the
* operation.
const char *msg)
{
struct AdvertisementContext *ac = cls;
+ const char *keyword;
+ GNUNET_HashCode key;
+ GNUNET_HashCode query;
+ struct GNUNET_CRYPTO_AesSessionKey skey;
+ struct GNUNET_CRYPTO_AesInitializationVector iv;
+ struct GNUNET_CRYPTO_RsaPrivateKey *pk;
if (GNUNET_OK != success)
- ac->cont (ac->cont_cls, NULL, msg);
- else
- ac->cont (ac->cont_cls, ac->uri, NULL);
- GNUNET_DATASTORE_disconnect (ac->dsh, GNUNET_NO);
- GNUNET_FS_uri_destroy (ac->uri);
- GNUNET_free (ac);
+ {
+ /* error! */
+ GNUNET_SCHEDULER_add_continuation (ac->sched,
+ &do_disconnect,
+ ac->dsh,
+ GNUNET_SCHEDULER_REASON_PREREQ_DONE);
+ ac->cont (ac->cont_cls, NULL, msg);
+ GNUNET_FS_uri_destroy (ac->ksk_uri);
+ GNUNET_free (ac->pt);
+ GNUNET_free (ac->nb);
+ GNUNET_FS_namespace_delete (ac->ns, GNUNET_NO);
+ GNUNET_free (ac);
+ return;
+ }
+ if (ac->pos == ac->ksk_uri->data.ksk.keywordCount)
+ {
+ /* done! */
+ GNUNET_SCHEDULER_add_continuation (ac->sched,
+ &do_disconnect,
+ ac->dsh,
+ GNUNET_SCHEDULER_REASON_PREREQ_DONE);
+ ac->cont (ac->cont_cls, ac->ksk_uri, NULL);
+ GNUNET_FS_uri_destroy (ac->ksk_uri);
+ GNUNET_free (ac->pt);
+ GNUNET_free (ac->nb);
+ GNUNET_FS_namespace_delete (ac->ns, GNUNET_NO);
+ GNUNET_free (ac);
+ return;
+ }
+ keyword = ac->ksk_uri->data.ksk.keywords[ac->pos++];
+ /* first character of keyword indicates if it is
+ mandatory or not -- ignore for hashing */
+ GNUNET_CRYPTO_hash (&keyword[1], strlen (&keyword[1]), &key);
+ GNUNET_CRYPTO_hash_to_aes_key (&key, &skey, &iv);
+ GNUNET_CRYPTO_aes_encrypt (ac->pt,
+ ac->pt_size,
+ &skey,
+ &iv,
+ &ac->nb[1]);
+ GNUNET_break (GNUNET_OK ==
+ GNUNET_CRYPTO_rsa_sign (ac->ns->key,
+ &ac->nb->ns_purpose,
+ &ac->nb->ns_signature));
+ pk = GNUNET_CRYPTO_rsa_key_create_from_hash (&key);
+ GNUNET_CRYPTO_rsa_key_get_public (pk, &ac->nb->keyspace);
+ GNUNET_CRYPTO_hash (&ac->nb->keyspace,
+ sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
+ &query);
+ GNUNET_break (GNUNET_OK ==
+ GNUNET_CRYPTO_rsa_sign (pk,
+ &ac->nb->ksk_purpose,
+ &ac->nb->ksk_signature));
+ GNUNET_CRYPTO_rsa_key_free (pk);
+ GNUNET_DATASTORE_put (ac->dsh,
+ 0 /* no reservation */,
+ &query,
+ ac->pt_size + sizeof (struct NBlock),
+ ac->nb,
+ GNUNET_BLOCK_TYPE_NBLOCK,
+ ac->priority,
+ ac->anonymity,
+ ac->expiration,
+ -2, 1,
+ GNUNET_CONSTANTS_SERVICE_TIMEOUT,
+ &advertisement_cont,
+ ac);
}
* Publish an advertismement for a namespace.
*
* @param h handle to the file sharing subsystem
+ * @param ksk_uri keywords to use for advertisment
* @param namespace handle for the namespace that should be advertised
* @param meta meta-data for the namespace advertisement
* @param anonymity for the namespace advertismement
*/
void
GNUNET_FS_namespace_advertise (struct GNUNET_FS_Handle *h,
+ struct GNUNET_FS_Uri *ksk_uri,
struct GNUNET_FS_Namespace *namespace,
const struct GNUNET_CONTAINER_MetaData *meta,
uint32_t anonymity,
size_t size;
ssize_t mdsize;
struct NBlock *nb;
- char *rtgt;
char *mdst;
struct GNUNET_DATASTORE_Handle *dsh;
struct AdvertisementContext *ctx;
+ char *pt;
/* create advertisements */
mdsize = GNUNET_CONTAINER_meta_data_get_serialized_size (meta);
size = MAX_NBLOCK_SIZE;
mdsize = size - sizeof (struct NBlock) - reslen;
}
- nb = GNUNET_malloc (size);
- GNUNET_CRYPTO_rsa_key_get_public (namespace->key, &nb->subspace);
- rtgt = (char *) &nb[1];
- memcpy (rtgt, rootEntry, reslen);
- mdst = &rtgt[reslen];
+
+ pt = GNUNET_malloc (mdsize + reslen);
+ memcpy (pt, rootEntry, reslen);
+ mdst = &pt[reslen];
mdsize = GNUNET_CONTAINER_meta_data_serialize (meta,
&mdst,
mdsize,
if (mdsize == -1)
{
GNUNET_break (0);
- GNUNET_free (nb);
+ GNUNET_free (pt);
cont (cont_cls, NULL, _("Failed to serialize meta data"));
return;
}
- size = mdsize + sizeof (struct NBlock) + reslen;
- nb->purpose.size = htonl (size - sizeof (struct GNUNET_CRYPTO_RsaSignature));
- nb->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_FS_NBLOCK);
- GNUNET_break (GNUNET_OK ==
- GNUNET_CRYPTO_rsa_sign (namespace->key,
- &nb->purpose,
- &nb->signature));
+ size = mdsize + sizeof (struct NBlock) + reslen;
+ nb = GNUNET_malloc (size);
+ GNUNET_CRYPTO_rsa_key_get_public (namespace->key,
+ &nb->subspace);
+ nb->ns_purpose.size = htonl (mdsize + reslen +
+ sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) +
+ sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded));
+ nb->ns_purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_FS_NBLOCK);
+ nb->ksk_purpose.size = htonl (size - sizeof (struct GNUNET_CRYPTO_RsaSignature));
+ nb->ksk_purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_FS_NBLOCK_KSIG);
dsh = GNUNET_DATASTORE_connect (h->cfg, h->sched);
if (NULL == dsh)
{
GNUNET_free (nb);
+ GNUNET_free (pt);
cont (cont_cls, NULL, _("Failed to connect to datastore service"));
return;
- }
+ }
ctx = GNUNET_malloc (sizeof (struct AdvertisementContext));
ctx->cont = cont;
ctx->cont_cls = cont_cls;
ctx->dsh = dsh;
- ctx->uri = GNUNET_malloc (sizeof (struct GNUNET_FS_Uri));
- ctx->uri->type = sks;
- ctx->uri->data.sks.identifier = GNUNET_strdup ("");
- GNUNET_CRYPTO_hash (&nb->subspace,
- sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
- &ctx->uri->data.sks.namespace);
- GNUNET_DATASTORE_put (dsh,
- 0,
- &ctx->uri->data.sks.namespace,
- size,
- nb,
- GNUNET_DATASTORE_BLOCKTYPE_NBLOCK,
- priority,
- anonymity,
- expiration,
- GNUNET_CONSTANTS_SERVICE_TIMEOUT,
- &advertisement_cont,
- ctx);
+ ctx->sched = h->sched;
+ ctx->ksk_uri = GNUNET_FS_uri_dup (ksk_uri);
+ ctx->nb = nb;
+ ctx->pt = pt;
+ ctx->pt_size = mdsize + reslen;
+ ctx->ns = namespace;
+ ctx->ns->rc++;
+ ctx->anonymity = anonymity;
+ ctx->priority = priority;
+ ctx->expiration = expiration;
+ advertisement_cont (ctx, GNUNET_OK, NULL);
}
dn,
DIR_SEPARATOR_STR,
name);
+ GNUNET_free (dn);
ret = GNUNET_malloc (sizeof (struct GNUNET_FS_Namespace));
ret->rc = 1;
ret->key = GNUNET_CRYPTO_rsa_key_create_from_file (fn);
GNUNET_free (fn);
return NULL;
}
+ ret->name = GNUNET_strdup (name);
ret->filename = fn;
return ret;
}
{
GNUNET_CRYPTO_rsa_key_free (namespace->key);
GNUNET_free (namespace->filename);
+ GNUNET_free (namespace->name);
GNUNET_free (namespace);
}
return GNUNET_OK;