From 303ab4dafbc680b1b362f95df5b12dae831b1593 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Tue, 6 Aug 2013 20:46:22 +0000 Subject: -fixing main FS build, updating man page of gnunet-pseudonym --- src/Makefile.am | 1 + src/fs/Makefile.am | 3 + src/fs/fs_api.c | 35 +- src/fs/fs_api.h | 128 +--- src/fs/fs_namespace.c | 772 ++++++++--------------- src/fs/fs_pseudonym.c | 977 ++--------------------------- src/fs/fs_publish.c | 30 +- src/fs/fs_publish_ksk.c | 179 ++---- src/fs/fs_publish_ublock.c | 262 ++++++++ src/fs/fs_publish_ublock.h | 108 ++++ src/fs/fs_search.c | 114 ++-- src/fs/fs_unindex.c | 25 +- src/fs/fs_uri.c | 109 ++-- src/fs/gnunet-pseudonym.c | 260 ++++---- src/fs/gnunet-publish.c | 211 ++++--- src/fs/plugin_block_fs.c | 9 +- src/fs/test_fs_namespace.c | 53 +- src/fs/test_fs_namespace_list_updateable.c | 14 +- src/fs/test_fs_uri.c | 9 +- src/fs/test_pseudonym.c | 148 +---- src/identity/identity_api.c | 25 +- src/include/block_fs.h | 9 +- src/include/gnunet_crypto_lib.h | 12 +- src/include/gnunet_fs_service.h | 375 +---------- src/include/gnunet_identity_service.h | 13 +- src/util/crypto_ecc.c | 25 + 26 files changed, 1257 insertions(+), 2649 deletions(-) create mode 100644 src/fs/fs_publish_ublock.c create mode 100644 src/fs/fs_publish_ublock.h (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 9126815f4..00c4d6f93 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -64,6 +64,7 @@ SUBDIRS = \ dns \ identity \ set \ + fs \ $(LINUX_DIR) \ $(MINGW_DIR) \ gns \ diff --git a/src/fs/Makefile.am b/src/fs/Makefile.am index e8928f770..ce70ff751 100644 --- a/src/fs/Makefile.am +++ b/src/fs/Makefile.am @@ -39,6 +39,7 @@ libgnunetfs_la_SOURCES = \ fs_pseudonym.c \ fs_publish.c \ fs_publish_ksk.c \ + fs_publish_ublock.c fs_publish_ublock.h \ fs_misc.c \ fs_namespace.c \ fs_search.c \ @@ -126,6 +127,7 @@ gnunet_download_DEPENDENCIES = \ gnunet_publish_SOURCES = \ gnunet-publish.c gnunet_publish_LDADD = \ + $(top_builddir)/src/identity/libgnunetidentity.la \ $(top_builddir)/src/fs/libgnunetfs.la \ $(top_builddir)/src/util/libgnunetutil.la \ -lextractor \ @@ -154,6 +156,7 @@ gnunet_helper_fs_publish_DEPENDENCIES = \ gnunet_pseudonym_SOURCES = \ gnunet-pseudonym.c gnunet_pseudonym_LDADD = \ + $(top_builddir)/src/identity/libgnunetidentity.la \ $(top_builddir)/src/fs/libgnunetfs.la \ $(top_builddir)/src/util/libgnunetutil.la \ -lextractor \ diff --git a/src/fs/fs_api.c b/src/fs/fs_api.c index ab49139b9..9676f2e3c 100644 --- a/src/fs/fs_api.c +++ b/src/fs/fs_api.c @@ -1467,17 +1467,17 @@ deserialize_publish_file (void *cls, const char *filename) struct GNUNET_FS_PublishContext *pc; int32_t options; int32_t all_done; + int32_t have_ns; char *fi_root; - char *ns; + struct GNUNET_CRYPTO_EccPrivateKey ns; char *fi_pos; char *emsg; - pc = GNUNET_malloc (sizeof (struct GNUNET_FS_PublishContext)); + pc = GNUNET_new (struct GNUNET_FS_PublishContext); pc->h = h; pc->serialization = get_serialization_short_name (filename); fi_root = NULL; fi_pos = NULL; - ns = NULL; rh = GNUNET_BIO_read_open (filename); if (NULL == rh) { @@ -1489,10 +1489,12 @@ deserialize_publish_file (void *cls, const char *filename) GNUNET_BIO_read_string (rh, "publish-nuid", &pc->nuid, 1024)) || (GNUNET_OK != GNUNET_BIO_read_int32 (rh, &options)) || (GNUNET_OK != GNUNET_BIO_read_int32 (rh, &all_done)) || + (GNUNET_OK != GNUNET_BIO_read_int32 (rh, &have_ns)) || (GNUNET_OK != GNUNET_BIO_read_string (rh, "publish-firoot", &fi_root, 128)) || (GNUNET_OK != GNUNET_BIO_read_string (rh, "publish-fipos", &fi_pos, 128)) - || (GNUNET_OK != GNUNET_BIO_read_string (rh, "publish-ns", &ns, 1024))) + || ( (GNUNET_YES == have_ns) && + (GNUNET_OK != GNUNET_BIO_read (rh, "publish-ns", &ns, sizeof (ns)))) ) { GNUNET_break (0); goto cleanup; @@ -1510,17 +1512,10 @@ deserialize_publish_file (void *cls, const char *filename) GNUNET_break (0); goto cleanup; } - if (NULL != ns) + if (GNUNET_YES == have_ns) { - pc->ns = GNUNET_FS_namespace_create (h, ns); - if (NULL == pc->ns) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - _ - ("Failed to recover namespace `%s', cannot resume publishing operation.\n"), - ns); - goto cleanup; - } + pc->ns = GNUNET_new (struct GNUNET_CRYPTO_EccPrivateKey); + *pc->ns = ns; } if ((0 == (pc->options & GNUNET_FS_PUBLISH_OPTION_SIMULATE_ONLY)) && (GNUNET_YES != pc->all_done)) @@ -1563,7 +1558,6 @@ deserialize_publish_file (void *cls, const char *filename) filename, emsg); GNUNET_free (emsg); } - GNUNET_free_non_null (ns); pc->top = GNUNET_FS_make_top (h, &GNUNET_FS_publish_signal_suspend_, pc); return GNUNET_OK; cleanup: @@ -1571,7 +1565,6 @@ cleanup: GNUNET_free_non_null (pc->nuid); GNUNET_free_non_null (fi_root); GNUNET_free_non_null (fi_pos); - GNUNET_free_non_null (ns); if ((NULL != rh) && (GNUNET_OK != GNUNET_BIO_read_close (rh, &emsg))) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, @@ -1601,6 +1594,7 @@ void GNUNET_FS_publish_sync_ (struct GNUNET_FS_PublishContext *pc) { struct GNUNET_BIO_WriteHandle *wh; + int32_t have_ns; if (NULL == pc->serialization) pc->serialization = @@ -1622,17 +1616,20 @@ GNUNET_FS_publish_sync_ (struct GNUNET_FS_PublishContext *pc) GNUNET_break (0); goto cleanup; } + have_ns = (NULL != pc->ns) ? GNUNET_YES : GNUNET_NO; if ((GNUNET_OK != GNUNET_BIO_write_string (wh, pc->nid)) || (GNUNET_OK != GNUNET_BIO_write_string (wh, pc->nuid)) || (GNUNET_OK != GNUNET_BIO_write_int32 (wh, pc->options)) || (GNUNET_OK != GNUNET_BIO_write_int32 (wh, pc->all_done)) || + (GNUNET_OK != GNUNET_BIO_write_int32 (wh, have_ns)) || (GNUNET_OK != GNUNET_BIO_write_string (wh, pc->fi->serialization)) || (GNUNET_OK != GNUNET_BIO_write_string (wh, (NULL == pc->fi_pos) ? NULL : pc->fi_pos->serialization)) || - (GNUNET_OK != - GNUNET_BIO_write_string (wh, - (NULL == pc->ns) ? NULL : pc->ns->name))) + ( (NULL != pc->ns) && + GNUNET_BIO_write (wh, + pc->ns, + sizeof (struct GNUNET_CRYPTO_EccPrivateKey)) ) ) { GNUNET_break (0); goto cleanup; diff --git a/src/fs/fs_api.h b/src/fs/fs_api.h index 2fe38f604..83e8c3801 100644 --- a/src/fs/fs_api.h +++ b/src/fs/fs_api.h @@ -182,16 +182,13 @@ struct GNUNET_FS_Uri struct { /** - * Keywords start with a '+' if they are - * mandatory (in which case the '+' is NOT - * part of the keyword) and with a - * simple space if they are optional - * (in which case the space is ALSO not - * part of the actual keyword). + * Keywords start with a '+' if they are mandatory (in which + * case the '+' is NOT part of the keyword) and with a simple + * space if they are optional (in which case the space is ALSO + * not part of the actual keyword). * - * Double-quotes to protect spaces and - * %-encoding are NOT used internally - * (only in URI-strings). + * Double-quotes to protect spaces and %-encoding are NOT used + * internally (only in URI-strings). */ char **keywords; @@ -206,7 +203,7 @@ struct GNUNET_FS_Uri /** * Identifier of the namespace. */ - struct GNUNET_FS_PseudonymIdentifier ns; + struct GNUNET_CRYPTO_EccPublicKey ns; /** * Human-readable identifier chosen for this @@ -1178,7 +1175,7 @@ struct GNUNET_FS_PublishContext /** * Namespace that we are publishing in, NULL if we have no namespace. */ - struct GNUNET_FS_Namespace *ns; + struct GNUNET_CRYPTO_EccPrivateKey *ns; /** * ID of the content in the namespace, NULL if we have no namespace. @@ -1459,17 +1456,23 @@ struct GNUNET_FS_UnindexContext */ struct SearchRequestEntry { - /** - * Hash of the original keyword, used to derive the - * key (for decrypting the KBlock). - */ - struct GNUNET_HashCode ukey; /** * Hash of the public key, also known as the query. */ struct GNUNET_HashCode uquery; + /** + * Derived public key, hashes to 'uquery'. + */ + struct GNUNET_CRYPTO_EccPublicKey dpub; + + /** + * The original keyword, used to derive the + * key (for decrypting the UBlock). + */ + char *keyword; + /** * Map that contains a "struct GNUNET_FS_SearchResult" for each result that * was found under this keyword. Note that the entries will point @@ -1963,99 +1966,6 @@ struct GNUNET_FS_DownloadContext }; -/** - * Information about an (updateable) node in the - * namespace. - */ -struct NamespaceUpdateNode -{ - /** - * Identifier for this node. - */ - char *id; - - /** - * Identifier of children of this node. - */ - char *update; - - /** - * Metadata for this entry. - */ - struct GNUNET_CONTAINER_MetaData *md; - - /** - * URI of this entry in the namespace. - */ - struct GNUNET_FS_Uri *uri; - - /** - * Namespace update generation ID. Used to ensure - * freshness of the tree_id. - */ - unsigned int nug; - - /** - * TREE this entry belongs to (if nug is current). - */ - unsigned int tree_id; - -}; - - -/** - * Handle to one of our namespaces. - */ -struct GNUNET_FS_Namespace -{ - - /** - * Handle to the FS service context. - */ - struct GNUNET_FS_Handle *h; - - /** - * Array with information about nodes in the namespace. - */ - struct NamespaceUpdateNode **update_nodes; - - /** - * Private key for the namespace. - */ - struct GNUNET_FS_PseudonymHandle *key; - - /** - * Hash map mapping identifiers of update nodes - * to the update nodes (initialized on-demand). - */ - struct GNUNET_CONTAINER_MultiHashMap *update_map; - - /** - * Name of the file with the private key. - */ - char *filename; - - /** - * Name of the namespace. - */ - char *name; - - /** - * Size of the update nodes array. - */ - unsigned int update_node_count; - - /** - * Reference counter. - */ - unsigned int rc; - - /** - * Generator for unique nug numbers. - */ - unsigned int nug_gen; -}; - #endif /* end of fs_api.h */ diff --git a/src/fs/fs_namespace.c b/src/fs/fs_namespace.c index d456dc34b..8537ba0e6 100644 --- a/src/fs/fs_namespace.c +++ b/src/fs/fs_namespace.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet - (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Christian Grothoff (and other contributing authors) + (C) 2003-2013 Christian Grothoff (and other contributing authors) GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published @@ -20,7 +20,7 @@ /** * @file fs/fs_namespace.c - * @brief create and destroy namespaces + * @brief publishing to namespaces, and tracking updateable entries * @author Christian Grothoff */ #include "platform.h" @@ -29,30 +29,91 @@ #include "gnunet_util_lib.h" #include "gnunet_fs_service.h" #include "fs_api.h" +#include "fs_publish_ublock.h" /** - * Return the name of the directory in which we store - * our local namespaces (or rather, their public keys). - * - * @param h global fs handle - * @return NULL on error, otherwise the name of the directory + * Information about an (updateable) node in the + * namespace. */ -static char * -get_namespace_directory (struct GNUNET_FS_Handle *h) +struct NamespaceUpdateNode { - char *dn; + /** + * Identifier for this node. + */ + char *id; - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_filename (h->cfg, "FS", "IDENTITY_DIR", - &dn)) - { - GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, - "fs", "IDENTITY_DIR"); - return NULL; - } - return dn; -} + /** + * Identifier of children of this node. + */ + char *update; + + /** + * Metadata for this entry. + */ + struct GNUNET_CONTAINER_MetaData *md; + + /** + * URI of this entry in the namespace. + */ + struct GNUNET_FS_Uri *uri; + + /** + * Namespace update generation ID. Used to ensure + * freshness of the tree_id. + */ + unsigned int nug; + + /** + * TREE this entry belongs to (if nug is current). + */ + unsigned int tree_id; + +}; + + +/** + * Handle to update information for a namespace. + */ +struct GNUNET_FS_UpdateInformationGraph +{ + + /** + * Handle to the FS service context. + */ + struct GNUNET_FS_Handle *h; + + /** + * Array with information about nodes in the namespace. + */ + struct NamespaceUpdateNode **update_nodes; + + /** + * Private key for the namespace. + */ + struct GNUNET_CRYPTO_EccPrivateKey ns; + + /** + * Hash map mapping identifiers of update nodes + * to the update nodes (initialized on-demand). + */ + struct GNUNET_CONTAINER_MultiHashMap *update_map; + + /** + * Size of the update nodes array. + */ + unsigned int update_node_count; + + /** + * Reference counter. + */ + unsigned int rc; + + /** + * Generator for unique nug numbers. + */ + unsigned int nug_gen; +}; /** @@ -63,32 +124,71 @@ get_namespace_directory (struct GNUNET_FS_Handle *h) * @return NULL on error, otherwise the name of the directory */ static char * -get_update_information_directory (struct GNUNET_FS_Namespace *ns) +get_update_information_directory (struct GNUNET_FS_Handle *h, + const struct GNUNET_CRYPTO_EccPrivateKey *ns) { char *dn; char *ret; + struct GNUNET_CRYPTO_EccPublicKey pub; + struct GNUNET_CRYPTO_ShortHashCode hc; + struct GNUNET_CRYPTO_ShortHashAsciiEncoded enc; if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_filename (ns->h->cfg, "FS", "UPDATE_DIR", + GNUNET_CONFIGURATION_get_value_filename (h->cfg, "FS", "UPDATE_DIR", &dn)) { GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "fs", "UPDATE_DIR"); return NULL; } - GNUNET_asprintf (&ret, "%s%s%s", dn, DIR_SEPARATOR_STR, ns->name); + GNUNET_CRYPTO_ecc_key_get_public (ns, &pub); + GNUNET_CRYPTO_short_hash (&pub, sizeof (pub), &hc); + GNUNET_CRYPTO_short_hash_to_enc (&hc, + &enc); + GNUNET_asprintf (&ret, "%s%s%s", + dn, + DIR_SEPARATOR_STR, + (const char *) enc.short_encoding); GNUNET_free (dn); return ret; } +/** + * Release memory occupied by UIG datastructure. + * + * @param uig data structure to free + */ +static void +free_update_information_graph (struct GNUNET_FS_UpdateInformationGraph *uig) +{ + unsigned int i; + struct NamespaceUpdateNode *nsn; + + for (i = 0; i < uig->update_node_count; i++) + { + nsn = uig->update_nodes[i]; + GNUNET_CONTAINER_meta_data_destroy (nsn->md); + GNUNET_FS_uri_destroy (nsn->uri); + GNUNET_free (nsn->id); + GNUNET_free (nsn->update); + GNUNET_free (nsn); + } + GNUNET_array_grow (uig->update_nodes, uig->update_node_count, + 0); + if (NULL != uig->update_map) + GNUNET_CONTAINER_multihashmap_destroy (uig->update_map); + GNUNET_free (uig); +} + + /** * Write the namespace update node graph to a file. * * @param ns namespace to dump */ static void -write_update_information_graph (struct GNUNET_FS_Namespace *ns) +write_update_information_graph (struct GNUNET_FS_UpdateInformationGraph *uig) { char *fn; struct GNUNET_BIO_WriteHandle *wh; @@ -96,7 +196,8 @@ write_update_information_graph (struct GNUNET_FS_Namespace *ns) struct NamespaceUpdateNode *n; char *uris; - fn = get_update_information_directory (ns); + fn = get_update_information_directory (uig->h, + &uig->ns); wh = GNUNET_BIO_write_open (fn); if (NULL == wh) { @@ -105,11 +206,11 @@ write_update_information_graph (struct GNUNET_FS_Namespace *ns) GNUNET_free (fn); return; } - if (GNUNET_OK != GNUNET_BIO_write_int32 (wh, ns->update_node_count)) + if (GNUNET_OK != GNUNET_BIO_write_int32 (wh, uig->update_node_count)) goto END; - for (i = 0; i < ns->update_node_count; i++) + for (i = 0; i < uig->update_node_count; i++) { - n = ns->update_nodes[i]; + n = uig->update_nodes[i]; uris = GNUNET_FS_uri_to_string (n->uri); if ((GNUNET_OK != GNUNET_BIO_write_string (wh, n->id)) || (GNUNET_OK != GNUNET_BIO_write_meta_data (wh, n->md)) || @@ -132,11 +233,15 @@ END: /** * Read the namespace update node graph from a file. * + * @param h FS handle to use * @param ns namespace to read + * @return update graph, never NULL */ -static void -read_update_information_graph (struct GNUNET_FS_Namespace *ns) +static struct GNUNET_FS_UpdateInformationGraph * +read_update_information_graph (struct GNUNET_FS_Handle *h, + const struct GNUNET_CRYPTO_EccPrivateKey *ns) { + struct GNUNET_FS_UpdateInformationGraph *uig; char *fn; struct GNUNET_BIO_ReadHandle *rh; unsigned int i; @@ -145,40 +250,43 @@ read_update_information_graph (struct GNUNET_FS_Namespace *ns) uint32_t count; char *emsg; - fn = get_update_information_directory (ns); + uig = GNUNET_new (struct GNUNET_FS_UpdateInformationGraph); + uig->h = h; + uig->ns = *ns; + fn = get_update_information_directory (h, ns); if (GNUNET_YES != GNUNET_DISK_file_test (fn)) { GNUNET_free (fn); - return; + return uig; } rh = GNUNET_BIO_read_open (fn); if (NULL == rh) { GNUNET_free (fn); - return; + return uig; } if (GNUNET_OK != GNUNET_BIO_read_int32 (rh, &count)) { GNUNET_break (0); - goto END; + goto ERROR; } if (count > 1024 * 1024) { GNUNET_break (0); - goto END; + goto ERROR; } if (0 == count) { GNUNET_break (GNUNET_OK == GNUNET_BIO_read_close (rh, NULL)); GNUNET_free (fn); - return; + return uig; } - ns->update_nodes = - GNUNET_malloc (count * sizeof (struct NamespaceUpdateNode *)); + uig->update_nodes = + GNUNET_malloc (count * sizeof (struct NamespaceUpdateNode *)); for (i = 0; i < count; i++) { - n = GNUNET_malloc (sizeof (struct NamespaceUpdateNode)); + n = GNUNET_new (struct NamespaceUpdateNode); if ((GNUNET_OK != GNUNET_BIO_read_string (rh, "identifier", &n->id, 1024)) || (GNUNET_OK != GNUNET_BIO_read_meta_data (rh, "meta", &n->md)) || (GNUNET_OK != @@ -205,304 +313,25 @@ read_update_information_graph (struct GNUNET_FS_Namespace *ns) GNUNET_free (n); break; } - ns->update_nodes[i] = n; + uig->update_nodes[i] = n; } - ns->update_node_count = i; -END: + uig->update_node_count = i; if (GNUNET_OK != GNUNET_BIO_read_close (rh, &emsg)) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Failed to write `%s': %s\n"), emsg); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Failed to read `%s': %s\n"), + fn, emsg); GNUNET_free (emsg); } - GNUNET_free (fn); -} - - -/** - * Create a namespace with the given name; if one already - * exists, return a handle to the existing namespace. - * - * @param h handle to the file sharing subsystem - * @param name name to use for the namespace - * @return handle to the namespace, NULL on error (i.e. invalid filename) - */ -struct GNUNET_FS_Namespace * -GNUNET_FS_namespace_create (struct GNUNET_FS_Handle *h, const char *name) -{ - char *dn; - char *fn; - struct GNUNET_FS_Namespace *ret; - - dn = get_namespace_directory (h); - if (NULL == dn) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _("Can't determine where namespace directory is\n")); - return NULL; - } - GNUNET_asprintf (&fn, "%s%s%s", dn, DIR_SEPARATOR_STR, name); - GNUNET_free (dn); - ret = GNUNET_malloc (sizeof (struct GNUNET_FS_Namespace)); - ret->h = h; - ret->rc = 1; - ret->key = GNUNET_FS_pseudonym_create (fn); - if (NULL == ret->key) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _("Failed to create or read private key for namespace `%s'\n"), - name); - GNUNET_free (ret); - GNUNET_free (fn); - return NULL; - } - ret->name = GNUNET_strdup (name); - ret->filename = fn; - return ret; -} - - -/** - * Open the namespace with the given name; if it does not exist, - * or the key file is corrupted, the function fails. - * - * @param h handle to the file sharing subsystem - * @param name name of the namespace - * @return handle to the namespace, - * NULL on error (i.e. invalid filename, non-existent filename) - */ -struct GNUNET_FS_Namespace * -GNUNET_FS_namespace_open_existing (struct GNUNET_FS_Handle *h, const char *name) -{ - char *dn; - char *fn; - struct GNUNET_FS_Namespace *ret; - - dn = get_namespace_directory (h); - if (NULL == dn) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _("Can't determine where namespace directory is\n")); - return NULL; - } - GNUNET_asprintf (&fn, "%s%s%s", dn, DIR_SEPARATOR_STR, name); - GNUNET_free (dn); - ret = GNUNET_malloc (sizeof (struct GNUNET_FS_Namespace)); - ret->h = h; - ret->rc = 1; - ret->key = GNUNET_FS_pseudonym_create_from_existing_file (fn); - if (NULL == ret->key) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _("Failed to read private key for namespace `%s'\n"), name); - GNUNET_free (ret); - GNUNET_free (fn); - return NULL; - } - ret->name = GNUNET_strdup (name); - ret->filename = fn; - return ret; -} - - -/** - * Rename a local namespace. - * - * @param h handle to the file sharing subsystem - * @param old_name old name of the namespace - * @param new_name new name of the namespace - * @return GNUNET_OK on success, GNUNET_SYSERR on error (see errno for details) - */ -int -GNUNET_FS_namespace_rename (struct GNUNET_FS_Handle *h, - const char *old_name, - const char *new_name) -{ - char *dn; - char *fn_old; - char *fn_new; - int result; - int save_errno; - - dn = get_namespace_directory (h); - if (NULL == dn) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _("Can't determine where namespace directory is\n")); - return GNUNET_SYSERR; - } - GNUNET_asprintf (&fn_old, "%s%s%s", dn, DIR_SEPARATOR_STR, old_name); - GNUNET_asprintf (&fn_new, "%s%s%s", dn, DIR_SEPARATOR_STR, new_name); - GNUNET_free (dn); - result = RENAME (fn_old, fn_new); - save_errno = errno; - GNUNET_free (fn_old); - GNUNET_free (fn_new); - errno = save_errno; - if (result == 0) - return GNUNET_OK; - return GNUNET_SYSERR; -} - - -/** - * Duplicate a namespace handle. - * - * @param ns namespace handle - * @return duplicated handle to the namespace - */ -struct GNUNET_FS_Namespace * -GNUNET_FS_namespace_dup (struct GNUNET_FS_Namespace *ns) -{ - ns->rc++; - return ns; -} - - -/** - * Delete a namespace handle. Can be used for a clean shutdown (free - * memory) or also to freeze the namespace to prevent further - * insertions by anyone. - * - * @param ns handle to the namespace that should be deleted / freed - * @param freeze prevents future insertions; creating a namespace - * with the same name again will create a fresh namespace instead - * - * @return GNUNET_OK on success, GNUNET_SYSERR on error - */ -int -GNUNET_FS_namespace_delete (struct GNUNET_FS_Namespace *ns, int freeze) -{ - unsigned int i; - struct NamespaceUpdateNode *nsn; - - ns->rc--; - if (freeze) - { - if (0 != UNLINK (ns->filename)) - GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "unlink", - ns->filename); - } - if (0 != ns->rc) - return GNUNET_OK; - GNUNET_FS_pseudonym_destroy (ns->key); - GNUNET_free (ns->filename); - GNUNET_free (ns->name); - for (i = 0; i < ns->update_node_count; i++) - { - nsn = ns->update_nodes[i]; - GNUNET_CONTAINER_meta_data_destroy (nsn->md); - GNUNET_FS_uri_destroy (nsn->uri); - GNUNET_free (nsn->id); - GNUNET_free (nsn->update); - GNUNET_free (nsn); - } - GNUNET_array_grow (ns->update_nodes, ns->update_node_count, - 0); - if (ns->update_map != NULL) - GNUNET_CONTAINER_multihashmap_destroy (ns->update_map); - GNUNET_free (ns); - return GNUNET_OK; -} - - -/** - * Context for the 'process_namespace' callback. - * Specifies a function to call on each namespace. - */ -struct ProcessNamespaceContext -{ - /** - * Function to call. - */ - GNUNET_FS_NamespaceInfoProcessor cb; - - /** - * Closure for 'cb'. - */ - void *cb_cls; -}; - - -/** - * Get hash of the public key of a namespace. - * - * @param ns namespace - * @param id buffer to store the key in - * @return GNUNET_OK on success - * GNUNET_SYSERR on failure (contents of id remain intact) - */ -int -GNUNET_FS_namespace_get_public_identifier (struct GNUNET_FS_Namespace *ns, - struct GNUNET_FS_PseudonymIdentifier *id) -{ - if ((NULL == ns) || (NULL == id)) - return GNUNET_SYSERR; - GNUNET_FS_pseudonym_get_identifier (ns->key, id); - return GNUNET_OK; -} - - -/** - * Function called with a filename of a namespace. Reads the key and - * calls the callback. - * - * @param cls closure (struct ProcessNamespaceContext) - * @param filename complete filename (absolute path) - * @return GNUNET_OK to continue to iterate, - * GNUNET_SYSERR to abort iteration with error! - */ -static int -process_namespace (void *cls, const char *filename) -{ - struct ProcessNamespaceContext *pnc = cls; - struct GNUNET_FS_PseudonymHandle *ph; - struct GNUNET_FS_PseudonymIdentifier id; - const char *name; - const char *t; - - if (NULL == (ph = GNUNET_FS_pseudonym_create (filename))) + return uig; +ERROR: + if (GNUNET_OK != GNUNET_BIO_read_close (rh, &emsg)) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _ - ("Failed to read namespace private key file `%s', deleting it!\n"), - filename); - if (0 != UNLINK (filename)) - GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "unlink", filename); - return GNUNET_OK; + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Failed to read `%s': %s\n"), + fn, emsg); + GNUNET_free (emsg); } - GNUNET_FS_pseudonym_get_identifier (ph, &id); - GNUNET_FS_pseudonym_destroy (ph); - name = filename; - while (NULL != (t = strstr (name, DIR_SEPARATOR_STR))) - name = t + 1; - pnc->cb (pnc->cb_cls, name, &id); - return GNUNET_OK; -} - - -/** - * Build a list of all available local (!) namespaces The returned - * names are only the nicknames since we only iterate over the local - * namespaces. - * - * @param h handle to the file sharing subsystem - * @param cb function to call on each known namespace - * @param cb_cls closure for cb - */ -void -GNUNET_FS_namespace_list (struct GNUNET_FS_Handle *h, - GNUNET_FS_NamespaceInfoProcessor cb, void *cb_cls) -{ - char *dn; - struct ProcessNamespaceContext ctx; - - dn = get_namespace_directory (h); - if (NULL == dn) - return; - ctx.cb = cb; - ctx.cb_cls = cb_cls; - GNUNET_DISK_directory_scan (dn, &process_namespace, &ctx); - GNUNET_free (dn); + GNUNET_free (fn); + return uig; } @@ -526,13 +355,18 @@ struct GNUNET_FS_PublishSksContext /** * Namespace we're publishing to. */ - struct GNUNET_FS_Namespace *ns; + struct GNUNET_CRYPTO_EccPrivateKey ns; /** * Handle to the datastore. */ struct GNUNET_DATASTORE_Handle *dsh; + /** + * Handle to FS. + */ + struct GNUNET_FS_Handle *h; + /** * Function to call once we're done. */ @@ -544,31 +378,28 @@ struct GNUNET_FS_PublishSksContext void *cont_cls; /** - * Handle for our datastore request. + * Handle for our UBlock operation request. */ - struct GNUNET_DATASTORE_QueueEntry *dqe; + struct GNUNET_FS_PublishUblockContext *uc; }; /** - * Function called by the datastore API with + * Function called by the UBlock construction with * the result from the PUT (UBlock) request. * * @param cls closure of type "struct GNUNET_FS_PublishSksContext*" - * @param success GNUNET_OK on success - * @param min_expiration minimum expiration time required for content to be stored * @param msg error message (or NULL) */ static void -sb_put_cont (void *cls, int success, - struct GNUNET_TIME_Absolute min_expiration, - const char *msg) +sks_publish_cont (void *cls, + const char *msg) { struct GNUNET_FS_PublishSksContext *psc = cls; - struct GNUNET_HashCode hc; + struct GNUNET_FS_UpdateInformationGraph *uig; - psc->dqe = NULL; - if (GNUNET_OK != success) + psc->uc = NULL; + if (NULL != msg) { if (NULL != psc->cont) psc->cont (psc->cont_cls, NULL, msg); @@ -580,19 +411,14 @@ sb_put_cont (void *cls, int success, /* FIXME: this can be done much more * efficiently by simply appending to the * file and overwriting the 4-byte header */ - if (psc->ns->update_nodes == NULL) - read_update_information_graph (psc->ns); - GNUNET_array_append (psc->ns->update_nodes, - psc->ns->update_node_count, psc->nsn); - if (NULL != psc->ns->update_map) - { - GNUNET_CRYPTO_hash (psc->nsn->id, strlen (psc->nsn->id), &hc); - GNUNET_CONTAINER_multihashmap_put (psc->ns->update_map, &hc, - psc->nsn, - GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); - } + uig = read_update_information_graph (psc->h, + &psc->ns); + GNUNET_array_append (uig->update_nodes, + uig->update_node_count, + psc->nsn); psc->nsn = NULL; - write_update_information_graph (psc->ns); + write_update_information_graph (uig); + free_update_information_graph (uig); } if (NULL != psc->cont) psc->cont (psc->cont_cls, psc->uri, NULL); @@ -617,7 +443,7 @@ sb_put_cont (void *cls, int success, */ struct GNUNET_FS_PublishSksContext * GNUNET_FS_publish_sks (struct GNUNET_FS_Handle *h, - struct GNUNET_FS_Namespace *ns, + const struct GNUNET_CRYPTO_EccPrivateKey *ns, const char *identifier, const char *update, const struct GNUNET_CONTAINER_MetaData *meta, const struct GNUNET_FS_Uri *uri, @@ -626,144 +452,49 @@ GNUNET_FS_publish_sks (struct GNUNET_FS_Handle *h, GNUNET_FS_PublishContinuation cont, void *cont_cls) { struct GNUNET_FS_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 UBlock *ub; - struct UBlock *ub_enc; - char *dest; - struct GNUNET_CONTAINER_MetaData *mmeta; - struct GNUNET_HashCode id_hash; /* hash of thisId */ - struct GNUNET_HashCode ns_hash; /* hash of namespace public key */ - struct GNUNET_HashCode key; /* id_hash ^ ns_hash, for AES key */ - struct GNUNET_HashCode signing_key; /* H(key) = input for public key */ - struct GNUNET_HashCode query; /* H(verification_key) = query */ - - idlen = strlen (identifier); - if (NULL != update) - nidlen = strlen (update) + 1; - else - nidlen = 1; - uris = GNUNET_FS_uri_to_string (uri); - slen = strlen (uris) + 1; - if ( (slen >= MAX_UBLOCK_SIZE - sizeof (struct UBlock)) || - (nidlen >= MAX_UBLOCK_SIZE - sizeof (struct UBlock) - slen) ) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _("Identifiers or URI too long to create UBlock")); - GNUNET_free (uris); - return NULL; - } - if (NULL == meta) - mmeta = GNUNET_CONTAINER_meta_data_create (); - else - mmeta = GNUNET_CONTAINER_meta_data_duplicate (meta); - mdsize = GNUNET_CONTAINER_meta_data_get_serialized_size (mmeta); - size = sizeof (struct UBlock) + slen + nidlen + mdsize; - if ( (size > MAX_UBLOCK_SIZE) || - (size < sizeof (struct UBlock) + slen + nidlen) ) - { - size = MAX_UBLOCK_SIZE; - mdsize = MAX_UBLOCK_SIZE - (sizeof (struct UBlock) + slen + nidlen); - } - ub = GNUNET_malloc (sizeof (struct UBlock) + size); - dest = (char *) &ub[1]; - if (NULL != update) - memcpy (dest, update, nidlen); - else - memset (dest, 0, 1); - dest += nidlen; - memcpy (dest, uris, slen); - GNUNET_free (uris); - dest += slen; - mdsize = - GNUNET_CONTAINER_meta_data_serialize (mmeta, &dest, mdsize, - GNUNET_CONTAINER_META_DATA_SERIALIZE_PART); - GNUNET_CONTAINER_meta_data_destroy (mmeta); - if (-1 == mdsize) - { - GNUNET_break (0); - GNUNET_free (ub); - if (NULL != cont) - cont (cont_cls, NULL, _("Internal error.")); - return NULL; - } - sks_uri = GNUNET_malloc (sizeof (struct GNUNET_FS_Uri)); + + sks_uri = GNUNET_new (struct GNUNET_FS_Uri); sks_uri->type = GNUNET_FS_URI_SKS; sks_uri->data.sks.identifier = GNUNET_strdup (identifier); - GNUNET_FS_namespace_get_public_identifier (ns, - &sks_uri->data.sks.ns); - - size = sizeof (struct UBlock) + mdsize + slen + nidlen; - ub_enc = GNUNET_malloc (size); - GNUNET_CRYPTO_hash (identifier, idlen, &id_hash); - GNUNET_CRYPTO_hash (&sks_uri->data.sks.ns, - sizeof (sks_uri->data.sks.ns), &ns_hash); - GNUNET_CRYPTO_hash_xor (&id_hash, &ns_hash, &key); - GNUNET_CRYPTO_hash_to_aes_key (&key, &sk, &iv); - GNUNET_CRYPTO_hash (&key, sizeof (struct GNUNET_HashCode), &signing_key); - - GNUNET_CRYPTO_aes_encrypt (&ub[1], - size - sizeof (struct UBlock), - &sk, &iv, - &ub_enc[1]); - ub_enc->purpose.size = htonl (nidlen + slen + mdsize + sizeof (struct UBlock) - - sizeof (struct GNUNET_FS_PseudonymSignature)); - ub_enc->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_FS_UBLOCK); - GNUNET_FS_pseudonym_derive_verification_key (&sks_uri->data.sks.ns, - &signing_key, - &ub_enc->verification_key); - GNUNET_CRYPTO_hash (&ub_enc->verification_key, - sizeof (ub_enc->verification_key), - &query); - GNUNET_FS_pseudonym_sign (ns->key, - &ub_enc->purpose, - NULL, - &signing_key, - &ub_enc->signature); - psc = GNUNET_malloc (sizeof (struct GNUNET_FS_PublishSksContext)); + GNUNET_CRYPTO_ecc_key_get_public (ns, + &sks_uri->data.sks.ns); + + psc = GNUNET_new (struct GNUNET_FS_PublishSksContext); + psc->h = h; psc->uri = sks_uri; psc->cont = cont; - psc->ns = GNUNET_FS_namespace_dup (ns); psc->cont_cls = cont_cls; - if (0 != (options & GNUNET_FS_PUBLISH_OPTION_SIMULATE_ONLY)) - { - GNUNET_free (ub_enc); - GNUNET_free (ub); - sb_put_cont (psc, GNUNET_OK, GNUNET_TIME_UNIT_ZERO_ABS, NULL); - return NULL; - } - psc->dsh = GNUNET_DATASTORE_connect (h->cfg); - if (NULL == psc->dsh) + psc->ns = *ns; + if (0 == (options & GNUNET_FS_PUBLISH_OPTION_SIMULATE_ONLY)) { - GNUNET_free (ub_enc); - GNUNET_free (ub); - sb_put_cont (psc, GNUNET_NO, GNUNET_TIME_UNIT_ZERO_ABS, _("Failed to connect to datastore.")); - return NULL; + psc->dsh = GNUNET_DATASTORE_connect (h->cfg); + if (NULL == psc->dsh) + { + sks_publish_cont (psc, + _("Failed to connect to datastore.")); + return NULL; + } } - if (NULL != update) { - psc->nsn = GNUNET_malloc (sizeof (struct NamespaceUpdateNode)); + psc->nsn = GNUNET_new (struct NamespaceUpdateNode); psc->nsn->id = GNUNET_strdup (identifier); psc->nsn->update = GNUNET_strdup (update); psc->nsn->md = GNUNET_CONTAINER_meta_data_duplicate (meta); psc->nsn->uri = GNUNET_FS_uri_dup (uri); } - - psc->dqe = GNUNET_DATASTORE_put (psc->dsh, 0, &query, size, ub_enc, - GNUNET_BLOCK_TYPE_FS_UBLOCK, bo->content_priority, - bo->anonymity_level, bo->replication_level, - bo->expiration_time, -2, 1, - GNUNET_CONSTANTS_SERVICE_TIMEOUT, &sb_put_cont, psc); - GNUNET_free (ub); - GNUNET_free (ub_enc); + psc->uc = GNUNET_FS_publish_ublock_ (h, + psc->dsh, + identifier, + update, + ns, + meta, + uri, + bo, + options, + &sks_publish_cont, + psc); return psc; } @@ -776,17 +507,16 @@ GNUNET_FS_publish_sks (struct GNUNET_FS_Handle *h, void GNUNET_FS_publish_sks_cancel (struct GNUNET_FS_PublishSksContext *psc) { - if (NULL != psc->dqe) + if (NULL != psc->uc) { - GNUNET_DATASTORE_cancel (psc->dqe); - psc->dqe = NULL; + GNUNET_FS_publish_ublock_cancel_ (psc->uc); + psc->uc = NULL; } if (NULL != psc->dsh) { GNUNET_DATASTORE_disconnect (psc->dsh, GNUNET_NO); psc->dsh = NULL; } - GNUNET_FS_namespace_delete (psc->ns, GNUNET_NO); GNUNET_FS_uri_destroy (psc->uri); if (NULL != psc->nsn) { @@ -828,12 +558,18 @@ struct ProcessUpdateClosure * GNUNET_NO if not. */ static int -process_update_node (void *cls, const struct GNUNET_HashCode * key, void *value) +process_update_node (void *cls, + const struct GNUNET_HashCode *key, + void *value) { struct ProcessUpdateClosure *pc = cls; struct NamespaceUpdateNode *nsn = value; - pc->ip (pc->ip_cls, nsn->id, nsn->uri, nsn->md, nsn->update); + pc->ip (pc->ip_cls, + nsn->id, + nsn->uri, + nsn->md, + nsn->update); return GNUNET_YES; } @@ -844,9 +580,9 @@ process_update_node (void *cls, const struct GNUNET_HashCode * key, void *value) struct FindTreeClosure { /** - * Namespace we are operating on. + * UIG we are operating on. */ - struct GNUNET_FS_Namespace *ns; + struct GNUNET_FS_UpdateInformationGraph *uig; /** * Array with 'head's of TREEs. @@ -891,7 +627,9 @@ struct FindTreeClosure * GNUNET_NO if not. */ static int -find_trees (void *cls, const struct GNUNET_HashCode * key, void *value) +find_trees (void *cls, + const struct GNUNET_HashCode *key, + void *value) { struct FindTreeClosure *fc = cls; struct NamespaceUpdateNode *nsn = value; @@ -918,7 +656,7 @@ find_trees (void *cls, const struct GNUNET_HashCode * key, void *value) nsn->tree_id = UINT_MAX; /* mark as undef */ /* trace */ GNUNET_CRYPTO_hash (nsn->update, strlen (nsn->update), &hc); - GNUNET_CONTAINER_multihashmap_get_multiple (fc->ns->update_map, &hc, + GNUNET_CONTAINER_multihashmap_get_multiple (fc->uig->update_map, &hc, &find_trees, fc); } return GNUNET_YES; @@ -942,13 +680,15 @@ find_trees (void *cls, const struct GNUNET_HashCode * key, void *value) * I know, odd definition of a tree, but the GUI will display an actual * tree (GtkTreeView), so that's what counts for the term here. * + * @param h fs handle to use * @param ns namespace to inspect for updateable content * @param next_id ID to look for; use NULL to look for tree roots * @param ip function to call on each updateable identifier * @param ip_cls closure for ip */ void -GNUNET_FS_namespace_list_updateable (struct GNUNET_FS_Namespace *ns, +GNUNET_FS_namespace_list_updateable (struct GNUNET_FS_Handle *h, + const struct GNUNET_CRYPTO_EccPrivateKey *ns, const char *next_id, GNUNET_FS_IdentifierProcessor ip, void *ip_cls) @@ -959,50 +699,48 @@ GNUNET_FS_namespace_list_updateable (struct GNUNET_FS_Namespace *ns, struct NamespaceUpdateNode *nsn; struct ProcessUpdateClosure pc; struct FindTreeClosure fc; + struct GNUNET_FS_UpdateInformationGraph *uig; - if (NULL == ns->update_nodes) - read_update_information_graph (ns); - if (NULL == ns->update_nodes) + uig = read_update_information_graph (h, ns); + if (NULL == uig->update_nodes) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "No updateable nodes found for ID `%s'\n", next_id); + free_update_information_graph (uig); return; /* no nodes */ } - if (NULL == ns->update_map) + uig->update_map = + GNUNET_CONTAINER_multihashmap_create (2 + + 3 * uig->update_node_count / + 4, + GNUNET_NO); + for (i = 0; i < uig->update_node_count; i++) { - /* need to construct */ - ns->update_map = - GNUNET_CONTAINER_multihashmap_create (2 + - 3 * ns->update_node_count / - 4, - GNUNET_NO); - for (i = 0; i < ns->update_node_count; i++) - { - nsn = ns->update_nodes[i]; - GNUNET_CRYPTO_hash (nsn->id, strlen (nsn->id), &hc); - GNUNET_CONTAINER_multihashmap_put (ns->update_map, &hc, nsn, - GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); - } + nsn = uig->update_nodes[i]; + GNUNET_CRYPTO_hash (nsn->id, strlen (nsn->id), &hc); + GNUNET_CONTAINER_multihashmap_put (uig->update_map, &hc, nsn, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); } if (NULL != next_id) { GNUNET_CRYPTO_hash (next_id, strlen (next_id), &hc); pc.ip = ip; pc.ip_cls = ip_cls; - GNUNET_CONTAINER_multihashmap_get_multiple (ns->update_map, &hc, + GNUNET_CONTAINER_multihashmap_get_multiple (uig->update_map, &hc, &process_update_node, &pc); + free_update_information_graph (uig); return; } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Calculating TREEs to find roots of update trees\n"); /* Find heads of TREEs in update graph */ - nug = ++ns->nug_gen; + nug = ++uig->nug_gen; fc.tree_array = NULL; fc.tree_array_size = 0; - for (i = 0; i < ns->update_node_count; i++) + for (i = 0; i < uig->update_node_count; i++) { - nsn = ns->update_nodes[i]; + nsn = uig->update_nodes[i]; if (nsn->nug == nug) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "TREE of node `%s' is %u\n", nsn->id, @@ -1014,15 +752,15 @@ GNUNET_FS_namespace_list_updateable (struct GNUNET_FS_Namespace *ns, nsn->tree_id = UINT_MAX; fc.id = UINT_MAX; fc.nug = nug; - fc.ns = ns; - GNUNET_CONTAINER_multihashmap_get_multiple (ns->update_map, &hc, + fc.uig = uig; + GNUNET_CONTAINER_multihashmap_get_multiple (uig->update_map, &hc, &find_trees, &fc); if (UINT_MAX == fc.id) { /* start new TREE */ for (fc.id = 0; fc.id < fc.tree_array_size; fc.id++) { - if (fc.tree_array[fc.id] == NULL) + if (NULL == fc.tree_array[fc.id]) { fc.tree_array[fc.id] = nsn; nsn->tree_id = fc.id; @@ -1041,8 +779,8 @@ GNUNET_FS_namespace_list_updateable (struct GNUNET_FS_Namespace *ns, GNUNET_CRYPTO_hash (nsn->id, strlen (nsn->id), &hc); fc.id = nsn->tree_id; fc.nug = nug; - fc.ns = ns; - GNUNET_CONTAINER_multihashmap_get_multiple (ns->update_map, &hc, + fc.uig = uig; + GNUNET_CONTAINER_multihashmap_get_multiple (uig->update_map, &hc, &find_trees, &fc); } else @@ -1051,7 +789,8 @@ GNUNET_FS_namespace_list_updateable (struct GNUNET_FS_Namespace *ns, fc.tree_array[fc.id] = nsn; nsn->tree_id = fc.id; } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "TREE of node `%s' is %u\n", nsn->id, + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "TREE of node `%s' is %u\n", nsn->id, fc.id); } for (i = 0; i < fc.tree_array_size; i++) @@ -1066,6 +805,7 @@ GNUNET_FS_namespace_list_updateable (struct GNUNET_FS_Namespace *ns, } GNUNET_array_grow (fc.tree_array, fc.tree_array_size, 0); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Done processing TREEs\n"); + free_update_information_graph (uig); } diff --git a/src/fs/fs_pseudonym.c b/src/fs/fs_pseudonym.c index 36eaab6fa..f5493ca16 100644 --- a/src/fs/fs_pseudonym.c +++ b/src/fs/fs_pseudonym.c @@ -21,15 +21,10 @@ * @file fs/fs_pseudonym.c * @brief pseudonym functions * @author Christian Grothoff - * - * TODO: - * - all cryptographic operations are currently NOT implemented and - * provided by stubs that merely pretend to work! */ #include "platform.h" #include "gnunet_util_lib.h" #include "gnunet_fs_service.h" -#include #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__) @@ -38,12 +33,6 @@ #define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util", syscall, filename) -/** - * Log an error message at log-level 'level' that indicates - * a failure of the command 'cmd' with the message given - * by gcry_strerror(rc). - */ -#define LOG_GCRY(level, cmd, rc) do { LOG(level, _("`%s' failed at %s:%d with error: %s\n"), cmd, __FILE__, __LINE__, gcry_strerror(rc)); } while(0); /** * Name of the directory which stores meta data for pseudonym @@ -67,17 +56,17 @@ /** * Registered callbacks for discovery of pseudonyms. */ -struct GNUNET_FS_pseudonym_DiscoveryHandle +struct GNUNET_FS_Pseudonym_DiscoveryHandle { /** * This is a doubly linked list. */ - struct GNUNET_FS_pseudonym_DiscoveryHandle *next; + struct GNUNET_FS_Pseudonym_DiscoveryHandle *next; /** * This is a doubly linked list. */ - struct GNUNET_FS_pseudonym_DiscoveryHandle *prev; + struct GNUNET_FS_Pseudonym_DiscoveryHandle *prev; /** * Function to call each time a pseudonym is discovered. @@ -95,19 +84,14 @@ struct GNUNET_FS_pseudonym_DiscoveryHandle * Head of the linked list of functions to call when * new pseudonyms are added. */ -static struct GNUNET_FS_pseudonym_DiscoveryHandle *disco_head; +static struct GNUNET_FS_Pseudonym_DiscoveryHandle *disco_head; /** * Tail of the linked list of functions to call when * new pseudonyms are added. */ -static struct GNUNET_FS_pseudonym_DiscoveryHandle *disco_tail; +static struct GNUNET_FS_Pseudonym_DiscoveryHandle *disco_tail; -/** - * Pointer to indiate 'anonymous' pseudonym (global static, - * d=1, public key = G (generator). - */ -static struct GNUNET_FS_PseudonymHandle anonymous; /** * Internal notification about new tracked URI. @@ -117,10 +101,10 @@ static struct GNUNET_FS_PseudonymHandle anonymous; * @param rating rating of pseudonym */ static void -internal_notify (const struct GNUNET_FS_PseudonymIdentifier *pseudonym, +internal_notify (const struct GNUNET_CRYPTO_EccPublicKey *pseudonym, const struct GNUNET_CONTAINER_MetaData *md, int rating) { - struct GNUNET_FS_pseudonym_DiscoveryHandle *pos; + struct GNUNET_FS_Pseudonym_DiscoveryHandle *pos; for (pos = disco_head; NULL != pos; pos = pos->next) pos->callback (pos->callback_cls, pseudonym, NULL, NULL, md, rating); @@ -138,15 +122,15 @@ internal_notify (const struct GNUNET_FS_PseudonymIdentifier *pseudonym, * @param iterator_cls point to a closure * @return registration handle */ -struct GNUNET_FS_pseudonym_DiscoveryHandle * +struct GNUNET_FS_Pseudonym_DiscoveryHandle * GNUNET_FS_pseudonym_discovery_callback_register (const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_FS_PseudonymIterator iterator, void *iterator_cls) { - struct GNUNET_FS_pseudonym_DiscoveryHandle *dh; + struct GNUNET_FS_Pseudonym_DiscoveryHandle *dh; - dh = GNUNET_malloc (sizeof (struct GNUNET_FS_pseudonym_DiscoveryHandle)); + dh = GNUNET_new (struct GNUNET_FS_Pseudonym_DiscoveryHandle); dh->callback = iterator; dh->callback_cls = iterator_cls; GNUNET_CONTAINER_DLL_insert (disco_head, disco_tail, dh); @@ -161,7 +145,7 @@ GNUNET_FS_pseudonym_discovery_callback_register (const struct * @param dh registration to unregister */ void -GNUNET_FS_pseudonym_discovery_callback_unregister (struct GNUNET_FS_pseudonym_DiscoveryHandle *dh) +GNUNET_FS_pseudonym_discovery_callback_unregister (struct GNUNET_FS_Pseudonym_DiscoveryHandle *dh) { GNUNET_CONTAINER_DLL_remove (disco_head, disco_tail, dh); GNUNET_free (dh); @@ -180,7 +164,7 @@ GNUNET_FS_pseudonym_discovery_callback_unregister (struct GNUNET_FS_pseudonym_Di static char * get_data_filename (const struct GNUNET_CONFIGURATION_Handle *cfg, const char *prefix, - const struct GNUNET_FS_PseudonymIdentifier *pseudonym) + const struct GNUNET_CRYPTO_EccPublicKey *pseudonym) { struct GNUNET_CRYPTO_HashAsciiEncoded enc; struct GNUNET_HashCode psid; @@ -188,7 +172,7 @@ get_data_filename (const struct GNUNET_CONFIGURATION_Handle *cfg, if (NULL != pseudonym) { GNUNET_CRYPTO_hash (pseudonym, - sizeof (struct GNUNET_FS_PseudonymIdentifier), + sizeof (struct GNUNET_CRYPTO_EccPublicKey), &psid); GNUNET_CRYPTO_hash_to_enc (&psid, &enc); } @@ -243,7 +227,7 @@ get_data_filename_hash (const struct GNUNET_CONFIGURATION_Handle *cfg, */ int GNUNET_FS_pseudonym_set_info (const struct GNUNET_CONFIGURATION_Handle *cfg, - const struct GNUNET_FS_PseudonymIdentifier *pseudonym, + const struct GNUNET_CRYPTO_EccPublicKey *pseudonym, const char *name, const struct GNUNET_CONTAINER_MetaData *md, int32_t rank) @@ -258,7 +242,7 @@ GNUNET_FS_pseudonym_set_info (const struct GNUNET_CONFIGURATION_Handle *cfg, return GNUNET_SYSERR; } if ((GNUNET_OK != GNUNET_BIO_write (fileW, pseudonym, - sizeof (struct GNUNET_FS_PseudonymIdentifier))) || + sizeof (struct GNUNET_CRYPTO_EccPublicKey))) || (GNUNET_OK != GNUNET_BIO_write_int32 (fileW, rank)) || (GNUNET_OK != GNUNET_BIO_write_string (fileW, name)) || (GNUNET_OK != GNUNET_BIO_write_meta_data (fileW, md))) @@ -295,12 +279,12 @@ GNUNET_FS_pseudonym_set_info (const struct GNUNET_CONFIGURATION_Handle *cfg, */ static int read_info (const struct GNUNET_CONFIGURATION_Handle *cfg, - const struct GNUNET_FS_PseudonymIdentifier *pseudonym, + const struct GNUNET_CRYPTO_EccPublicKey *pseudonym, struct GNUNET_CONTAINER_MetaData **meta, int32_t *rank, char **ns_name) { - struct GNUNET_FS_PseudonymIdentifier pd; + struct GNUNET_CRYPTO_EccPublicKey pd; char *fn; char *emsg; struct GNUNET_BIO_ReadHandle *fileR; @@ -367,12 +351,12 @@ read_info (const struct GNUNET_CONFIGURATION_Handle *cfg, */ char * GNUNET_FS_pseudonym_name_uniquify (const struct GNUNET_CONFIGURATION_Handle *cfg, - const struct GNUNET_FS_PseudonymIdentifier *pseudonym, + const struct GNUNET_CRYPTO_EccPublicKey *pseudonym, const char *name, unsigned int *suffix) { struct GNUNET_HashCode nh; - struct GNUNET_FS_PseudonymIdentifier pi; + struct GNUNET_CRYPTO_EccPublicKey pi; uint64_t len; char *fn; struct GNUNET_DISK_FileHandle *fh; @@ -393,11 +377,11 @@ GNUNET_FS_pseudonym_name_uniquify (const struct GNUNET_CONFIGURATION_Handle *cfg GNUNET_DISK_PERM_USER_WRITE); i = 0; idx = -1; - while ((len >= sizeof (struct GNUNET_FS_PseudonymIdentifier)) && - (sizeof (struct GNUNET_FS_PseudonymIdentifier) == - GNUNET_DISK_file_read (fh, &pi, sizeof (struct GNUNET_FS_PseudonymIdentifier)))) + while ((len >= sizeof (struct GNUNET_CRYPTO_EccPublicKey)) && + (sizeof (struct GNUNET_CRYPTO_EccPublicKey) == + GNUNET_DISK_file_read (fh, &pi, sizeof (struct GNUNET_CRYPTO_EccPublicKey)))) { - if (0 == memcmp (&pi, pseudonym, sizeof (struct GNUNET_FS_PseudonymIdentifier))) + if (0 == memcmp (&pi, pseudonym, sizeof (struct GNUNET_CRYPTO_EccPublicKey))) { idx = i; break; @@ -408,8 +392,8 @@ GNUNET_FS_pseudonym_name_uniquify (const struct GNUNET_CONFIGURATION_Handle *cfg if (-1 == idx) { idx = i; - if (sizeof (struct GNUNET_FS_PseudonymIdentifier) != - GNUNET_DISK_file_write (fh, pseudonym, sizeof (struct GNUNET_FS_PseudonymIdentifier))) + if (sizeof (struct GNUNET_CRYPTO_EccPublicKey) != + GNUNET_DISK_file_write (fh, pseudonym, sizeof (struct GNUNET_CRYPTO_EccPublicKey))) LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "write", fn); } GNUNET_DISK_file_close (fh); @@ -442,11 +426,11 @@ GNUNET_FS_pseudonym_name_uniquify (const struct GNUNET_CONFIGURATION_Handle *cfg */ int GNUNET_FS_pseudonym_get_info (const struct GNUNET_CONFIGURATION_Handle *cfg, - const struct GNUNET_FS_PseudonymIdentifier *pseudonym, - struct GNUNET_CONTAINER_MetaData **ret_meta, - int32_t *ret_rank, - char **ret_name, - int *name_is_a_dup) + const struct GNUNET_CRYPTO_EccPublicKey *pseudonym, + struct GNUNET_CONTAINER_MetaData **ret_meta, + int32_t *ret_rank, + char **ret_name, + int *name_is_a_dup) { struct GNUNET_CONTAINER_MetaData *meta; char *name; @@ -521,7 +505,7 @@ GNUNET_FS_pseudonym_get_info (const struct GNUNET_CONFIGURATION_Handle *cfg, int GNUNET_FS_pseudonym_name_to_id (const struct GNUNET_CONFIGURATION_Handle *cfg, const char *ns_uname, - struct GNUNET_FS_PseudonymIdentifier *pseudonym) + struct GNUNET_CRYPTO_EccPublicKey *pseudonym) { size_t slen; uint64_t len; @@ -546,7 +530,7 @@ GNUNET_FS_pseudonym_name_to_id (const struct GNUNET_CONFIGURATION_Handle *cfg, if ((GNUNET_OK != GNUNET_DISK_file_test (fn) || (GNUNET_OK != GNUNET_DISK_file_size (fn, &len, GNUNET_YES, GNUNET_YES))) || - ((idx + 1) * sizeof (struct GNUNET_FS_PseudonymIdentifier) > len)) + ((idx + 1) * sizeof (struct GNUNET_CRYPTO_EccPublicKey) > len)) { GNUNET_free (fn); return GNUNET_SYSERR; @@ -558,14 +542,14 @@ GNUNET_FS_pseudonym_name_to_id (const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_DISK_PERM_USER_WRITE); GNUNET_free (fn); if (GNUNET_SYSERR == - GNUNET_DISK_file_seek (fh, idx * sizeof (struct GNUNET_FS_PseudonymIdentifier), + GNUNET_DISK_file_seek (fh, idx * sizeof (struct GNUNET_CRYPTO_EccPublicKey), GNUNET_DISK_SEEK_SET)) { GNUNET_DISK_file_close (fh); return GNUNET_SYSERR; } - if (sizeof (struct GNUNET_FS_PseudonymIdentifier) != - GNUNET_DISK_file_read (fh, pseudonym, sizeof (struct GNUNET_FS_PseudonymIdentifier))) + if (sizeof (struct GNUNET_CRYPTO_EccPublicKey) != + GNUNET_DISK_file_read (fh, pseudonym, sizeof (struct GNUNET_CRYPTO_EccPublicKey))) { GNUNET_DISK_file_close (fh); return GNUNET_SYSERR; @@ -610,7 +594,7 @@ static int list_pseudonym_helper (void *cls, const char *fullname) { struct ListPseudonymClosure *lpc = cls; - struct GNUNET_FS_PseudonymIdentifier pd; + struct GNUNET_CRYPTO_EccPublicKey pd; char *emsg; struct GNUNET_BIO_ReadHandle *fileR; int32_t rank; @@ -699,7 +683,7 @@ GNUNET_FS_pseudonym_list_all (const struct GNUNET_CONFIGURATION_Handle *cfg, */ int GNUNET_FS_pseudonym_rank (const struct GNUNET_CONFIGURATION_Handle *cfg, - const struct GNUNET_FS_PseudonymIdentifier *pseudonym, + const struct GNUNET_CRYPTO_EccPublicKey *pseudonym, int32_t delta) { struct GNUNET_CONTAINER_MetaData *meta; @@ -734,8 +718,8 @@ GNUNET_FS_pseudonym_rank (const struct GNUNET_CONFIGURATION_Handle *cfg, */ int GNUNET_FS_pseudonym_add (const struct GNUNET_CONFIGURATION_Handle *cfg, - const struct GNUNET_FS_PseudonymIdentifier *pseudonym, - const struct GNUNET_CONTAINER_MetaData *meta) + const struct GNUNET_CRYPTO_EccPublicKey *pseudonym, + const struct GNUNET_CONTAINER_MetaData *meta) { char *name; int32_t rank; @@ -766,888 +750,5 @@ GNUNET_FS_pseudonym_add (const struct GNUNET_CONFIGURATION_Handle *cfg, } -/* ***************************** cryptographic operations ************************* */ - -/** - * Handle for a pseudonym (private key). - */ -struct GNUNET_FS_PseudonymHandle -{ - /** - * 256-bit 'd' secret value (mod 'n', where n is 256-bit for NIST P-256). - */ - unsigned char d[256 / 8]; - - /** - * Public key corresponding to the private key. - */ - struct GNUNET_FS_PseudonymIdentifier public_key; -}; - - -/** - * If target != size, move target bytes to the end of the size-sized - * buffer and zero out the first target-size bytes. - * - * @param buf original buffer - * @param size number of bytes in the buffer - * @param target target size of the buffer - */ -static void -adjust (unsigned char *buf, size_t size, size_t target) -{ - if (size < target) - { - memmove (&buf[target - size], buf, size); - memset (buf, 0, target - size); - } -} - - -/** - * Extract values from an S-expression. - * - * @param array where to store the result(s) - * @param sexp S-expression to parse - * @param topname top-level name in the S-expression that is of interest - * @param elems names of the elements to extract - * @return 0 on success - */ -static int -key_from_sexp (gcry_mpi_t * array, gcry_sexp_t sexp, const char *topname, - const char *elems) -{ - gcry_sexp_t list; - gcry_sexp_t l2; - const char *s; - unsigned int i; - unsigned int idx; - - if (! (list = gcry_sexp_find_token (sexp, topname, 0))) - return 1; - l2 = gcry_sexp_cadr (list); - gcry_sexp_release (list); - list = l2; - if (! list) - return 2; - idx = 0; - for (s = elems; *s; s++, idx++) - { - if (! (l2 = gcry_sexp_find_token (list, s, 1))) - { - for (i = 0; i < idx; i++) - { - gcry_free (array[i]); - array[i] = NULL; - } - gcry_sexp_release (list); - return 3; /* required parameter not found */ - } - array[idx] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG); - gcry_sexp_release (l2); - if (! array[idx]) - { - for (i = 0; i < idx; i++) - { - gcry_free (array[i]); - array[i] = NULL; - } - gcry_sexp_release (list); - return 4; /* required parameter is invalid */ - } - } - gcry_sexp_release (list); - return 0; -} - - -/** - * Create a pseudonym. - * - * @param filename name of the file to use for storage, NULL for in-memory only - * @return handle to the private key of the pseudonym - */ -struct GNUNET_FS_PseudonymHandle * -GNUNET_FS_pseudonym_create (const char *filename) -{ - struct GNUNET_FS_PseudonymHandle *ph; - ssize_t ret; - gcry_sexp_t r_key; - gcry_sexp_t params; - gcry_ctx_t ctx; - gcry_mpi_point_t q; - gcry_mpi_t q_x; - gcry_mpi_t q_y; - gcry_error_t rc; - gcry_mpi_t d; - size_t size; - - ph = GNUNET_malloc (sizeof (struct GNUNET_FS_PseudonymHandle)); - if ( (NULL != filename) && - (GNUNET_YES == GNUNET_DISK_file_test (filename)) ) - { - ret = GNUNET_DISK_fn_read (filename, ph, - sizeof (struct GNUNET_FS_PseudonymHandle)); - /* Note: we don't do any validation here, maybe we should? */ - if (sizeof (struct GNUNET_FS_PseudonymHandle) == ret) - return ph; - } - if (0 != (rc = gcry_sexp_build (¶ms, NULL, - "(genkey(ecdsa(curve \"NIST P-256\")))"))) - { - LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc); - return NULL; - } - if (0 != (rc = gcry_pk_genkey (&r_key, params))) - { - LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_pk_genkey", rc); - gcry_sexp_release (params); - gcry_sexp_release (r_key); - return NULL; - } - gcry_sexp_release (params); - /* extract "d" (secret key) from r_key */ - rc = key_from_sexp (&d, r_key, "private-key", "d"); - if (0 != rc) - rc = key_from_sexp (&d, r_key, "private-key", "d"); - if (0 != rc) - rc = key_from_sexp (&d, r_key, "ecc", "d"); - if (0 != rc) - { - gcry_sexp_release (r_key); - LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "key_from_sexp", rc); - return NULL; - } - size = sizeof (ph->d); - GNUNET_assert (0 == - gcry_mpi_print (GCRYMPI_FMT_USG, ph->d, size, &size, - d)); - gcry_mpi_release (d); - adjust (ph->d, size, sizeof (ph->d)); - - /* extract 'q' (public key) from r_key */ - if (0 != (rc = gcry_mpi_ec_new (&ctx, r_key, NULL))) - { - LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_ec_new", rc); /* erroff gives more info */ - gcry_sexp_release (r_key); - return NULL; - } - gcry_sexp_release (r_key); - q = gcry_mpi_ec_get_point ("q", ctx, 0); - q_x = gcry_mpi_new (256); - q_y = gcry_mpi_new (256); - gcry_mpi_ec_get_affine (q_x, q_y, q, ctx); - gcry_mpi_point_release (q); - gcry_ctx_release (ctx); - - /* store q_x/q_y in public key */ - size = sizeof (ph->public_key.q_x); - if (0 != - gcry_mpi_print (GCRYMPI_FMT_USG, ph->public_key.q_x, size, &size, - q_x)) - { - LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_print", rc); - gcry_mpi_release (q_x); - gcry_mpi_release (q_y); - return NULL; - - } - adjust (ph->public_key.q_x, size, sizeof (ph->public_key.q_x)); - gcry_mpi_release (q_x); - - size = sizeof (ph->public_key.q_y); - if (0 != - gcry_mpi_print (GCRYMPI_FMT_USG, ph->public_key.q_y, size, &size, - q_y)) - { - LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_print", rc); - gcry_mpi_release (q_y); - return NULL; - } - adjust (ph->public_key.q_y, size, sizeof (ph->public_key.q_y)); - gcry_mpi_release (q_y); - - /* write to disk */ - if (NULL != filename) - { - ret = GNUNET_DISK_fn_write (filename, ph, sizeof (struct GNUNET_FS_PseudonymHandle), - GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE); - if (sizeof (struct GNUNET_FS_PseudonymHandle) != ret) - { - GNUNET_free (ph); - return NULL; - } - } - return ph; -} - - -/** - * Create a pseudonym, from a file that must already exist. - * - * @param filename name of the file to use for storage, NULL for in-memory only - * @return handle to the private key of the pseudonym - */ -struct GNUNET_FS_PseudonymHandle * -GNUNET_FS_pseudonym_create_from_existing_file (const char *filename) -{ - struct GNUNET_FS_PseudonymHandle *ph; - ssize_t ret; - - ph = GNUNET_malloc (sizeof (struct GNUNET_FS_PseudonymHandle)); - ret = GNUNET_DISK_fn_read (filename, ph, - sizeof (struct GNUNET_FS_PseudonymHandle)); - if (sizeof (struct GNUNET_FS_PseudonymHandle) != ret) - { - GNUNET_free (ph); - return NULL; - } - /* Note: we don't do any validation here; maybe we should? */ - return ph; -} - - -/** - * Get the handle for the 'anonymous' pseudonym shared by all users. - * That pseudonym uses a fixed 'secret' for the private key; this - * construction is useful to make anonymous and pseudonymous APIs - * (and packets) indistinguishable on the network. See #2564. - * - * @return handle to the (non-secret) private key of the 'anonymous' pseudonym - */ -struct GNUNET_FS_PseudonymHandle * -GNUNET_FS_pseudonym_get_anonymous_pseudonym_handle () -{ - static int once; - gcry_mpi_t d; - size_t size; - gcry_ctx_t ctx; - int rc; - gcry_mpi_t g_x; - gcry_mpi_t g_y; - gcry_mpi_point_t g; - - if (once) - return &anonymous; - d = gcry_mpi_new (1); - gcry_mpi_set_ui (d, 1); - size = sizeof (anonymous.d); - GNUNET_assert (0 == - gcry_mpi_print (GCRYMPI_FMT_USG, anonymous.d, size, &size, - d)); - gcry_mpi_release (d); - adjust (anonymous.d, size, sizeof (anonymous.d)); - - /* create basic ECC context */ - if (0 != (rc = gcry_mpi_ec_new (&ctx, NULL, "NIST P-256"))) - { - LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, - "gcry_mpi_ec_new", rc); - return NULL; - } - - g = gcry_mpi_ec_get_point ("g", ctx, 0); - g_x = gcry_mpi_new (256); - g_y = gcry_mpi_new (256); - gcry_mpi_ec_get_affine (g_x, g_y, g, ctx); - gcry_mpi_point_release (g); - gcry_ctx_release (ctx); - - /* store g_x/g_y in public key */ - size = sizeof (anonymous.public_key.q_x); - if (0 != - gcry_mpi_print (GCRYMPI_FMT_USG, anonymous.public_key.q_x, size, &size, - g_x)) - { - LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_print", rc); - gcry_mpi_release (g_x); - gcry_mpi_release (g_y); - return NULL; - } - adjust (anonymous.public_key.q_x, size, sizeof (anonymous.public_key.q_x)); - gcry_mpi_release (g_x); - - size = sizeof (anonymous.public_key.q_y); - if (0 != - gcry_mpi_print (GCRYMPI_FMT_USG, anonymous.public_key.q_y, size, &size, - g_y)) - { - LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_print", rc); - gcry_mpi_release (g_y); - return NULL; - } - adjust (anonymous.public_key.q_y, size, sizeof (anonymous.public_key.q_y)); - gcry_mpi_release (g_y); - - once = 1; - return &anonymous; -} - - -/** - * Destroy a pseudonym handle. Does NOT remove the private key from - * the disk. - * - * @param ph pseudonym handle to destroy - */ -void -GNUNET_FS_pseudonym_destroy (struct GNUNET_FS_PseudonymHandle *ph) -{ - if (&anonymous != ph) - GNUNET_free (ph); -} - - -/** - * Convert the data specified in the given purpose argument to an - * S-expression suitable for signature operations. - * - * @param purpose data to convert - * @param rfc6979 GNUNET_YES if we are to use deterministic ECDSA - * @return converted s-expression - */ -static gcry_sexp_t -data_to_pkcs1 (const struct GNUNET_FS_PseudonymSignaturePurpose *purpose, - int rfc6979) -{ - struct GNUNET_CRYPTO_ShortHashCode hc; - size_t bufSize; - gcry_sexp_t data; - const char *fmt; - int rc; - - GNUNET_CRYPTO_short_hash (purpose, ntohl (purpose->size), &hc); - if (rfc6979) - { - if (0 != (rc = gcry_sexp_build (&data, NULL, - "(data(flags rfc6979)(hash %s %b))", - "sha256", - sizeof (hc), - &hc))) - { - LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc); - return NULL; - } - } - else - { - fmt = "(data(flags raw)(5:value32:01234567890123456789012345678901))"; - bufSize = strlen (fmt) + 1; - { - char buff[bufSize]; - - memcpy (buff, fmt, bufSize); - memcpy (&buff - [bufSize - - strlen - ("01234567890123456789012345678901))") - - 1], &hc, sizeof (struct GNUNET_CRYPTO_ShortHashCode)); - GNUNET_assert (0 == gcry_sexp_new (&data, buff, bufSize, 0)); - } - } - return data; -} - - -/** - * Cryptographically sign some data with the pseudonym. - * - * @param ph private key 'd' used for signing (corresponds to 'x' in #2564) - * @param purpose data to sign - * @param seed hash of the plaintext of the data that we are signing, - * used for deterministic PRNG for anonymous signing; - * corresponds to 'k' in section 2.7 of #2564 - * @param signing_key modifier to apply to the private key for signing ('h'); - * see section 2.3 of #2564. - * @param signature where to store the signature - * @return GNUNET_SYSERR on failure - */ -int -GNUNET_FS_pseudonym_sign (struct GNUNET_FS_PseudonymHandle *ph, - const struct GNUNET_FS_PseudonymSignaturePurpose *purpose, - const struct GNUNET_HashCode *seed, - const struct GNUNET_HashCode *signing_key, - struct GNUNET_FS_PseudonymSignature *signature) -{ - size_t size; - size_t erroff; - gcry_mpi_t d; - gcry_mpi_t k; - gcry_mpi_t h; - gcry_mpi_t dh; - gcry_mpi_t n; /* n from P-256 */ - gcry_sexp_t spriv; - gcry_sexp_t data; - gcry_sexp_t result; - gcry_mpi_t rs[2]; - int rc; - - /* get private key 'd' from pseudonym */ - size = sizeof (ph->d); - if (0 != (rc = gcry_mpi_scan (&d, GCRYMPI_FMT_USG, - &ph->d, - size, &size))) - { - LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc); - return GNUNET_SYSERR; - } - /* get 'x' value from signing key */ - size = sizeof (struct GNUNET_HashCode); - if (0 != (rc = gcry_mpi_scan (&h, GCRYMPI_FMT_USG, - signing_key, - size, &size))) - { - LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc); - gcry_mpi_release (d); - return GNUNET_SYSERR; - } - - /* initialize 'n' from P-256; hex copied from libgcrypt code */ - if (0 != (rc = gcry_mpi_scan (&n, GCRYMPI_FMT_HEX, - "0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", 0, NULL))) - { - LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc); - gcry_mpi_release (d); - gcry_mpi_release (h); - return GNUNET_SYSERR; - } - - /* calculate dh = d * h mod n */ - dh = gcry_mpi_new (256); - gcry_mpi_mulm (dh, d, h, n); - gcry_mpi_release (d); - gcry_mpi_release (h); - gcry_mpi_release (n); - - /* now build sexpression with the signing key */ - if (0 != (rc = gcry_sexp_build (&spriv, &erroff, - "(private-key(ecdsa(curve \"NIST P-256\")(d %m)))", - dh))) - { - LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc); - gcry_mpi_release (dh); - return GNUNET_SYSERR; - } - gcry_mpi_release (dh); - /* prepare data for signing */ - data = data_to_pkcs1 (purpose, NULL != seed); - if (NULL == data) - { - gcry_sexp_release (spriv); - return GNUNET_SYSERR; - } - /* get 'k' value from seed, if available */ - if (NULL != seed) - { - size = sizeof (struct GNUNET_HashCode); - if (0 != (rc = gcry_mpi_scan (&k, GCRYMPI_FMT_USG, - seed, - size, &size))) - { - LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc); - gcry_sexp_release (spriv); - gcry_sexp_release (data); - return GNUNET_SYSERR; - } - } - - /* actually create signature */ - /* FIXME: need API to pass 'k' if 'seed' was non-NULL! */ - if (0 != (rc = gcry_pk_sign (&result, data, spriv))) - { - LOG (GNUNET_ERROR_TYPE_WARNING, - _("ECC signing failed at %s:%d: %s\n"), __FILE__, - __LINE__, gcry_strerror (rc)); - gcry_sexp_release (data); - gcry_sexp_release (spriv); - if (NULL != seed) - gcry_mpi_release (k); - memset (signature, 0, sizeof (struct GNUNET_FS_PseudonymSignature)); - return GNUNET_SYSERR; - } - if (NULL != seed) - gcry_mpi_release (k); - gcry_sexp_release (data); - gcry_sexp_release (spriv); - - - /* extract 'r' and 's' values from sexpression 'result' and store in 'signature' */ - if (0 != (rc = key_from_sexp (rs, result, "sig-val", "rs"))) - { - GNUNET_break (0); - gcry_sexp_release (result); - return GNUNET_SYSERR; - } - gcry_sexp_release (result); - size = sizeof (signature->sig_r); - if (0 != (rc = gcry_mpi_print (GCRYMPI_FMT_USG, signature->sig_r, size, - &size, rs[0]))) - { - LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_print", rc); - gcry_mpi_release (rs[0]); - gcry_mpi_release (rs[1]); - return GNUNET_SYSERR; - } - adjust (signature->sig_r, size, sizeof (signature->sig_r)); - gcry_mpi_release (rs[0]); - - size = sizeof (signature->sig_s); - if (0 != (rc = gcry_mpi_print (GCRYMPI_FMT_USG, signature->sig_s, size, - &size, rs[1]))) - { - LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_print", rc); - gcry_mpi_release (rs[1]); - return GNUNET_SYSERR; - } - adjust (signature->sig_s, size, sizeof (signature->sig_s)); - gcry_mpi_release (rs[1]); - -#if EXTRA_CHECKS - { - struct GNUNET_FS_PseudonymIdentifier vk; - struct GNUNET_FS_PseudonymIdentifier pi; - - GNUNET_FS_pseudonym_get_identifier (ph, &pi); - GNUNET_assert (GNUNET_OK == - GNUNET_FS_pseudonym_derive_verification_key (&pi, signing_key, &vk)); - GNUNET_assert (GNUNET_OK == - GNUNET_FS_pseudonym_verify (purpose, - signature, - &vk)); - } -#endif - - GNUNET_FS_pseudonym_get_identifier (ph, &signature->signer); - return GNUNET_OK; -} - - -/** - * Get an ECC context (with Q set to the respective public key) from - * a pseudonym. - * - * @param pseudonym with information on 'q' - * @return curve context - */ -static gcry_ctx_t -get_context_from_pseudonym (struct GNUNET_FS_PseudonymIdentifier *pseudonym) -{ - static struct GNUNET_FS_PseudonymIdentifier zerop; - gcry_ctx_t ctx; - gcry_mpi_t q_x; - gcry_mpi_t q_y; - gcry_mpi_t zero; - gcry_mpi_point_t q; - size_t size; - int rc; - - /* extract 'q' from pseudonym */ - if (0 == memcmp (pseudonym, &zerop, sizeof (zerop))) - { - /* create basic ECC context */ - if (0 != (rc = gcry_mpi_ec_new (&ctx, NULL, "NIST P-256"))) - { - LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_ec_new", rc); /* erroff gives more info */ - return NULL; - } - /* FIXME: initialize 'ctx' with 'q' = G */ - zero = gcry_mpi_new (0); - gcry_mpi_set_ui (zero, 0); - q = gcry_mpi_point_new (0); - gcry_mpi_point_set (q, zero, zero, zero); - gcry_mpi_ec_set_point ("q", q, ctx); - gcry_mpi_release (zero); - gcry_mpi_point_release (q); - return ctx; - } - size = sizeof (pseudonym->q_x); - if (0 != (rc = gcry_mpi_scan (&q_x, GCRYMPI_FMT_USG, pseudonym->q_x, size, &size))) - { - LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc); - return NULL; - } - size = sizeof (pseudonym->q_y); - if (0 != (rc = gcry_mpi_scan (&q_y, GCRYMPI_FMT_USG, pseudonym->q_y, size, &size))) - { - LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc); - gcry_mpi_release (q_x); - return NULL; - } - q = gcry_mpi_point_new (256); - gcry_mpi_point_set (q, q_x, q_y, GCRYMPI_CONST_ONE); - gcry_mpi_release (q_x); - gcry_mpi_release (q_y); - - /* create basic ECC context */ - if (0 != (rc = gcry_mpi_ec_new (&ctx, NULL, "NIST P-256"))) - { - LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_ec_new", rc); /* erroff gives more info */ - gcry_mpi_point_release (q); - return NULL; - } - /* initialize 'ctx' with 'q' */ - gcry_mpi_ec_set_point ("q", q, ctx); - gcry_mpi_point_release (q); - return ctx; -} - - -/** - * Given a pseudonym and a signing key, derive the corresponding public - * key that would be used to verify the resulting signature. - * - * @param pseudonym the public key (dQ in ECDSA) - * @param signing_key input to derive 'h' (see section 2.4 of #2564) - * @param verification_key resulting public key to verify the signature - * created from the '(d*h)' of 'pseudonym' and the 'signing_key'; - * the value stored here can then be given to GNUNET_FS_pseudonym_verify. - * @return GNUNET_OK on success, GNUNET_SYSERR on error - */ -int -GNUNET_FS_pseudonym_derive_verification_key (struct GNUNET_FS_PseudonymIdentifier *pseudonym, - const struct GNUNET_HashCode *signing_key, - struct GNUNET_FS_PseudonymIdentifier *verification_key) -{ - gcry_mpi_t h; - size_t size; - int rc; - gcry_ctx_t ctx; - gcry_mpi_point_t q; - gcry_mpi_point_t v; - gcry_mpi_t v_x; - gcry_mpi_t v_y; - gcry_mpi_t h_mod_n; - gcry_mpi_t n; /* n from P-256 */ - - /* get 'h' value from signing key */ - size = sizeof (struct GNUNET_HashCode); - if (0 != (rc = gcry_mpi_scan (&h, GCRYMPI_FMT_USG, - signing_key, - size, &size))) - { - LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc); - return GNUNET_SYSERR; - } - /* create ECC context based on Q from pseudonym */ - if (NULL == (ctx = get_context_from_pseudonym (pseudonym))) - { - gcry_mpi_release (h); - return GNUNET_SYSERR; - } - /* initialize 'n' from P-256; hex copied from libgcrypt code */ - if (0 != (rc = gcry_mpi_scan (&n, GCRYMPI_FMT_HEX, - "0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", 0, NULL))) - { - LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc); - gcry_mpi_release (h); - return GNUNET_SYSERR; - } - h_mod_n = gcry_mpi_new (0); - gcry_mpi_mod (h_mod_n, h, n); - gcry_mpi_release (h); - - /* get Q = dG from 'pseudonym' */ - q = gcry_mpi_ec_get_point ("q", ctx, 0); - /* calculate V = hQ = hdG */ - v = gcry_mpi_point_new (0); - - gcry_mpi_ec_mul (v, h_mod_n, q, ctx); - gcry_mpi_release (h_mod_n); - - /* store 'v' point in "verification_key" */ - v_x = gcry_mpi_new (256); - v_y = gcry_mpi_new (256); - gcry_mpi_ec_get_affine (v_x, v_y, v, ctx); - - gcry_mpi_point_release (v); - gcry_ctx_release (ctx); - - size = sizeof (verification_key->q_x); - if (0 != (rc = gcry_mpi_print (GCRYMPI_FMT_USG, verification_key->q_x, size, - &size, v_x))) - { - LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_print", rc); - gcry_mpi_release (v_x); - gcry_mpi_release (v_y); - return GNUNET_SYSERR; - } - gcry_mpi_release (v_x); - size = sizeof (verification_key->q_y); - if (0 != (rc = gcry_mpi_print (GCRYMPI_FMT_USG, verification_key->q_y, size, - &size, v_y))) - { - LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_print", rc); - gcry_mpi_release (v_y); - return GNUNET_SYSERR; - } - gcry_mpi_release (v_y); - return GNUNET_OK; -} - - -/** - * Verify a signature made with a pseudonym. - * - * @param purpose data that was signed - * @param signature signature to verify - * @param verification_key public key to use for checking the signature; - * corresponds to 'g^(x+h)' in section 2.4 of #2564. - * @return GNUNET_OK on success (signature valid, 'pseudonym' set), - * GNUNET_SYSERR if the signature is invalid - */ -int -GNUNET_FS_pseudonym_verify (const struct GNUNET_FS_PseudonymSignaturePurpose *purpose, - const struct GNUNET_FS_PseudonymSignature *signature, - const struct GNUNET_FS_PseudonymIdentifier *verification_key) -{ - gcry_sexp_t data; - gcry_sexp_t sig_sexpr; - gcry_sexp_t pk_sexpr; - size_t size; - gcry_ctx_t ctx; - gcry_mpi_t r; - gcry_mpi_t s; - gcry_mpi_point_t q; - gcry_mpi_t q_x; - gcry_mpi_t q_y; - size_t erroff; - int rc; - - /* build s-expression for signature */ - size = sizeof (signature->sig_r); - if (0 != (rc = gcry_mpi_scan (&r, GCRYMPI_FMT_USG, - signature->sig_r, size, &size))) - { - LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc); - return GNUNET_SYSERR; - } - size = sizeof (signature->sig_s); - if (0 != (rc = gcry_mpi_scan (&s, GCRYMPI_FMT_USG, - signature->sig_s, size, &size))) - { - LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc); - gcry_mpi_release (r); - return GNUNET_SYSERR; - } - if (0 != (rc = gcry_sexp_build (&sig_sexpr, &erroff, "(sig-val(ecdsa(r %m)(s %m)))", - r, s))) - { - LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc); - gcry_mpi_release (r); - gcry_mpi_release (s); - return GNUNET_SYSERR; - } - gcry_mpi_release (r); - gcry_mpi_release (s); - - - /* build s-expression for data that was signed */ - data = data_to_pkcs1 (purpose, GNUNET_NO); - if (NULL == data) - { - gcry_sexp_release (sig_sexpr); - return GNUNET_SYSERR; - } - /* create context of public key and initialize Q */ - size = sizeof (verification_key->q_x); - if (0 != (rc = gcry_mpi_scan (&q_x, GCRYMPI_FMT_USG, - verification_key->q_x, size, &size))) - { - LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc); - gcry_sexp_release (data); - gcry_sexp_release (sig_sexpr); - return GNUNET_SYSERR; - } - size = sizeof (verification_key->q_y); - if (0 != (rc = gcry_mpi_scan (&q_y, GCRYMPI_FMT_USG, - verification_key->q_y, size, &size))) - { - LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc); - gcry_sexp_release (data); - gcry_sexp_release (sig_sexpr); - gcry_mpi_release (q_x); - return GNUNET_SYSERR; - } - q = gcry_mpi_point_new (256); - gcry_mpi_point_set (q, q_x, q_y, GCRYMPI_CONST_ONE); - gcry_mpi_release (q_x); - gcry_mpi_release (q_y); - - /* create basic ECC context */ - if (0 != (rc = gcry_mpi_ec_new (&ctx, NULL, "NIST P-256"))) - { - LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_ec_new", rc); /* erroff gives more info */ - gcry_sexp_release (data); - gcry_sexp_release (sig_sexpr); - gcry_mpi_point_release (q); - return GNUNET_SYSERR; - } - /* initialize 'ctx' with 'q' */ - gcry_mpi_ec_set_point ("q", q, ctx); - gcry_mpi_point_release (q); - - /* convert 'ctx' to 'sexp' */ - if (0 != (rc = gcry_pubkey_get_sexp (&pk_sexpr, GCRY_PK_GET_PUBKEY, ctx))) - { - LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_from_context", rc); - gcry_ctx_release (ctx); - gcry_sexp_release (data); - gcry_sexp_release (sig_sexpr); - return GNUNET_SYSERR; - } - gcry_ctx_release (ctx); - - /* finally, verify the signature */ - rc = gcry_pk_verify (sig_sexpr, data, pk_sexpr); - gcry_sexp_release (sig_sexpr); - gcry_sexp_release (data); - gcry_sexp_release (pk_sexpr); - if (rc) - { - LOG (GNUNET_ERROR_TYPE_WARNING, - _("ECDSA signature verification failed at %s:%d: %s\n"), __FILE__, - __LINE__, gcry_strerror (rc)); - return GNUNET_SYSERR; - } - return GNUNET_OK; -} - - -/** - * Get the identifier (public key) of a pseudonym. - * - * @param ph pseudonym handle with the private key - * @param pseudonym pseudonym identifier (set based on 'ph') - */ -void -GNUNET_FS_pseudonym_get_identifier (struct GNUNET_FS_PseudonymHandle *ph, - struct GNUNET_FS_PseudonymIdentifier *pseudonym) -{ - memcpy (pseudonym, &ph->public_key, - sizeof (struct GNUNET_FS_PseudonymIdentifier)); -} - - -/** - * Remove pseudonym from the set of known pseudonyms. - * - * @param cfg overall configuration - * @param id the pseudonym identifier - * @return GNUNET_OK on success, GNUNET_SYSERR on failure - */ -int -GNUNET_FS_pseudonym_remove (const struct GNUNET_CONFIGURATION_Handle *cfg, - const struct GNUNET_FS_PseudonymIdentifier *id) -{ - char *fn; - int result; - - fn = get_data_filename (cfg, PS_METADATA_DIR, id); - if (NULL == fn) - return GNUNET_SYSERR; - result = UNLINK (fn); - GNUNET_free (fn); - return (0 == result) ? GNUNET_OK : GNUNET_SYSERR; -} /* end of pseudonym.c */ diff --git a/src/fs/fs_publish.c b/src/fs/fs_publish.c index 041d4213c..1ed37d7e4 100644 --- a/src/fs/fs_publish.c +++ b/src/fs/fs_publish.c @@ -84,11 +84,6 @@ publish_cleanup (struct GNUNET_FS_PublishContext *pc) pc->fhc = NULL; } GNUNET_FS_file_information_destroy (pc->fi, NULL, NULL); - if (pc->ns != NULL) - { - GNUNET_FS_namespace_delete (pc->ns, GNUNET_NO); - pc->ns = NULL; - } GNUNET_free_non_null (pc->nid); GNUNET_free_non_null (pc->nuid); GNUNET_free_non_null (pc->serialization); @@ -271,9 +266,15 @@ static void publish_sblock (struct GNUNET_FS_PublishContext *pc) { if (NULL != pc->ns) - pc->sks_pc = GNUNET_FS_publish_sks (pc->h, pc->ns, pc->nid, pc->nuid, - pc->fi->meta, pc->fi->chk_uri, &pc->fi->bo, - pc->options, &publish_sblocks_cont, pc); + pc->sks_pc = GNUNET_FS_publish_sks (pc->h, + pc->ns, + pc->nid, + pc->nuid, + pc->fi->meta, + pc->fi->chk_uri, + &pc->fi->bo, + pc->options, + &publish_sblocks_cont, pc); else publish_sblocks_cont (pc, NULL, NULL); } @@ -1117,7 +1118,8 @@ finish_reserve (void *cls, int success, struct GNUNET_FS_PublishContext * GNUNET_FS_publish_start (struct GNUNET_FS_Handle *h, struct GNUNET_FS_FileInformation *fi, - struct GNUNET_FS_Namespace *ns, const char *nid, + const struct GNUNET_CRYPTO_EccPrivateKey *ns, + const char *nid, const char *nuid, enum GNUNET_FS_PublishOptions options) { @@ -1135,20 +1137,20 @@ GNUNET_FS_publish_start (struct GNUNET_FS_Handle *h, { dsh = NULL; } - ret = GNUNET_malloc (sizeof (struct GNUNET_FS_PublishContext)); + ret = GNUNET_new (struct GNUNET_FS_PublishContext); ret->dsh = dsh; ret->h = h; ret->fi = fi; - ret->ns = ns; - ret->options = options; - if (ns != NULL) + if (NULL != ns) { - ns->rc++; + ret->ns = GNUNET_new (struct GNUNET_CRYPTO_EccPrivateKey); + *ret->ns = *ns; GNUNET_assert (NULL != nid); ret->nid = GNUNET_strdup (nid); if (NULL != nuid) ret->nuid = GNUNET_strdup (nuid); } + ret->options = options; /* signal start */ GNUNET_FS_file_information_inspect (ret->fi, &fip_signal_start, ret); ret->fi_pos = ret->fi; diff --git a/src/fs/fs_publish_ksk.c b/src/fs/fs_publish_ksk.c index 10512af5f..7cbc880a2 100644 --- a/src/fs/fs_publish_ksk.c +++ b/src/fs/fs_publish_ksk.c @@ -33,7 +33,7 @@ #include "gnunet_fs_service.h" #include "fs_api.h" #include "fs_tree.h" - +#include "fs_publish_ublock.h" /** * Context for the KSK publication. @@ -47,33 +47,29 @@ struct GNUNET_FS_PublishKskContext struct GNUNET_FS_Uri *ksk_uri; /** - * Global FS context. + * URI to publish. */ - struct GNUNET_FS_Handle *h; + struct GNUNET_FS_Uri *uri; /** - * The master block that we are sending - * (in plaintext), has "mdsize+slen" more - * bytes than the struct would suggest. + * Metadata to use. */ - struct UBlock *ub; + struct GNUNET_CONTAINER_MetaData *meta; /** - * Buffer of the same size as "kb" for - * the encrypted version. + * Global FS context. */ - struct UBlock *cpy; + struct GNUNET_FS_Handle *h; /** - * Handle to the datastore, NULL if we are just - * simulating. + * UBlock publishing operation that is active. */ - struct GNUNET_DATASTORE_Handle *dsh; + struct GNUNET_FS_PublishUblockContext *uc; /** - * Handle to datastore PUT request. + * Handle to the datastore, NULL if we are just simulating. */ - struct GNUNET_DATASTORE_QueueEntry *qre; + struct GNUNET_DATASTORE_Handle *dsh; /** * Current task. @@ -96,14 +92,9 @@ struct GNUNET_FS_PublishKskContext struct GNUNET_FS_BlockOptions bo; /** - * Size of the serialized metadata. - */ - ssize_t mdsize; - - /** - * Size of the (CHK) URI as a string. - */ - size_t slen; + * Options to use. + */ + enum GNUNET_FS_PublishOptions options; /** * Keyword that we are currently processing. @@ -122,7 +113,8 @@ struct GNUNET_FS_PublishKskContext * @param tc unused */ static void -publish_ksk_cont (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); +publish_ksk_cont (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc); /** @@ -130,19 +122,16 @@ publish_ksk_cont (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); * the result from the PUT request. * * @param cls closure of type "struct GNUNET_FS_PublishKskContext*" - * @param success GNUNET_OK on success - * @param min_expiration minimum expiration time required for content to be stored * @param msg error message (or NULL) */ static void -kb_put_cont (void *cls, int success, - struct GNUNET_TIME_Absolute min_expiration, +kb_put_cont (void *cls, const char *msg) { struct GNUNET_FS_PublishKskContext *pkc = cls; - pkc->qre = NULL; - if (GNUNET_OK != success) + pkc->uc = NULL; + if (NULL != msg) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "KBlock PUT operation failed: %s\n", msg); @@ -166,15 +155,6 @@ publish_ksk_cont (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { struct GNUNET_FS_PublishKskContext *pkc = cls; const char *keyword; - struct GNUNET_HashCode key; - struct GNUNET_HashCode seed; - struct GNUNET_HashCode signing_key; - struct GNUNET_HashCode query; - struct GNUNET_CRYPTO_AesSessionKey skey; - struct GNUNET_CRYPTO_AesInitializationVector iv; - struct GNUNET_FS_PseudonymHandle *ph; - struct GNUNET_FS_PseudonymIdentifier pseudonym; - struct UBlock *ub_dst; pkc->ksk_task = GNUNET_SCHEDULER_NO_TASK; if ( (pkc->i == pkc->ksk_uri->data.ksk.keywordCount) || @@ -186,61 +166,15 @@ publish_ksk_cont (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) return; } keyword = pkc->ksk_uri->data.ksk.keywords[pkc->i++]; - pkc->sks_task = GNUNET_FS_publish_sks (pkc->h, - anonymous, - keyword, NULL, - pkc->meta, - pkc->uri, - &pkc->bo, - pkc->options, - &publish_ksk_cont, pkc); - - - /* derive signing seed from plaintext */ - GNUNET_CRYPTO_hash (&pkc->ub[1], - 1 + pkc->slen + pkc->mdsize, - &seed); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Publishing under keyword `%s'\n", - &keyword[1]); - /* 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); - ub_dst = pkc->cpy; - GNUNET_CRYPTO_aes_encrypt (&pkc->ub[1], - 1 + pkc->slen + pkc->mdsize, - &skey, &iv, - &ub_dst[1]); - ph = GNUNET_FS_pseudonym_get_anonymous_pseudonym_handle (); - GNUNET_CRYPTO_hash (&key, sizeof (key), &signing_key); - ub_dst->purpose.size = htonl (1 + pkc->slen + pkc->mdsize + - sizeof (struct UBlock) - - sizeof (struct GNUNET_FS_PseudonymSignature)); - ub_dst->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_FS_UBLOCK); - - GNUNET_FS_pseudonym_get_identifier (ph, &pseudonym); - GNUNET_FS_pseudonym_derive_verification_key (&pseudonym, - &signing_key, - &ub_dst->verification_key); - GNUNET_FS_pseudonym_sign (ph, - &ub_dst->purpose, - &seed, - &signing_key, - &ub_dst->signature); - - GNUNET_CRYPTO_hash (&ub_dst->verification_key, - sizeof (ub_dst->verification_key), - &query); - GNUNET_FS_pseudonym_destroy (ph); - pkc->qre = - GNUNET_DATASTORE_put (pkc->dsh, 0, &query, - 1 + pkc->slen + pkc->mdsize + sizeof (struct UBlock), - ub_dst, GNUNET_BLOCK_TYPE_FS_UBLOCK, - pkc->bo.content_priority, pkc->bo.anonymity_level, - pkc->bo.replication_level, pkc->bo.expiration_time, - -2, 1, GNUNET_CONSTANTS_SERVICE_TIMEOUT, - &kb_put_cont, pkc); + pkc->uc = GNUNET_FS_publish_ublock_ (pkc->h, + pkc->dsh, + keyword, NULL, + GNUNET_CRYPTO_ecc_key_get_anonymous (), + pkc->meta, + pkc->uri, + &pkc->bo, + pkc->options, + &kb_put_cont, pkc); } @@ -267,17 +201,15 @@ GNUNET_FS_publish_ksk (struct GNUNET_FS_Handle *h, GNUNET_FS_PublishContinuation cont, void *cont_cls) { struct GNUNET_FS_PublishKskContext *pkc; - char *uris; - size_t size; - char *kbe; - char *sptr; GNUNET_assert (NULL != uri); - pkc = GNUNET_malloc (sizeof (struct GNUNET_FS_PublishKskContext)); + pkc = GNUNET_new (struct GNUNET_FS_PublishKskContext); pkc->h = h; pkc->bo = *bo; + pkc->options = options; pkc->cont = cont; pkc->cont_cls = cont_cls; + pkc->meta = GNUNET_CONTAINER_meta_data_duplicate (meta); if (0 == (options & GNUNET_FS_PUBLISH_OPTION_SIMULATE_ONLY)) { pkc->dsh = GNUNET_DATASTORE_connect (h->cfg); @@ -288,44 +220,7 @@ GNUNET_FS_publish_ksk (struct GNUNET_FS_Handle *h, return NULL; } } - if (meta == NULL) - pkc->mdsize = 0; - else - pkc->mdsize = GNUNET_CONTAINER_meta_data_get_serialized_size (meta); - GNUNET_assert (pkc->mdsize >= 0); - uris = GNUNET_FS_uri_to_string (uri); - pkc->slen = strlen (uris) + 1; - size = pkc->mdsize + sizeof (struct UBlock) + pkc->slen + 1; - if (size > MAX_UBLOCK_SIZE) - { - size = MAX_UBLOCK_SIZE; - pkc->mdsize = size - sizeof (struct UBlock) - pkc->slen + 1; - } - pkc->ub = GNUNET_malloc (size); - kbe = (char *) &pkc->ub[1]; - kbe++; /* leave one '\0' for the update identifier */ - memcpy (kbe, uris, pkc->slen); - GNUNET_free (uris); - sptr = &kbe[pkc->slen]; - if (meta != NULL) - pkc->mdsize = - GNUNET_CONTAINER_meta_data_serialize (meta, &sptr, pkc->mdsize, - GNUNET_CONTAINER_META_DATA_SERIALIZE_PART); - if (-1 == pkc->mdsize) - { - GNUNET_break (0); - GNUNET_free (pkc->ub); - if (NULL != pkc->dsh) - { - GNUNET_DATASTORE_disconnect (pkc->dsh, GNUNET_NO); - pkc->dsh = NULL; - } - GNUNET_free (pkc); - cont (cont_cls, NULL, _("Internal error.")); - return NULL; - } - size = sizeof (struct UBlock) + pkc->slen + pkc->mdsize + 1; - pkc->cpy = GNUNET_malloc (size); + pkc->uri = GNUNET_FS_uri_dup (uri); pkc->ksk_uri = GNUNET_FS_uri_dup (ksk_uri); pkc->ksk_task = GNUNET_SCHEDULER_add_now (&publish_ksk_cont, pkc); return pkc; @@ -345,19 +240,19 @@ GNUNET_FS_publish_ksk_cancel (struct GNUNET_FS_PublishKskContext *pkc) GNUNET_SCHEDULER_cancel (pkc->ksk_task); pkc->ksk_task = GNUNET_SCHEDULER_NO_TASK; } - if (NULL != pkc->qre) + if (NULL != pkc->uc) { - GNUNET_DATASTORE_cancel (pkc->qre); - pkc->qre = NULL; + GNUNET_FS_publish_ublock_cancel_ (pkc->uc); + pkc->uc = NULL; } if (NULL != pkc->dsh) { GNUNET_DATASTORE_disconnect (pkc->dsh, GNUNET_NO); pkc->dsh = NULL; } - GNUNET_free (pkc->cpy); - GNUNET_free (pkc->ub); + GNUNET_CONTAINER_meta_data_destroy (pkc->meta); GNUNET_FS_uri_destroy (pkc->ksk_uri); + GNUNET_FS_uri_destroy (pkc->uri); GNUNET_free (pkc); } diff --git a/src/fs/fs_publish_ublock.c b/src/fs/fs_publish_ublock.c new file mode 100644 index 000000000..9ddff0655 --- /dev/null +++ b/src/fs/fs_publish_ublock.c @@ -0,0 +1,262 @@ +/* + This file is part of GNUnet. + (C) 2009, 2010, 2012, 2013 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +/** + * @file fs/fs_publish_ublock.c + * @brief publish a UBLOCK in GNUnet + * @see https://gnunet.org/encoding and #2564 + * @author Krista Bennett + * @author Christian Grothoff + */ +#include "platform.h" +#include "gnunet_constants.h" +#include "gnunet_signatures.h" +#include "fs_publish_ublock.h" +#include "fs_api.h" +#include "fs_tree.h" + + +/** + * Decrypt the given UBlock, storing the result in output. + * + * @param input input data + * @param input_len number of bytes in input + * @param ns public key under which the UBlock was stored + * @param label label under which the UBlock was stored + * @param output where to write the result, has input_len bytes + */ +void +GNUNET_FS_ublock_decrypt_ (const void *input, + size_t input_len, + const struct GNUNET_CRYPTO_EccPublicKey *ns, + const char *label, + void *output) +{ + GNUNET_break (0); +} + + +/** + * Context for 'ublock_put_cont'. + */ +struct GNUNET_FS_PublishUblockContext +{ + + /** + * Function to call when done. + */ + GNUNET_FS_UBlockContinuation cont; + + /** + * Closure of 'cont'. + */ + void *cont_cls; + + /** + * Handle for active datastore operation. + */ + struct GNUNET_DATASTORE_QueueEntry *qre; +}; + + +/** + * Continuation of "GNUNET_FS_publish_ublock_". + * + * @param cls closure of type "struct GNUNET_FS_PublishUblockContext*" + * @param success GNUNET_SYSERR on failure (including timeout/queue drop) + * GNUNET_NO if content was already there + * GNUNET_YES (or other positive value) on success + * @param min_expiration minimum expiration time required for 0-priority content to be stored + * by the datacache at this time, zero for unknown, forever if we have no + * space for 0-priority content + * @param msg NULL on success, otherwise an error message + */ +static void +ublock_put_cont (void *cls, + int32_t success, + struct GNUNET_TIME_Absolute min_expiration, + const char *msg) +{ + struct GNUNET_FS_PublishUblockContext *uc = cls; + + uc->qre = NULL; + uc->cont (uc->cont_cls, msg); + GNUNET_free (uc); +} + + +/** + * Publish a UBlock. + * + * @param h handle to the file sharing subsystem + * @param dsh datastore handle to use for storage operation + * @param label identifier to use + * @param ulabel update label to use, may be an empty string for none + * @param ns namespace to publish in + * @param meta metadata to use + * @param uri URI to refer to in the UBlock + * @param bo per-block options + * @param options publication options + * @param cont continuation + * @param cont_cls closure for cont + * @return NULL on error ('cont' will still be called) + */ +struct GNUNET_FS_PublishUblockContext * +GNUNET_FS_publish_ublock_ (struct GNUNET_FS_Handle *h, + struct GNUNET_DATASTORE_Handle *dsh, + const char *label, + const char *ulabel, + const struct GNUNET_CRYPTO_EccPrivateKey *ns, + const struct GNUNET_CONTAINER_MetaData *meta, + const struct GNUNET_FS_Uri *uri, + const struct GNUNET_FS_BlockOptions *bo, + enum GNUNET_FS_PublishOptions options, + GNUNET_FS_UBlockContinuation cont, void *cont_cls) +{ + struct GNUNET_FS_PublishUblockContext *uc; + struct GNUNET_HashCode key; + struct GNUNET_HashCode seed; + struct GNUNET_HashCode signing_key; + struct GNUNET_HashCode query; + struct GNUNET_CRYPTO_AesSessionKey skey; + struct GNUNET_CRYPTO_AesInitializationVector iv; + struct GNUNET_CRYPTO_EccPrivateKey *nsd; + struct GNUNET_CRYPTO_EccPublicKey pub; + char *uris; + size_t size; + char *kbe; + char *sptr; + ssize_t mdsize; + size_t slen; + size_t ulen; + struct UBlock *ub_plain; + struct UBlock *ub_enc; + + /* compute ublock to publish */ + if (NULL == meta) + mdsize = 0; + else + mdsize = GNUNET_CONTAINER_meta_data_get_serialized_size (meta); + GNUNET_assert (mdsize >= 0); + uris = GNUNET_FS_uri_to_string (uri); + slen = strlen (uris) + 1; + ulen = strlen (ulabel) + 1; + size = mdsize + sizeof (struct UBlock) + slen + ulen; + if (size > MAX_UBLOCK_SIZE) + { + size = MAX_UBLOCK_SIZE; + mdsize = size - sizeof (struct UBlock) - (slen + ulen); + } + ub_plain = GNUNET_malloc (size); + kbe = (char *) &ub_plain[1]; + memcpy (kbe, ulabel, ulen); + kbe += ulen; + memcpy (kbe, uris, slen); + kbe += slen; + GNUNET_free (uris); + sptr = kbe; + if (NULL != meta) + mdsize = + GNUNET_CONTAINER_meta_data_serialize (meta, &sptr, mdsize, + GNUNET_CONTAINER_META_DATA_SERIALIZE_PART); + if (-1 == mdsize) + { + GNUNET_break (0); + GNUNET_free (ub_plain); + cont (cont_cls, _("Internal error.")); + return NULL; + } + size = sizeof (struct UBlock) + slen + mdsize + ulen; + + /* derive signing seed from plaintext */ + GNUNET_CRYPTO_hash (&ub_plain[1], + ulen + slen + mdsize, + &seed); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Publishing under identifier `%s'\n", + label); + /* get public key of the namespace */ + GNUNET_CRYPTO_ecc_key_get_public (ns, + &pub); + /* derive key from 'label' and public key of the namespace */ + GNUNET_assert (GNUNET_YES == + GNUNET_CRYPTO_kdf (&key, sizeof (key), + "UBLOCK-ENC", strlen ("UBLOCK-ENC"), + label, strlen (label), + &pub, sizeof (pub), + NULL, 0)); + GNUNET_CRYPTO_hash_to_aes_key (&key, &skey, &iv); + + /* encrypt ublock */ + ub_enc = GNUNET_malloc (size); + GNUNET_CRYPTO_aes_encrypt (&ub_plain[1], + ulen + slen + mdsize, + &skey, &iv, + &ub_enc[1]); + ub_enc->purpose.size = htonl (ulen + slen + mdsize + + sizeof (struct UBlock) + - sizeof (struct GNUNET_CRYPTO_EccSignature)); + ub_enc->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_FS_UBLOCK); + + /* derive signing-key from 'label' and public key of the namespace */ + GNUNET_assert (GNUNET_YES == + GNUNET_CRYPTO_kdf (&signing_key, sizeof (signing_key), + "UBLOCK-SIGN", strlen ("UBLOCK-SIGN"), + label, strlen (label), + &pub, sizeof (pub), + NULL, 0)); + nsd = GNUNET_CRYPTO_ecc_key_derive (ns, label); + GNUNET_CRYPTO_ecc_key_get_public (nsd, + &ub_enc->verification_key); + GNUNET_assert (GNUNET_OK == + GNUNET_CRYPTO_ecc_sign (nsd, + &ub_enc->purpose, + &ub_enc->signature)); + GNUNET_CRYPTO_hash (&ub_enc->verification_key, + sizeof (ub_enc->verification_key), + &query); + GNUNET_CRYPTO_ecc_key_free (nsd); + + uc = GNUNET_new (struct GNUNET_FS_PublishUblockContext); + uc->cont = cont; + uc->cont_cls = cont_cls; + uc->qre = + GNUNET_DATASTORE_put (dsh, 0, &query, + ulen + slen + mdsize + sizeof (struct UBlock), + ub_enc, GNUNET_BLOCK_TYPE_FS_UBLOCK, + bo->content_priority, bo->anonymity_level, + bo->replication_level, bo->expiration_time, + -2, 1, GNUNET_CONSTANTS_SERVICE_TIMEOUT, + &ublock_put_cont, uc); + return uc; +} + + +/** + * Abort UBlock publishing operation. + * + * @param uc operation to abort. + */ +void +GNUNET_FS_publish_ublock_cancel_ (struct GNUNET_FS_PublishUblockContext *uc) +{ + GNUNET_DATASTORE_cancel (uc->qre); + GNUNET_free (uc); +} diff --git a/src/fs/fs_publish_ublock.h b/src/fs/fs_publish_ublock.h new file mode 100644 index 000000000..9a2db54ac --- /dev/null +++ b/src/fs/fs_publish_ublock.h @@ -0,0 +1,108 @@ +/* + This file is part of GNUnet. + (C) 2009, 2010, 2012, 2013 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +/** + * @file fs/fs_publish_ublock.h + * @brief publish a UBLOCK in GNUnet + * @see https://gnunet.org/encoding and #2564 + * @author Krista Bennett + * @author Christian Grothoff + */ +#ifndef FS_PUBLISH_UBLOCK_H +#define FS_PUBLISH_UBLOCK_H + +#include "gnunet_util_lib.h" +#include "gnunet_datastore_service.h" +#include "gnunet_fs_service.h" +#include "gnunet_identity_service.h" + + +/** + * Decrypt the given UBlock, storing the result in output. + * + * @param input input data + * @param input_len number of bytes in input + * @param ns public key under which the UBlock was stored + * @param label label under which the UBlock was stored + * @param output where to write the result, has input_len bytes + */ +void +GNUNET_FS_ublock_decrypt_ (const void *input, + size_t input_len, + const struct GNUNET_CRYPTO_EccPublicKey *ns, + const char *label, + void *output); + + +/** + * Context for 'ublock_put_cont'. + */ +struct GNUNET_FS_PublishUblockContext; + + +/** + * Signature of a function called as the continuation of a UBlock + * publication. + * + * @param cls closure + * @param emsg error message, NULL on success + */ +typedef void (*GNUNET_FS_UBlockContinuation) (void *cls, + const char *emsg); + + +/** + * Publish a UBlock. + * + * @param h handle to the file sharing subsystem + * @param dsh datastore handle to use for storage operation + * @param label identifier to use + * @param ulabel update label to use, may be an empty string for none + * @param ns namespace to publish in + * @param meta metadata to use + * @param uri URI to refer to in the UBlock + * @param bo per-block options + * @param options publication options + * @param cont continuation + * @param cont_cls closure for cont + * @return NULL on error ('cont' will still be called) + */ +struct GNUNET_FS_PublishUblockContext * +GNUNET_FS_publish_ublock_ (struct GNUNET_FS_Handle *h, + struct GNUNET_DATASTORE_Handle *dsh, + const char *label, + const char *ulabel, + const struct GNUNET_CRYPTO_EccPrivateKey *ns, + const struct GNUNET_CONTAINER_MetaData *meta, + const struct GNUNET_FS_Uri *uri, + const struct GNUNET_FS_BlockOptions *bo, + enum GNUNET_FS_PublishOptions options, + GNUNET_FS_UBlockContinuation cont, void *cont_cls); + + +/** + * Abort UBlock publishing operation. + * + * @param uc operation to abort. + */ +void +GNUNET_FS_publish_ublock_cancel_ (struct GNUNET_FS_PublishUblockContext *uc); + +#endif diff --git a/src/fs/fs_search.c b/src/fs/fs_search.c index 10627753a..3b0db0429 100644 --- a/src/fs/fs_search.c +++ b/src/fs/fs_search.c @@ -27,6 +27,7 @@ #include "gnunet_fs_service.h" #include "gnunet_protocols.h" #include "fs_api.h" +#include "fs_publish_ublock.h" /** @@ -669,7 +670,7 @@ process_sks_result (struct GNUNET_FS_SearchContext *sc, const char *id_update, * given ciphertext block. * * @param sc search context with the keywords - * @param verification_key public key to use to lookup the keyword + * @param dpub derived public key used for the search * @param edata encrypted data * @param edata_size number of bytes in 'edata' (and 'data') * @param data where to store the plaintext @@ -678,22 +679,20 @@ process_sks_result (struct GNUNET_FS_SearchContext *sc, const char *id_update, */ static int decrypt_block_with_keyword (const struct GNUNET_FS_SearchContext *sc, - const struct GNUNET_FS_PseudonymIdentifier *verification_key, + const struct GNUNET_CRYPTO_EccPublicKey *dpub, const void *edata, size_t edata_size, char *data) { - struct GNUNET_HashCode q; - struct GNUNET_CRYPTO_AesSessionKey skey; - struct GNUNET_CRYPTO_AesInitializationVector iv; - int i; + const struct GNUNET_CRYPTO_EccPrivateKey *anon; + struct GNUNET_CRYPTO_EccPublicKey anon_pub; + unsigned int i; - GNUNET_CRYPTO_hash (verification_key, - sizeof (struct GNUNET_FS_PseudonymIdentifier), - &q); /* find key */ for (i = 0; i < sc->uri->data.ksk.keywordCount; i++) - if (0 == memcmp (&q, &sc->requests[i].uquery, sizeof (struct GNUNET_HashCode))) + if (0 == memcmp (dpub, + &sc->requests[i].dpub, + sizeof (struct GNUNET_CRYPTO_EccPublicKey))) break; if (i == sc->uri->data.ksk.keywordCount) { @@ -702,14 +701,12 @@ decrypt_block_with_keyword (const struct GNUNET_FS_SearchContext *sc, return GNUNET_SYSERR; } /* decrypt */ - GNUNET_CRYPTO_hash_to_aes_key (&sc->requests[i].ukey, &skey, &iv); - if (-1 == - GNUNET_CRYPTO_aes_decrypt (edata, edata_size, &skey, - &iv, data)) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } + anon = GNUNET_CRYPTO_ecc_key_get_anonymous (); + GNUNET_CRYPTO_ecc_key_get_public (anon, &anon_pub); + GNUNET_FS_ublock_decrypt_ (edata, edata_size, + &anon_pub, + sc->requests[i].keyword, + data); return i; } @@ -789,31 +786,18 @@ process_sblock (struct GNUNET_FS_SearchContext *sc, { size_t len = size - sizeof (struct UBlock); char pt[len]; - struct GNUNET_CRYPTO_AesSessionKey skey; - struct GNUNET_CRYPTO_AesInitializationVector iv; struct GNUNET_FS_Uri *uri; struct GNUNET_CONTAINER_MetaData *meta; const char *id; const char *uris; size_t off; char *emsg; - struct GNUNET_HashCode key; - struct GNUNET_HashCode id_hash; - struct GNUNET_HashCode ns_hash; - char *identifier; /* decrypt */ - identifier = sc->uri->data.sks.identifier; - GNUNET_CRYPTO_hash (identifier, strlen (identifier), &id_hash); - GNUNET_CRYPTO_hash (&sc->uri->data.sks.ns, - sizeof (sc->uri->data.sks.ns), &ns_hash); - GNUNET_CRYPTO_hash_xor (&id_hash, &ns_hash, &key); - GNUNET_CRYPTO_hash_to_aes_key (&key, &skey, &iv); - if (-1 == GNUNET_CRYPTO_aes_decrypt (&ub[1], len, &skey, &iv, pt)) - { - GNUNET_break (0); - return; - } + GNUNET_FS_ublock_decrypt_ (&ub[1], len, + &sc->uri->data.sks.ns, + sc->uri->data.sks.identifier, + pt); /* parse */ if (0 == (off = GNUNET_STRINGS_buffer_tokenize (pt, len, 2, &id, &uris))) { @@ -1050,12 +1034,7 @@ transmit_search_request (void *cls, size_t size, void *buf) struct MessageBuilderContext mbc; size_t msize; struct SearchMessage *sm; - const char *identifier; - struct GNUNET_HashCode key; - struct GNUNET_HashCode signing_key; - struct GNUNET_HashCode ns_hash; - struct GNUNET_HashCode id_hash; - struct GNUNET_FS_PseudonymIdentifier verification_key; + struct GNUNET_CRYPTO_EccPublicKey dpub; unsigned int sqms; uint32_t options; @@ -1122,18 +1101,11 @@ transmit_search_request (void *cls, size_t size, void *buf) sm->type = htonl (GNUNET_BLOCK_TYPE_FS_UBLOCK); sm->anonymity_level = htonl (sc->anonymity); memset (&sm->target, 0, sizeof (struct GNUNET_HashCode)); - - identifier = sc->uri->data.sks.identifier; - GNUNET_CRYPTO_hash (identifier, strlen (identifier), &id_hash); - GNUNET_CRYPTO_hash (&sc->uri->data.sks.ns, - sizeof (sc->uri->data.sks.ns), &ns_hash); - GNUNET_CRYPTO_hash_xor (&id_hash, &ns_hash, &key); - GNUNET_CRYPTO_hash (&key, sizeof (struct GNUNET_HashCode), &signing_key); - GNUNET_FS_pseudonym_derive_verification_key (&sc->uri->data.sks.ns, - &signing_key, - &verification_key); - GNUNET_CRYPTO_hash (&verification_key, - sizeof (verification_key), + GNUNET_CRYPTO_ecc_public_key_derive (&sc->uri->data.sks.ns, + sc->uri->data.sks.identifier, + &dpub); + GNUNET_CRYPTO_hash (&dpub, + sizeof (dpub), &sm->query); mbc.put_cnt = (size - msize) / sizeof (struct GNUNET_HashCode); sqms = GNUNET_CONTAINER_multihashmap_size (sc->master_result_map); @@ -1297,35 +1269,34 @@ GNUNET_FS_search_start_searching_ (struct GNUNET_FS_SearchContext *sc) { unsigned int i; const char *keyword; - struct GNUNET_HashCode signing_key; - struct GNUNET_FS_PseudonymHandle *ph; - struct GNUNET_FS_PseudonymIdentifier anon; - struct GNUNET_FS_PseudonymIdentifier verification_key; + const struct GNUNET_CRYPTO_EccPrivateKey *anon; + struct GNUNET_CRYPTO_EccPublicKey anon_pub; + struct SearchRequestEntry *sre; GNUNET_assert (NULL == sc->client); if (GNUNET_FS_uri_test_ksk (sc->uri)) { GNUNET_assert (0 != sc->uri->data.ksk.keywordCount); - ph = GNUNET_FS_pseudonym_get_anonymous_pseudonym_handle (); - GNUNET_FS_pseudonym_get_identifier (ph, &anon); - GNUNET_FS_pseudonym_destroy (ph); + anon = GNUNET_CRYPTO_ecc_key_get_anonymous (); + GNUNET_CRYPTO_ecc_key_get_public (anon, &anon_pub); sc->requests = GNUNET_malloc (sizeof (struct SearchRequestEntry) * sc->uri->data.ksk.keywordCount); for (i = 0; i < sc->uri->data.ksk.keywordCount; i++) { keyword = &sc->uri->data.ksk.keywords[i][1]; - GNUNET_CRYPTO_hash (keyword, strlen (keyword), &sc->requests[i].ukey); - GNUNET_CRYPTO_hash (&sc->requests[i].ukey, sizeof (struct GNUNET_HashCode), &signing_key); - GNUNET_FS_pseudonym_derive_verification_key (&anon, - &signing_key, - &verification_key); - GNUNET_CRYPTO_hash (&verification_key, sizeof (struct GNUNET_FS_PseudonymIdentifier), - &sc->requests[i].uquery); - sc->requests[i].mandatory = (sc->uri->data.ksk.keywords[i][0] == '+'); - if (sc->requests[i].mandatory) + sre = &sc->requests[i]; + sre->keyword = GNUNET_strdup (keyword); + GNUNET_CRYPTO_ecc_public_key_derive (&anon_pub, + keyword, + &sre->dpub); + GNUNET_CRYPTO_hash (&sre->dpub, + sizeof (struct GNUNET_CRYPTO_EccPublicKey), + &sre->uquery); + sre->mandatory = (sc->uri->data.ksk.keywords[i][0] == '+'); + if (sre->mandatory) sc->mandatory_count++; - sc->requests[i].results = GNUNET_CONTAINER_multihashmap_create (4, GNUNET_NO); + sre->results = GNUNET_CONTAINER_multihashmap_create (4, GNUNET_NO); } } sc->client = GNUNET_CLIENT_connect ("fs", sc->h->cfg); @@ -1475,7 +1446,10 @@ GNUNET_FS_search_signal_suspend_ (void *cls) { GNUNET_assert (GNUNET_FS_uri_test_ksk (sc->uri)); for (i = 0; i < sc->uri->data.ksk.keywordCount; i++) + { GNUNET_CONTAINER_multihashmap_destroy (sc->requests[i].results); + GNUNET_free (sc->requests[i].keyword); + } } GNUNET_free_non_null (sc->requests); GNUNET_free_non_null (sc->emsg); diff --git a/src/fs/fs_unindex.c b/src/fs/fs_unindex.c index 132109c59..cfe73d617 100644 --- a/src/fs/fs_unindex.c +++ b/src/fs/fs_unindex.c @@ -553,10 +553,9 @@ void GNUNET_FS_unindex_do_remove_kblocks_ (struct GNUNET_FS_UnindexContext *uc) { const char *keyword; - struct GNUNET_FS_PseudonymHandle *ph; - struct GNUNET_FS_PseudonymIdentifier anon; - struct GNUNET_FS_PseudonymIdentifier verification_key; - struct GNUNET_HashCode signing_key; + const struct GNUNET_CRYPTO_EccPrivateKey *anon; + struct GNUNET_CRYPTO_EccPublicKey anon_pub; + struct GNUNET_CRYPTO_EccPublicKey dpub; if (NULL == uc->dsh) uc->dsh = GNUNET_DATASTORE_connect (uc->h->cfg); @@ -574,18 +573,14 @@ GNUNET_FS_unindex_do_remove_kblocks_ (struct GNUNET_FS_UnindexContext *uc) unindex_finish (uc); return; } - /* FIXME: code duplication with fs_search.c here... */ - ph = GNUNET_FS_pseudonym_get_anonymous_pseudonym_handle (); - GNUNET_FS_pseudonym_get_identifier (ph, &anon); - GNUNET_FS_pseudonym_destroy (ph); + anon = GNUNET_CRYPTO_ecc_key_get_anonymous (); + GNUNET_CRYPTO_ecc_key_get_public (anon, &anon_pub); keyword = &uc->ksk_uri->data.ksk.keywords[uc->ksk_offset][1]; - GNUNET_CRYPTO_hash (keyword, strlen (keyword), &uc->ukey); - GNUNET_CRYPTO_hash (&uc->ukey, sizeof (struct GNUNET_HashCode), &signing_key); - GNUNET_FS_pseudonym_derive_verification_key (&anon, - &signing_key, - &verification_key); - GNUNET_CRYPTO_hash (&verification_key, - sizeof (struct GNUNET_FS_PseudonymIdentifier), + GNUNET_CRYPTO_ecc_public_key_derive (&anon_pub, + keyword, + &dpub); + GNUNET_CRYPTO_hash (&dpub, + sizeof (dpub), &uc->uquery); uc->first_uid = 0; uc->dqe = GNUNET_DATASTORE_get_key (uc->dsh, diff --git a/src/fs/fs_uri.c b/src/fs/fs_uri.c index 78b5459fd..e0bdc7ed6 100644 --- a/src/fs/fs_uri.c +++ b/src/fs/fs_uri.c @@ -95,10 +95,11 @@ * into HashMaps. The key may change between FS implementations. * * @param uri uri to convert to a unique key - * @param key wherer to store the unique key + * @param key where to store the unique key */ void -GNUNET_FS_uri_to_key (const struct GNUNET_FS_Uri *uri, struct GNUNET_HashCode * key) +GNUNET_FS_uri_to_key (const struct GNUNET_FS_Uri *uri, + struct GNUNET_HashCode *key) { switch (uri->type) { @@ -144,7 +145,7 @@ GNUNET_FS_uri_ksk_to_string_fancy (const struct GNUNET_FS_Uri *uri) char **keywords; unsigned int keywordCount; - if ((uri == NULL) || (uri->type != GNUNET_FS_URI_KSK)) + if ((NULL == uri) || (GNUNET_FS_URI_KSK != uri->type)) { GNUNET_break (0); return NULL; @@ -269,7 +270,7 @@ uri_ksk_parse (const char *s, char **emsg) char *dup; int saw_quote; - GNUNET_assert (s != NULL); + GNUNET_assert (NULL != s); slen = strlen (s); pos = strlen (GNUNET_FS_URI_KSK_PREFIX); if ((slen <= pos) || (0 != strncmp (s, GNUNET_FS_URI_KSK_PREFIX, pos))) @@ -329,7 +330,7 @@ uri_ksk_parse (const char *s, char **emsg) goto CLEANUP; GNUNET_assert (max == 0); GNUNET_free (dup); - ret = GNUNET_malloc (sizeof (struct GNUNET_FS_Uri)); + ret = GNUNET_new (struct GNUNET_FS_Uri); ret->type = GNUNET_FS_URI_KSK; ret->data.ksk.keywordCount = iret; ret->data.ksk.keywords = keywords; @@ -356,7 +357,7 @@ static struct GNUNET_FS_Uri * uri_sks_parse (const char *s, char **emsg) { struct GNUNET_FS_Uri *ret; - struct GNUNET_FS_PseudonymIdentifier id; + struct GNUNET_CRYPTO_EccPublicKey ns; size_t pos; char *end; @@ -369,16 +370,16 @@ uri_sks_parse (const char *s, char **emsg) (GNUNET_OK != GNUNET_STRINGS_string_to_data (&s[pos], end - &s[pos], - &id, - sizeof (id))) ) + &ns, + sizeof (ns))) ) { *emsg = GNUNET_strdup (_("Malformed SKS URI")); return NULL; /* malformed */ } end++; /* skip over '/' */ - ret = GNUNET_malloc (sizeof (struct GNUNET_FS_Uri)); + ret = GNUNET_new (struct GNUNET_FS_Uri); ret->type = GNUNET_FS_URI_SKS; - ret->data.sks.ns = id; + ret->data.sks.ns = ns; ret->data.sks.identifier = GNUNET_strdup (end); return ret; } @@ -434,7 +435,7 @@ uri_chk_parse (const char *s, char **emsg) return NULL; } fi.file_length = GNUNET_htonll (flen); - ret = GNUNET_malloc (sizeof (struct GNUNET_FS_Uri)); + ret = GNUNET_new (struct GNUNET_FS_Uri); ret->type = GNUNET_FS_URI_CHK; ret->data.chk = fi; return ret; @@ -505,24 +506,36 @@ enc2bin (const char *input, void *data, size_t size) } +GNUNET_NETWORK_STRUCT_BEGIN /** - * Structure that defines how the - * contents of a location URI must be - * assembled in memory to create or - * verify the signature of a location + * Structure that defines how the contents of a location URI must be + * assembled in memory to create or verify the signature of a location * URI. */ struct LocUriAssembly { + /** + * What is being signed (rest of this struct). + */ struct GNUNET_CRYPTO_EccSignaturePurpose purpose; + /** + * Expiration time of the offer. + */ struct GNUNET_TIME_AbsoluteNBO exptime; + /** + * File being offered. + */ struct FileIdentifier fi; + /** + * Peer offering the file. + */ struct GNUNET_CRYPTO_EccPublicKey peer; }; +GNUNET_NETWORK_STRUCT_END #define GNUNET_FS_URI_LOC_PREFIX GNUNET_FS_URI_PREFIX GNUNET_FS_URI_LOC_INFIX @@ -635,7 +648,7 @@ uri_loc_parse (const char *s, char **emsg) GNUNET_strdup (_("SKS URI malformed (signature failed validation)")); goto ERR; } - uri = GNUNET_malloc (sizeof (struct GNUNET_FS_Uri)); + uri = GNUNET_new (struct GNUNET_FS_Uri); uri->type = GNUNET_FS_URI_LOC; uri->data.loc.fi = ass.fi; uri->data.loc.peer = ass.peer; @@ -862,7 +875,7 @@ GNUNET_FS_uri_loc_get_uri (const struct GNUNET_FS_Uri *uri) if (uri->type != GNUNET_FS_URI_LOC) return NULL; - ret = GNUNET_malloc (sizeof (struct GNUNET_FS_Uri)); + ret = GNUNET_new (struct GNUNET_FS_Uri); ret->type = GNUNET_FS_URI_CHK; ret->data.chk = uri->data.loc.fi; return ret; @@ -912,7 +925,7 @@ GNUNET_FS_uri_loc_create (const struct GNUNET_FS_Uri *baseUri, ass.exptime = GNUNET_TIME_absolute_hton (expiration_time); ass.fi = baseUri->data.chk; ass.peer = my_public_key; - uri = GNUNET_malloc (sizeof (struct GNUNET_FS_Uri)); + uri = GNUNET_new (struct GNUNET_FS_Uri); uri->type = GNUNET_FS_URI_LOC; uri->data.loc.fi = baseUri->data.chk; uri->data.loc.expirationTime = expiration_time; @@ -925,58 +938,22 @@ GNUNET_FS_uri_loc_create (const struct GNUNET_FS_Uri *baseUri, } -/** - * Create an SKS URI from a namespace and an identifier. - * - * @param ns namespace - * @param id identifier - * @param emsg where to store an error message - * @return an FS URI for the given namespace and identifier - */ -struct GNUNET_FS_Uri * -GNUNET_FS_uri_sks_create (struct GNUNET_FS_Namespace *ns, const char *id, - char **emsg) -{ - struct GNUNET_FS_Uri *ns_uri; - - if (NULL == id) - { - if (NULL != emsg) - *emsg = GNUNET_strdup (_("identifier is NULL!")); - return NULL; - } - else if ('\0' == id[0]) - { - if (NULL != emsg) - *emsg = GNUNET_strdup (_("identifier has zero length!")); - return NULL; - } - if (NULL != emsg) - *emsg = NULL; - ns_uri = GNUNET_malloc (sizeof (struct GNUNET_FS_Uri)); - ns_uri->type = GNUNET_FS_URI_SKS; - GNUNET_FS_namespace_get_public_identifier (ns, &ns_uri->data.sks.ns); - ns_uri->data.sks.identifier = GNUNET_strdup (id); - return ns_uri; -} - - /** * Create an SKS URI from a namespace ID and an identifier. * - * @param pseudonym namespace ID + * @param ns namespace ID * @param id identifier * @return an FS URI for the given namespace and identifier */ struct GNUNET_FS_Uri * -GNUNET_FS_uri_sks_create_from_nsid (struct GNUNET_FS_PseudonymIdentifier *pseudonym, - const char *id) +GNUNET_FS_uri_sks_create (const struct GNUNET_CRYPTO_EccPublicKey *ns, + const char *id) { struct GNUNET_FS_Uri *ns_uri; - ns_uri = GNUNET_malloc (sizeof (struct GNUNET_FS_Uri)); + ns_uri = GNUNET_new (struct GNUNET_FS_Uri); ns_uri->type = GNUNET_FS_URI_SKS; - ns_uri->data.sks.ns = *pseudonym; + ns_uri->data.sks.ns = *ns; ns_uri->data.sks.identifier = GNUNET_strdup (id); return ns_uri; } @@ -1033,7 +1010,7 @@ GNUNET_FS_uri_ksk_merge (const struct GNUNET_FS_Uri *u1, if (0 == found) kl[kc++] = GNUNET_strdup (kp); } - ret = GNUNET_malloc (sizeof (struct GNUNET_FS_Uri)); + ret = GNUNET_new (struct GNUNET_FS_Uri); ret->type = GNUNET_FS_URI_KSK; ret->data.ksk.keywordCount = kc; ret->data.ksk.keywords = kl; @@ -1055,7 +1032,7 @@ GNUNET_FS_uri_dup (const struct GNUNET_FS_Uri *uri) if (uri == NULL) return NULL; - ret = GNUNET_malloc (sizeof (struct GNUNET_FS_Uri)); + ret = GNUNET_new (struct GNUNET_FS_Uri); memcpy (ret, uri, sizeof (struct GNUNET_FS_Uri)); switch (ret->type) { @@ -1224,7 +1201,7 @@ GNUNET_FS_uri_ksk_create_from_args (unsigned int argc, const char **argv) && (NULL != (uri = GNUNET_FS_uri_parse (argv[0], &emsg)))) return uri; GNUNET_free_non_null (emsg); - uri = GNUNET_malloc (sizeof (struct GNUNET_FS_Uri)); + uri = GNUNET_new (struct GNUNET_FS_Uri); uri->type = GNUNET_FS_URI_KSK; uri->data.ksk.keywordCount = argc; uri->data.ksk.keywords = GNUNET_malloc (argc * sizeof (char *)); @@ -1280,7 +1257,7 @@ GNUNET_FS_uri_test_equal (const struct GNUNET_FS_Uri *u1, case GNUNET_FS_URI_SKS: if ((0 == memcmp (&u1->data.sks.ns, &u2->data.sks.ns, - sizeof (struct GNUNET_FS_PseudonymIdentifier))) && + sizeof (struct GNUNET_CRYPTO_EccPublicKey))) && (0 == strcmp (u1->data.sks.identifier, u2->data.sks.identifier))) return GNUNET_YES; @@ -1341,7 +1318,7 @@ GNUNET_FS_uri_test_sks (const struct GNUNET_FS_Uri *uri) */ int GNUNET_FS_uri_sks_get_namespace (const struct GNUNET_FS_Uri *uri, - struct GNUNET_FS_PseudonymIdentifier *pseudonym) + struct GNUNET_CRYPTO_EccPublicKey *pseudonym) { if (!GNUNET_FS_uri_test_sks (uri)) { @@ -1812,7 +1789,7 @@ GNUNET_FS_uri_ksk_create_from_meta_data (const struct GNUNET_CONTAINER_MetaData if (md == NULL) return NULL; - ret = GNUNET_malloc (sizeof (struct GNUNET_FS_Uri)); + ret = GNUNET_new (struct GNUNET_FS_Uri); ret->type = GNUNET_FS_URI_KSK; ent = GNUNET_CONTAINER_meta_data_iterate (md, NULL, NULL); if (ent > 0) @@ -1944,7 +1921,7 @@ uri_sks_to_string (const struct GNUNET_FS_Uri *uri) if (GNUNET_FS_URI_SKS != uri->type) return NULL; ret = GNUNET_STRINGS_data_to_string (&uri->data.sks.ns, - sizeof (struct GNUNET_FS_PseudonymIdentifier), + sizeof (struct GNUNET_CRYPTO_EccPublicKey), buf, sizeof (buf)); GNUNET_assert (NULL != ret); diff --git a/src/fs/gnunet-pseudonym.c b/src/fs/gnunet-pseudonym.c index 61975e463..c87679641 100644 --- a/src/fs/gnunet-pseudonym.c +++ b/src/fs/gnunet-pseudonym.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - (C) 2001, 2002, 2004, 2005, 2006, 2007, 2009, 2010 Christian Grothoff (and other contributing authors) + (C) 2001-2013 Christian Grothoff (and other contributing authors) GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published @@ -24,27 +24,19 @@ */ #include "platform.h" #include "gnunet_fs_service.h" +#include "gnunet_identity_service.h" -/** - * -C option - */ -static char *create_ns; /** - * -D option + * -A option */ -static char *delete_ns; +static char *advertise_ns; /** * -k option */ static struct GNUNET_FS_Uri *ksk_uri; -/** - * -l option. - */ -static int print_local_only; - /** * -m option. */ @@ -76,17 +68,37 @@ static char *rating_change; static struct GNUNET_FS_Handle *h; /** - * Namespace we are looking at. + * Our configuration. + */ +static const struct GNUNET_CONFIGURATION_Handle *cfg; + +/** + * Handle to identity service. */ -static struct GNUNET_FS_Namespace *ns; +static struct GNUNET_IDENTITY_Handle *identity; /** - * Our configuration. + * Target namespace. */ -static const struct GNUNET_CONFIGURATION_Handle *cfg; +static struct GNUNET_IDENTITY_Ego *namespace; +/** + * URI to advertise. + */ +static struct GNUNET_FS_Uri *sks_uri; + +/** + * Global return value. + */ static int ret; + +/** + * Progress callback given to FS. + * + * @param cls unused + * @param info progress information, unused + */ static void * progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *info) { @@ -94,20 +106,6 @@ progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *info) } -static void -ns_printer (void *cls, const char *name, const struct GNUNET_FS_PseudonymIdentifier *pseudonym) -{ - struct GNUNET_CRYPTO_HashAsciiEncoded enc; - struct GNUNET_HashCode hc; - - GNUNET_CRYPTO_hash (pseudonym, - sizeof (struct GNUNET_FS_PseudonymIdentifier), - &hc); - GNUNET_CRYPTO_hash_to_enc (&hc, &enc); - FPRINTF (stdout, "%s (%s)\n", name, (const char *) &enc); -} - - /** * Output information about a pseudonym. * @@ -121,7 +119,7 @@ ns_printer (void *cls, const char *name, const struct GNUNET_FS_PseudonymIdentif */ static int pseudo_printer (void *cls, - const struct GNUNET_FS_PseudonymIdentifier *pseudonym, + const struct GNUNET_CRYPTO_EccPublicKey *pseudonym, const char *name, const char *unique_name, const struct GNUNET_CONTAINER_MetaData *md, @@ -135,77 +133,105 @@ pseudo_printer (void *cls, * GNUNET_FS_pseudonym_get_info () never returns NULL. */ getinfo_result = GNUNET_FS_pseudonym_get_info (cfg, pseudonym, - NULL, NULL, &id, NULL); - if (getinfo_result != GNUNET_OK) + NULL, NULL, &id, NULL); + if (GNUNET_OK != getinfo_result) { GNUNET_break (0); return GNUNET_OK; } unique_id = GNUNET_FS_pseudonym_name_uniquify (cfg, pseudonym, id, NULL); GNUNET_free (id); - FPRINTF (stdout, "%s (%d):\n", unique_id, rating); + FPRINTF (stdout, + "%s (%d):\n", + unique_id, rating); GNUNET_CONTAINER_meta_data_iterate (md, &EXTRACTOR_meta_data_print, stdout); - FPRINTF (stdout, "%s", "\n"); + FPRINTF (stdout, + "%s", + "\n"); GNUNET_free (unique_id); return GNUNET_OK; } +/** + * Function called once advertising is finished. + * + * @param cls closure (NULL) + * @param uri the advertised URI + * @param emsg error message, NULL on success + */ static void -post_advertising (void *cls, const struct GNUNET_FS_Uri *uri, const char *emsg) +post_advertising (void *cls, + const struct GNUNET_FS_Uri *uri, + const char *emsg) { - struct GNUNET_FS_PseudonymIdentifier nsid; - char *set; - int delta; - if (emsg != NULL) { FPRINTF (stderr, "%s", emsg); ret = 1; } - if (ns != NULL) - { - if (GNUNET_OK != GNUNET_FS_namespace_delete (ns, GNUNET_NO)) - ret = 1; - } - if (NULL != rating_change) + GNUNET_FS_stop (h); + GNUNET_IDENTITY_disconnect (identity); +} + + +/** + * Function called by identity service with known pseudonyms. + * + * @param cls closure, NULL + * @param ego ego handle + * @param ego_ctx context for application to store data for this ego + * (during the lifetime of this process, initially NULL) + * @param name name assigned by the user for this ego, + * NULL if the user just deleted the ego and it + * must thus no longer be used + */ +static void +identity_cb (void *cls, + struct GNUNET_IDENTITY_Ego *ego, + void **ctx, + const char *name) +{ + char *emsg; + struct GNUNET_CRYPTO_EccPublicKey pub; + + if (NULL == ego) { - set = rating_change; - while ((*set != '\0') && (*set != ':')) - set++; - if (*set != ':') + if (NULL == namespace) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Invalid argument `%s'\n"), - rating_change); + ret = 1; + return; } - else + if (NULL != root_identifier) { - *set = '\0'; - delta = strtol (&set[1], NULL, /* no error handling yet */ - 10); - if (GNUNET_OK == GNUNET_FS_pseudonym_name_to_id (cfg, rating_change, &nsid)) + if (NULL == ksk_uri) { - (void) GNUNET_FS_pseudonym_rank (cfg, &nsid, delta); - } - else - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - ("Namespace `%s' unknown. Make sure you specify its numeric suffix, if any.\n"), - rating_change); + emsg = NULL; + ksk_uri = GNUNET_FS_uri_parse ("gnunet://fs/ksk/namespace", &emsg); + GNUNET_assert (NULL == emsg); } + GNUNET_IDENTITY_ego_get_public_key (namespace, + &pub); + sks_uri = GNUNET_FS_uri_sks_create (&pub, + root_identifier); + GNUNET_FS_publish_ksk (h, ksk_uri, adv_metadata, sks_uri, + &bo, + GNUNET_FS_PUBLISH_OPTION_NONE, + &post_advertising, NULL); + GNUNET_FS_uri_destroy (sks_uri); + return; } - GNUNET_free (rating_change); - rating_change = NULL; - } - if (0 != print_local_only) - { - GNUNET_FS_namespace_list (h, &ns_printer, NULL); - } - else if (0 == no_remote_printing) - { - GNUNET_FS_pseudonym_list_all (cfg, &pseudo_printer, NULL); + else + { + if (NULL != ksk_uri) + FPRINTF (stderr, _("Option `%s' ignored\n"), "-k"); + if (NULL != advertise_ns) + FPRINTF (stderr, _("Option `%s' ignored\n"), "-A"); + } + return; } - GNUNET_FS_stop (h); + if (0 == strcmp (name, advertise_ns)) + namespace = ego; } @@ -221,68 +247,50 @@ static void run (void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *c) { - struct GNUNET_FS_Uri *sks_uri; - char *emsg; + struct GNUNET_CRYPTO_EccPublicKey nsid; + char *set; + int delta; cfg = c; h = GNUNET_FS_start (cfg, "gnunet-pseudonym", &progress_cb, NULL, GNUNET_FS_FLAGS_NONE, GNUNET_FS_OPTIONS_END); - if (NULL != delete_ns) - { - ns = GNUNET_FS_namespace_create (h, delete_ns); - if (ns == NULL) - { - ret = 1; - } - else - { - if (GNUNET_OK != GNUNET_FS_namespace_delete (ns, GNUNET_YES)) - ret = 1; - ns = NULL; - } - } - if (NULL != create_ns) + if (NULL != rating_change) { - ns = GNUNET_FS_namespace_create (h, create_ns); - if (ns == NULL) + set = rating_change; + while ((*set != '\0') && (*set != ':')) + set++; + if (*set != ':') { - ret = 1; + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Invalid argument `%s'\n"), + rating_change); } else { - if (NULL != root_identifier) + *set = '\0'; + delta = strtol (&set[1], NULL, /* no error handling yet */ + 10); + if (GNUNET_OK == GNUNET_FS_pseudonym_name_to_id (cfg, rating_change, &nsid)) { - if (ksk_uri == NULL) - { - emsg = NULL; - ksk_uri = GNUNET_FS_uri_parse ("gnunet://fs/ksk/namespace", &emsg); - GNUNET_assert (NULL == emsg); - } - sks_uri = GNUNET_FS_uri_sks_create (ns, root_identifier, &emsg); - GNUNET_assert (NULL == emsg); - GNUNET_FS_publish_ksk (h, ksk_uri, adv_metadata, sks_uri, - &bo, - GNUNET_FS_PUBLISH_OPTION_NONE, - &post_advertising, NULL); - GNUNET_FS_uri_destroy (sks_uri); - return; + (void) GNUNET_FS_pseudonym_rank (cfg, &nsid, delta); } else { - if (ksk_uri != NULL) - FPRINTF (stderr, _("Option `%s' ignored\n"), "-k"); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + ("Namespace `%s' unknown. Make sure you specify its numeric suffix, if any.\n"), + rating_change); } } + GNUNET_free (rating_change); + rating_change = NULL; } - else - { - if (root_identifier != NULL) - FPRINTF (stderr, _("Option `%s' ignored\n"), "-r"); - if (ksk_uri != NULL) - FPRINTF (stderr, _("Option `%s' ignored\n"), "-k"); - } + if (0 == no_remote_printing) + GNUNET_FS_pseudonym_list_all (cfg, &pseudo_printer, NULL); - post_advertising (NULL, NULL, NULL); + if (NULL != advertise_ns) + identity = GNUNET_IDENTITY_connect (cfg, + &identity_cb, + NULL); } @@ -301,12 +309,9 @@ main (int argc, char *const *argv) {'a', "anonymity", "LEVEL", gettext_noop ("set the desired LEVEL of sender-anonymity"), 1, &GNUNET_GETOPT_set_uint, &bo.anonymity_level}, - {'C', "create", "NAME", - gettext_noop ("create or advertise namespace NAME"), - 1, &GNUNET_GETOPT_set_string, &create_ns}, - {'D', "delete", "NAME", - gettext_noop ("delete namespace NAME "), - 1, &GNUNET_GETOPT_set_string, &delete_ns}, + {'A', "advertise", "NAME", + gettext_noop ("advertise namespace NAME"), + 1, &GNUNET_GETOPT_set_string, &advertise_ns}, {'k', "keyword", "VALUE", gettext_noop ("add an additional keyword for the advertisment" " (this option can be specified multiple times)"), @@ -314,9 +319,6 @@ main (int argc, char *const *argv) {'m', "meta", "TYPE:VALUE", gettext_noop ("set the meta-data for the given TYPE to the given VALUE"), 1, &GNUNET_FS_getopt_set_metadata, &adv_metadata}, - {'o', "only-local", NULL, - gettext_noop ("print names of local namespaces"), - 0, &GNUNET_GETOPT_set_one, &print_local_only}, {'p', "priority", "PRIORITY", gettext_noop ("use the given PRIORITY for the advertisments"), 1, &GNUNET_GETOPT_set_uint, &bo.content_priority}, diff --git a/src/fs/gnunet-publish.c b/src/fs/gnunet-publish.c index 59b40a5e4..39235683c 100644 --- a/src/fs/gnunet-publish.c +++ b/src/fs/gnunet-publish.c @@ -27,6 +27,7 @@ */ #include "platform.h" #include "gnunet_fs_service.h" +#include "gnunet_identity_service.h" /** * Global return value from 'main'. @@ -137,7 +138,12 @@ static struct GNUNET_FS_DirScanner *ds; * Which namespace do we publish to? NULL if we do not publish to * a namespace. */ -static struct GNUNET_FS_Namespace *namespace; +static struct GNUNET_IDENTITY_Ego *namespace; + +/** + * Handle to identity service. + */ +static struct GNUNET_IDENTITY_Handle *identity; /** @@ -153,7 +159,7 @@ do_stop_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) struct GNUNET_FS_PublishContext *p; kill_task = GNUNET_SCHEDULER_NO_TASK; - if (pc != NULL) + if (NULL != pc) { p = pc; pc = NULL; @@ -182,10 +188,10 @@ stop_scanner_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_FS_directory_scan_abort (ds); ds = NULL; } - if (NULL != namespace) + if (NULL != identity) { - GNUNET_FS_namespace_delete (namespace, GNUNET_NO); - namespace = NULL; + GNUNET_IDENTITY_disconnect (identity); + identity = NULL; } GNUNET_FS_stop (ctx); ctx = NULL; @@ -432,29 +438,20 @@ static void uri_ksk_continuation (void *cls, const struct GNUNET_FS_Uri *ksk_uri, const char *emsg) { - struct GNUNET_FS_Namespace *ns; + const struct GNUNET_CRYPTO_EccPrivateKey *priv; if (NULL != emsg) { FPRINTF (stderr, "%s\n", emsg); ret = 1; } - if (NULL != pseudonym) + if (NULL != namespace) { - ns = GNUNET_FS_namespace_create (ctx, pseudonym); - if (NULL == ns) - { - FPRINTF (stderr, _("Failed to create namespace `%s' (illegal filename?)\n"), pseudonym); - ret = 1; - } - else - { - GNUNET_FS_publish_sks (ctx, ns, this_id, next_id, meta, uri, &bo, - GNUNET_FS_PUBLISH_OPTION_NONE, - &uri_sks_continuation, NULL); - GNUNET_assert (GNUNET_OK == GNUNET_FS_namespace_delete (ns, GNUNET_NO)); - return; - } + priv = GNUNET_IDENTITY_ego_get_private_key (namespace); + GNUNET_FS_publish_sks (ctx, priv, this_id, next_id, meta, uri, &bo, + GNUNET_FS_PUBLISH_OPTION_NONE, + &uri_sks_continuation, NULL); + return; } GNUNET_FS_uri_destroy (uri); uri = NULL; @@ -523,40 +520,37 @@ static void directory_trim_complete (struct GNUNET_FS_ShareTreeItem *directory_scan_result) { struct GNUNET_FS_FileInformation *fi; + const struct GNUNET_CRYPTO_EccPrivateKey *priv; fi = get_file_information (directory_scan_result); GNUNET_FS_share_tree_free (directory_scan_result); if (NULL == fi) { FPRINTF (stderr, "%s", _("Could not publish\n")); - if (NULL != namespace) - GNUNET_FS_namespace_delete (namespace, GNUNET_NO); - GNUNET_FS_stop (ctx); + GNUNET_SCHEDULER_shutdown (); ret = 1; return; } GNUNET_FS_file_information_inspect (fi, &publish_inspector, NULL); if (extract_only) { - if (NULL != namespace) - GNUNET_FS_namespace_delete (namespace, GNUNET_NO); GNUNET_FS_file_information_destroy (fi, NULL, NULL); - GNUNET_FS_stop (ctx); - if (GNUNET_SCHEDULER_NO_TASK != kill_task) - { - GNUNET_SCHEDULER_cancel (kill_task); - kill_task = GNUNET_SCHEDULER_NO_TASK; - } + GNUNET_SCHEDULER_shutdown (); return; } - pc = GNUNET_FS_publish_start (ctx, fi, namespace, this_id, next_id, + if (NULL == namespace) + priv = NULL; + else + priv = GNUNET_IDENTITY_ego_get_private_key (namespace); + pc = GNUNET_FS_publish_start (ctx, fi, + priv, this_id, next_id, (do_simulate) ? GNUNET_FS_PUBLISH_OPTION_SIMULATE_ONLY : GNUNET_FS_PUBLISH_OPTION_NONE); if (NULL == pc) { FPRINTF (stderr, "%s", _("Could not start publishing.\n")); - GNUNET_FS_stop (ctx); + GNUNET_SCHEDULER_shutdown (); ret = 1; return; } @@ -631,6 +625,94 @@ directory_scan_cb (void *cls, } +/** + * Continuation proceeding with initialization after identity subsystem + * has been initialized. + * + * @param args0 filename to publish + */ +static void +identity_continuation (const char *args0) +{ + char *ex; + char *emsg; + + if ( (NULL != pseudonym) && + (NULL == namespace) ) + { + FPRINTF (stderr, _("Selected pseudonym `%s' unknown\n"), pseudonym); + GNUNET_SCHEDULER_shutdown (); + return; + } + if (NULL != uri_string) + { + emsg = NULL; + if (NULL == (uri = GNUNET_FS_uri_parse (uri_string, &emsg))) + { + FPRINTF (stderr, _("Failed to parse URI: %s\n"), emsg); + GNUNET_free (emsg); + GNUNET_SCHEDULER_shutdown (); + ret = 1; + return; + } + GNUNET_FS_publish_ksk (ctx, topKeywords, meta, uri, &bo, + GNUNET_FS_PUBLISH_OPTION_NONE, &uri_ksk_continuation, + NULL); + return; + } + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_string (cfg, "FS", "EXTRACTORS", &ex)) + ex = NULL; + if (0 != ACCESS (args0, R_OK)) + { + FPRINTF (stderr, + _("Failed to access `%s': %s\n"), + args0, + STRERROR (errno)); + return; + } + ds = GNUNET_FS_directory_scan_start (args0, + disable_extractor, + ex, + &directory_scan_cb, NULL); + if (NULL == ds) + { + FPRINTF (stderr, + "%s", _("Failed to start meta directory scanner. Is gnunet-helper-publish-fs installed?\n")); + return; + } +} + + +/** + * Function called by identity service with known pseudonyms. + * + * @param cls closure with 'const char *' of filename to publish + * @param ego ego handle + * @param ego_ctx context for application to store data for this ego + * (during the lifetime of this process, initially NULL) + * @param name name assigned by the user for this ego, + * NULL if the user just deleted the ego and it + * must thus no longer be used + */ +static void +identity_cb (void *cls, + struct GNUNET_IDENTITY_Ego *ego, + void **ctx, + const char *name) +{ + const char *args0 = cls; + + if (NULL == ego) + { + identity_continuation (args0); + return; + } + if (0 == strcmp (name, pseudonym)) + namespace = ego; +} + + /** * Main function that will be run by the scheduler. * @@ -643,9 +725,6 @@ static void run (void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *c) { - char *ex; - char *emsg; - /* check arguments */ if ((NULL != uri_string) && (extract_only)) { @@ -703,62 +782,14 @@ run (void *cls, char *const *args, const char *cfgfile, ret = 1; return; } - namespace = NULL; - if (NULL != pseudonym) - { - namespace = GNUNET_FS_namespace_create (ctx, pseudonym); - if (NULL == namespace) - { - FPRINTF (stderr, _("Failed to create namespace `%s' (illegal filename?)\n"), pseudonym); - GNUNET_FS_stop (ctx); - ret = 1; - return; - } - } - if (NULL != uri_string) - { - emsg = NULL; - if (NULL == (uri = GNUNET_FS_uri_parse (uri_string, &emsg))) - { - FPRINTF (stderr, _("Failed to parse URI: %s\n"), emsg); - GNUNET_free (emsg); - if (namespace != NULL) - GNUNET_FS_namespace_delete (namespace, GNUNET_NO); - GNUNET_FS_stop (ctx); - ret = 1; - return; - } - GNUNET_FS_publish_ksk (ctx, topKeywords, meta, uri, &bo, - GNUNET_FS_PUBLISH_OPTION_NONE, &uri_ksk_continuation, - NULL); - if (NULL != namespace) - GNUNET_FS_namespace_delete (namespace, GNUNET_NO); - return; - } - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_string (cfg, "FS", "EXTRACTORS", &ex)) - ex = NULL; - if (0 != ACCESS (args[0], R_OK)) - { - FPRINTF (stderr, - _("Failed to access `%s': %s\n"), - args[0], - STRERROR (errno)); - return; - } - ds = GNUNET_FS_directory_scan_start (args[0], - disable_extractor, - ex, - &directory_scan_cb, NULL); - if (NULL == ds) - { - FPRINTF (stderr, - "%s", _("Failed to start meta directory scanner. Is gnunet-helper-publish-fs installed?\n")); - return; - } kill_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &do_stop_task, NULL); + if (NULL != pseudonym) + identity = GNUNET_IDENTITY_connect (cfg, + &identity_cb, args[0]); + else + identity_continuation (args[0]); } diff --git a/src/fs/plugin_block_fs.c b/src/fs/plugin_block_fs.c index 453338614..e493319be 100644 --- a/src/fs/plugin_block_fs.c +++ b/src/fs/plugin_block_fs.c @@ -105,15 +105,16 @@ block_plugin_fs_evaluate (void *cls, enum GNUNET_BLOCK_Type type, GNUNET_break_op (0); return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; } - if (reply_block_size != ntohl (ub->purpose.size) + sizeof (struct GNUNET_FS_PseudonymSignature)) + if (reply_block_size != ntohl (ub->purpose.size) + sizeof (struct GNUNET_CRYPTO_EccSignature)) { GNUNET_break_op (0); return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; } if (GNUNET_OK != - GNUNET_FS_pseudonym_verify (&ub->purpose, - &ub->signature, - &ub->verification_key)) + GNUNET_CRYPTO_ecc_verify (GNUNET_SIGNATURE_PURPOSE_FS_UBLOCK, + &ub->purpose, + &ub->signature, + &ub->verification_key)) { GNUNET_break_op (0); return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; diff --git a/src/fs/test_fs_namespace.c b/src/fs/test_fs_namespace.c index c720cb919..c8371f0b5 100644 --- a/src/fs/test_fs_namespace.c +++ b/src/fs/test_fs_namespace.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - (C) 2005, 2006, 2008, 2009 Christian Grothoff (and other contributing authors) + (C) 2005-2013 Christian Grothoff (and other contributing authors) GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published @@ -29,7 +29,7 @@ #include "gnunet_fs_service.h" -static struct GNUNET_FS_PseudonymIdentifier nsid; +static struct GNUNET_CRYPTO_EccPublicKey nsid; static struct GNUNET_FS_Uri *sks_expect_uri; @@ -68,15 +68,10 @@ abort_ksk_search_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) static void abort_sks_search_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { - struct GNUNET_FS_Namespace *ns; - if (sks_search == NULL) return; GNUNET_FS_search_stop (sks_search); sks_search = NULL; - ns = GNUNET_FS_namespace_create (fs, "testNamespace"); - GNUNET_assert (NULL != ns); - GNUNET_assert (GNUNET_OK == GNUNET_FS_namespace_delete (ns, GNUNET_YES)); if (ksk_search == NULL) { GNUNET_FS_stop (fs); @@ -242,7 +237,7 @@ static void adv_cont (void *cls, const struct GNUNET_FS_Uri *uri, const char *emsg) { struct GNUNET_CONTAINER_MetaData *meta; - struct GNUNET_FS_Namespace *ns; + struct GNUNET_CRYPTO_EccPrivateKey *ns; struct GNUNET_FS_BlockOptions bo; if (NULL != emsg) @@ -252,57 +247,32 @@ adv_cont (void *cls, const struct GNUNET_FS_Uri *uri, const char *emsg) GNUNET_FS_stop (fs); return; } - ns = GNUNET_FS_namespace_create (fs, "testNamespace"); - GNUNET_assert (NULL != ns); + ns = GNUNET_CRYPTO_ecc_key_create (); meta = GNUNET_CONTAINER_meta_data_create (); - GNUNET_assert (NULL == emsg); sks_expect_uri = GNUNET_FS_uri_dup (uri); bo.content_priority = 1; bo.anonymity_level = 1; bo.replication_level = 0; bo.expiration_time = GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_MINUTES); + GNUNET_CRYPTO_ecc_key_get_public (ns, &nsid); GNUNET_FS_publish_sks (fs, ns, "this", "next", meta, uri, &bo, GNUNET_FS_PUBLISH_OPTION_NONE, &sks_cont, NULL); GNUNET_CONTAINER_meta_data_destroy (meta); - GNUNET_FS_namespace_delete (ns, GNUNET_NO); -} - - -static void -ns_iterator (void *cls, const char *name, const struct GNUNET_FS_PseudonymIdentifier *id) -{ - int *ok = cls; - - if (0 != strcmp (name, "testNamespace")) - return; - *ok = GNUNET_YES; - nsid = *id; + GNUNET_CRYPTO_ecc_key_free (ns); } static void testNamespace () { - struct GNUNET_FS_Namespace *ns; + struct GNUNET_CRYPTO_EccPrivateKey *ns; struct GNUNET_FS_BlockOptions bo; struct GNUNET_CONTAINER_MetaData *meta; struct GNUNET_FS_Uri *ksk_uri; struct GNUNET_FS_Uri *sks_uri; - int ok; - ns = GNUNET_FS_namespace_create (fs, "testNamespace"); - GNUNET_assert (NULL != ns); - ok = GNUNET_NO; - GNUNET_FS_namespace_list (fs, &ns_iterator, &ok); - if (GNUNET_NO == ok) - { - FPRINTF (stderr, "%s", "namespace_list failed to find namespace!\n"); - GNUNET_FS_namespace_delete (ns, GNUNET_YES); - GNUNET_FS_stop (fs); - err = 1; - return; - } + ns = GNUNET_CRYPTO_ecc_key_create (); meta = GNUNET_CONTAINER_meta_data_create (); ksk_uri = GNUNET_FS_uri_parse ("gnunet://fs/ksk/testnsa", NULL); bo.content_priority = 1; @@ -310,17 +280,18 @@ testNamespace () bo.replication_level = 0; bo.expiration_time = GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_MINUTES); - sks_uri = GNUNET_FS_uri_sks_create (ns, "root", NULL); + sks_uri = GNUNET_FS_uri_sks_create (&nsid, "root"); GNUNET_FS_publish_ksk (fs, - ksk_uri, meta, sks_uri, &bo, GNUNET_FS_PUBLISH_OPTION_NONE, + ksk_uri, meta, sks_uri, + &bo, GNUNET_FS_PUBLISH_OPTION_NONE, &adv_cont, NULL); GNUNET_FS_uri_destroy (sks_uri); kill_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES, &do_timeout, NULL); GNUNET_FS_uri_destroy (ksk_uri); - GNUNET_FS_namespace_delete (ns, GNUNET_NO); GNUNET_CONTAINER_meta_data_destroy (meta); + GNUNET_CRYPTO_ecc_key_free (ns); } diff --git a/src/fs/test_fs_namespace_list_updateable.c b/src/fs/test_fs_namespace_list_updateable.c index dc17ce458..ff662c9e6 100644 --- a/src/fs/test_fs_namespace_list_updateable.c +++ b/src/fs/test_fs_namespace_list_updateable.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - (C) 2005, 2006, 2008, 2009 Christian Grothoff (and other contributing authors) + (C) 2005-2013 Christian Grothoff (and other contributing authors) GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published @@ -33,7 +33,7 @@ static struct GNUNET_FS_Handle *fs; static int err; -static struct GNUNET_FS_Namespace *ns; +static struct GNUNET_CRYPTO_EccPrivateKey *ns; static struct GNUNET_CONTAINER_MetaData *meta; @@ -59,7 +59,7 @@ do_shutdown () if (uri_next != NULL) GNUNET_FS_uri_destroy (uri_next); if (ns != NULL) - GNUNET_FS_namespace_delete (ns, GNUNET_NO); + GNUNET_CRYPTO_ecc_key_free (ns); if (meta != NULL) GNUNET_CONTAINER_meta_data_destroy (meta); } @@ -87,7 +87,7 @@ check_this_next (void *cls, const char *last_id, GNUNET_break (0 == strcmp (next_id, "next")); err -= 2; err += 4; - GNUNET_FS_namespace_list_updateable (ns, next_id, &check_next, NULL); + GNUNET_FS_namespace_list_updateable (fs, ns, next_id, &check_next, NULL); } @@ -96,7 +96,7 @@ sks_cont_next (void *cls, const struct GNUNET_FS_Uri *uri, const char *emsg) { GNUNET_assert (NULL == emsg); err += 2; - GNUNET_FS_namespace_list_updateable (ns, NULL, &check_this_next, NULL); + GNUNET_FS_namespace_list_updateable (fs, ns, NULL, &check_this_next, NULL); } @@ -117,7 +117,7 @@ sks_cont_this (void *cls, const struct GNUNET_FS_Uri *uri, const char *emsg) { GNUNET_assert (NULL == emsg); err = 1; - GNUNET_FS_namespace_list_updateable (ns, NULL, &check_this, NULL); + GNUNET_FS_namespace_list_updateable (fs, ns, NULL, &check_this, NULL); GNUNET_FS_publish_sks (fs, ns, "next", "future", meta, uri_next, &bo, GNUNET_FS_PUBLISH_OPTION_NONE, &sks_cont_next, NULL); @@ -127,7 +127,7 @@ sks_cont_this (void *cls, const struct GNUNET_FS_Uri *uri, const char *emsg) static void testNamespace () { - ns = GNUNET_FS_namespace_create (fs, "testNamespace"); + ns = GNUNET_CRYPTO_ecc_key_create (); GNUNET_assert (NULL != ns); bo.content_priority = 1; bo.anonymity_level = 1; diff --git a/src/fs/test_fs_uri.c b/src/fs/test_fs_uri.c index d0aa26b79..ca89a7652 100644 --- a/src/fs/test_fs_uri.c +++ b/src/fs/test_fs_uri.c @@ -162,8 +162,8 @@ testNamespace (int i) char *uri; struct GNUNET_FS_Uri *ret; char *emsg; - struct GNUNET_FS_PseudonymHandle *ph; - struct GNUNET_FS_PseudonymIdentifier id; + struct GNUNET_CRYPTO_EccPrivateKey *ph; + struct GNUNET_CRYPTO_EccPublicKey id; char buf[1024]; char ubuf[1024]; char *sret; @@ -192,8 +192,8 @@ testNamespace (int i) GNUNET_assert (0); } GNUNET_free (emsg); - ph = GNUNET_FS_pseudonym_create (NULL); - GNUNET_FS_pseudonym_get_identifier (ph, &id); + ph = GNUNET_CRYPTO_ecc_key_create (); + GNUNET_CRYPTO_ecc_key_get_public (ph, &id); sret = GNUNET_STRINGS_data_to_string (&id, sizeof (id), ubuf, sizeof (ubuf) - 1); GNUNET_assert (NULL != sret); @@ -232,6 +232,7 @@ testNamespace (int i) return 0; } + static int testFile (int i) { diff --git a/src/fs/test_pseudonym.c b/src/fs/test_pseudonym.c index a6e258038..c3b459420 100644 --- a/src/fs/test_pseudonym.c +++ b/src/fs/test_pseudonym.c @@ -33,17 +33,18 @@ static struct GNUNET_CONTAINER_MetaData *meta; -static struct GNUNET_FS_PseudonymIdentifier id1; +static struct GNUNET_CRYPTO_EccPublicKey id1; static int -iter (void *cls, const struct GNUNET_FS_PseudonymIdentifier * pseudonym, +iter (void *cls, + const struct GNUNET_CRYPTO_EccPublicKey *pseudonym, const char *name, const char *unique_name, const struct GNUNET_CONTAINER_MetaData *md, int32_t rating) { int *ok = cls; - if ((0 == memcmp (pseudonym, &id1, sizeof (struct GNUNET_FS_PseudonymIdentifier))) && + if ((0 == memcmp (pseudonym, &id1, sizeof (struct GNUNET_CRYPTO_EccPublicKey))) && (!GNUNET_CONTAINER_meta_data_test_equal (md, meta))) { *ok = GNUNET_NO; @@ -54,7 +55,7 @@ iter (void *cls, const struct GNUNET_FS_PseudonymIdentifier * pseudonym, static int -noti_callback (void *cls, const struct GNUNET_FS_PseudonymIdentifier * pseudonym, +noti_callback (void *cls, const struct GNUNET_CRYPTO_EccPublicKey *pseudonym, const char *name, const char *unique_name, const struct GNUNET_CONTAINER_MetaData *md, int32_t rating) { @@ -66,7 +67,8 @@ noti_callback (void *cls, const struct GNUNET_FS_PseudonymIdentifier * pseudonym static int -fake_noti_callback (void *cls, const struct GNUNET_FS_PseudonymIdentifier * pseudonym, +fake_noti_callback (void *cls, + const struct GNUNET_CRYPTO_EccPublicKey * pseudonym, const char *name, const char *unique_name, const struct GNUNET_CONTAINER_MetaData *md, int32_t rating) { @@ -78,13 +80,13 @@ fake_noti_callback (void *cls, const struct GNUNET_FS_PseudonymIdentifier * pseu static void -create_pseu (struct GNUNET_FS_PseudonymIdentifier *pseu) +create_pseu (struct GNUNET_CRYPTO_EccPublicKey *pseu) { - struct GNUNET_FS_PseudonymHandle *ph; + struct GNUNET_CRYPTO_EccPrivateKey *ph; - ph = GNUNET_FS_pseudonym_create (NULL); - GNUNET_FS_pseudonym_get_identifier (ph, pseu); - GNUNET_FS_pseudonym_destroy (ph); + ph = GNUNET_CRYPTO_ecc_key_create (); + GNUNET_CRYPTO_ecc_key_get_public (ph, pseu); + GNUNET_CRYPTO_ecc_key_free (ph); } @@ -95,11 +97,11 @@ static int test_io () { int ok; - struct GNUNET_FS_PseudonymIdentifier rid1; - struct GNUNET_FS_PseudonymIdentifier id2; - struct GNUNET_FS_PseudonymIdentifier rid2; - struct GNUNET_FS_PseudonymIdentifier fid; - struct GNUNET_FS_PseudonymIdentifier id3; + struct GNUNET_CRYPTO_EccPublicKey rid1; + struct GNUNET_CRYPTO_EccPublicKey id2; + struct GNUNET_CRYPTO_EccPublicKey rid2; + struct GNUNET_CRYPTO_EccPublicKey fid; + struct GNUNET_CRYPTO_EccPublicKey id3; int old; int newVal; struct GNUNET_CONFIGURATION_Handle *cfg; @@ -112,12 +114,11 @@ test_io () int noname_is_a_dup; int notiCount, fakenotiCount; static char m[1024 * 1024 * 10]; - struct GNUNET_FS_pseudonym_DiscoveryHandle *dh1; - struct GNUNET_FS_pseudonym_DiscoveryHandle *dh2; + struct GNUNET_FS_Pseudonym_DiscoveryHandle *dh1; + struct GNUNET_FS_Pseudonym_DiscoveryHandle *dh2; memset (m, 'b', sizeof (m)); m[sizeof (m) - 1] = '\0'; - GNUNET_log_setup ("test-pseudonym", "WARNING", NULL); ok = GNUNET_YES; (void) GNUNET_DISK_directory_remove ("/tmp/gnunet-pseudonym-test"); @@ -178,8 +179,8 @@ test_io () CHECK (GNUNET_SYSERR == GNUNET_FS_pseudonym_name_to_id (cfg, name1, &rid1)); CHECK (GNUNET_OK == GNUNET_FS_pseudonym_name_to_id (cfg, name2_unique, &rid2)); CHECK (GNUNET_OK == GNUNET_FS_pseudonym_name_to_id (cfg, name1_unique, &rid1)); - CHECK (0 == memcmp (&id1, &rid1, sizeof (struct GNUNET_FS_PseudonymIdentifier))); - CHECK (0 == memcmp (&id2, &rid2, sizeof (struct GNUNET_FS_PseudonymIdentifier))); + CHECK (0 == memcmp (&id1, &rid1, sizeof (struct GNUNET_CRYPTO_EccPublicKey))); + CHECK (0 == memcmp (&id2, &rid2, sizeof (struct GNUNET_CRYPTO_EccPublicKey))); create_pseu (&fid); GNUNET_log_skip (1, GNUNET_NO); @@ -207,119 +208,12 @@ FAILURE: } -/** - * Use the given input to sign and check the resulting signature. - */ -static void -test_signature (struct GNUNET_FS_PseudonymHandle *ph, - struct GNUNET_FS_PseudonymSignaturePurpose *purpose, - struct GNUNET_HashCode *seed, - struct GNUNET_HashCode *signing_key, - char *bit) -{ - struct GNUNET_FS_PseudonymSignature signature; - struct GNUNET_FS_PseudonymSignature signature2; - struct GNUNET_FS_PseudonymIdentifier pseudonym; - struct GNUNET_FS_PseudonymIdentifier verification_key; - - GNUNET_FS_pseudonym_sign (ph, purpose, seed, signing_key, &signature); - GNUNET_FS_pseudonym_sign (ph, purpose, seed, signing_key, &signature2); - /* with seed, two sigs must be identical, without, they must be different! */ - if (NULL != seed) - GNUNET_break (0 == memcmp (&signature, &signature2, sizeof (signature))); - else /* crypto not implemented, thus for now 'break' */ - GNUNET_break (0 != memcmp (&signature, &signature2, sizeof (signature))); - GNUNET_FS_pseudonym_get_identifier (ph, &pseudonym); - GNUNET_FS_pseudonym_derive_verification_key (&pseudonym, - signing_key, - &verification_key); - GNUNET_break (GNUNET_OK == - GNUNET_FS_pseudonym_verify (purpose, &signature, &verification_key)); - /* also check that if the data is changed, the signature no longer matches */ - (*bit)++; - GNUNET_log_skip (1, GNUNET_NO); - /* crypto not implemented, thus for now 'break' */ - GNUNET_break (GNUNET_OK != - GNUNET_FS_pseudonym_verify (purpose, &signature, &verification_key)); - (*bit)--; -} - - -/** - * Test cryptographic operations for a given private key. - * - * @param ph private key to test - */ -static void -test_crypto_ops (struct GNUNET_FS_PseudonymHandle *ph) -{ - char data[16]; - struct GNUNET_FS_PseudonymSignaturePurpose *purpose; - struct GNUNET_HashCode seed; - struct GNUNET_HashCode signing_key; - - memset (data, 42, sizeof (data)); - purpose = (struct GNUNET_FS_PseudonymSignaturePurpose *) data; - purpose->size = htonl (sizeof (data)); - purpose->purpose = htonl (GNUNET_SIGNATURE_PURPOSE_TEST); - memset (&seed, 41, sizeof (seed)); - memset (&signing_key, 40, sizeof (signing_key)); - test_signature (ph, purpose, &seed, - &signing_key, &data[sizeof (struct GNUNET_FS_PseudonymSignaturePurpose)]); - test_signature (ph, purpose, NULL, - &signing_key, &data[sizeof (struct GNUNET_FS_PseudonymSignaturePurpose)]); -} - - -/** - * Test cryptographic operations. - */ -static int -test_crypto () -{ - struct GNUNET_FS_PseudonymHandle *ph; - struct GNUNET_FS_PseudonymIdentifier pseudonym; - struct GNUNET_FS_PseudonymIdentifier pseudonym2; - - /* check writing to and reading from disk */ - ph = GNUNET_FS_pseudonym_create ("/tmp/gnunet-pseudonym-test/pseu.dsa"); - GNUNET_FS_pseudonym_get_identifier (ph, &pseudonym); - GNUNET_FS_pseudonym_destroy (ph); - ph = GNUNET_FS_pseudonym_create ("/tmp/gnunet-pseudonym-test/pseu.dsa"); - GNUNET_FS_pseudonym_get_identifier (ph, &pseudonym2); - test_crypto_ops (ph); - GNUNET_FS_pseudonym_destroy (ph); - if (0 != memcmp (&pseudonym, &pseudonym2, sizeof (pseudonym))) - return 1; - - /* check in-memory generation */ - ph = GNUNET_FS_pseudonym_create (NULL); - GNUNET_FS_pseudonym_get_identifier (ph, &pseudonym2); - if (0 == memcmp (&pseudonym, &pseudonym2, sizeof (pseudonym))) - return 1; - test_crypto_ops (ph); - GNUNET_FS_pseudonym_destroy (ph); - - /* check anonymous pseudonym operations generation */ - fprintf (stderr, "Checking anonymous ops\n"); - ph = GNUNET_FS_pseudonym_get_anonymous_pseudonym_handle (); - GNUNET_FS_pseudonym_get_identifier (ph, &pseudonym2); - if (0 == memcmp (&pseudonym, &pseudonym2, sizeof (pseudonym))) - return 1; - test_crypto_ops (ph); - GNUNET_FS_pseudonym_destroy (ph); - return 0; -} - - int main (int argc, char *argv[]) { GNUNET_log_setup ("test-pseudonym", "WARNING", NULL); if (0 != test_io ()) return 1; - if (0 != test_crypto ()) - return 1; GNUNET_break (GNUNET_OK == GNUNET_DISK_directory_remove ("/tmp/gnunet-pseudonym-test")); return 0; diff --git a/src/identity/identity_api.c b/src/identity/identity_api.c index 2062ddc63..84ecb8765 100644 --- a/src/identity/identity_api.c +++ b/src/identity/identity_api.c @@ -175,6 +175,24 @@ struct GNUNET_IDENTITY_Handle }; +/** + * Obtain the ego representing 'anonymous' users. + */ +const struct GNUNET_IDENTITY_Ego * +GNUNET_IDENTITY_ego_get_anonymous () +{ + static struct GNUNET_IDENTITY_Ego anon; + struct GNUNET_CRYPTO_EccPublicKey pub; + + if (NULL != anon.pk) + return &anon; + anon.pk = GNUNET_CRYPTO_ecc_key_get_anonymous (); + GNUNET_CRYPTO_ecc_key_get_public (anon.pk, + &pub); + GNUNET_CRYPTO_hash (&pub, sizeof (pub), &anon.id); + return &anon; +} + /** * Try again to connect to network size estimation service. @@ -566,7 +584,7 @@ GNUNET_IDENTITY_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, * @return associated ECC key, valid as long as the ego is valid */ const struct GNUNET_CRYPTO_EccPrivateKey * -GNUNET_IDENTITY_ego_get_private_key (struct GNUNET_IDENTITY_Ego *ego) +GNUNET_IDENTITY_ego_get_private_key (const struct GNUNET_IDENTITY_Ego *ego) { return ego->pk; } @@ -579,10 +597,11 @@ GNUNET_IDENTITY_ego_get_private_key (struct GNUNET_IDENTITY_Ego *ego) * @param pk set to ego's public key */ void -GNUNET_IDENTITY_ego_get_public_key (struct GNUNET_IDENTITY_Ego *ego, +GNUNET_IDENTITY_ego_get_public_key (const struct GNUNET_IDENTITY_Ego *ego, struct GNUNET_CRYPTO_EccPublicKey *pk) { - GNUNET_assert (0); + GNUNET_CRYPTO_ecc_key_get_public (ego->pk, + pk); } diff --git a/src/include/block_fs.h b/src/include/block_fs.h index a2063270e..772180fc8 100644 --- a/src/include/block_fs.h +++ b/src/include/block_fs.h @@ -48,18 +48,17 @@ struct UBlock /** * Signature using pseudonym and search keyword / identifier. */ - struct GNUNET_FS_PseudonymSignature signature; + struct GNUNET_CRYPTO_EccSignature signature; /** * What is being signed and why? */ - struct GNUNET_FS_PseudonymSignaturePurpose purpose GNUNET_PACKED; + struct GNUNET_CRYPTO_EccSignaturePurpose purpose; /** - * Public key used to sign this block. Hash of this value - * is the query. + * Public key used to sign this block. */ - struct GNUNET_FS_PseudonymIdentifier verification_key; + struct GNUNET_CRYPTO_EccPublicKey verification_key; /* rest of the data is encrypted */ diff --git a/src/include/gnunet_crypto_lib.h b/src/include/gnunet_crypto_lib.h index 5f209efea..52bb983b0 100644 --- a/src/include/gnunet_crypto_lib.h +++ b/src/include/gnunet_crypto_lib.h @@ -884,8 +884,7 @@ GNUNET_CRYPTO_ecc_key_create_from_configuration (const struct GNUNET_CONFIGURATI /** - * Create a new private key. Caller must free return value. Blocking version - * (blocks to gather entropy). + * Create a new private key. Caller must free return value. * * @return fresh private key */ @@ -893,6 +892,15 @@ struct GNUNET_CRYPTO_EccPrivateKey * GNUNET_CRYPTO_ecc_key_create (void); +/** + * Get the shared private key we use for anonymous users. + * + * @return "anonymous" private key + */ +const struct GNUNET_CRYPTO_EccPrivateKey * +GNUNET_CRYPTO_ecc_key_get_anonymous (void); + + /** * Setup a hostkey file for a peer given the name of the * configuration file (!). This function is used so that diff --git a/src/include/gnunet_fs_service.h b/src/include/gnunet_fs_service.h index afe53b0e0..5dcee17cd 100644 --- a/src/include/gnunet_fs_service.h +++ b/src/include/gnunet_fs_service.h @@ -26,7 +26,6 @@ #define GNUNET_FS_LIB_H #include "gnunet_util_lib.h" -#include "gnunet_scheduler_lib.h" #ifdef __cplusplus extern "C" @@ -80,78 +79,6 @@ extern "C" struct GNUNET_FS_Uri; -/** - * Identifier for a GNUnet pseudonym (the public key). Q-point, Q=dP. - * Note that we (ab)use an identifier of 'Q=G=1P' to mean the - * 'anonymous' pseudonym. - */ -struct GNUNET_FS_PseudonymIdentifier -{ - /** - * Q consists of an x- and a y-value, each mod p (256 bits), - * given here in affine coordinates. - */ - unsigned char q_x[256 / 8]; - - /** - * Q consists of an x- and a y-value, each mod p (256 bits), - * given here in affine coordinates. - */ - unsigned char q_y[256 / 8]; - -}; - - -/** - * Handle for a pseudonym (private key). - */ -struct GNUNET_FS_PseudonymHandle; - - -/** - * Signature made with a pseudonym (includes the full public key). - * The ECDSA signature is a pair (r,s) with r = x1 mod n where - * (x1,y1) = kG for "random" k and s = k^{-1}(z + rd) mod n, - * where z is derived from the hash of the message that is being - * signed. - */ -struct GNUNET_FS_PseudonymSignature -{ - - /** - * Who created the signature? (public key of the signer), 'd' value in NIST P-256. - */ - struct GNUNET_FS_PseudonymIdentifier signer; - - /** - * Binary ECDSA signature data, r-value. Value is mod n, and n is 256 bits. - */ - unsigned char sig_r[256 / 8]; - - /** - * Binary ECDSA signature data, s-value. Value is mod n, and n is 256 bits. - */ - unsigned char sig_s[256 / 8]; -}; - - -/** - * Purpose for signature made with a pseudonym. - */ -struct GNUNET_FS_PseudonymSignaturePurpose -{ - /** - * How many bytes are being signed (including this header)? - */ - uint32_t size; - - /** - * What is the context/purpose of the signature? - */ - uint32_t purpose; -}; - - /** * Iterator over keywords * @@ -165,120 +92,11 @@ typedef int (*GNUNET_FS_KeywordIterator) (void *cls, const char *keyword, - -/** - * Create a pseudonym. - * - * @param filename name of the file to use for storage, NULL for in-memory only - * @return handle to the private key of the pseudonym - */ -struct GNUNET_FS_PseudonymHandle * -GNUNET_FS_pseudonym_create (const char *filename); - - -/** - * Create a pseudonym, from a file that must already exist. - * - * @param filename name of the file to use for storage, NULL for in-memory only - * @return handle to the private key of the pseudonym - */ -struct GNUNET_FS_PseudonymHandle * -GNUNET_FS_pseudonym_create_from_existing_file (const char *filename); - - -/** - * Get the handle for the 'anonymous' pseudonym shared by all users. - * That pseudonym uses a fixed 'secret' for the private key; this - * construction is useful to make anonymous and pseudonymous APIs - * (and packets) indistinguishable on the network. See #2564. - * - * @return handle to the (non-secret) private key of the 'anonymous' pseudonym - */ -struct GNUNET_FS_PseudonymHandle * -GNUNET_FS_pseudonym_get_anonymous_pseudonym_handle (void); - - -/** - * Destroy a pseudonym handle. Does NOT remove the private key from - * the disk. - * - * @param ph pseudonym handle to destroy - */ -void -GNUNET_FS_pseudonym_destroy (struct GNUNET_FS_PseudonymHandle *ph); - - -/** - * Cryptographically sign some data with the pseudonym. - * - * @param ph private key used for signing (corresponds to 'x' in #2564) - * @param purpose data to sign - * @param seed hash of the plaintext of the data that we are signing, - * used for deterministic PRNG for anonymous signing; - * corresponds to 'k' in section 2.7 of #2564 - * @param signing_key modifier to apply to the private key for signing; - * corresponds to 'h' in section 2.3 of #2564. - * @param signature where to store the signature - * @return GNUNET_SYSERR on failure - */ -int -GNUNET_FS_pseudonym_sign (struct GNUNET_FS_PseudonymHandle *ph, - const struct GNUNET_FS_PseudonymSignaturePurpose *purpose, - const struct GNUNET_HashCode *seed, - const struct GNUNET_HashCode *signing_key, - struct GNUNET_FS_PseudonymSignature *signature); - - -/** - * Given a pseudonym and a signing key, derive the corresponding public - * key that would be used to verify the resulting signature. - * - * @param pseudonym the public key (g^x in DSA, dQ in ECDSA) - * @param signing_key input to derive 'h' (see section 2.4 of #2564) - * @param verification_key resulting public key to verify the signature - * created from the 'ph' of 'pseudonym' and the 'signing_key'; - * the value stored here can then be given to GNUNET_FS_pseudonym_verify. - * @return GNUNET_OK on success, GNUNET_SYSERR on error - */ -int -GNUNET_FS_pseudonym_derive_verification_key (struct GNUNET_FS_PseudonymIdentifier *pseudonym, - const struct GNUNET_HashCode *signing_key, - struct GNUNET_FS_PseudonymIdentifier *verification_key); - - -/** - * Verify a signature made with a pseudonym. - * - * @param purpose data that was signed - * @param signature signature to verify - * @param verification_key public key to use for checking the signature; - * corresponds to 'g^(x+h)' in section 2.4 of #2564. - * @return GNUNET_OK on success (signature valid, 'pseudonym' set), - * GNUNET_SYSERR if the signature is invalid - */ -int -GNUNET_FS_pseudonym_verify (const struct GNUNET_FS_PseudonymSignaturePurpose *purpose, - const struct GNUNET_FS_PseudonymSignature *signature, - const struct GNUNET_FS_PseudonymIdentifier *verification_key); - - -/** - * Get the identifier (public key) of a pseudonym. - * - * @param ph pseudonym handle with the private key - * @param pseudonym pseudonym identifier (set based on 'ph') - */ -void -GNUNET_FS_pseudonym_get_identifier (struct GNUNET_FS_PseudonymHandle *ph, - struct GNUNET_FS_PseudonymIdentifier *pseudonym); - - - /** * Iterator over all known pseudonyms. * * @param cls closure - * @param pseudonym hash code of public key of pseudonym + * @param pseudonym public key of pseudonym * @param name name of the pseudonym (might be NULL) * @param unique_name unique name of the pseudonym (might be NULL) * @param md meta data known about the pseudonym @@ -286,11 +104,11 @@ GNUNET_FS_pseudonym_get_identifier (struct GNUNET_FS_PseudonymHandle *ph, * @return GNUNET_OK to continue iteration, GNUNET_SYSERR to abort */ typedef int (*GNUNET_FS_PseudonymIterator) (void *cls, - const struct GNUNET_FS_PseudonymIdentifier *pseudonym, + const struct GNUNET_CRYPTO_EccPublicKey *pseudonym, const char *name, const char *unique_name, const struct GNUNET_CONTAINER_MetaData *md, - int32_t rating); + int32_t rating); /** @@ -303,7 +121,7 @@ typedef int (*GNUNET_FS_PseudonymIterator) (void *cls, */ int GNUNET_FS_pseudonym_rank (const struct GNUNET_CONFIGURATION_Handle *cfg, - const struct GNUNET_FS_PseudonymIdentifier *pseudonym, + const struct GNUNET_CRYPTO_EccPublicKey *pseudonym, int32_t delta); @@ -319,7 +137,7 @@ GNUNET_FS_pseudonym_rank (const struct GNUNET_CONFIGURATION_Handle *cfg, */ int GNUNET_FS_pseudonym_add (const struct GNUNET_CONFIGURATION_Handle *cfg, - const struct GNUNET_FS_PseudonymIdentifier *pseudonym, + const struct GNUNET_CRYPTO_EccPublicKey *pseudonym, const struct GNUNET_CONTAINER_MetaData *meta); @@ -340,7 +158,7 @@ GNUNET_FS_pseudonym_list_all (const struct GNUNET_CONFIGURATION_Handle *cfg, /** * Handle for a discovery callback registration. */ -struct GNUNET_FS_pseudonym_DiscoveryHandle; +struct GNUNET_FS_Pseudonym_DiscoveryHandle; /** @@ -352,7 +170,7 @@ struct GNUNET_FS_pseudonym_DiscoveryHandle; * @param iterator_cls closure for iterator * @return registration handle */ -struct GNUNET_FS_pseudonym_DiscoveryHandle * +struct GNUNET_FS_Pseudonym_DiscoveryHandle * GNUNET_FS_pseudonym_discovery_callback_register (const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_FS_PseudonymIterator iterator, void *iterator_cls); @@ -364,7 +182,7 @@ GNUNET_FS_pseudonym_discovery_callback_register (const struct GNUNET_CONFIGURATI * @param dh registration to unregister */ void -GNUNET_FS_pseudonym_discovery_callback_unregister (struct GNUNET_FS_pseudonym_DiscoveryHandle *dh); +GNUNET_FS_pseudonym_discovery_callback_unregister (struct GNUNET_FS_Pseudonym_DiscoveryHandle *dh); /** @@ -380,7 +198,7 @@ GNUNET_FS_pseudonym_discovery_callback_unregister (struct GNUNET_FS_pseudonym_Di */ char * GNUNET_FS_pseudonym_name_uniquify (const struct GNUNET_CONFIGURATION_Handle *cfg, - const struct GNUNET_FS_PseudonymIdentifier *pseudonym, + const struct GNUNET_CRYPTO_EccPublicKey *pseudonym, const char *name, unsigned int *suffix); @@ -407,7 +225,7 @@ GNUNET_FS_pseudonym_name_uniquify (const struct GNUNET_CONFIGURATION_Handle *cfg */ int GNUNET_FS_pseudonym_get_info (const struct GNUNET_CONFIGURATION_Handle *cfg, - const struct GNUNET_FS_PseudonymIdentifier *pseudonym, + const struct GNUNET_CRYPTO_EccPublicKey *pseudonym, struct GNUNET_CONTAINER_MetaData **ret_meta, int32_t *ret_rank, char **ret_name, @@ -425,7 +243,7 @@ GNUNET_FS_pseudonym_get_info (const struct GNUNET_CONFIGURATION_Handle *cfg, int GNUNET_FS_pseudonym_name_to_id (const struct GNUNET_CONFIGURATION_Handle *cfg, const char *ns_uname, - struct GNUNET_FS_PseudonymIdentifier *pseudonym); + struct GNUNET_CRYPTO_EccPublicKey *pseudonym); /** @@ -442,24 +260,12 @@ GNUNET_FS_pseudonym_name_to_id (const struct GNUNET_CONFIGURATION_Handle *cfg, */ int GNUNET_FS_pseudonym_set_info (const struct GNUNET_CONFIGURATION_Handle *cfg, - const struct GNUNET_FS_PseudonymIdentifier *pseudonym, + const struct GNUNET_CRYPTO_EccPublicKey *pseudonym, const char *name, const struct GNUNET_CONTAINER_MetaData *md, int32_t rank); -/** - * Remove pseudonym from the set of known pseudonyms. - * - * @param cfg overall configuration - * @param id the pseudonym identifier - * @return GNUNET_OK on success, GNUNET_SYSERR on failure - */ -int -GNUNET_FS_pseudonym_remove (const struct GNUNET_CONFIGURATION_Handle *cfg, - const struct GNUNET_FS_PseudonymIdentifier *id); - - /** * Get a unique key from a URI. This is for putting URIs * into HashMaps. The key may change between FS implementations. @@ -468,7 +274,8 @@ GNUNET_FS_pseudonym_remove (const struct GNUNET_CONFIGURATION_Handle *cfg, * @param key wherer to store the unique key */ void -GNUNET_FS_uri_to_key (const struct GNUNET_FS_Uri *uri, struct GNUNET_HashCode * key); +GNUNET_FS_uri_to_key (const struct GNUNET_FS_Uri *uri, + struct GNUNET_HashCode *key); /** @@ -501,7 +308,8 @@ GNUNET_FS_uri_ksk_to_string_fancy (const struct GNUNET_FS_Uri *uri); * @param is_mandatory is this keyword mandatory? */ void -GNUNET_FS_uri_ksk_add_keyword (struct GNUNET_FS_Uri *uri, const char *keyword, +GNUNET_FS_uri_ksk_add_keyword (struct GNUNET_FS_Uri *uri, + const char *keyword, int is_mandatory); @@ -694,35 +502,16 @@ int GNUNET_FS_uri_test_sks (const struct GNUNET_FS_Uri *uri); -/** - * Handle to one of our namespaces. - */ -struct GNUNET_FS_Namespace; - - -/** - * Create an SKS URI from a namespace and an identifier. - * - * @param ns namespace - * @param id identifier - * @param emsg where to store an error message - * @return an FS URI for the given namespace and identifier - */ -struct GNUNET_FS_Uri * -GNUNET_FS_uri_sks_create (struct GNUNET_FS_Namespace *ns, const char *id, - char **emsg); - - /** * Create an SKS URI from a namespace ID and an identifier. * - * @param pseudonym pseudonym to use + * @param ns pseudonym to use * @param id identifier * @return an FS URI for the given namespace and identifier */ struct GNUNET_FS_Uri * -GNUNET_FS_uri_sks_create_from_nsid (struct GNUNET_FS_PseudonymIdentifier *pseudonym, - const char *id); +GNUNET_FS_uri_sks_create (const struct GNUNET_CRYPTO_EccPublicKey *ns, + const char *id); /** @@ -735,7 +524,7 @@ GNUNET_FS_uri_sks_create_from_nsid (struct GNUNET_FS_PseudonymIdentifier *pseudo */ int GNUNET_FS_uri_sks_get_namespace (const struct GNUNET_FS_Uri *uri, - struct GNUNET_FS_PseudonymIdentifier *pseudonym); + struct GNUNET_CRYPTO_EccPublicKey *pseudonym); /** @@ -1756,12 +1545,6 @@ struct GNUNET_FS_ProgressInfo struct { - /** - * Handle to the namespace (NULL if it is not a local - * namespace). - */ - struct GNUNET_FS_Namespace *ns; - /** * Short, human-readable name of the namespace. */ @@ -1780,7 +1563,7 @@ struct GNUNET_FS_ProgressInfo /** * Public key of the namespace. */ - struct GNUNET_FS_PseudonymIdentifier pseudonym; + struct GNUNET_CRYPTO_EccPublicKey pseudonym; } ns; @@ -2379,6 +2162,7 @@ enum GNUNET_FS_PublishOptions GNUNET_FS_PUBLISH_OPTION_SIMULATE_ONLY = 1 }; + /** * Publish a file or directory. * @@ -2395,7 +2179,8 @@ enum GNUNET_FS_PublishOptions struct GNUNET_FS_PublishContext * GNUNET_FS_publish_start (struct GNUNET_FS_Handle *h, struct GNUNET_FS_FileInformation *fi, - struct GNUNET_FS_Namespace *ns, const char *nid, + const struct GNUNET_CRYPTO_EccPrivateKey *ns, + const char *nid, const char *nuid, enum GNUNET_FS_PublishOptions options); @@ -2421,7 +2206,7 @@ GNUNET_FS_publish_stop (struct GNUNET_FS_PublishContext *pc); * @param emsg error message, NULL on success */ typedef void (*GNUNET_FS_PublishContinuation) (void *cls, - const struct GNUNET_FS_Uri * uri, + const struct GNUNET_FS_Uri *uri, const char *emsg); @@ -2486,7 +2271,7 @@ struct GNUNET_FS_PublishSksContext; */ struct GNUNET_FS_PublishSksContext * GNUNET_FS_publish_sks (struct GNUNET_FS_Handle *h, - struct GNUNET_FS_Namespace *ns, + const struct GNUNET_CRYPTO_EccPrivateKey *ns, const char *identifier, const char *update, const struct GNUNET_CONTAINER_MetaData *meta, const struct GNUNET_FS_Uri *uri, @@ -2567,110 +2352,6 @@ void GNUNET_FS_unindex_stop (struct GNUNET_FS_UnindexContext *uc); -/** - * Create a namespace with the given name; if one already - * exists, return a handle to the existing namespace. - * - * @param h handle to the file sharing subsystem - * @param name name to use for the namespace - * @return handle to the namespace, NULL on error (i.e. invalid filename) - */ -struct GNUNET_FS_Namespace * -GNUNET_FS_namespace_create (struct GNUNET_FS_Handle *h, const char *name); - - -/** - * Open the namespace with the given name; if it does not exist, - * or the key file is corrupted, the function fails. - * - * @param h handle to the file sharing subsystem - * @param name name of the namespace - * @return handle to the namespace, - * NULL on error (i.e. invalid filename, non-existent filename) - */ -struct GNUNET_FS_Namespace * -GNUNET_FS_namespace_open_existing (struct GNUNET_FS_Handle *h, const char *name); - - -/** - * Rename a local namespace. - * - * @param h handle to the file sharing subsystem - * @param old_name old name of the namespace - * @param new_name new name of the namespace - * @return GNUNET_OK on success, GNUNET_SYSERR on error (see errno for details) - */ -int -GNUNET_FS_namespace_rename (struct GNUNET_FS_Handle *h, - const char *old_name, - const char *new_name); - - -/** - * Duplicate a namespace handle. - * - * @param ns namespace handle - * @return duplicated handle to the namespace - */ -struct GNUNET_FS_Namespace * -GNUNET_FS_namespace_dup (struct GNUNET_FS_Namespace *ns); - - -/** - * Get hash of the public key of a namespace. - * - * @param ns namespace - * @param id buffer to store the key in - * @return GNUNET_OK on success - * GNUNET_SYSERR on failure (contents of id remain intact) - */ -int -GNUNET_FS_namespace_get_public_identifier (struct GNUNET_FS_Namespace *ns, - struct GNUNET_FS_PseudonymIdentifier *id); - - -/** - * Delete a namespace handle. Can be used for a clean shutdown (free - * memory) or also to freeze the namespace to prevent further - * insertions by anyone. - * - * @param ns handle to the namespace that should be deleted / freed - * @param freeze prevents future insertions; creating a namespace - * with the same name again will create a fresh namespace instead - * - * @return GNUNET_OK on success, GNUNET_SYSERR on error - */ -int -GNUNET_FS_namespace_delete (struct GNUNET_FS_Namespace *ns, int freeze); - - -/** - * Callback with information about local (!) namespaces. - * Contains the names of the local namespace and the global - * ID. - * - * @param cls closure - * @param name human-readable identifier of the namespace - * @param id identifier for the namespace - */ -typedef void (*GNUNET_FS_NamespaceInfoProcessor) (void *cls, const char *name, - const struct GNUNET_FS_PseudonymIdentifier *id); - - -/** - * Build a list of all available local (!) namespaces The returned - * names are only the nicknames since we only iterate over the local - * namespaces. - * - * @param h handle to the file sharing subsystem - * @param cb function to call on each known namespace - * @param cb_cls closure for cb - */ -void -GNUNET_FS_namespace_list (struct GNUNET_FS_Handle *h, - GNUNET_FS_NamespaceInfoProcessor cb, void *cb_cls); - - /** * Function called on updateable identifiers. * @@ -2703,13 +2384,15 @@ typedef void (*GNUNET_FS_IdentifierProcessor) (void *cls, const char *last_id, * cause the library to call "ip" with all children of the node. Note * that cycles within an SCC are possible (including self-loops). * +* @param h fs handle to use * @param ns namespace to inspect for updateable content * @param next_id ID to look for; use NULL to look for SCC roots * @param ip function to call on each updateable identifier * @param ip_cls closure for ip */ void -GNUNET_FS_namespace_list_updateable (struct GNUNET_FS_Namespace *ns, +GNUNET_FS_namespace_list_updateable (struct GNUNET_FS_Handle *h, + const struct GNUNET_CRYPTO_EccPrivateKey *ns, const char *next_id, GNUNET_FS_IdentifierProcessor ip, void *ip_cls); diff --git a/src/include/gnunet_identity_service.h b/src/include/gnunet_identity_service.h index dfc643d22..23dee600f 100644 --- a/src/include/gnunet_identity_service.h +++ b/src/include/gnunet_identity_service.h @@ -74,7 +74,16 @@ struct GNUNET_IDENTITY_Operation; * @return associated ECC key, valid as long as the ego is valid */ const struct GNUNET_CRYPTO_EccPrivateKey * -GNUNET_IDENTITY_ego_get_private_key (struct GNUNET_IDENTITY_Ego *ego); +GNUNET_IDENTITY_ego_get_private_key (const struct GNUNET_IDENTITY_Ego *ego); + + +/** + * Obtain the ego representing 'anonymous' users. + * + * @returns handle for the anonymous user, must not be freed + */ +const struct GNUNET_IDENTITY_Ego * +GNUNET_IDENTITY_ego_get_anonymous (void); /** @@ -84,7 +93,7 @@ GNUNET_IDENTITY_ego_get_private_key (struct GNUNET_IDENTITY_Ego *ego); * @param pk set to ego's public key */ void -GNUNET_IDENTITY_ego_get_public_key (struct GNUNET_IDENTITY_Ego *ego, +GNUNET_IDENTITY_ego_get_public_key (const struct GNUNET_IDENTITY_Ego *ego, struct GNUNET_CRYPTO_EccPublicKey *pk); diff --git a/src/util/crypto_ecc.c b/src/util/crypto_ecc.c index a93512e38..122c1857d 100644 --- a/src/util/crypto_ecc.c +++ b/src/util/crypto_ecc.c @@ -445,6 +445,31 @@ GNUNET_CRYPTO_ecc_key_create () } +/** + * Get the shared private key we use for anonymous users. + * + * @return "anonymous" private key + */ +const struct GNUNET_CRYPTO_EccPrivateKey * +GNUNET_CRYPTO_ecc_key_get_anonymous () +{ + /** + * 'anonymous' pseudonym (global static, d=1, public key = G + * (generator). + */ + static struct GNUNET_CRYPTO_EccPrivateKey anonymous; + static int once; + + if (once) + return &anonymous; + mpi_print (anonymous.d, + sizeof (anonymous.d), + GCRYMPI_CONST_ONE); + once = 1; + return &anonymous; +} + + /** * Wait for a short time (we're trying to lock a file or want * to give another process a shot at finishing a disk write, etc.). -- cgit v1.2.3