From: Christian Grothoff Date: Sun, 30 Aug 2009 19:03:53 +0000 (+0000) Subject: sblocks X-Git-Tag: initial-import-from-subversion-38251~23556 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=0ed78fc783399971276412dc48130ec5e7256512;p=oweals%2Fgnunet.git sblocks --- diff --git a/src/fs/fs.h b/src/fs/fs.h index f0d9718a2..f13619041 100644 --- a/src/fs/fs.h +++ b/src/fs/fs.h @@ -493,6 +493,12 @@ struct GNUNET_FS_DownloadContext struct GNUNET_FS_Namespace { + + /** + * Private key for the namespace. + */ + struct GNUNET_CRYPTO_RsaPrivateKey *key; + /** * Reference counter. */ @@ -527,6 +533,46 @@ struct GNUNET_FS_KBlock }; +/** + * @brief namespace content block (advertising data under an identifier in a namespace) + */ +struct GNUNET_FS_SBlock +{ + + /** + * GNUNET_RSA_Signature using RSA-key of the namespace + */ + struct GNUNET_CRYPTO_RsaSignature signature; + + /** + * What is being signed and why? + */ + struct GNUNET_CRYPTO_RsaSignaturePurpose purpose; + + /** + * Hash of the hash of the human-readable identifier used for + * this entry (the hash of the human-readable identifier is + * used as the key for decryption; the xor of this identifier + * and the hash of the "keyspace" is the datastore-query hash). + */ + GNUNET_HashCode identifier; + + /** + * Public key of the namespace. + */ + struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded subspace; + + /* 0-terminated update-identifier here */ + + /* 0-terminated URI here */ + + /* variable-size Meta-Data follows here */ + +}; + + + + #endif /* end of fs.h */ diff --git a/src/fs/fs_publish.c b/src/fs/fs_publish.c index b9bf1dc9c..55541fc33 100644 --- a/src/fs/fs_publish.c +++ b/src/fs/fs_publish.c @@ -26,7 +26,6 @@ * @author Christian Grothoff * * TODO: - * - SBlocks * - indexing support * - code-sharing with unindex (can wait) * - persistence support (can wait) @@ -42,8 +41,17 @@ #define DEBUG_PUBLISH GNUNET_YES +/** + * Maximum allowed size for a KBlock. + */ #define MAX_KBLOCK_SIZE 60000 +/** + * Maximum allowed size for an SBlock. + */ +#define MAX_SBLOCK_SIZE 60000 + + /** * Main function that performs the upload. * @param cls "struct GNUNET_FS_PublishContext" identifies the upload @@ -1200,7 +1208,10 @@ GNUNET_FS_publish_ksk (struct GNUNET_FS_Handle *h, size = sizeof (struct GNUNET_FS_KBlock) + pkc->slen + pkc->mdsize; pkc->cpy = GNUNET_malloc (size); - pkc->cpy->purpose.size = htonl (sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) + pkc->mdsize + pkc->slen); + pkc->cpy->purpose.size = htonl (sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) + + sizeof(struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded) + + pkc->mdsize + + pkc->slen); pkc->cpy->purpose.purpose = htonl(GNUNET_SIGNATURE_PURPOSE_FS_KBLOCK); pkc->ksk_uri = GNUNET_FS_uri_dup (ksk_uri); GNUNET_SCHEDULER_add_continuation (h->sched, @@ -1211,6 +1222,65 @@ GNUNET_FS_publish_ksk (struct GNUNET_FS_Handle *h, } +/** + * Context for the SKS publication. + */ +struct PublishSksContext +{ + + /** + * Global FS context. + */ + struct GNUNET_FS_Uri *uri; + + /** + * Handle to the datastore. + */ + struct GNUNET_DATASTORE_Handle *dsh; + + /** + * Function to call once we're done. + */ + GNUNET_FS_PublishContinuation cont; + + /** + * Closure for cont. + */ + void *cont_cls; + +}; + + +/** + * Function called by the datastore API with + * the result from the PUT (SBlock) request. + * + * @param cls closure of type "struct PublishSksContext*" + * @param success GNUNET_OK on success + * @param msg error message (or NULL) + */ +static void +sb_put_cont (void *cls, + int success, + const char *msg) +{ + struct PublishSksContext *psc = cls; + + if (NULL != psc->dsh) + GNUNET_DATASTORE_disconnect (psc->dsh, GNUNET_NO); + if (GNUNET_OK != success) + psc->cont (psc->cont_cls, + NULL, + msg); + else + psc->cont (psc->cont_cls, + psc->uri, + NULL); + GNUNET_FS_uri_destroy (psc->uri); + GNUNET_free (psc); +} + + /** * Publish an SBlock on GNUnet. * @@ -1240,100 +1310,123 @@ GNUNET_FS_publish_sks (struct GNUNET_FS_Handle *h, enum GNUNET_FS_PublishOptions options, GNUNET_FS_PublishContinuation cont, void *cont_cls) -{ -#if 0 - struct GNUNET_ECRS_URI *uri; - struct GNUNET_ClientServerConnection *sock; - GNUNET_DatastoreValue *value; - unsigned int size; - unsigned int mdsize; - struct GNUNET_RSA_PrivateKey *hk; - GNUNET_EC_SBlock *sb; - char *dstURI; - char *destPos; - GNUNET_HashCode hc; /* hash of thisId = key */ - GNUNET_HashCode hc2; /* hash of hc = identifier */ - int ret; - unsigned int nidlen; - - hk = read_namespace_key (cfg, pid); - if (hk == NULL) - return NULL; - - /* THEN: construct GNUNET_EC_SBlock */ - dstURI = GNUNET_ECRS_uri_to_string (dstU); - mdsize = GNUNET_meta_data_get_serialized_size (md, GNUNET_SERIALIZE_PART); - if (nextId == NULL) - nextId = ""; - nidlen = strlen (nextId) + 1; - size = mdsize + sizeof (GNUNET_EC_SBlock) + strlen (dstURI) + 1 + nidlen; +{ + struct PublishSksContext *psc; + struct GNUNET_CRYPTO_AesSessionKey sk; + struct GNUNET_CRYPTO_AesInitializationVector iv; + struct GNUNET_FS_Uri *sks_uri; + char *uris; + size_t size; + size_t slen; + size_t nidlen; + size_t idlen; + ssize_t mdsize; + struct GNUNET_FS_SBlock *sb; + struct GNUNET_FS_SBlock *sb_enc; + char *dest; + GNUNET_HashCode key; /* hash of thisId = key */ + GNUNET_HashCode id; /* hash of hc = identifier */ + + uris = GNUNET_FS_uri_to_string (uri); + slen = strlen (uris) + 1; + idlen = strlen (identifier); + if (update == NULL) + update = ""; + nidlen = strlen (update) + 1; + mdsize = GNUNET_CONTAINER_meta_data_get_serialized_size (meta, + GNUNET_CONTAINER_META_DATA_SERIALIZE_PART); + + size = sizeof (struct GNUNET_FS_SBlock) + slen + nidlen + mdsize; if (size > MAX_SBLOCK_SIZE) { size = MAX_SBLOCK_SIZE; - mdsize = - size - (sizeof (GNUNET_EC_SBlock) + strlen (dstURI) + 1 + nidlen); + mdsize = size - (sizeof (struct GNUNET_FS_SBlock) + slen + nidlen); } - value = GNUNET_malloc (sizeof (GNUNET_DatastoreValue) + size); - sb = (GNUNET_EC_SBlock *) & value[1]; - sb->type = htonl (GNUNET_ECRS_BLOCKTYPE_SIGNED); - destPos = (char *) &sb[1]; - memcpy (destPos, nextId, nidlen); - destPos += nidlen; - memcpy (destPos, dstURI, strlen (dstURI) + 1); - destPos += strlen (dstURI) + 1; - mdsize = GNUNET_meta_data_serialize (ectx, - md, - destPos, - mdsize, GNUNET_SERIALIZE_PART); + sb = GNUNET_malloc (sizeof (struct GNUNET_FS_SBlock) + size); + dest = (char *) &sb[1]; + memcpy (dest, update, nidlen); + dest += nidlen; + memcpy (dest, uris, slen); + dest += slen; + mdsize = GNUNET_CONTAINER_meta_data_serialize (meta, + dest, + mdsize, + GNUNET_CONTAINER_META_DATA_SERIALIZE_PART); if (mdsize == -1) { - GNUNET_GE_BREAK (ectx, 0); - GNUNET_free (dstURI); - GNUNET_RSA_free_key (hk); - GNUNET_free (value); - return NULL; + GNUNET_break (0); + GNUNET_free (uris); + GNUNET_free (sb); + cont (cont_cls, + NULL, + _("Internal error.")); + return; } - size = sizeof (GNUNET_EC_SBlock) + mdsize + strlen (dstURI) + 1 + nidlen; - value->size = htonl (sizeof (GNUNET_DatastoreValue) + size); - value->type = htonl (GNUNET_ECRS_BLOCKTYPE_SIGNED); - value->priority = htonl (priority); - value->anonymity_level = htonl (anonymityLevel); - value->expiration_time = GNUNET_htonll (expiration); - GNUNET_hash (thisId, strlen (thisId), &hc); - GNUNET_hash (&hc, sizeof (GNUNET_HashCode), &hc2); - uri = GNUNET_malloc (sizeof (URI)); - uri->type = sks; - GNUNET_RSA_get_public_key (hk, &sb->subspace); - GNUNET_hash (&sb->subspace, - sizeof (GNUNET_RSA_PublicKey), &uri->data.sks.namespace); - GNUNET_GE_BREAK (ectx, 0 == memcmp (&uri->data.sks.namespace, - pid, sizeof (GNUNET_HashCode))); - uri->data.sks.identifier = GNUNET_strdup (thisId); - GNUNET_hash_xor (&hc2, &uri->data.sks.namespace, &sb->identifier); - GNUNET_ECRS_encryptInPlace (&hc, &sb[1], size - sizeof (GNUNET_EC_SBlock)); - GNUNET_GE_ASSERT (ectx, - GNUNET_OK == GNUNET_RSA_sign (hk, - size - - - sizeof - (GNUNET_RSA_Signature) - - sizeof - (GNUNET_RSA_PublicKey) - - sizeof (unsigned int), - &sb->identifier, - &sb->signature)); - GNUNET_RSA_free_key (hk); - sock = GNUNET_client_connection_create (ectx, cfg); - ret = GNUNET_FS_insert (sock, value); - if (ret != GNUNET_OK) + size = sizeof (struct GNUNET_FS_SBlock) + mdsize + slen + nidlen; + sb_enc = GNUNET_malloc (sizeof (struct GNUNET_FS_SBlock) + size); + GNUNET_CRYPTO_hash (identifier, idlen, &key); + GNUNET_CRYPTO_hash (&key, sizeof (GNUNET_HashCode), &id); + sks_uri = GNUNET_malloc (sizeof (struct GNUNET_FS_Uri)); + sks_uri->type = sks; + GNUNET_CRYPTO_rsa_key_get_public (namespace->key, &sb_enc->subspace); + GNUNET_CRYPTO_hash (&sb_enc->subspace, + sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), + &sks_uri->data.sks.namespace); + sks_uri->data.sks.identifier = GNUNET_strdup (identifier); + GNUNET_CRYPTO_hash_xor (&id, + &sks_uri->data.sks.namespace, + &sb_enc->identifier); + GNUNET_CRYPTO_hash_to_aes_key (&key, &sk, &iv); + GNUNET_CRYPTO_aes_encrypt (&sb[1], + size - sizeof (struct GNUNET_FS_SBlock), + &sk, + &iv, + &sb_enc[1]); + GNUNET_free (sb); + sb_enc->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_FS_SBLOCK); + sb_enc->purpose.size = htonl(slen + mdsize + nidlen + + sizeof(struct GNUNET_FS_SBlock) + - sizeof(struct GNUNET_CRYPTO_RsaSignature)); + GNUNET_assert (GNUNET_OK == + GNUNET_CRYPTO_rsa_sign (namespace->key, + &sb_enc->purpose, + &sb_enc->signature)); + psc = GNUNET_malloc (sizeof(struct PublishSksContext)); + psc->uri = sks_uri; + psc->cont = cont; + psc->cont_cls = cont_cls; + if (0 != (options & GNUNET_FS_PUBLISH_OPTION_SIMULATE_ONLY)) { - GNUNET_free (uri); - uri = NULL; + GNUNET_free (sb_enc); + sb_put_cont (psc, + GNUNET_OK, + NULL); + return; + } + psc->dsh = GNUNET_DATASTORE_connect (h->cfg, h->sched); + if (NULL == psc->dsh) + { + GNUNET_free (sb_enc); + sb_put_cont (psc, + GNUNET_NO, + _("Failed to connect to datastore.")); + return; } - GNUNET_client_connection_destroy (sock); - GNUNET_free (value); - GNUNET_free (dstURI); -#endif + + GNUNET_DATASTORE_put (psc->dsh, + 0, + &sb->identifier, + size, + sb_enc, + GNUNET_DATASTORE_BLOCKTYPE_SBLOCK, + priority, + anonymity, + expirationTime, + GNUNET_CONSTANTS_SERVICE_TIMEOUT, + &sb_put_cont, + psc); + GNUNET_free (sb_enc); } + /* end of fs_publish.c */ diff --git a/src/fs/fs_uri.c b/src/fs/fs_uri.c index 8e69a8425..47bad3454 100644 --- a/src/fs/fs_uri.c +++ b/src/fs/fs_uri.c @@ -628,11 +628,11 @@ uri_loc_parse (const char *s, char **emsg) goto ERR; } ass.purpose.size = htonl(sizeof(struct LocUriAssembly)); - ass.purpose.purpose = htonl(GNUNET_SIGNATURE_PURPOSE_NAMESPACE_PLACEMENT); + ass.purpose.purpose = htonl(GNUNET_SIGNATURE_PURPOSE_PEER_PLACEMENT); et.value = exptime; ass.exptime = GNUNET_TIME_absolute_hton (et); if (GNUNET_OK != - GNUNET_CRYPTO_rsa_verify (GNUNET_SIGNATURE_PURPOSE_NAMESPACE_PLACEMENT, + GNUNET_CRYPTO_rsa_verify (GNUNET_SIGNATURE_PURPOSE_PEER_PLACEMENT, &ass.purpose, &sig, &ass.peer)) @@ -847,7 +847,7 @@ GNUNET_FS_uri_loc_create (const struct GNUNET_FS_Uri *baseUri, GNUNET_free (keyfile); GNUNET_CRYPTO_rsa_key_get_public (my_private_key, &my_public_key); ass.purpose.size = htonl(sizeof(struct LocUriAssembly)); - ass.purpose.purpose = htonl(GNUNET_SIGNATURE_PURPOSE_NAMESPACE_PLACEMENT); + ass.purpose.purpose = htonl(GNUNET_SIGNATURE_PURPOSE_PEER_PLACEMENT); ass.exptime = GNUNET_TIME_absolute_hton (expiration_time); ass.fi = baseUri->data.chk; ass.peer = my_public_key;