[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] r26869 - in gnunet/src: . fs include util
From: |
gnunet |
Subject: |
[GNUnet-SVN] r26869 - in gnunet/src: . fs include util |
Date: |
Sun, 14 Apr 2013 20:45:55 +0200 |
Author: grothoff
Date: 2013-04-14 20:45:55 +0200 (Sun, 14 Apr 2013)
New Revision: 26869
Added:
gnunet/src/fs/fs_pseudonym.c
gnunet/src/fs/test_pseudonym.c
Removed:
gnunet/src/include/gnunet_pseudonym_lib.h
gnunet/src/util/pseudonym.c
gnunet/src/util/test_pseudonym.c
Modified:
gnunet/src/Makefile.am
gnunet/src/fs/Makefile.am
gnunet/src/fs/plugin_block_fs.c
gnunet/src/include/Makefile.am
gnunet/src/include/block_fs.h
gnunet/src/include/gnunet_fs_service.h
gnunet/src/include/gnunet_util_lib.h
gnunet/src/util/Makefile.am
Log:
-move pseudonym code to fs, mark fs as experimental for now
Modified: gnunet/src/Makefile.am
===================================================================
--- gnunet/src/Makefile.am 2013-04-14 18:37:43 UTC (rev 26868)
+++ gnunet/src/Makefile.am 2013-04-14 18:45:55 UTC (rev 26869)
@@ -3,7 +3,7 @@
#endif
if HAVE_EXPERIMENTAL
- EXP_DIR = chat consensus dv
+ EXP_DIR = fs chat consensus dv
endif
if LINUX
@@ -55,7 +55,6 @@
mesh \
lockmanager \
stream \
- fs \
$(LINUX_DIR) \
$(MINGW_DIR) \
integration-tests \
Modified: gnunet/src/fs/Makefile.am
===================================================================
--- gnunet/src/fs/Makefile.am 2013-04-14 18:37:43 UTC (rev 26868)
+++ gnunet/src/fs/Makefile.am 2013-04-14 18:45:55 UTC (rev 26869)
@@ -34,6 +34,7 @@
fs_file_information.c \
fs_getopt.c \
fs_list_indexed.c \
+ fs_pseudonym.c \
fs_publish.c \
fs_publish_ksk.c \
fs_misc.c \
@@ -47,7 +48,7 @@
libgnunetfs_la_LIBADD = \
$(top_builddir)/src/datastore/libgnunetdatastore.la \
$(top_builddir)/src/util/libgnunetutil.la \
- $(GN_LIBINTL) $(XLIB) -lunistring -lextractor
+ $(GN_LIBINTL) $(XLIB) -lunistring -lextractor -lgcrypt
libgnunetfs_la_LDFLAGS = \
$(GN_LIB_LDFLAGS) $(WINFLAGS) \
@@ -214,6 +215,7 @@
plugin_block_fs.c
libgnunet_plugin_block_fs_la_LIBADD = \
$(top_builddir)/src/block/libgnunetblock.la \
+ $(top_builddir)/src/fs/libgnunetfs.la \
$(top_builddir)/src/util/libgnunetutil.la \
$(LTLIBINTL)
libgnunet_plugin_block_fs_la_LDFLAGS = \
@@ -243,6 +245,7 @@
test_fs_list_indexed \
test_fs_namespace \
test_fs_namespace_list_updateable \
+ test_pseudonym \
test_fs_publish \
test_fs_publish_persistence \
test_fs_search \
@@ -288,6 +291,7 @@
test_fs_list_indexed \
test_fs_namespace \
test_fs_namespace_list_updateable \
+ test_pseudonym \
test_fs_publish \
test_fs_publish_persistence \
test_fs_search \
@@ -308,6 +312,14 @@
endif
+test_pseudonym_SOURCES = \
+ test_pseudonym.c
+test_pseudonym_LDADD = \
+ -lgcrypt \
+ $(top_builddir)/src/fs/libgnunetfs.la \
+ $(top_builddir)/src/util/libgnunetutil.la
+
+
test_fs_directory_SOURCES = \
test_fs_directory.c
test_fs_directory_LDADD = \
Copied: gnunet/src/fs/fs_pseudonym.c (from rev 26867,
gnunet/src/util/pseudonym.c)
===================================================================
--- gnunet/src/fs/fs_pseudonym.c (rev 0)
+++ gnunet/src/fs/fs_pseudonym.c 2013-04-14 18:45:55 UTC (rev 26869)
@@ -0,0 +1,1590 @@
+/*
+ This file is part of GNUnet
+ (C) 2003, 2004, 2005, 2006, 2007, 2008, 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 2, 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_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 <gcrypt.h>
+
+
+#define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__)
+
+#define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util",
syscall)
+
+#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
+ */
+#define PS_METADATA_DIR DIR_SEPARATOR_STR "data" DIR_SEPARATOR_STR "pseudonym"
DIR_SEPARATOR_STR "metadata" DIR_SEPARATOR_STR
+
+/**
+ * Name of the directory which stores names for pseudonyms
+ */
+#define PS_NAMES_DIR DIR_SEPARATOR_STR "data" DIR_SEPARATOR_STR "pseudonym"
DIR_SEPARATOR_STR "names" DIR_SEPARATOR_STR
+
+
+/**
+ * Configuration section we use.
+ */
+#define GNUNET_CLIENT_SERVICE_NAME "fs"
+
+
+/* ************************* Disk operations (pseudonym data mgmt)
**************** */
+
+/**
+ * Registered callbacks for discovery of pseudonyms.
+ */
+struct GNUNET_PSEUDONYM_DiscoveryHandle
+{
+ /**
+ * This is a doubly linked list.
+ */
+ struct GNUNET_PSEUDONYM_DiscoveryHandle *next;
+
+ /**
+ * This is a doubly linked list.
+ */
+ struct GNUNET_PSEUDONYM_DiscoveryHandle *prev;
+
+ /**
+ * Function to call each time a pseudonym is discovered.
+ */
+ GNUNET_PSEUDONYM_Iterator callback;
+
+ /**
+ * Closure for callback.
+ */
+ void *callback_cls;
+};
+
+
+/**
+ * Head of the linked list of functions to call when
+ * new pseudonyms are added.
+ */
+static struct GNUNET_PSEUDONYM_DiscoveryHandle *disco_head;
+
+/**
+ * Tail of the linked list of functions to call when
+ * new pseudonyms are added.
+ */
+static struct GNUNET_PSEUDONYM_DiscoveryHandle *disco_tail;
+
+
+/**
+ * Internal notification about new tracked URI.
+ *
+ * @param pseudonym public key of the pseudonym
+ * @param md meta data to be written
+ * @param rating rating of pseudonym
+ */
+static void
+internal_notify (const struct GNUNET_PseudonymIdentifier *pseudonym,
+ const struct GNUNET_CONTAINER_MetaData *md, int rating)
+{
+ struct GNUNET_PSEUDONYM_DiscoveryHandle *pos;
+
+ for (pos = disco_head; NULL != pos; pos = pos->next)
+ pos->callback (pos->callback_cls, pseudonym, NULL, NULL, md, rating);
+}
+
+
+/**
+ * Register callback to be invoked whenever we discover
+ * a new pseudonym.
+ * Will immediately call provided iterator callback for all
+ * already discovered pseudonyms.
+ *
+ * @param cfg configuration to use
+ * @param iterator iterator over pseudonym
+ * @param iterator_cls point to a closure
+ * @return registration handle
+ */
+struct GNUNET_PSEUDONYM_DiscoveryHandle *
+GNUNET_PSEUDONYM_discovery_callback_register (const struct
+ GNUNET_CONFIGURATION_Handle *cfg,
+ GNUNET_PSEUDONYM_Iterator
iterator,
+ void *iterator_cls)
+{
+ struct GNUNET_PSEUDONYM_DiscoveryHandle *dh;
+
+ dh = GNUNET_malloc (sizeof (struct GNUNET_PSEUDONYM_DiscoveryHandle));
+ dh->callback = iterator;
+ dh->callback_cls = iterator_cls;
+ GNUNET_CONTAINER_DLL_insert (disco_head, disco_tail, dh);
+ GNUNET_PSEUDONYM_list_all (cfg, iterator, iterator_cls);
+ return dh;
+}
+
+
+/**
+ * Unregister pseudonym discovery callback.
+ *
+ * @param dh registration to unregister
+ */
+void
+GNUNET_PSEUDONYM_discovery_callback_unregister (struct
GNUNET_PSEUDONYM_DiscoveryHandle *dh)
+{
+ GNUNET_CONTAINER_DLL_remove (disco_head, disco_tail, dh);
+ GNUNET_free (dh);
+}
+
+
+/**
+ * Get the filename (or directory name) for the given
+ * pseudonym identifier and directory prefix.
+ *
+ * @param cfg configuration to use
+ * @param prefix path components to append to the private directory name
+ * @param pseudonym the pseudonym, can be NULL
+ * @return filename of the pseudonym (if pseudonym != NULL) or directory with
the data (if pseudonym == NULL)
+ */
+static char *
+get_data_filename (const struct GNUNET_CONFIGURATION_Handle *cfg,
+ const char *prefix,
+ const struct GNUNET_PseudonymIdentifier *pseudonym)
+{
+ struct GNUNET_CRYPTO_HashAsciiEncoded enc;
+ struct GNUNET_HashCode psid;
+
+ if (NULL != pseudonym)
+ {
+ GNUNET_CRYPTO_hash (pseudonym,
+ sizeof (struct GNUNET_PseudonymIdentifier),
+ &psid);
+ GNUNET_CRYPTO_hash_to_enc (&psid, &enc);
+ }
+ return GNUNET_DISK_get_home_filename (cfg,
+ GNUNET_CLIENT_SERVICE_NAME, prefix,
+ (NULL == pseudonym)
+ ? NULL
+ : (const char *) &enc,
+ NULL);
+}
+
+
+/**
+ * Get the filename (or directory name) for the given
+ * hash code and directory prefix.
+ *
+ * @param cfg configuration to use
+ * @param prefix path components to append to the private directory name
+ * @param hc some hash code
+ * @return filename of the pseudonym (if hc != NULL) or directory with the
data (if hc == NULL)
+ */
+static char *
+get_data_filename_hash (const struct GNUNET_CONFIGURATION_Handle *cfg,
+ const char *prefix,
+ const struct GNUNET_HashCode *hc)
+{
+ struct GNUNET_CRYPTO_HashAsciiEncoded enc;
+
+ if (NULL != hc)
+ GNUNET_CRYPTO_hash_to_enc (hc, &enc);
+ return GNUNET_DISK_get_home_filename (cfg,
+ GNUNET_CLIENT_SERVICE_NAME, prefix,
+ (NULL == hc)
+ ? NULL
+ : (const char *) &enc,
+ NULL);
+}
+
+
+/**
+ * Set the pseudonym metadata, rank and name.
+ * Writes the pseudonym infomation into a file
+ *
+ * @param cfg overall configuration
+ * @param pseudonym id of the pseudonym
+ * @param name name to set. Must be the non-unique version of it.
+ * May be NULL, in which case it erases pseudonym's name!
+ * @param md metadata to set
+ * May be NULL, in which case it erases pseudonym's metadata!
+ * @param rank rank to assign
+ * @return GNUNET_OK on success, GNUNET_SYSERR on failure
+ */
+int
+GNUNET_PSEUDONYM_set_info (const struct GNUNET_CONFIGURATION_Handle *cfg,
+ const struct GNUNET_PseudonymIdentifier *pseudonym,
+ const char *name,
+ const struct GNUNET_CONTAINER_MetaData *md,
+ int32_t rank)
+{
+ char *fn;
+ struct GNUNET_BIO_WriteHandle *fileW;
+
+ fn = get_data_filename (cfg, PS_METADATA_DIR, pseudonym);
+ if (NULL == (fileW = GNUNET_BIO_write_open (fn)))
+ {
+ GNUNET_free (fn);
+ return GNUNET_SYSERR;
+ }
+ if ((GNUNET_OK != GNUNET_BIO_write (fileW, pseudonym,
+ sizeof (struct
GNUNET_PseudonymIdentifier))) ||
+ (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)))
+ {
+ (void) GNUNET_BIO_write_close (fileW);
+ GNUNET_break (GNUNET_OK == GNUNET_DISK_directory_remove (fn));
+ GNUNET_free (fn);
+ return GNUNET_SYSERR;
+ }
+ if (GNUNET_OK != GNUNET_BIO_write_close (fileW))
+ {
+ GNUNET_break (GNUNET_OK == GNUNET_DISK_directory_remove (fn));
+ GNUNET_free (fn);
+ return GNUNET_SYSERR;
+ }
+ GNUNET_free (fn);
+ /* create entry for pseudonym name in names */
+ if (NULL != name)
+ GNUNET_free_non_null (GNUNET_PSEUDONYM_name_uniquify (cfg, pseudonym,
+ name, NULL));
+ return GNUNET_OK;
+}
+
+
+/**
+ * Read pseudonym infomation from a file
+ *
+ * @param cfg configuration to use
+ * @param pseudonym hash code of a pseudonym
+ * @param meta meta data to be read from a file
+ * @param rank rank of a pseudonym
+ * @param ns_name name of a pseudonym
+ * @return GNUNET_OK on success, GNUNET_SYSERR on error
+ */
+static int
+read_info (const struct GNUNET_CONFIGURATION_Handle *cfg,
+ const struct GNUNET_PseudonymIdentifier *pseudonym,
+ struct GNUNET_CONTAINER_MetaData **meta,
+ int32_t *rank,
+ char **ns_name)
+{
+ struct GNUNET_PseudonymIdentifier pd;
+ char *fn;
+ char *emsg;
+ struct GNUNET_BIO_ReadHandle *fileR;
+
+ fn = get_data_filename (cfg, PS_METADATA_DIR, pseudonym);
+ if (GNUNET_YES !=
+ GNUNET_DISK_file_test (fn))
+ {
+ GNUNET_free (fn);
+ return GNUNET_SYSERR;
+ }
+ if (NULL == (fileR = GNUNET_BIO_read_open (fn)))
+ {
+ GNUNET_free (fn);
+ return GNUNET_SYSERR;
+ }
+ emsg = NULL;
+ *ns_name = NULL;
+ if ( (GNUNET_OK != GNUNET_BIO_read (fileR, "pseudonym", &pd, sizeof (pd))) ||
+ (0 != memcmp (&pd, pseudonym, sizeof (pd))) ||
+ (GNUNET_OK != GNUNET_BIO_read_int32 (fileR, rank)) ||
+ (GNUNET_OK !=
+ GNUNET_BIO_read_string (fileR, "Read string error!", ns_name, 200)) ||
+ (GNUNET_OK !=
+ GNUNET_BIO_read_meta_data (fileR, "Read meta data error!", meta)) )
+ {
+ (void) GNUNET_BIO_read_close (fileR, &emsg);
+ GNUNET_free_non_null (emsg);
+ GNUNET_free_non_null (*ns_name);
+ *ns_name = NULL;
+ GNUNET_break (GNUNET_OK == GNUNET_DISK_directory_remove (fn));
+ GNUNET_free (fn);
+ return GNUNET_SYSERR;
+ }
+ if (GNUNET_OK != GNUNET_BIO_read_close (fileR, &emsg))
+ {
+ LOG (GNUNET_ERROR_TYPE_WARNING,
+ _("Failed to parse metadata about pseudonym from file `%s': %s\n"),
fn,
+ emsg);
+ GNUNET_break (GNUNET_OK == GNUNET_DISK_directory_remove (fn));
+ GNUNET_CONTAINER_meta_data_destroy (*meta);
+ *meta = NULL;
+ GNUNET_free_non_null (*ns_name);
+ *ns_name = NULL;
+ GNUNET_free_non_null (emsg);
+ GNUNET_free (fn);
+ return GNUNET_SYSERR;
+ }
+ GNUNET_free (fn);
+ return GNUNET_OK;
+}
+
+
+/**
+ * Return unique variant of the namespace name. Use it after
+ * GNUNET_PSEUDONYM_get_info() to make sure that name is unique.
+ *
+ * @param cfg configuration
+ * @param pseudonym public key of the pseudonym
+ * @param name name to uniquify
+ * @param suffix if not NULL, filled with the suffix value
+ * @return NULL on failure (should never happen), name on success.
+ * Free the name with GNUNET_free().
+ */
+char *
+GNUNET_PSEUDONYM_name_uniquify (const struct GNUNET_CONFIGURATION_Handle *cfg,
+ const struct GNUNET_PseudonymIdentifier
*pseudonym,
+ const char *name,
+ unsigned int *suffix)
+{
+ struct GNUNET_HashCode nh;
+ struct GNUNET_PseudonymIdentifier pi;
+ uint64_t len;
+ char *fn;
+ struct GNUNET_DISK_FileHandle *fh;
+ unsigned int i;
+ unsigned int idx;
+ char *ret;
+ struct stat sbuf;
+
+ GNUNET_CRYPTO_hash (name, strlen (name), &nh);
+ fn = get_data_filename_hash (cfg, PS_NAMES_DIR, &nh);
+ len = 0;
+ if (0 == STAT (fn, &sbuf))
+ GNUNET_break (GNUNET_OK == GNUNET_DISK_file_size (fn, &len, GNUNET_YES,
GNUNET_YES));
+ fh = GNUNET_DISK_file_open (fn,
+ GNUNET_DISK_OPEN_CREATE |
+ GNUNET_DISK_OPEN_READWRITE,
+ GNUNET_DISK_PERM_USER_READ |
+ GNUNET_DISK_PERM_USER_WRITE);
+ i = 0;
+ idx = -1;
+ while ((len >= sizeof (struct GNUNET_PseudonymIdentifier)) &&
+ (sizeof (struct GNUNET_PseudonymIdentifier) ==
+ GNUNET_DISK_file_read (fh, &pi, sizeof (struct
GNUNET_PseudonymIdentifier))))
+ {
+ if (0 == memcmp (&pi, pseudonym, sizeof (struct
GNUNET_PseudonymIdentifier)))
+ {
+ idx = i;
+ break;
+ }
+ i++;
+ len -= sizeof (struct GNUNET_HashCode);
+ }
+ if (-1 == idx)
+ {
+ idx = i;
+ if (sizeof (struct GNUNET_PseudonymIdentifier) !=
+ GNUNET_DISK_file_write (fh, pseudonym, sizeof (struct
GNUNET_PseudonymIdentifier)))
+ LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "write", fn);
+ }
+ GNUNET_DISK_file_close (fh);
+ ret = GNUNET_malloc (strlen (name) + 32);
+ GNUNET_snprintf (ret, strlen (name) + 32, "%s-%u", name, idx);
+ if (suffix != NULL)
+ *suffix = idx;
+ GNUNET_free (fn);
+ return ret;
+}
+
+
+/**
+ * Get namespace name, metadata and rank
+ * This is a wrapper around internal read_info() call, and ensures that
+ * returned data is not invalid (not NULL).
+ *
+ * @param cfg configuration
+ * @param pseudonym public key of the pseudonym
+ * @param ret_meta a location to store metadata pointer. NULL, if metadata
+ * is not needed. Destroy with GNUNET_CONTAINER_meta_data_destroy().
+ * @param ret_rank a location to store rank. NULL, if rank not needed.
+ * @param ret_name a location to store human-readable name. Name is not unique.
+ * NULL, if name is not needed. Free with GNUNET_free().
+ * @param name_is_a_dup is set to GNUNET_YES, if ret_name was filled with
+ * a duplicate of a "no-name" placeholder
+ * @return GNUNET_OK on success. GNUENT_SYSERR if the data was
+ * unobtainable (in that case ret_* are filled with placeholders -
+ * empty metadata container, rank -1 and a "no-name" name).
+ */
+int
+GNUNET_PSEUDONYM_get_info (const struct GNUNET_CONFIGURATION_Handle *cfg,
+ const struct GNUNET_PseudonymIdentifier *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;
+ int32_t rank = -1;
+
+ meta = NULL;
+ name = NULL;
+ if (GNUNET_OK == read_info (cfg, pseudonym, &meta, &rank, &name))
+ {
+ if ((meta != NULL) && (name == NULL))
+ name =
+ GNUNET_CONTAINER_meta_data_get_first_by_types (meta,
+
EXTRACTOR_METATYPE_TITLE,
+
EXTRACTOR_METATYPE_GNUNET_ORIGINAL_FILENAME,
+
EXTRACTOR_METATYPE_FILENAME,
+
EXTRACTOR_METATYPE_DESCRIPTION,
+
EXTRACTOR_METATYPE_SUBJECT,
+
EXTRACTOR_METATYPE_PUBLISHER,
+
EXTRACTOR_METATYPE_AUTHOR_NAME,
+
EXTRACTOR_METATYPE_COMMENT,
+
EXTRACTOR_METATYPE_SUMMARY,
+ -1);
+ if (ret_name != NULL)
+ {
+ if (name == NULL)
+ {
+ name = GNUNET_strdup (_("no-name"));
+ if (name_is_a_dup != NULL)
+ *name_is_a_dup = GNUNET_YES;
+ }
+ else if (name_is_a_dup != NULL)
+ *name_is_a_dup = GNUNET_NO;
+ *ret_name = name;
+ }
+ else if (name != NULL)
+ GNUNET_free (name);
+
+ if (ret_meta != NULL)
+ {
+ if (meta == NULL)
+ meta = GNUNET_CONTAINER_meta_data_create ();
+ *ret_meta = meta;
+ }
+ else if (meta != NULL)
+ GNUNET_CONTAINER_meta_data_destroy (meta);
+
+ if (ret_rank != NULL)
+ *ret_rank = rank;
+
+ return GNUNET_OK;
+ }
+ if (ret_name != NULL)
+ *ret_name = GNUNET_strdup (_("no-name"));
+ if (ret_meta != NULL)
+ *ret_meta = GNUNET_CONTAINER_meta_data_create ();
+ if (ret_rank != NULL)
+ *ret_rank = -1;
+ if (name_is_a_dup != NULL)
+ *name_is_a_dup = GNUNET_YES;
+ return GNUNET_SYSERR;
+}
+
+
+/**
+ * Get the namespace ID belonging to the given namespace name.
+ *
+ * @param cfg configuration to use
+ * @param ns_uname unique (!) human-readable name for the namespace
+ * @param pseudonym set to public key of pseudonym based on 'ns_uname'
+ * @return GNUNET_OK on success, GNUNET_SYSERR on failure
+ */
+int
+GNUNET_PSEUDONYM_name_to_id (const struct GNUNET_CONFIGURATION_Handle *cfg,
+ const char *ns_uname,
+ struct GNUNET_PseudonymIdentifier *pseudonym)
+{
+ size_t slen;
+ uint64_t len;
+ unsigned int idx;
+ char *name;
+ struct GNUNET_HashCode nh;
+ char *fn;
+ struct GNUNET_DISK_FileHandle *fh;
+
+ idx = -1;
+ slen = strlen (ns_uname);
+ while ((slen > 0) && (1 != SSCANF (&ns_uname[slen - 1], "-%u", &idx)))
+ slen--;
+ if (0 == slen)
+ return GNUNET_SYSERR;
+ name = GNUNET_strdup (ns_uname);
+ name[slen - 1] = '\0';
+
+ GNUNET_CRYPTO_hash (name, strlen (name), &nh);
+ GNUNET_free (name);
+ fn = get_data_filename_hash (cfg, PS_NAMES_DIR, &nh);
+
+ 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_PseudonymIdentifier) > len))
+ {
+ GNUNET_free (fn);
+ return GNUNET_SYSERR;
+ }
+ fh = GNUNET_DISK_file_open (fn,
+ GNUNET_DISK_OPEN_CREATE |
+ GNUNET_DISK_OPEN_READWRITE,
+ GNUNET_DISK_PERM_USER_READ |
+ GNUNET_DISK_PERM_USER_WRITE);
+ GNUNET_free (fn);
+ if (GNUNET_SYSERR ==
+ GNUNET_DISK_file_seek (fh, idx * sizeof (struct
GNUNET_PseudonymIdentifier),
+ GNUNET_DISK_SEEK_SET))
+ {
+ GNUNET_DISK_file_close (fh);
+ return GNUNET_SYSERR;
+ }
+ if (sizeof (struct GNUNET_PseudonymIdentifier) !=
+ GNUNET_DISK_file_read (fh, pseudonym, sizeof (struct
GNUNET_PseudonymIdentifier)))
+ {
+ GNUNET_DISK_file_close (fh);
+ return GNUNET_SYSERR;
+ }
+ GNUNET_DISK_file_close (fh);
+ return GNUNET_OK;
+}
+
+
+
+/**
+ * struct used to list the pseudonym
+ */
+struct ListPseudonymClosure
+{
+
+ /**
+ * iterator over pseudonym
+ */
+ GNUNET_PSEUDONYM_Iterator iterator;
+
+ /**
+ * Closure for iterator.
+ */
+ void *iterator_cls;
+
+ /**
+ * Configuration to use.
+ */
+ const struct GNUNET_CONFIGURATION_Handle *cfg;
+};
+
+
+
+/**
+ * Helper function to list all available pseudonyms
+ *
+ * @param cls point to a struct ListPseudonymClosure
+ * @param fullname name of pseudonym
+ */
+static int
+list_pseudonym_helper (void *cls, const char *fullname)
+{
+ struct ListPseudonymClosure *lpc = cls;
+ struct GNUNET_PseudonymIdentifier pd;
+ char *emsg;
+ struct GNUNET_BIO_ReadHandle *fileR;
+ int32_t rank;
+ char *ns_name;
+ struct GNUNET_CONTAINER_MetaData *meta;
+ int ret;
+ char *name_unique;
+
+ if (NULL == (fileR = GNUNET_BIO_read_open (fullname)))
+ return GNUNET_SYSERR;
+ emsg = NULL;
+ ns_name = NULL;
+ if ( (GNUNET_OK != GNUNET_BIO_read (fileR, "pseudonym", &pd, sizeof (pd))) ||
+ (GNUNET_OK != GNUNET_BIO_read_int32 (fileR, &rank)) ||
+ (GNUNET_OK !=
+ GNUNET_BIO_read_string (fileR, "Read string error!", &ns_name, 200)) ||
+ (GNUNET_OK !=
+ GNUNET_BIO_read_meta_data (fileR, "Read meta data error!", &meta)) )
+ {
+ (void) GNUNET_BIO_read_close (fileR, &emsg);
+ GNUNET_free_non_null (emsg);
+ GNUNET_free_non_null (ns_name);
+ GNUNET_break (GNUNET_OK == GNUNET_DISK_directory_remove (fullname));
+ return GNUNET_SYSERR;
+ }
+ if (NULL == ns_name)
+ ns_name = GNUNET_strdup (_("no-name"));
+ if (GNUNET_OK != GNUNET_BIO_read_close (fileR, &emsg))
+ {
+ LOG (GNUNET_ERROR_TYPE_WARNING,
+ _("Failed to parse metadata about pseudonym from file `%s': %s\n"),
fullname,
+ emsg);
+ GNUNET_break (GNUNET_OK == GNUNET_DISK_directory_remove (fullname));
+ GNUNET_CONTAINER_meta_data_destroy (meta);
+ GNUNET_free (ns_name);
+ GNUNET_free_non_null (emsg);
+ return GNUNET_SYSERR;
+ }
+ ret = GNUNET_OK;
+ name_unique = GNUNET_PSEUDONYM_name_uniquify (lpc->cfg, &pd, ns_name, NULL);
+ if (NULL != lpc->iterator)
+ ret = lpc->iterator (lpc->iterator_cls, &pd, ns_name, name_unique, meta,
rank);
+ GNUNET_free (ns_name);
+ GNUNET_free_non_null (name_unique);
+ GNUNET_CONTAINER_meta_data_destroy (meta);
+ return ret;
+}
+
+
+/**
+ * List all available pseudonyms.
+ *
+ * @param cfg overall configuration
+ * @param iterator function to call for each pseudonym
+ * @param iterator_cls closure for iterator
+ * @return number of pseudonyms found
+ */
+int
+GNUNET_PSEUDONYM_list_all (const struct GNUNET_CONFIGURATION_Handle *cfg,
+ GNUNET_PSEUDONYM_Iterator iterator,
+ void *iterator_cls)
+{
+ struct ListPseudonymClosure cls;
+ char *fn;
+ int ret;
+
+ cls.iterator = iterator;
+ cls.iterator_cls = iterator_cls;
+ cls.cfg = cfg;
+ fn = get_data_filename (cfg, PS_METADATA_DIR, NULL);
+ GNUNET_assert (fn != NULL);
+ GNUNET_DISK_directory_create (fn);
+ ret = GNUNET_DISK_directory_scan (fn, &list_pseudonym_helper, &cls);
+ GNUNET_free (fn);
+ return ret;
+}
+
+
+/**
+ * Change the rank of a pseudonym.
+ *
+ * @param cfg overall configuration
+ * @param pseudonym the pseudonym
+ * @param delta by how much should the rating be changed?
+ * @return new rating of the pseudonym
+ */
+int
+GNUNET_PSEUDONYM_rank (const struct GNUNET_CONFIGURATION_Handle *cfg,
+ const struct GNUNET_PseudonymIdentifier *pseudonym,
+ int32_t delta)
+{
+ struct GNUNET_CONTAINER_MetaData *meta;
+ int ret;
+ int32_t rank;
+ char *name;
+
+ name = NULL;
+ ret = read_info (cfg, pseudonym, &meta, &rank, &name);
+ if (ret == GNUNET_SYSERR)
+ {
+ rank = 0;
+ meta = GNUNET_CONTAINER_meta_data_create ();
+ }
+ rank += delta;
+ GNUNET_PSEUDONYM_set_info (cfg, pseudonym, name, meta, rank);
+ GNUNET_CONTAINER_meta_data_destroy (meta);
+ GNUNET_free_non_null (name);
+ return rank;
+}
+
+
+/**
+ * Add a pseudonym to the set of known pseudonyms.
+ * For all pseudonym advertisements that we discover
+ * FS should automatically call this function.
+ *
+ * @param cfg overall configuration
+ * @param pseudonym the pseudonym to add
+ * @param meta metadata for the pseudonym
+ * @return GNUNET_OK on success, GNUNET_SYSERR on failure
+ */
+int
+GNUNET_PSEUDONYM_add (const struct GNUNET_CONFIGURATION_Handle *cfg,
+ const struct GNUNET_PseudonymIdentifier *pseudonym,
+ const struct GNUNET_CONTAINER_MetaData *meta)
+{
+ char *name;
+ int32_t rank;
+ struct GNUNET_CONTAINER_MetaData *old;
+ char *fn;
+ struct stat sbuf;
+ int ret;
+
+ rank = 0;
+ fn = get_data_filename (cfg, PS_METADATA_DIR, pseudonym);
+ GNUNET_assert (fn != NULL);
+
+ if ((0 == STAT (fn, &sbuf)) &&
+ (GNUNET_OK == read_info (cfg, pseudonym, &old, &rank, &name)))
+ {
+ GNUNET_CONTAINER_meta_data_merge (old, meta);
+ ret = GNUNET_PSEUDONYM_set_info (cfg, pseudonym, name, old, rank);
+ GNUNET_CONTAINER_meta_data_destroy (old);
+ GNUNET_free_non_null (name);
+ }
+ else
+ {
+ ret = GNUNET_PSEUDONYM_set_info (cfg, pseudonym, NULL, meta, rank);
+ }
+ GNUNET_free (fn);
+ internal_notify (pseudonym, meta, rank);
+ return ret;
+}
+
+
+/* ***************************** cryptographic operations
************************* */
+
+/**
+ * Handle for a pseudonym (private key).
+ */
+struct GNUNET_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_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_PseudonymHandle *
+GNUNET_PSEUDONYM_create (const char *filename)
+{
+ struct GNUNET_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_PseudonymHandle));
+ if ( (NULL != filename) &&
+ (GNUNET_YES == GNUNET_DISK_file_test (filename)) )
+ {
+ ret = GNUNET_DISK_fn_read (filename, ph,
+ sizeof (struct GNUNET_PseudonymHandle));
+ /* Note: we don't do any validation here, maybe we should? */
+ if (sizeof (struct GNUNET_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 (r_key);
+ return NULL;
+ }
+ /* 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);
+
+ /* 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_PseudonymHandle),
+ GNUNET_DISK_PERM_USER_READ |
GNUNET_DISK_PERM_USER_WRITE);
+ if (sizeof (struct GNUNET_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_PseudonymHandle *
+GNUNET_PSEUDONYM_create_from_existing_file (const char *filename)
+{
+ struct GNUNET_PseudonymHandle *ph;
+ ssize_t ret;
+
+ ph = GNUNET_malloc (sizeof (struct GNUNET_PseudonymHandle));
+ ret = GNUNET_DISK_fn_read (filename, ph,
+ sizeof (struct GNUNET_PseudonymHandle));
+ if (sizeof (struct GNUNET_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_PseudonymHandle *
+GNUNET_PSEUDONYM_get_anonymous_pseudonym_handle ()
+{
+ struct GNUNET_PseudonymHandle *ph;
+
+ ph = GNUNET_malloc (sizeof (struct GNUNET_PseudonymHandle));
+ /* Note if we use 'd=0' for the anonymous handle (as per#2564),
+ then I believe the public key should be also zero, as Q=0P=0;
+ so setting everything to all-zeros (as per GNUNET_malloc)
+ should be all that is needed here).
+ */
+ return ph;
+}
+
+
+/**
+ * Destroy a pseudonym handle. Does NOT remove the private key from
+ * the disk.
+ *
+ * @param ph pseudonym handle to destroy
+ */
+void
+GNUNET_PSEUDONYM_destroy (struct GNUNET_PseudonymHandle *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
+ * @return converted s-expression
+ */
+static gcry_sexp_t
+data_to_pkcs1 (const struct GNUNET_PseudonymSignaturePurpose *purpose)
+{
+ struct GNUNET_CRYPTO_ShortHashCode hc;
+ size_t bufSize;
+ gcry_sexp_t data;
+
+ GNUNET_CRYPTO_short_hash (purpose, ntohl (purpose->size), &hc);
+#define FORMATSTRING
"(4:data(5:flags3:raw)(5:value32:01234567890123456789012345678901))"
+ bufSize = strlen (FORMATSTRING) + 1;
+ {
+ char buff[bufSize];
+
+ memcpy (buff, FORMATSTRING, bufSize);
+ memcpy (&buff
+ [bufSize -
+ strlen
+ ("01234567890123456789012345678901))")
+ - 1], &hc, sizeof (struct GNUNET_CRYPTO_ShortHashCode));
+ GNUNET_assert (0 == gcry_sexp_new (&data, buff, bufSize, 0));
+ }
+#undef FORMATSTRING
+ return data;
+}
+
+gcry_ctx_t xctx;
+
+
+/**
+ * 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_PSEUDONYM_sign (struct GNUNET_PseudonymHandle *ph,
+ const struct GNUNET_PseudonymSignaturePurpose *purpose,
+ const struct GNUNET_HashCode *seed,
+ const struct GNUNET_HashCode *signing_key,
+ struct GNUNET_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 dx = d + h mod n */
+ dh = gcry_mpi_new (256);
+ gcry_mpi_addm (dh, d, h, n);
+ // gcry_mpi_release (d);
+ // gcry_mpi_release (h);
+ gcry_mpi_release (n);
+
+ if (1) {
+ gcry_mpi_point_t g;
+ gcry_mpi_point_t v;
+ gcry_mpi_point_t hg;
+ gcry_mpi_point_t q;
+ gcry_mpi_t v_x;
+ gcry_mpi_t v_y;
+
+ gcry_mpi_ec_new (&xctx, NULL, "NIST P-256");
+ g = gcry_mpi_ec_get_point ("g", xctx, 0);
+
+ hg = gcry_mpi_point_new (0);
+ gcry_mpi_ec_mul (hg, h, g, xctx);
+ fprintf (stderr, "\nExpected verification hG value:\n");
+ v_x = gcry_mpi_new (256);
+ v_y = gcry_mpi_new (256);
+ gcry_mpi_ec_get_affine (v_x, v_y, hg, xctx);
+ gcry_mpi_dump (v_x);
+ gcry_mpi_dump (v_y);
+
+ q = gcry_mpi_point_new (0);
+ gcry_mpi_ec_mul (q, d, g, xctx);
+ fprintf (stderr, "\nExpected verification q value:\n");
+ gcry_mpi_ec_get_affine (v_x, v_y, q, xctx);
+ gcry_mpi_dump (v_x);
+ gcry_mpi_dump (v_y);
+
+ v = gcry_mpi_point_new (0);
+ gcry_mpi_ec_add (v, q, hg, xctx);
+ gcry_mpi_ec_get_affine (v_x, v_y, v, xctx);
+ fprintf (stderr, "\nExpected verification key public point value V := q +
hG:\n");
+ gcry_mpi_dump (v_x);
+ gcry_mpi_dump (v_y);
+ fprintf (stderr, "\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);
+
+ /* 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);
+ 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_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;
+ }
+ 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;
+ }
+ gcry_mpi_release (rs[1]);
+ 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_PseudonymIdentifier *pseudonym)
+{
+ gcry_ctx_t ctx;
+ gcry_mpi_t ONE;
+ gcry_mpi_t q_x;
+ gcry_mpi_t q_y;
+ gcry_mpi_point_t q;
+ size_t size;
+ int rc;
+
+ /* extract 'q' from pseudonym */
+ 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);
+ ONE = gcry_mpi_new (1);
+ gcry_mpi_set_ui (ONE, 1);
+ gcry_mpi_point_set (q, q_x, q_y, ONE); /* FIXME: convenience function
'set_affine'? */
+ gcry_mpi_release (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_PSEUDONYM_verify.
+ * @return GNUNET_OK on success, GNUNET_SYSERR on error
+ */
+int
+GNUNET_PSEUDONYM_derive_verification_key (struct GNUNET_PseudonymIdentifier
*pseudonym,
+ const struct GNUNET_HashCode
*signing_key,
+ struct GNUNET_PseudonymIdentifier
*verification_key)
+{
+ gcry_mpi_t h;
+ size_t size;
+ int rc;
+ gcry_ctx_t ctx;
+ gcry_mpi_point_t g;
+ gcry_mpi_point_t q;
+ gcry_mpi_point_t hg;
+ gcry_mpi_point_t v;
+ gcry_mpi_t v_x;
+ gcry_mpi_t v_y;
+
+ /* 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;
+ }
+ /* get G */
+ g = gcry_mpi_ec_get_point ("g", ctx, 0);
+
+ /* then call the 'multiply' function, to compute the product hG */
+ hg = gcry_mpi_point_new (0);
+ gcry_mpi_ec_mul (hg, h, g, ctx);
+
+ {
+ fprintf (stderr, "\nVerification hG value:\n");
+ v_x = gcry_mpi_new (256);
+ v_y = gcry_mpi_new (256);
+ gcry_mpi_ec_get_affine (v_x, v_y, hg, ctx);
+ gcry_mpi_dump (v_x);
+ gcry_mpi_dump (v_y);
+ }
+ gcry_mpi_release (h);
+
+ /* get Q = dG from 'pseudonym' */
+ q = gcry_mpi_ec_get_point ("q", ctx, 0);
+ {
+ fprintf (stderr, "\nVerification q value:\n");
+ v_x = gcry_mpi_new (256);
+ v_y = gcry_mpi_new (256);
+ gcry_mpi_ec_get_affine (v_x, v_y, q, ctx);
+ gcry_mpi_dump (v_x);
+ gcry_mpi_dump (v_y);
+ }
+ /* calculate V = Q + hG = dG + hG = (d + h)G*/
+ v = gcry_mpi_point_new (0);
+ gcry_mpi_ec_add (v, q, hg, xctx);
+ /* FIXME: free 'hg'? */
+
+ /* 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, xctx);
+
+ {
+ fprintf (stderr, "\nVerification key public point value V := q + hG:\n");
+ gcry_mpi_dump (v_x);
+ gcry_mpi_dump (v_y);
+ fprintf (stderr, " <=== WTF!?\n");
+ }
+
+
+ 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_PSEUDONYM_verify (const struct GNUNET_PseudonymSignaturePurpose
*purpose,
+ const struct GNUNET_PseudonymSignature *signature,
+ const struct GNUNET_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 ONE;
+ 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);
+
+ /* 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);
+ ONE = gcry_mpi_new (1);
+ gcry_mpi_set_ui (ONE, 1);
+ gcry_mpi_point_set (q, q_x, q_y, ONE); /* FIXME: convenience function
'set_affine'? */
+ gcry_mpi_release (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));
+exit (1);
+ 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_PSEUDONYM_get_identifier (struct GNUNET_PseudonymHandle *ph,
+ struct GNUNET_PseudonymIdentifier *pseudonym)
+{
+ memcpy (pseudonym, &ph->public_key,
+ sizeof (struct GNUNET_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_PSEUDONYM_remove (const struct GNUNET_CONFIGURATION_Handle *cfg,
+ const struct GNUNET_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 */
Modified: gnunet/src/fs/plugin_block_fs.c
===================================================================
--- gnunet/src/fs/plugin_block_fs.c 2013-04-14 18:37:43 UTC (rev 26868)
+++ gnunet/src/fs/plugin_block_fs.c 2013-04-14 18:45:55 UTC (rev 26869)
@@ -26,6 +26,7 @@
#include "platform.h"
#include "gnunet_block_plugin.h"
+#include "gnunet_fs_service.h"
#include "block_fs.h"
#include "gnunet_signatures.h"
Copied: gnunet/src/fs/test_pseudonym.c (from rev 26867,
gnunet/src/util/test_pseudonym.c)
===================================================================
--- gnunet/src/fs/test_pseudonym.c (rev 0)
+++ gnunet/src/fs/test_pseudonym.c 2013-04-14 18:45:55 UTC (rev 26869)
@@ -0,0 +1,327 @@
+/*
+ This file is part of GNUnet.
+ (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
+ 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/test_pseudonym.c
+ * @brief testcase for fs_pseudonym.c
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include "gnunet_common.h"
+#include "gnunet_util_lib.h"
+#include "gnunet_fs_service.h"
+#include "gnunet_signatures.h"
+
+#define CHECK(a) do { if (!(a)) { ok = GNUNET_NO; GNUNET_break(0); goto
FAILURE; } } while (0)
+
+static struct GNUNET_CONTAINER_MetaData *meta;
+
+static struct GNUNET_PseudonymIdentifier id1;
+
+
+static int
+iter (void *cls, const struct GNUNET_PseudonymIdentifier * 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_PseudonymIdentifier))) &&
+ (!GNUNET_CONTAINER_meta_data_test_equal (md, meta)))
+ {
+ *ok = GNUNET_NO;
+ GNUNET_break (0);
+ }
+ return GNUNET_OK;
+}
+
+
+static int
+noti_callback (void *cls, const struct GNUNET_PseudonymIdentifier * pseudonym,
+ const char *name, const char *unique_name,
+ const struct GNUNET_CONTAINER_MetaData *md, int32_t rating)
+{
+ int *ret = cls;
+
+ (*ret)++;
+ return GNUNET_OK;
+}
+
+
+static int
+fake_noti_callback (void *cls, const struct GNUNET_PseudonymIdentifier *
pseudonym,
+ const char *name, const char *unique_name,
+ const struct GNUNET_CONTAINER_MetaData *md, int32_t rating)
+{
+ int *ret = cls;
+
+ (*ret)++;
+ return GNUNET_OK;
+}
+
+
+static void
+create_pseu (struct GNUNET_PseudonymIdentifier *pseu)
+{
+ struct GNUNET_PseudonymHandle *ph;
+
+ ph = GNUNET_PSEUDONYM_create (NULL);
+ GNUNET_PSEUDONYM_get_identifier (ph, pseu);
+ GNUNET_PSEUDONYM_destroy (ph);
+}
+
+
+/**
+ * Testcase for meta data / ranking IO routines.
+ */
+static int
+test_io ()
+{
+ int ok;
+ struct GNUNET_PseudonymIdentifier rid1;
+ struct GNUNET_PseudonymIdentifier id2;
+ struct GNUNET_PseudonymIdentifier rid2;
+ struct GNUNET_PseudonymIdentifier fid;
+ struct GNUNET_PseudonymIdentifier id3;
+ int old;
+ int newVal;
+ struct GNUNET_CONFIGURATION_Handle *cfg;
+ char *name1;
+ char *name2;
+ char *name3;
+ char *name1_unique;
+ char *name2_unique;
+ char *noname;
+ int noname_is_a_dup;
+ int notiCount, fakenotiCount;
+ static char m[1024 * 1024 * 10];
+ struct GNUNET_PSEUDONYM_DiscoveryHandle *dh1;
+ struct GNUNET_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");
+ cfg = GNUNET_CONFIGURATION_create ();
+ if (-1 == GNUNET_CONFIGURATION_parse (cfg, "test_pseudonym_data.conf"))
+ {
+ GNUNET_CONFIGURATION_destroy (cfg);
+ GNUNET_break (0);
+ return -1;
+ }
+ notiCount = 0;
+ fakenotiCount = 0;
+ dh1 = GNUNET_PSEUDONYM_discovery_callback_register (cfg, &fake_noti_callback,
+ &fakenotiCount);
+ dh2 = GNUNET_PSEUDONYM_discovery_callback_register (cfg, ¬i_callback,
+ ¬iCount);
+ GNUNET_PSEUDONYM_discovery_callback_unregister (dh1);
+
+ /* ACTUAL TEST CODE */
+ old = GNUNET_PSEUDONYM_list_all (cfg, NULL, NULL);
+ meta = GNUNET_CONTAINER_meta_data_create ();
+ GNUNET_CONTAINER_meta_data_insert (meta, "<test>", EXTRACTOR_METATYPE_TITLE,
+ EXTRACTOR_METAFORMAT_UTF8, "text/plain",
+ "test", strlen ("test") + 1);
+ create_pseu (&id1);
+ GNUNET_PSEUDONYM_add (cfg, &id1, meta);
+ CHECK (notiCount == 1);
+ GNUNET_PSEUDONYM_add (cfg, &id1, meta);
+ CHECK (notiCount == 2);
+ newVal = GNUNET_PSEUDONYM_list_all (cfg, &iter, &ok);
+ CHECK (old < newVal);
+ old = newVal;
+ create_pseu (&id2);
+ GNUNET_PSEUDONYM_add (cfg, &id2, meta);
+ CHECK (notiCount == 3);
+ newVal = GNUNET_PSEUDONYM_list_all (cfg, &iter, &ok);
+ CHECK (old < newVal);
+ GNUNET_assert (GNUNET_OK ==
+ GNUNET_CONTAINER_meta_data_insert (meta, "<test>",
+ EXTRACTOR_METATYPE_COMMENT,
+ EXTRACTOR_METAFORMAT_UTF8,
+ "text/plain", m,
+ strlen (m) + 1));
+ create_pseu (&id3);
+ GNUNET_PSEUDONYM_add (cfg, &id3, meta);
+ GNUNET_PSEUDONYM_get_info (cfg, &id3, NULL, NULL, &name3, NULL);
+ CHECK (name3 != NULL);
+ GNUNET_PSEUDONYM_get_info (cfg, &id2, NULL, NULL, &name2, NULL);
+ CHECK (name2 != NULL);
+ GNUNET_PSEUDONYM_get_info (cfg, &id1, NULL, NULL, &name1, NULL);
+ CHECK (name1 != NULL);
+ CHECK (0 == strcmp (name1, name2));
+ name1_unique = GNUNET_PSEUDONYM_name_uniquify (cfg, &id1, name1, NULL);
+ name2_unique = GNUNET_PSEUDONYM_name_uniquify (cfg, &id2, name2, NULL);
+ CHECK (0 != strcmp (name1_unique, name2_unique));
+ CHECK (GNUNET_SYSERR == GNUNET_PSEUDONYM_name_to_id (cfg, "fake", &rid2));
+ CHECK (GNUNET_SYSERR == GNUNET_PSEUDONYM_name_to_id (cfg, name2, &rid2));
+ CHECK (GNUNET_SYSERR == GNUNET_PSEUDONYM_name_to_id (cfg, name1, &rid1));
+ CHECK (GNUNET_OK == GNUNET_PSEUDONYM_name_to_id (cfg, name2_unique, &rid2));
+ CHECK (GNUNET_OK == GNUNET_PSEUDONYM_name_to_id (cfg, name1_unique, &rid1));
+ CHECK (0 == memcmp (&id1, &rid1, sizeof (struct
GNUNET_PseudonymIdentifier)));
+ CHECK (0 == memcmp (&id2, &rid2, sizeof (struct
GNUNET_PseudonymIdentifier)));
+
+ create_pseu (&fid);
+ GNUNET_log_skip (1, GNUNET_NO);
+ CHECK (0 == GNUNET_PSEUDONYM_rank (cfg, &fid, 0));
+ GNUNET_log_skip (0, GNUNET_NO);
+ CHECK (GNUNET_OK == GNUNET_PSEUDONYM_get_info (cfg, &fid, NULL, NULL,
&noname, &noname_is_a_dup));
+ CHECK (noname != NULL);
+ CHECK (noname_is_a_dup == GNUNET_YES);
+ CHECK (0 == GNUNET_PSEUDONYM_rank (cfg, &id1, 0));
+ CHECK (5 == GNUNET_PSEUDONYM_rank (cfg, &id1, 5));
+ CHECK (-5 == GNUNET_PSEUDONYM_rank (cfg, &id1, -10));
+ CHECK (0 == GNUNET_PSEUDONYM_rank (cfg, &id1, 5));
+ GNUNET_free (name1);
+ GNUNET_free (name2);
+ GNUNET_free (name1_unique);
+ GNUNET_free (name2_unique);
+ GNUNET_free (name3);
+ GNUNET_free (noname);
+ /* END OF TEST CODE */
+FAILURE:
+ GNUNET_PSEUDONYM_discovery_callback_unregister (dh2);
+ GNUNET_CONTAINER_meta_data_destroy (meta);
+ GNUNET_CONFIGURATION_destroy (cfg);
+ return (ok == GNUNET_YES) ? 0 : 1;
+}
+
+
+/**
+ * Use the given input to sign and check the resulting signature.
+ */
+static void
+test_signature (struct GNUNET_PseudonymHandle *ph,
+ struct GNUNET_PseudonymSignaturePurpose *purpose,
+ struct GNUNET_HashCode *seed,
+ struct GNUNET_HashCode *signing_key,
+ char *bit)
+{
+ struct GNUNET_PseudonymSignature signature;
+ struct GNUNET_PseudonymSignature signature2;
+ struct GNUNET_PseudonymIdentifier pseudonym;
+ struct GNUNET_PseudonymIdentifier verification_key;
+
+ GNUNET_PSEUDONYM_sign (ph, purpose, seed, signing_key, &signature);
+ if (0)
+ {
+ GNUNET_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_PSEUDONYM_get_identifier (ph, &pseudonym);
+ GNUNET_PSEUDONYM_derive_verification_key (&pseudonym,
+ signing_key,
+ &verification_key);
+ GNUNET_break (GNUNET_OK ==
+ GNUNET_PSEUDONYM_verify (purpose, &signature,
&verification_key));
+ /* also check that if the data is changed, the signature no longer matches */
+ (*bit)++;
+ /* crypto not implemented, thus for now 'break' */
+ GNUNET_break (GNUNET_OK !=
+ GNUNET_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_PseudonymHandle *ph)
+{
+ char data[16];
+ struct GNUNET_PseudonymSignaturePurpose *purpose;
+ struct GNUNET_HashCode seed;
+ struct GNUNET_HashCode signing_key;
+
+ memset (data, 42, sizeof (data));
+ purpose = (struct GNUNET_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_PseudonymSignaturePurpose)]);
+ test_signature (ph, purpose, NULL, &signing_key, &data[sizeof (struct
GNUNET_PseudonymSignaturePurpose)]);
+}
+
+
+/**
+ * Test cryptographic operations.
+ */
+static int
+test_crypto ()
+{
+ struct GNUNET_PseudonymHandle *ph;
+ struct GNUNET_PseudonymIdentifier pseudonym;
+ struct GNUNET_PseudonymIdentifier pseudonym2;
+
+ /* check writing to and reading from disk */
+ ph = GNUNET_PSEUDONYM_create ("/tmp/gnunet-pseudonym-test/pseu.dsa");
+ GNUNET_PSEUDONYM_get_identifier (ph, &pseudonym);
+ GNUNET_PSEUDONYM_destroy (ph);
+ ph = GNUNET_PSEUDONYM_create ("/tmp/gnunet-pseudonym-test/pseu.dsa");
+ GNUNET_PSEUDONYM_get_identifier (ph, &pseudonym2);
+ test_crypto_ops (ph);
+ GNUNET_PSEUDONYM_destroy (ph);
+ if (0 != memcmp (&pseudonym, &pseudonym2, sizeof (pseudonym)))
+ return 1;
+
+ /* check in-memory generation */
+ ph = GNUNET_PSEUDONYM_create (NULL);
+ GNUNET_PSEUDONYM_get_identifier (ph, &pseudonym2);
+ if (0 == memcmp (&pseudonym, &pseudonym2, sizeof (pseudonym)))
+ return 1;
+ test_crypto_ops (ph);
+ GNUNET_PSEUDONYM_destroy (ph);
+
+ /* check anonymous pseudonym operations generation */
+ ph = GNUNET_PSEUDONYM_get_anonymous_pseudonym_handle ();
+ GNUNET_PSEUDONYM_get_identifier (ph, &pseudonym2);
+ if (0 == memcmp (&pseudonym, &pseudonym2, sizeof (pseudonym)))
+ return 1;
+ test_crypto_ops (ph);
+ GNUNET_PSEUDONYM_destroy (ph);
+ return 0;
+}
+
+
+int
+main (int argc, char *argv[])
+{
+ 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;
+}
+
+
+/* end of test_pseudoynm.c */
Modified: gnunet/src/include/Makefile.am
===================================================================
--- gnunet/src/include/Makefile.am 2013-04-14 18:37:43 UTC (rev 26868)
+++ gnunet/src/include/Makefile.am 2013-04-14 18:45:55 UTC (rev 26869)
@@ -67,7 +67,6 @@
gnunet_postgres_lib.h \
gnunet_program_lib.h \
gnunet_protocols.h \
- gnunet_pseudonym_lib.h \
gnunet_resolver_service.h \
gnunet_regex_lib.h \
gnunet_scheduler_lib.h \
Modified: gnunet/src/include/block_fs.h
===================================================================
--- gnunet/src/include/block_fs.h 2013-04-14 18:37:43 UTC (rev 26868)
+++ gnunet/src/include/block_fs.h 2013-04-14 18:45:55 UTC (rev 26869)
@@ -27,6 +27,7 @@
#define BLOCK_FS_H
#include "gnunet_util_lib.h"
+#include "gnunet_fs_service.h"
/**
Modified: gnunet/src/include/gnunet_fs_service.h
===================================================================
--- gnunet/src/include/gnunet_fs_service.h 2013-04-14 18:37:43 UTC (rev
26868)
+++ gnunet/src/include/gnunet_fs_service.h 2013-04-14 18:45:55 UTC (rev
26869)
@@ -79,7 +79,79 @@
*/
struct GNUNET_FS_Uri;
+
/**
+ * Identifier for a GNUnet pseudonym (the public key).
+ * Q-point, Q=dp.
+ */
+struct GNUNET_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_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_PseudonymSignature
+{
+
+ /**
+ * Who created the signature? (public key of the signer), 'd' value in NIST
P-256.
+ */
+ struct GNUNET_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_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
*
* @param cls closure
@@ -90,7 +162,304 @@
typedef int (*GNUNET_FS_KeywordIterator) (void *cls, const char *keyword,
int is_mandatory);
+
+
+
/**
+ * 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_PseudonymHandle *
+GNUNET_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_PseudonymHandle *
+GNUNET_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_PseudonymHandle *
+GNUNET_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_PSEUDONYM_destroy (struct GNUNET_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_PSEUDONYM_sign (struct GNUNET_PseudonymHandle *ph,
+ const struct GNUNET_PseudonymSignaturePurpose *purpose,
+ const struct GNUNET_HashCode *seed,
+ const struct GNUNET_HashCode *signing_key,
+ struct GNUNET_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_PSEUDONYM_verify.
+ * @return GNUNET_OK on success, GNUNET_SYSERR on error
+ */
+int
+GNUNET_PSEUDONYM_derive_verification_key (struct GNUNET_PseudonymIdentifier
*pseudonym,
+ const struct GNUNET_HashCode
*signing_key,
+ struct GNUNET_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_PSEUDONYM_verify (const struct GNUNET_PseudonymSignaturePurpose
*purpose,
+ const struct GNUNET_PseudonymSignature *signature,
+ const struct GNUNET_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_PSEUDONYM_get_identifier (struct GNUNET_PseudonymHandle *ph,
+ struct GNUNET_PseudonymIdentifier *pseudonym);
+
+
+
+/**
+ * Iterator over all known pseudonyms.
+ *
+ * @param cls closure
+ * @param pseudonym hash code of 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
+ * @param rating the local rating of the pseudonym
+ * @return GNUNET_OK to continue iteration, GNUNET_SYSERR to abort
+ */
+typedef int (*GNUNET_PSEUDONYM_Iterator) (void *cls,
+ const struct
GNUNET_PseudonymIdentifier *pseudonym,
+ const char *name,
+ const char *unique_name,
+ const struct
GNUNET_CONTAINER_MetaData *md,
+ int32_t rating);
+
+
+/**
+ * Change the rank of a pseudonym.
+ *
+ * @param cfg overall configuration
+ * @param pseudonym identity of the pseudonym
+ * @param delta by how much should the rating be changed?
+ * @return new rating of the pseudonym
+ */
+int
+GNUNET_PSEUDONYM_rank (const struct GNUNET_CONFIGURATION_Handle *cfg,
+ const struct GNUNET_PseudonymIdentifier *pseudonym,
+ int32_t delta);
+
+
+/**
+ * Add a pseudonym to the set of known pseudonyms.
+ * For all pseudonym advertisements that we discover
+ * FS should automatically call this function.
+ *
+ * @param cfg overall configuration
+ * @param pseudonym the pseudonym identifier
+ * @param meta metadata for the pseudonym
+ * @return GNUNET_OK on success, GNUNET_SYSERR on failure
+ */
+int
+GNUNET_PSEUDONYM_add (const struct GNUNET_CONFIGURATION_Handle *cfg,
+ const struct GNUNET_PseudonymIdentifier *pseudonym,
+ const struct GNUNET_CONTAINER_MetaData *meta);
+
+
+/**
+ * List all known pseudonyms.
+ *
+ * @param cfg overall configuration
+ * @param iterator function to call for each pseudonym
+ * @param iterator_cls closure for iterator
+ * @return number of pseudonyms found
+ */
+int
+GNUNET_PSEUDONYM_list_all (const struct GNUNET_CONFIGURATION_Handle *cfg,
+ GNUNET_PSEUDONYM_Iterator iterator,
+ void *iterator_cls);
+
+
+/**
+ * Handle for a discovery callback registration.
+ */
+struct GNUNET_PSEUDONYM_DiscoveryHandle;
+
+
+/**
+ * Register callback to be invoked whenever we discover
+ * a new pseudonym.
+ *
+ * @param cfg our configuration
+ * @param iterator function to invoke on discovery
+ * @param iterator_cls closure for iterator
+ * @return registration handle
+ */
+struct GNUNET_PSEUDONYM_DiscoveryHandle *
+GNUNET_PSEUDONYM_discovery_callback_register (const struct
GNUNET_CONFIGURATION_Handle *cfg,
+ GNUNET_PSEUDONYM_Iterator
iterator,
+ void *iterator_cls);
+
+
+/**
+ * Unregister pseudonym discovery callback.
+ *
+ * @param dh registration to unregister
+ */
+void
+GNUNET_PSEUDONYM_discovery_callback_unregister (struct
GNUNET_PSEUDONYM_DiscoveryHandle *dh);
+
+
+/**
+ * Return unique variant of the pseudonym name. Use after
+ * GNUNET_PSEUDONYM_id_to_name() to make sure that name is unique.
+ *
+ * @param cfg configuration
+ * @param pseudonym cryptographic ID of the pseudonym
+ * @param name name to uniquify
+ * @param suffix if not NULL, filled with the suffix value
+ * @return NULL on failure (should never happen), name on success.
+ * Free the name with GNUNET_free().
+ */
+char *
+GNUNET_PSEUDONYM_name_uniquify (const struct GNUNET_CONFIGURATION_Handle *cfg,
+ const struct GNUNET_PseudonymIdentifier
*pseudonym,
+ const char *name,
+ unsigned int *suffix);
+
+
+/**
+ * Get pseudonym name, metadata and rank. This is a wrapper around
+ * internal read_info() call, and ensures that returned data is not
+ * invalid (not NULL). Writing back information returned by this
+ * function will give a name "no-name" to pseudonyms that have no
+ * name. This side-effect is unavoidable, but hardly harmful.
+ *
+ * @param cfg configuration
+ * @param pseudonym cryptographic ID of the pseudonym
+ * @param ret_meta a location to store metadata pointer. NULL, if metadata
+ * is not needed. Destroy with GNUNET_CONTAINER_meta_data_destroy().
+ * @param ret_rank a location to store rank. NULL, if rank not needed.
+ * @param ret_name a location to store human-readable name. Name is not unique.
+ * NULL, if name is not needed. Free with GNUNET_free().
+ * @param name_is_a_dup is set to GNUNET_YES, if ret_name was filled with
+ * a duplicate of a "no-name" placeholder
+ * @return GNUNET_OK on success. GNUENT_SYSERR if the data was
+ * unobtainable (in that case ret_* are filled with placeholders -
+ * empty metadata container, rank -1 and a "no-name" name).
+ */
+int
+GNUNET_PSEUDONYM_get_info (const struct GNUNET_CONFIGURATION_Handle *cfg,
+ const struct GNUNET_PseudonymIdentifier *pseudonym,
+ struct GNUNET_CONTAINER_MetaData **ret_meta,
+ int32_t *ret_rank,
+ char **ret_name,
+ int *name_is_a_dup);
+
+
+/**
+ * Get the pseudonym ID belonging to the given pseudonym name.
+ *
+ * @param cfg configuration to use
+ * @param ns_uname unique (!) human-readable name for the pseudonym
+ * @param pseudonym set to pseudonym ID based on 'ns_uname'
+ * @return GNUNET_OK on success, GNUNET_SYSERR on failure
+ */
+int
+GNUNET_PSEUDONYM_name_to_id (const struct GNUNET_CONFIGURATION_Handle *cfg,
+ const char *ns_uname,
+ struct GNUNET_PseudonymIdentifier *pseudonym);
+
+
+/**
+ * Set the pseudonym metadata, rank and name.
+ *
+ * @param cfg overall configuration
+ * @param pseudonym id of the pseudonym
+ * @param name name to set. Must be the non-unique version of it.
+ * May be NULL, in which case it erases pseudonym's name!
+ * @param md metadata to set
+ * May be NULL, in which case it erases pseudonym's metadata!
+ * @param rank rank to assign
+ * @return GNUNET_OK on success, GNUNET_SYSERR on failure
+ */
+int
+GNUNET_PSEUDONYM_set_info (const struct GNUNET_CONFIGURATION_Handle *cfg,
+ const struct GNUNET_PseudonymIdentifier *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_PSEUDONYM_remove (const struct GNUNET_CONFIGURATION_Handle *cfg,
+ const struct GNUNET_PseudonymIdentifier *id);
+
+
+/**
* Get a unique key from a URI. This is for putting URIs
* into HashMaps. The key may change between FS implementations.
*
@@ -100,6 +469,7 @@
void
GNUNET_FS_uri_to_key (const struct GNUNET_FS_Uri *uri, struct GNUNET_HashCode
* key);
+
/**
* Convert a URI to a UTF-8 String.
*
@@ -109,6 +479,7 @@
char *
GNUNET_FS_uri_to_string (const struct GNUNET_FS_Uri *uri);
+
/**
* Convert keyword URI to a human readable format
* (i.e. the search query that was used in the first place)
Deleted: gnunet/src/include/gnunet_pseudonym_lib.h
===================================================================
--- gnunet/src/include/gnunet_pseudonym_lib.h 2013-04-14 18:37:43 UTC (rev
26868)
+++ gnunet/src/include/gnunet_pseudonym_lib.h 2013-04-14 18:45:55 UTC (rev
26869)
@@ -1,418 +0,0 @@
-/*
- This file is part of GNUnet.
- (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
- by the Free Software Foundation; either version 2, 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 include/gnunet_pseudonym_lib.h
- * @brief functions related to pseudonyms
- * @author Christian Grothoff
- */
-
-#ifndef GNUNET_PSEUDONYM_LIB_H
-#define GNUNET_PSEUDONYM_LIB_H
-
-#ifdef __cplusplus
-extern "C"
-{
-#if 0 /* keep Emacsens' auto-indent happy */
-}
-#endif
-#endif
-
-#include "gnunet_common.h"
-#include "gnunet_configuration_lib.h"
-#include "gnunet_container_lib.h"
-
-
-/**
- * Identifier for a GNUnet pseudonym (the public key).
- * Q-point, Q=dp.
- */
-struct GNUNET_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_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_PseudonymSignature
-{
-
- /**
- * Who created the signature? (public key of the signer), 'd' value in NIST
P-256.
- */
- struct GNUNET_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_PseudonymSignaturePurpose
-{
- /**
- * How many bytes are being signed (including this header)?
- */
- uint32_t size;
-
- /**
- * What is the context/purpose of the signature?
- */
- uint32_t purpose;
-};
-
-
-/**
- * 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_PseudonymHandle *
-GNUNET_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_PseudonymHandle *
-GNUNET_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_PseudonymHandle *
-GNUNET_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_PSEUDONYM_destroy (struct GNUNET_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_PSEUDONYM_sign (struct GNUNET_PseudonymHandle *ph,
- const struct GNUNET_PseudonymSignaturePurpose *purpose,
- const struct GNUNET_HashCode *seed,
- const struct GNUNET_HashCode *signing_key,
- struct GNUNET_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_PSEUDONYM_verify.
- * @return GNUNET_OK on success, GNUNET_SYSERR on error
- */
-int
-GNUNET_PSEUDONYM_derive_verification_key (struct GNUNET_PseudonymIdentifier
*pseudonym,
- const struct GNUNET_HashCode
*signing_key,
- struct GNUNET_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_PSEUDONYM_verify (const struct GNUNET_PseudonymSignaturePurpose
*purpose,
- const struct GNUNET_PseudonymSignature *signature,
- const struct GNUNET_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_PSEUDONYM_get_identifier (struct GNUNET_PseudonymHandle *ph,
- struct GNUNET_PseudonymIdentifier *pseudonym);
-
-
-
-/**
- * Iterator over all known pseudonyms.
- *
- * @param cls closure
- * @param pseudonym hash code of 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
- * @param rating the local rating of the pseudonym
- * @return GNUNET_OK to continue iteration, GNUNET_SYSERR to abort
- */
-typedef int (*GNUNET_PSEUDONYM_Iterator) (void *cls,
- const struct
GNUNET_PseudonymIdentifier *pseudonym,
- const char *name,
- const char *unique_name,
- const struct
GNUNET_CONTAINER_MetaData *md,
- int32_t rating);
-
-
-/**
- * Change the rank of a pseudonym.
- *
- * @param cfg overall configuration
- * @param pseudonym identity of the pseudonym
- * @param delta by how much should the rating be changed?
- * @return new rating of the pseudonym
- */
-int
-GNUNET_PSEUDONYM_rank (const struct GNUNET_CONFIGURATION_Handle *cfg,
- const struct GNUNET_PseudonymIdentifier *pseudonym,
- int32_t delta);
-
-
-/**
- * Add a pseudonym to the set of known pseudonyms.
- * For all pseudonym advertisements that we discover
- * FS should automatically call this function.
- *
- * @param cfg overall configuration
- * @param pseudonym the pseudonym identifier
- * @param meta metadata for the pseudonym
- * @return GNUNET_OK on success, GNUNET_SYSERR on failure
- */
-int
-GNUNET_PSEUDONYM_add (const struct GNUNET_CONFIGURATION_Handle *cfg,
- const struct GNUNET_PseudonymIdentifier *pseudonym,
- const struct GNUNET_CONTAINER_MetaData *meta);
-
-
-/**
- * List all known pseudonyms.
- *
- * @param cfg overall configuration
- * @param iterator function to call for each pseudonym
- * @param iterator_cls closure for iterator
- * @return number of pseudonyms found
- */
-int
-GNUNET_PSEUDONYM_list_all (const struct GNUNET_CONFIGURATION_Handle *cfg,
- GNUNET_PSEUDONYM_Iterator iterator,
- void *iterator_cls);
-
-
-/**
- * Handle for a discovery callback registration.
- */
-struct GNUNET_PSEUDONYM_DiscoveryHandle;
-
-
-/**
- * Register callback to be invoked whenever we discover
- * a new pseudonym.
- *
- * @param cfg our configuration
- * @param iterator function to invoke on discovery
- * @param iterator_cls closure for iterator
- * @return registration handle
- */
-struct GNUNET_PSEUDONYM_DiscoveryHandle *
-GNUNET_PSEUDONYM_discovery_callback_register (const struct
GNUNET_CONFIGURATION_Handle *cfg,
- GNUNET_PSEUDONYM_Iterator
iterator,
- void *iterator_cls);
-
-
-/**
- * Unregister pseudonym discovery callback.
- *
- * @param dh registration to unregister
- */
-void
-GNUNET_PSEUDONYM_discovery_callback_unregister (struct
GNUNET_PSEUDONYM_DiscoveryHandle *dh);
-
-
-/**
- * Return unique variant of the pseudonym name. Use after
- * GNUNET_PSEUDONYM_id_to_name() to make sure that name is unique.
- *
- * @param cfg configuration
- * @param pseudonym cryptographic ID of the pseudonym
- * @param name name to uniquify
- * @param suffix if not NULL, filled with the suffix value
- * @return NULL on failure (should never happen), name on success.
- * Free the name with GNUNET_free().
- */
-char *
-GNUNET_PSEUDONYM_name_uniquify (const struct GNUNET_CONFIGURATION_Handle *cfg,
- const struct GNUNET_PseudonymIdentifier
*pseudonym,
- const char *name,
- unsigned int *suffix);
-
-
-/**
- * Get pseudonym name, metadata and rank. This is a wrapper around
- * internal read_info() call, and ensures that returned data is not
- * invalid (not NULL). Writing back information returned by this
- * function will give a name "no-name" to pseudonyms that have no
- * name. This side-effect is unavoidable, but hardly harmful.
- *
- * @param cfg configuration
- * @param pseudonym cryptographic ID of the pseudonym
- * @param ret_meta a location to store metadata pointer. NULL, if metadata
- * is not needed. Destroy with GNUNET_CONTAINER_meta_data_destroy().
- * @param ret_rank a location to store rank. NULL, if rank not needed.
- * @param ret_name a location to store human-readable name. Name is not unique.
- * NULL, if name is not needed. Free with GNUNET_free().
- * @param name_is_a_dup is set to GNUNET_YES, if ret_name was filled with
- * a duplicate of a "no-name" placeholder
- * @return GNUNET_OK on success. GNUENT_SYSERR if the data was
- * unobtainable (in that case ret_* are filled with placeholders -
- * empty metadata container, rank -1 and a "no-name" name).
- */
-int
-GNUNET_PSEUDONYM_get_info (const struct GNUNET_CONFIGURATION_Handle *cfg,
- const struct GNUNET_PseudonymIdentifier *pseudonym,
- struct GNUNET_CONTAINER_MetaData **ret_meta,
- int32_t *ret_rank,
- char **ret_name,
- int *name_is_a_dup);
-
-
-/**
- * Get the pseudonym ID belonging to the given pseudonym name.
- *
- * @param cfg configuration to use
- * @param ns_uname unique (!) human-readable name for the pseudonym
- * @param pseudonym set to pseudonym ID based on 'ns_uname'
- * @return GNUNET_OK on success, GNUNET_SYSERR on failure
- */
-int
-GNUNET_PSEUDONYM_name_to_id (const struct GNUNET_CONFIGURATION_Handle *cfg,
- const char *ns_uname,
- struct GNUNET_PseudonymIdentifier *pseudonym);
-
-
-/**
- * Set the pseudonym metadata, rank and name.
- *
- * @param cfg overall configuration
- * @param pseudonym id of the pseudonym
- * @param name name to set. Must be the non-unique version of it.
- * May be NULL, in which case it erases pseudonym's name!
- * @param md metadata to set
- * May be NULL, in which case it erases pseudonym's metadata!
- * @param rank rank to assign
- * @return GNUNET_OK on success, GNUNET_SYSERR on failure
- */
-int
-GNUNET_PSEUDONYM_set_info (const struct GNUNET_CONFIGURATION_Handle *cfg,
- const struct GNUNET_PseudonymIdentifier *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_PSEUDONYM_remove (const struct GNUNET_CONFIGURATION_Handle *cfg,
- const struct GNUNET_PseudonymIdentifier *id);
-
-
-
-#if 0 /* keep Emacsens' auto-indent happy */
-{
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-/* ifndef GNUNET_PSEUDONYM_LIB_H */
-#endif
-/* end of gnunet_pseudonym_lib.h */
Modified: gnunet/src/include/gnunet_util_lib.h
===================================================================
--- gnunet/src/include/gnunet_util_lib.h 2013-04-14 18:37:43 UTC (rev
26868)
+++ gnunet/src/include/gnunet_util_lib.h 2013-04-14 18:45:55 UTC (rev
26869)
@@ -53,7 +53,6 @@
#include "gnunet_plugin_lib.h"
#include "gnunet_program_lib.h"
#include "gnunet_protocols.h"
-#include "gnunet_pseudonym_lib.h"
#include "gnunet_scheduler_lib.h"
#include "gnunet_server_lib.h"
#include "gnunet_service_lib.h"
Modified: gnunet/src/util/Makefile.am
===================================================================
--- gnunet/src/util/Makefile.am 2013-04-14 18:37:43 UTC (rev 26868)
+++ gnunet/src/util/Makefile.am 2013-04-14 18:45:55 UTC (rev 26869)
@@ -96,7 +96,6 @@
peer.c \
plugin.c \
program.c \
- pseudonym.c \
resolver_api.c resolver.h \
scheduler.c \
server.c \
@@ -234,7 +233,6 @@
test_peer \
test_plugin \
test_program \
- test_pseudonym \
test_resolver_api \
test_scheduler \
test_scheduler_delay \
@@ -436,11 +434,6 @@
test_program_LDADD = \
$(top_builddir)/src/util/libgnunetutil.la
-test_pseudonym_SOURCES = \
- test_pseudonym.c
-test_pseudonym_LDADD = \
- $(top_builddir)/src/util/libgnunetutil.la
-
test_resolver_api_SOURCES = \
test_resolver_api.c
test_resolver_api_LDADD = \
Deleted: gnunet/src/util/pseudonym.c
===================================================================
--- gnunet/src/util/pseudonym.c 2013-04-14 18:37:43 UTC (rev 26868)
+++ gnunet/src/util/pseudonym.c 2013-04-14 18:45:55 UTC (rev 26869)
@@ -1,1526 +0,0 @@
-/*
- This file is part of GNUnet
- (C) 2003, 2004, 2005, 2006, 2007, 2008, 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 2, 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 util/pseudonym.c
- * @brief helper 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_common.h"
-#include "gnunet_container_lib.h"
-#include "gnunet_disk_lib.h"
-#include "gnunet_pseudonym_lib.h"
-#include "gnunet_bio_lib.h"
-#include <gcrypt.h>
-
-#define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__)
-
-#define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util",
syscall)
-
-#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
- */
-#define PS_METADATA_DIR DIR_SEPARATOR_STR "data" DIR_SEPARATOR_STR "pseudonym"
DIR_SEPARATOR_STR "metadata" DIR_SEPARATOR_STR
-
-/**
- * Name of the directory which stores names for pseudonyms
- */
-#define PS_NAMES_DIR DIR_SEPARATOR_STR "data" DIR_SEPARATOR_STR "pseudonym"
DIR_SEPARATOR_STR "names" DIR_SEPARATOR_STR
-
-
-/**
- * Configuration section we use.
- */
-#define GNUNET_CLIENT_SERVICE_NAME "client"
-
-
-/* ************************* Disk operations (pseudonym data mgmt)
**************** */
-
-/**
- * Registered callbacks for discovery of pseudonyms.
- */
-struct GNUNET_PSEUDONYM_DiscoveryHandle
-{
- /**
- * This is a doubly linked list.
- */
- struct GNUNET_PSEUDONYM_DiscoveryHandle *next;
-
- /**
- * This is a doubly linked list.
- */
- struct GNUNET_PSEUDONYM_DiscoveryHandle *prev;
-
- /**
- * Function to call each time a pseudonym is discovered.
- */
- GNUNET_PSEUDONYM_Iterator callback;
-
- /**
- * Closure for callback.
- */
- void *callback_cls;
-};
-
-
-/**
- * Head of the linked list of functions to call when
- * new pseudonyms are added.
- */
-static struct GNUNET_PSEUDONYM_DiscoveryHandle *disco_head;
-
-/**
- * Tail of the linked list of functions to call when
- * new pseudonyms are added.
- */
-static struct GNUNET_PSEUDONYM_DiscoveryHandle *disco_tail;
-
-
-/**
- * Internal notification about new tracked URI.
- *
- * @param pseudonym public key of the pseudonym
- * @param md meta data to be written
- * @param rating rating of pseudonym
- */
-static void
-internal_notify (const struct GNUNET_PseudonymIdentifier *pseudonym,
- const struct GNUNET_CONTAINER_MetaData *md, int rating)
-{
- struct GNUNET_PSEUDONYM_DiscoveryHandle *pos;
-
- for (pos = disco_head; NULL != pos; pos = pos->next)
- pos->callback (pos->callback_cls, pseudonym, NULL, NULL, md, rating);
-}
-
-
-/**
- * Register callback to be invoked whenever we discover
- * a new pseudonym.
- * Will immediately call provided iterator callback for all
- * already discovered pseudonyms.
- *
- * @param cfg configuration to use
- * @param iterator iterator over pseudonym
- * @param iterator_cls point to a closure
- * @return registration handle
- */
-struct GNUNET_PSEUDONYM_DiscoveryHandle *
-GNUNET_PSEUDONYM_discovery_callback_register (const struct
- GNUNET_CONFIGURATION_Handle *cfg,
- GNUNET_PSEUDONYM_Iterator
iterator,
- void *iterator_cls)
-{
- struct GNUNET_PSEUDONYM_DiscoveryHandle *dh;
-
- dh = GNUNET_malloc (sizeof (struct GNUNET_PSEUDONYM_DiscoveryHandle));
- dh->callback = iterator;
- dh->callback_cls = iterator_cls;
- GNUNET_CONTAINER_DLL_insert (disco_head, disco_tail, dh);
- GNUNET_PSEUDONYM_list_all (cfg, iterator, iterator_cls);
- return dh;
-}
-
-
-/**
- * Unregister pseudonym discovery callback.
- *
- * @param dh registration to unregister
- */
-void
-GNUNET_PSEUDONYM_discovery_callback_unregister (struct
GNUNET_PSEUDONYM_DiscoveryHandle *dh)
-{
- GNUNET_CONTAINER_DLL_remove (disco_head, disco_tail, dh);
- GNUNET_free (dh);
-}
-
-
-/**
- * Get the filename (or directory name) for the given
- * pseudonym identifier and directory prefix.
- *
- * @param cfg configuration to use
- * @param prefix path components to append to the private directory name
- * @param pseudonym the pseudonym, can be NULL
- * @return filename of the pseudonym (if pseudonym != NULL) or directory with
the data (if pseudonym == NULL)
- */
-static char *
-get_data_filename (const struct GNUNET_CONFIGURATION_Handle *cfg,
- const char *prefix,
- const struct GNUNET_PseudonymIdentifier *pseudonym)
-{
- struct GNUNET_CRYPTO_HashAsciiEncoded enc;
- struct GNUNET_HashCode psid;
-
- if (NULL != pseudonym)
- {
- GNUNET_CRYPTO_hash (pseudonym,
- sizeof (struct GNUNET_PseudonymIdentifier),
- &psid);
- GNUNET_CRYPTO_hash_to_enc (&psid, &enc);
- }
- return GNUNET_DISK_get_home_filename (cfg,
- GNUNET_CLIENT_SERVICE_NAME, prefix,
- (NULL == pseudonym)
- ? NULL
- : (const char *) &enc,
- NULL);
-}
-
-
-/**
- * Get the filename (or directory name) for the given
- * hash code and directory prefix.
- *
- * @param cfg configuration to use
- * @param prefix path components to append to the private directory name
- * @param hc some hash code
- * @return filename of the pseudonym (if hc != NULL) or directory with the
data (if hc == NULL)
- */
-static char *
-get_data_filename_hash (const struct GNUNET_CONFIGURATION_Handle *cfg,
- const char *prefix,
- const struct GNUNET_HashCode *hc)
-{
- struct GNUNET_CRYPTO_HashAsciiEncoded enc;
-
- if (NULL != hc)
- GNUNET_CRYPTO_hash_to_enc (hc, &enc);
- return GNUNET_DISK_get_home_filename (cfg,
- GNUNET_CLIENT_SERVICE_NAME, prefix,
- (NULL == hc)
- ? NULL
- : (const char *) &enc,
- NULL);
-}
-
-
-/**
- * Set the pseudonym metadata, rank and name.
- * Writes the pseudonym infomation into a file
- *
- * @param cfg overall configuration
- * @param pseudonym id of the pseudonym
- * @param name name to set. Must be the non-unique version of it.
- * May be NULL, in which case it erases pseudonym's name!
- * @param md metadata to set
- * May be NULL, in which case it erases pseudonym's metadata!
- * @param rank rank to assign
- * @return GNUNET_OK on success, GNUNET_SYSERR on failure
- */
-int
-GNUNET_PSEUDONYM_set_info (const struct GNUNET_CONFIGURATION_Handle *cfg,
- const struct GNUNET_PseudonymIdentifier *pseudonym,
- const char *name,
- const struct GNUNET_CONTAINER_MetaData *md,
- int32_t rank)
-{
- char *fn;
- struct GNUNET_BIO_WriteHandle *fileW;
-
- fn = get_data_filename (cfg, PS_METADATA_DIR, pseudonym);
- if (NULL == (fileW = GNUNET_BIO_write_open (fn)))
- {
- GNUNET_free (fn);
- return GNUNET_SYSERR;
- }
- if ((GNUNET_OK != GNUNET_BIO_write (fileW, pseudonym,
- sizeof (struct
GNUNET_PseudonymIdentifier))) ||
- (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)))
- {
- (void) GNUNET_BIO_write_close (fileW);
- GNUNET_break (GNUNET_OK == GNUNET_DISK_directory_remove (fn));
- GNUNET_free (fn);
- return GNUNET_SYSERR;
- }
- if (GNUNET_OK != GNUNET_BIO_write_close (fileW))
- {
- GNUNET_break (GNUNET_OK == GNUNET_DISK_directory_remove (fn));
- GNUNET_free (fn);
- return GNUNET_SYSERR;
- }
- GNUNET_free (fn);
- /* create entry for pseudonym name in names */
- if (NULL != name)
- GNUNET_free_non_null (GNUNET_PSEUDONYM_name_uniquify (cfg, pseudonym,
- name, NULL));
- return GNUNET_OK;
-}
-
-
-/**
- * Read pseudonym infomation from a file
- *
- * @param cfg configuration to use
- * @param pseudonym hash code of a pseudonym
- * @param meta meta data to be read from a file
- * @param rank rank of a pseudonym
- * @param ns_name name of a pseudonym
- * @return GNUNET_OK on success, GNUNET_SYSERR on error
- */
-static int
-read_info (const struct GNUNET_CONFIGURATION_Handle *cfg,
- const struct GNUNET_PseudonymIdentifier *pseudonym,
- struct GNUNET_CONTAINER_MetaData **meta,
- int32_t *rank,
- char **ns_name)
-{
- struct GNUNET_PseudonymIdentifier pd;
- char *fn;
- char *emsg;
- struct GNUNET_BIO_ReadHandle *fileR;
-
- fn = get_data_filename (cfg, PS_METADATA_DIR, pseudonym);
- if (GNUNET_YES !=
- GNUNET_DISK_file_test (fn))
- {
- GNUNET_free (fn);
- return GNUNET_SYSERR;
- }
- if (NULL == (fileR = GNUNET_BIO_read_open (fn)))
- {
- GNUNET_free (fn);
- return GNUNET_SYSERR;
- }
- emsg = NULL;
- *ns_name = NULL;
- if ( (GNUNET_OK != GNUNET_BIO_read (fileR, "pseudonym", &pd, sizeof (pd))) ||
- (0 != memcmp (&pd, pseudonym, sizeof (pd))) ||
- (GNUNET_OK != GNUNET_BIO_read_int32 (fileR, rank)) ||
- (GNUNET_OK !=
- GNUNET_BIO_read_string (fileR, "Read string error!", ns_name, 200)) ||
- (GNUNET_OK !=
- GNUNET_BIO_read_meta_data (fileR, "Read meta data error!", meta)) )
- {
- (void) GNUNET_BIO_read_close (fileR, &emsg);
- GNUNET_free_non_null (emsg);
- GNUNET_free_non_null (*ns_name);
- *ns_name = NULL;
- GNUNET_break (GNUNET_OK == GNUNET_DISK_directory_remove (fn));
- GNUNET_free (fn);
- return GNUNET_SYSERR;
- }
- if (GNUNET_OK != GNUNET_BIO_read_close (fileR, &emsg))
- {
- LOG (GNUNET_ERROR_TYPE_WARNING,
- _("Failed to parse metadata about pseudonym from file `%s': %s\n"),
fn,
- emsg);
- GNUNET_break (GNUNET_OK == GNUNET_DISK_directory_remove (fn));
- GNUNET_CONTAINER_meta_data_destroy (*meta);
- *meta = NULL;
- GNUNET_free_non_null (*ns_name);
- *ns_name = NULL;
- GNUNET_free_non_null (emsg);
- GNUNET_free (fn);
- return GNUNET_SYSERR;
- }
- GNUNET_free (fn);
- return GNUNET_OK;
-}
-
-
-/**
- * Return unique variant of the namespace name. Use it after
- * GNUNET_PSEUDONYM_get_info() to make sure that name is unique.
- *
- * @param cfg configuration
- * @param pseudonym public key of the pseudonym
- * @param name name to uniquify
- * @param suffix if not NULL, filled with the suffix value
- * @return NULL on failure (should never happen), name on success.
- * Free the name with GNUNET_free().
- */
-char *
-GNUNET_PSEUDONYM_name_uniquify (const struct GNUNET_CONFIGURATION_Handle *cfg,
- const struct GNUNET_PseudonymIdentifier
*pseudonym,
- const char *name,
- unsigned int *suffix)
-{
- struct GNUNET_HashCode nh;
- struct GNUNET_PseudonymIdentifier pi;
- uint64_t len;
- char *fn;
- struct GNUNET_DISK_FileHandle *fh;
- unsigned int i;
- unsigned int idx;
- char *ret;
- struct stat sbuf;
-
- GNUNET_CRYPTO_hash (name, strlen (name), &nh);
- fn = get_data_filename_hash (cfg, PS_NAMES_DIR, &nh);
- len = 0;
- if (0 == STAT (fn, &sbuf))
- GNUNET_break (GNUNET_OK == GNUNET_DISK_file_size (fn, &len, GNUNET_YES,
GNUNET_YES));
- fh = GNUNET_DISK_file_open (fn,
- GNUNET_DISK_OPEN_CREATE |
- GNUNET_DISK_OPEN_READWRITE,
- GNUNET_DISK_PERM_USER_READ |
- GNUNET_DISK_PERM_USER_WRITE);
- i = 0;
- idx = -1;
- while ((len >= sizeof (struct GNUNET_PseudonymIdentifier)) &&
- (sizeof (struct GNUNET_PseudonymIdentifier) ==
- GNUNET_DISK_file_read (fh, &pi, sizeof (struct
GNUNET_PseudonymIdentifier))))
- {
- if (0 == memcmp (&pi, pseudonym, sizeof (struct
GNUNET_PseudonymIdentifier)))
- {
- idx = i;
- break;
- }
- i++;
- len -= sizeof (struct GNUNET_HashCode);
- }
- if (-1 == idx)
- {
- idx = i;
- if (sizeof (struct GNUNET_PseudonymIdentifier) !=
- GNUNET_DISK_file_write (fh, pseudonym, sizeof (struct
GNUNET_PseudonymIdentifier)))
- LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "write", fn);
- }
- GNUNET_DISK_file_close (fh);
- ret = GNUNET_malloc (strlen (name) + 32);
- GNUNET_snprintf (ret, strlen (name) + 32, "%s-%u", name, idx);
- if (suffix != NULL)
- *suffix = idx;
- GNUNET_free (fn);
- return ret;
-}
-
-
-/**
- * Get namespace name, metadata and rank
- * This is a wrapper around internal read_info() call, and ensures that
- * returned data is not invalid (not NULL).
- *
- * @param cfg configuration
- * @param pseudonym public key of the pseudonym
- * @param ret_meta a location to store metadata pointer. NULL, if metadata
- * is not needed. Destroy with GNUNET_CONTAINER_meta_data_destroy().
- * @param ret_rank a location to store rank. NULL, if rank not needed.
- * @param ret_name a location to store human-readable name. Name is not unique.
- * NULL, if name is not needed. Free with GNUNET_free().
- * @param name_is_a_dup is set to GNUNET_YES, if ret_name was filled with
- * a duplicate of a "no-name" placeholder
- * @return GNUNET_OK on success. GNUENT_SYSERR if the data was
- * unobtainable (in that case ret_* are filled with placeholders -
- * empty metadata container, rank -1 and a "no-name" name).
- */
-int
-GNUNET_PSEUDONYM_get_info (const struct GNUNET_CONFIGURATION_Handle *cfg,
- const struct GNUNET_PseudonymIdentifier *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;
- int32_t rank = -1;
-
- meta = NULL;
- name = NULL;
- if (GNUNET_OK == read_info (cfg, pseudonym, &meta, &rank, &name))
- {
- if ((meta != NULL) && (name == NULL))
- name =
- GNUNET_CONTAINER_meta_data_get_first_by_types (meta,
-
EXTRACTOR_METATYPE_TITLE,
-
EXTRACTOR_METATYPE_GNUNET_ORIGINAL_FILENAME,
-
EXTRACTOR_METATYPE_FILENAME,
-
EXTRACTOR_METATYPE_DESCRIPTION,
-
EXTRACTOR_METATYPE_SUBJECT,
-
EXTRACTOR_METATYPE_PUBLISHER,
-
EXTRACTOR_METATYPE_AUTHOR_NAME,
-
EXTRACTOR_METATYPE_COMMENT,
-
EXTRACTOR_METATYPE_SUMMARY,
- -1);
- if (ret_name != NULL)
- {
- if (name == NULL)
- {
- name = GNUNET_strdup (_("no-name"));
- if (name_is_a_dup != NULL)
- *name_is_a_dup = GNUNET_YES;
- }
- else if (name_is_a_dup != NULL)
- *name_is_a_dup = GNUNET_NO;
- *ret_name = name;
- }
- else if (name != NULL)
- GNUNET_free (name);
-
- if (ret_meta != NULL)
- {
- if (meta == NULL)
- meta = GNUNET_CONTAINER_meta_data_create ();
- *ret_meta = meta;
- }
- else if (meta != NULL)
- GNUNET_CONTAINER_meta_data_destroy (meta);
-
- if (ret_rank != NULL)
- *ret_rank = rank;
-
- return GNUNET_OK;
- }
- if (ret_name != NULL)
- *ret_name = GNUNET_strdup (_("no-name"));
- if (ret_meta != NULL)
- *ret_meta = GNUNET_CONTAINER_meta_data_create ();
- if (ret_rank != NULL)
- *ret_rank = -1;
- if (name_is_a_dup != NULL)
- *name_is_a_dup = GNUNET_YES;
- return GNUNET_SYSERR;
-}
-
-
-/**
- * Get the namespace ID belonging to the given namespace name.
- *
- * @param cfg configuration to use
- * @param ns_uname unique (!) human-readable name for the namespace
- * @param pseudonym set to public key of pseudonym based on 'ns_uname'
- * @return GNUNET_OK on success, GNUNET_SYSERR on failure
- */
-int
-GNUNET_PSEUDONYM_name_to_id (const struct GNUNET_CONFIGURATION_Handle *cfg,
- const char *ns_uname,
- struct GNUNET_PseudonymIdentifier *pseudonym)
-{
- size_t slen;
- uint64_t len;
- unsigned int idx;
- char *name;
- struct GNUNET_HashCode nh;
- char *fn;
- struct GNUNET_DISK_FileHandle *fh;
-
- idx = -1;
- slen = strlen (ns_uname);
- while ((slen > 0) && (1 != SSCANF (&ns_uname[slen - 1], "-%u", &idx)))
- slen--;
- if (0 == slen)
- return GNUNET_SYSERR;
- name = GNUNET_strdup (ns_uname);
- name[slen - 1] = '\0';
-
- GNUNET_CRYPTO_hash (name, strlen (name), &nh);
- GNUNET_free (name);
- fn = get_data_filename_hash (cfg, PS_NAMES_DIR, &nh);
-
- 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_PseudonymIdentifier) > len))
- {
- GNUNET_free (fn);
- return GNUNET_SYSERR;
- }
- fh = GNUNET_DISK_file_open (fn,
- GNUNET_DISK_OPEN_CREATE |
- GNUNET_DISK_OPEN_READWRITE,
- GNUNET_DISK_PERM_USER_READ |
- GNUNET_DISK_PERM_USER_WRITE);
- GNUNET_free (fn);
- if (GNUNET_SYSERR ==
- GNUNET_DISK_file_seek (fh, idx * sizeof (struct
GNUNET_PseudonymIdentifier),
- GNUNET_DISK_SEEK_SET))
- {
- GNUNET_DISK_file_close (fh);
- return GNUNET_SYSERR;
- }
- if (sizeof (struct GNUNET_PseudonymIdentifier) !=
- GNUNET_DISK_file_read (fh, pseudonym, sizeof (struct
GNUNET_PseudonymIdentifier)))
- {
- GNUNET_DISK_file_close (fh);
- return GNUNET_SYSERR;
- }
- GNUNET_DISK_file_close (fh);
- return GNUNET_OK;
-}
-
-
-
-/**
- * struct used to list the pseudonym
- */
-struct ListPseudonymClosure
-{
-
- /**
- * iterator over pseudonym
- */
- GNUNET_PSEUDONYM_Iterator iterator;
-
- /**
- * Closure for iterator.
- */
- void *iterator_cls;
-
- /**
- * Configuration to use.
- */
- const struct GNUNET_CONFIGURATION_Handle *cfg;
-};
-
-
-
-/**
- * Helper function to list all available pseudonyms
- *
- * @param cls point to a struct ListPseudonymClosure
- * @param fullname name of pseudonym
- */
-static int
-list_pseudonym_helper (void *cls, const char *fullname)
-{
- struct ListPseudonymClosure *lpc = cls;
- struct GNUNET_PseudonymIdentifier pd;
- char *emsg;
- struct GNUNET_BIO_ReadHandle *fileR;
- int32_t rank;
- char *ns_name;
- struct GNUNET_CONTAINER_MetaData *meta;
- int ret;
- char *name_unique;
-
- if (NULL == (fileR = GNUNET_BIO_read_open (fullname)))
- return GNUNET_SYSERR;
- emsg = NULL;
- ns_name = NULL;
- if ( (GNUNET_OK != GNUNET_BIO_read (fileR, "pseudonym", &pd, sizeof (pd))) ||
- (GNUNET_OK != GNUNET_BIO_read_int32 (fileR, &rank)) ||
- (GNUNET_OK !=
- GNUNET_BIO_read_string (fileR, "Read string error!", &ns_name, 200)) ||
- (GNUNET_OK !=
- GNUNET_BIO_read_meta_data (fileR, "Read meta data error!", &meta)) )
- {
- (void) GNUNET_BIO_read_close (fileR, &emsg);
- GNUNET_free_non_null (emsg);
- GNUNET_free_non_null (ns_name);
- GNUNET_break (GNUNET_OK == GNUNET_DISK_directory_remove (fullname));
- return GNUNET_SYSERR;
- }
- if (NULL == ns_name)
- ns_name = GNUNET_strdup (_("no-name"));
- if (GNUNET_OK != GNUNET_BIO_read_close (fileR, &emsg))
- {
- LOG (GNUNET_ERROR_TYPE_WARNING,
- _("Failed to parse metadata about pseudonym from file `%s': %s\n"),
fullname,
- emsg);
- GNUNET_break (GNUNET_OK == GNUNET_DISK_directory_remove (fullname));
- GNUNET_CONTAINER_meta_data_destroy (meta);
- GNUNET_free (ns_name);
- GNUNET_free_non_null (emsg);
- return GNUNET_SYSERR;
- }
- ret = GNUNET_OK;
- name_unique = GNUNET_PSEUDONYM_name_uniquify (lpc->cfg, &pd, ns_name, NULL);
- if (NULL != lpc->iterator)
- ret = lpc->iterator (lpc->iterator_cls, &pd, ns_name, name_unique, meta,
rank);
- GNUNET_free (ns_name);
- GNUNET_free_non_null (name_unique);
- GNUNET_CONTAINER_meta_data_destroy (meta);
- return ret;
-}
-
-
-/**
- * List all available pseudonyms.
- *
- * @param cfg overall configuration
- * @param iterator function to call for each pseudonym
- * @param iterator_cls closure for iterator
- * @return number of pseudonyms found
- */
-int
-GNUNET_PSEUDONYM_list_all (const struct GNUNET_CONFIGURATION_Handle *cfg,
- GNUNET_PSEUDONYM_Iterator iterator,
- void *iterator_cls)
-{
- struct ListPseudonymClosure cls;
- char *fn;
- int ret;
-
- cls.iterator = iterator;
- cls.iterator_cls = iterator_cls;
- cls.cfg = cfg;
- fn = get_data_filename (cfg, PS_METADATA_DIR, NULL);
- GNUNET_assert (fn != NULL);
- GNUNET_DISK_directory_create (fn);
- ret = GNUNET_DISK_directory_scan (fn, &list_pseudonym_helper, &cls);
- GNUNET_free (fn);
- return ret;
-}
-
-
-/**
- * Change the rank of a pseudonym.
- *
- * @param cfg overall configuration
- * @param pseudonym the pseudonym
- * @param delta by how much should the rating be changed?
- * @return new rating of the pseudonym
- */
-int
-GNUNET_PSEUDONYM_rank (const struct GNUNET_CONFIGURATION_Handle *cfg,
- const struct GNUNET_PseudonymIdentifier *pseudonym,
- int32_t delta)
-{
- struct GNUNET_CONTAINER_MetaData *meta;
- int ret;
- int32_t rank;
- char *name;
-
- name = NULL;
- ret = read_info (cfg, pseudonym, &meta, &rank, &name);
- if (ret == GNUNET_SYSERR)
- {
- rank = 0;
- meta = GNUNET_CONTAINER_meta_data_create ();
- }
- rank += delta;
- GNUNET_PSEUDONYM_set_info (cfg, pseudonym, name, meta, rank);
- GNUNET_CONTAINER_meta_data_destroy (meta);
- GNUNET_free_non_null (name);
- return rank;
-}
-
-
-/**
- * Add a pseudonym to the set of known pseudonyms.
- * For all pseudonym advertisements that we discover
- * FS should automatically call this function.
- *
- * @param cfg overall configuration
- * @param pseudonym the pseudonym to add
- * @param meta metadata for the pseudonym
- * @return GNUNET_OK on success, GNUNET_SYSERR on failure
- */
-int
-GNUNET_PSEUDONYM_add (const struct GNUNET_CONFIGURATION_Handle *cfg,
- const struct GNUNET_PseudonymIdentifier *pseudonym,
- const struct GNUNET_CONTAINER_MetaData *meta)
-{
- char *name;
- int32_t rank;
- struct GNUNET_CONTAINER_MetaData *old;
- char *fn;
- struct stat sbuf;
- int ret;
-
- rank = 0;
- fn = get_data_filename (cfg, PS_METADATA_DIR, pseudonym);
- GNUNET_assert (fn != NULL);
-
- if ((0 == STAT (fn, &sbuf)) &&
- (GNUNET_OK == read_info (cfg, pseudonym, &old, &rank, &name)))
- {
- GNUNET_CONTAINER_meta_data_merge (old, meta);
- ret = GNUNET_PSEUDONYM_set_info (cfg, pseudonym, name, old, rank);
- GNUNET_CONTAINER_meta_data_destroy (old);
- GNUNET_free_non_null (name);
- }
- else
- {
- ret = GNUNET_PSEUDONYM_set_info (cfg, pseudonym, NULL, meta, rank);
- }
- GNUNET_free (fn);
- internal_notify (pseudonym, meta, rank);
- return ret;
-}
-
-
-/* ***************************** cryptographic operations
************************* */
-
-/**
- * Handle for a pseudonym (private key).
- */
-struct GNUNET_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_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_PseudonymHandle *
-GNUNET_PSEUDONYM_create (const char *filename)
-{
- struct GNUNET_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_PseudonymHandle));
- if ( (NULL != filename) &&
- (GNUNET_YES == GNUNET_DISK_file_test (filename)) )
- {
- ret = GNUNET_DISK_fn_read (filename, ph,
- sizeof (struct GNUNET_PseudonymHandle));
- /* Note: we don't do any validation here, maybe we should? */
- if (sizeof (struct GNUNET_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 (r_key);
- return NULL;
- }
- /* 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);
-
- /* 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_PseudonymHandle),
- GNUNET_DISK_PERM_USER_READ |
GNUNET_DISK_PERM_USER_WRITE);
- if (sizeof (struct GNUNET_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_PseudonymHandle *
-GNUNET_PSEUDONYM_create_from_existing_file (const char *filename)
-{
- struct GNUNET_PseudonymHandle *ph;
- ssize_t ret;
-
- ph = GNUNET_malloc (sizeof (struct GNUNET_PseudonymHandle));
- ret = GNUNET_DISK_fn_read (filename, ph,
- sizeof (struct GNUNET_PseudonymHandle));
- if (sizeof (struct GNUNET_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_PseudonymHandle *
-GNUNET_PSEUDONYM_get_anonymous_pseudonym_handle ()
-{
- struct GNUNET_PseudonymHandle *ph;
-
- ph = GNUNET_malloc (sizeof (struct GNUNET_PseudonymHandle));
- /* Note if we use 'd=0' for the anonymous handle (as per#2564),
- then I believe the public key should be also zero, as Q=0P=0;
- so setting everything to all-zeros (as per GNUNET_malloc)
- should be all that is needed here).
- */
- return ph;
-}
-
-
-/**
- * Destroy a pseudonym handle. Does NOT remove the private key from
- * the disk.
- *
- * @param ph pseudonym handle to destroy
- */
-void
-GNUNET_PSEUDONYM_destroy (struct GNUNET_PseudonymHandle *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
- * @return converted s-expression
- */
-static gcry_sexp_t
-data_to_pkcs1 (const struct GNUNET_PseudonymSignaturePurpose *purpose)
-{
- struct GNUNET_CRYPTO_ShortHashCode hc;
- size_t bufSize;
- gcry_sexp_t data;
-
- GNUNET_CRYPTO_short_hash (purpose, ntohl (purpose->size), &hc);
-#define FORMATSTRING
"(4:data(5:flags3:raw)(5:value32:01234567890123456789012345678901))"
- bufSize = strlen (FORMATSTRING) + 1;
- {
- char buff[bufSize];
-
- memcpy (buff, FORMATSTRING, bufSize);
- memcpy (&buff
- [bufSize -
- strlen
- ("01234567890123456789012345678901))")
- - 1], &hc, sizeof (struct GNUNET_CRYPTO_ShortHashCode));
- GNUNET_assert (0 == gcry_sexp_new (&data, buff, bufSize, 0));
- }
-#undef FORMATSTRING
- return data;
-}
-
-
-/**
- * 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_PSEUDONYM_sign (struct GNUNET_PseudonymHandle *ph,
- const struct GNUNET_PseudonymSignaturePurpose *purpose,
- const struct GNUNET_HashCode *seed,
- const struct GNUNET_HashCode *signing_key,
- struct GNUNET_PseudonymSignature *signature)
-{
- size_t size;
- size_t erroff;
- gcry_mpi_t x;
- gcry_mpi_t k;
- gcry_mpi_t h;
- gcry_mpi_t d;
- 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 'x' from pseudonym */
- size = sizeof (ph->d);
- if (0 != (rc = gcry_mpi_scan (&x, GCRYMPI_FMT_USG,
- &ph->d,
- size, &size)))
- {
- LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
- return GNUNET_SYSERR;
- }
- /* 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);
- gcry_mpi_release (x);
- 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 (x);
- gcry_mpi_release (h);
- return GNUNET_SYSERR;
- }
-
- /* calculate d = x + h mod n */
- d = gcry_mpi_new (256);
- gcry_mpi_addm (d, x, h, n);
- gcry_mpi_release (x);
- 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)))",
- d)))
- {
- LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
- gcry_mpi_release (d);
- return GNUNET_SYSERR;
- }
- gcry_mpi_release (d);
- /* prepare data for signing */
- data = data_to_pkcs1 (purpose);
-
- /* 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_mpi_release (x);
- 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_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;
- }
- 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;
- }
- gcry_mpi_release (rs[1]);
- 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_PseudonymIdentifier *pseudonym)
-{
- gcry_ctx_t ctx;
- gcry_mpi_t ONE;
- gcry_mpi_t q_x;
- gcry_mpi_t q_y;
- gcry_mpi_point_t q;
- size_t size;
- int rc;
-
- /* extract 'q' from pseudonym */
- 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);
- ONE = gcry_mpi_new (1);
- gcry_mpi_set_ui (ONE, 1);
- gcry_mpi_point_set (q, q_x, q_y, ONE); /* FIXME: convenience function
'set_affine'? */
- gcry_mpi_release (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 (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_PSEUDONYM_verify.
- * @return GNUNET_OK on success, GNUNET_SYSERR on error
- */
-int
-GNUNET_PSEUDONYM_derive_verification_key (struct GNUNET_PseudonymIdentifier
*pseudonym,
- const struct GNUNET_HashCode
*signing_key,
- struct GNUNET_PseudonymIdentifier
*verification_key)
-{
- gcry_mpi_t h;
- size_t size;
- int rc;
- gcry_ctx_t ctx;
- gcry_mpi_point_t g;
- gcry_mpi_point_t q;
- gcry_mpi_point_t hg;
- gcry_mpi_point_t v;
- gcry_mpi_t v_x;
- gcry_mpi_t v_y;
-
- /* 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;
- }
- /* get G */
- g = gcry_mpi_ec_get_point ("g", ctx, 0);
-
- /* then call the 'multiply' function, to compute the product hG */
- hg = gcry_mpi_point_new (0);
- gcry_mpi_ec_mul (hg, h, g, ctx);
- gcry_mpi_release (h);
-
- /* get Q = dG from 'pseudonym' */
- q = gcry_mpi_ec_get_point ("q", ctx, 0);
-
- /* calculate V = q + hG = dG + hG */
- v = gcry_mpi_point_new (0);
- gcry_mpi_ec_add (v, q, hg, ctx);
-
- /* 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_PSEUDONYM_verify (const struct GNUNET_PseudonymSignaturePurpose
*purpose,
- const struct GNUNET_PseudonymSignature *signature,
- const struct GNUNET_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 ONE;
- 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);
-
- /* 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);
- ONE = gcry_mpi_new (1);
- gcry_mpi_set_ui (ONE, 1);
- gcry_mpi_point_set (q, q_x, q_y, ONE); /* FIXME: convenience function
'set_affine'? */
- gcry_mpi_release (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_PSEUDONYM_get_identifier (struct GNUNET_PseudonymHandle *ph,
- struct GNUNET_PseudonymIdentifier *pseudonym)
-{
- memcpy (pseudonym, &ph->public_key,
- sizeof (struct GNUNET_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_PSEUDONYM_remove (const struct GNUNET_CONFIGURATION_Handle *cfg,
- const struct GNUNET_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 */
Deleted: gnunet/src/util/test_pseudonym.c
===================================================================
--- gnunet/src/util/test_pseudonym.c 2013-04-14 18:37:43 UTC (rev 26868)
+++ gnunet/src/util/test_pseudonym.c 2013-04-14 18:45:55 UTC (rev 26869)
@@ -1,323 +0,0 @@
-/*
- This file is part of GNUnet.
- (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
- 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 util/test_pseudonym.c
- * @brief testcase for pseudonym.c
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include "gnunet_common.h"
-#include "gnunet_util_lib.h"
-#include "gnunet_signatures.h"
-
-#define CHECK(a) do { if (!(a)) { ok = GNUNET_NO; GNUNET_break(0); goto
FAILURE; } } while (0)
-
-static struct GNUNET_CONTAINER_MetaData *meta;
-
-static struct GNUNET_PseudonymIdentifier id1;
-
-
-static int
-iter (void *cls, const struct GNUNET_PseudonymIdentifier * 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_PseudonymIdentifier))) &&
- (!GNUNET_CONTAINER_meta_data_test_equal (md, meta)))
- {
- *ok = GNUNET_NO;
- GNUNET_break (0);
- }
- return GNUNET_OK;
-}
-
-
-static int
-noti_callback (void *cls, const struct GNUNET_PseudonymIdentifier * pseudonym,
- const char *name, const char *unique_name,
- const struct GNUNET_CONTAINER_MetaData *md, int32_t rating)
-{
- int *ret = cls;
-
- (*ret)++;
- return GNUNET_OK;
-}
-
-
-static int
-fake_noti_callback (void *cls, const struct GNUNET_PseudonymIdentifier *
pseudonym,
- const char *name, const char *unique_name,
- const struct GNUNET_CONTAINER_MetaData *md, int32_t rating)
-{
- int *ret = cls;
-
- (*ret)++;
- return GNUNET_OK;
-}
-
-
-static void
-create_pseu (struct GNUNET_PseudonymIdentifier *pseu)
-{
- struct GNUNET_PseudonymHandle *ph;
-
- ph = GNUNET_PSEUDONYM_create (NULL);
- GNUNET_PSEUDONYM_get_identifier (ph, pseu);
- GNUNET_PSEUDONYM_destroy (ph);
-}
-
-
-/**
- * Testcase for meta data / ranking IO routines.
- */
-static int
-test_io ()
-{
- int ok;
- struct GNUNET_PseudonymIdentifier rid1;
- struct GNUNET_PseudonymIdentifier id2;
- struct GNUNET_PseudonymIdentifier rid2;
- struct GNUNET_PseudonymIdentifier fid;
- struct GNUNET_PseudonymIdentifier id3;
- int old;
- int newVal;
- struct GNUNET_CONFIGURATION_Handle *cfg;
- char *name1;
- char *name2;
- char *name3;
- char *name1_unique;
- char *name2_unique;
- char *noname;
- int noname_is_a_dup;
- int notiCount, fakenotiCount;
- static char m[1024 * 1024 * 10];
- struct GNUNET_PSEUDONYM_DiscoveryHandle *dh1;
- struct GNUNET_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");
- cfg = GNUNET_CONFIGURATION_create ();
- if (-1 == GNUNET_CONFIGURATION_parse (cfg, "test_pseudonym_data.conf"))
- {
- GNUNET_CONFIGURATION_destroy (cfg);
- GNUNET_break (0);
- return -1;
- }
- notiCount = 0;
- fakenotiCount = 0;
- dh1 = GNUNET_PSEUDONYM_discovery_callback_register (cfg, &fake_noti_callback,
- &fakenotiCount);
- dh2 = GNUNET_PSEUDONYM_discovery_callback_register (cfg, ¬i_callback,
- ¬iCount);
- GNUNET_PSEUDONYM_discovery_callback_unregister (dh1);
-
- /* ACTUAL TEST CODE */
- old = GNUNET_PSEUDONYM_list_all (cfg, NULL, NULL);
- meta = GNUNET_CONTAINER_meta_data_create ();
- GNUNET_CONTAINER_meta_data_insert (meta, "<test>", EXTRACTOR_METATYPE_TITLE,
- EXTRACTOR_METAFORMAT_UTF8, "text/plain",
- "test", strlen ("test") + 1);
- create_pseu (&id1);
- GNUNET_PSEUDONYM_add (cfg, &id1, meta);
- CHECK (notiCount == 1);
- GNUNET_PSEUDONYM_add (cfg, &id1, meta);
- CHECK (notiCount == 2);
- newVal = GNUNET_PSEUDONYM_list_all (cfg, &iter, &ok);
- CHECK (old < newVal);
- old = newVal;
- create_pseu (&id2);
- GNUNET_PSEUDONYM_add (cfg, &id2, meta);
- CHECK (notiCount == 3);
- newVal = GNUNET_PSEUDONYM_list_all (cfg, &iter, &ok);
- CHECK (old < newVal);
- GNUNET_assert (GNUNET_OK ==
- GNUNET_CONTAINER_meta_data_insert (meta, "<test>",
- EXTRACTOR_METATYPE_COMMENT,
- EXTRACTOR_METAFORMAT_UTF8,
- "text/plain", m,
- strlen (m) + 1));
- create_pseu (&id3);
- GNUNET_PSEUDONYM_add (cfg, &id3, meta);
- GNUNET_PSEUDONYM_get_info (cfg, &id3, NULL, NULL, &name3, NULL);
- CHECK (name3 != NULL);
- GNUNET_PSEUDONYM_get_info (cfg, &id2, NULL, NULL, &name2, NULL);
- CHECK (name2 != NULL);
- GNUNET_PSEUDONYM_get_info (cfg, &id1, NULL, NULL, &name1, NULL);
- CHECK (name1 != NULL);
- CHECK (0 == strcmp (name1, name2));
- name1_unique = GNUNET_PSEUDONYM_name_uniquify (cfg, &id1, name1, NULL);
- name2_unique = GNUNET_PSEUDONYM_name_uniquify (cfg, &id2, name2, NULL);
- CHECK (0 != strcmp (name1_unique, name2_unique));
- CHECK (GNUNET_SYSERR == GNUNET_PSEUDONYM_name_to_id (cfg, "fake", &rid2));
- CHECK (GNUNET_SYSERR == GNUNET_PSEUDONYM_name_to_id (cfg, name2, &rid2));
- CHECK (GNUNET_SYSERR == GNUNET_PSEUDONYM_name_to_id (cfg, name1, &rid1));
- CHECK (GNUNET_OK == GNUNET_PSEUDONYM_name_to_id (cfg, name2_unique, &rid2));
- CHECK (GNUNET_OK == GNUNET_PSEUDONYM_name_to_id (cfg, name1_unique, &rid1));
- CHECK (0 == memcmp (&id1, &rid1, sizeof (struct
GNUNET_PseudonymIdentifier)));
- CHECK (0 == memcmp (&id2, &rid2, sizeof (struct
GNUNET_PseudonymIdentifier)));
-
- create_pseu (&fid);
- GNUNET_log_skip (1, GNUNET_NO);
- CHECK (0 == GNUNET_PSEUDONYM_rank (cfg, &fid, 0));
- GNUNET_log_skip (0, GNUNET_NO);
- CHECK (GNUNET_OK == GNUNET_PSEUDONYM_get_info (cfg, &fid, NULL, NULL,
&noname, &noname_is_a_dup));
- CHECK (noname != NULL);
- CHECK (noname_is_a_dup == GNUNET_YES);
- CHECK (0 == GNUNET_PSEUDONYM_rank (cfg, &id1, 0));
- CHECK (5 == GNUNET_PSEUDONYM_rank (cfg, &id1, 5));
- CHECK (-5 == GNUNET_PSEUDONYM_rank (cfg, &id1, -10));
- CHECK (0 == GNUNET_PSEUDONYM_rank (cfg, &id1, 5));
- GNUNET_free (name1);
- GNUNET_free (name2);
- GNUNET_free (name1_unique);
- GNUNET_free (name2_unique);
- GNUNET_free (name3);
- GNUNET_free (noname);
- /* END OF TEST CODE */
-FAILURE:
- GNUNET_PSEUDONYM_discovery_callback_unregister (dh2);
- GNUNET_CONTAINER_meta_data_destroy (meta);
- GNUNET_CONFIGURATION_destroy (cfg);
- return (ok == GNUNET_YES) ? 0 : 1;
-}
-
-
-/**
- * Use the given input to sign and check the resulting signature.
- */
-static void
-test_signature (struct GNUNET_PseudonymHandle *ph,
- struct GNUNET_PseudonymSignaturePurpose *purpose,
- struct GNUNET_HashCode *seed,
- struct GNUNET_HashCode *signing_key,
- char *bit)
-{
- struct GNUNET_PseudonymSignature signature;
- struct GNUNET_PseudonymSignature signature2;
- struct GNUNET_PseudonymIdentifier pseudonym;
- struct GNUNET_PseudonymIdentifier verification_key;
-
- GNUNET_PSEUDONYM_sign (ph, purpose, seed, signing_key, &signature);
- GNUNET_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_PSEUDONYM_get_identifier (ph, &pseudonym);
- GNUNET_PSEUDONYM_derive_verification_key (&pseudonym,
- signing_key,
- &verification_key);
- GNUNET_break (GNUNET_OK ==
- GNUNET_PSEUDONYM_verify (purpose, &signature,
&verification_key));
- /* also check that if the data is changed, the signature no longer matches */
- (*bit)++;
- /* crypto not implemented, thus for now 'break' */
- GNUNET_break (GNUNET_OK !=
- GNUNET_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_PseudonymHandle *ph)
-{
- char data[16];
- struct GNUNET_PseudonymSignaturePurpose *purpose;
- struct GNUNET_HashCode seed;
- struct GNUNET_HashCode signing_key;
-
- memset (data, 42, sizeof (data));
- purpose = (struct GNUNET_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_PseudonymSignaturePurpose)]);
- test_signature (ph, purpose, NULL, &signing_key, &data[sizeof (struct
GNUNET_PseudonymSignaturePurpose)]);
-}
-
-
-/**
- * Test cryptographic operations.
- */
-static int
-test_crypto ()
-{
- struct GNUNET_PseudonymHandle *ph;
- struct GNUNET_PseudonymIdentifier pseudonym;
- struct GNUNET_PseudonymIdentifier pseudonym2;
-
- /* check writing to and reading from disk */
- ph = GNUNET_PSEUDONYM_create ("/tmp/gnunet-pseudonym-test/pseu.dsa");
- GNUNET_PSEUDONYM_get_identifier (ph, &pseudonym);
- GNUNET_PSEUDONYM_destroy (ph);
- ph = GNUNET_PSEUDONYM_create ("/tmp/gnunet-pseudonym-test/pseu.dsa");
- GNUNET_PSEUDONYM_get_identifier (ph, &pseudonym2);
- test_crypto_ops (ph);
- GNUNET_PSEUDONYM_destroy (ph);
- if (0 != memcmp (&pseudonym, &pseudonym2, sizeof (pseudonym)))
- return 1;
-
- /* check in-memory generation */
- ph = GNUNET_PSEUDONYM_create (NULL);
- GNUNET_PSEUDONYM_get_identifier (ph, &pseudonym2);
- if (0 == memcmp (&pseudonym, &pseudonym2, sizeof (pseudonym)))
- return 1;
- test_crypto_ops (ph);
- GNUNET_PSEUDONYM_destroy (ph);
-
- /* check anonymous pseudonym operations generation */
- ph = GNUNET_PSEUDONYM_get_anonymous_pseudonym_handle ();
- GNUNET_PSEUDONYM_get_identifier (ph, &pseudonym2);
- if (0 == memcmp (&pseudonym, &pseudonym2, sizeof (pseudonym)))
- return 1;
- test_crypto_ops (ph);
- GNUNET_PSEUDONYM_destroy (ph);
- return 0;
-}
-
-
-int
-main (int argc, char *argv[])
-{
- 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;
-}
-
-
-/* end of test_pseudoynm.c */
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r26869 - in gnunet/src: . fs include util,
gnunet <=