-round expiration times to full seconds
[oweals/gnunet.git] / src / fs / fs_pseudonym.c
index 3f0c6b6c700605fa569eca6f4f6a831168412b8e..2600e51eb4da87235002d40e9b0595389538b82f 100644 (file)
@@ -1,10 +1,10 @@
 /*
      This file is part of GNUnet
-     (C) 2003, 2004, 2005, 2006, 2007, 2008, 2013 Christian Grothoff (and other contributing authors)
+     (C) 2003-2013 Christian Grothoff (and other contributing authors)
 
      GNUnet is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published
-     by the Free Software Foundation; either version 2, or (at your
+     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
 */
 /**
  * @file fs/fs_pseudonym.c
- * @brief pseudonym functions
+ * @brief pseudonym functions; these functions are about namespaces
+ *        managed by other users; we might want to eliminate this
+ *        entire API and instead manage pseudonyms only via GNS
  * @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_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
 /**
  * Registered callbacks for discovery of pseudonyms.
  */
-struct GNUNET_FS_pseudonym_DiscoveryHandle
+struct GNUNET_FS_Pseudonym_DiscoveryHandle
 {
   /**
    * This is a doubly linked list.
    */
-  struct GNUNET_FS_pseudonym_DiscoveryHandle *next;
+  struct GNUNET_FS_Pseudonym_DiscoveryHandle *next;
 
   /**
    * This is a doubly linked list.
    */
-  struct GNUNET_FS_pseudonym_DiscoveryHandle *prev;
+  struct GNUNET_FS_Pseudonym_DiscoveryHandle *prev;
 
   /**
    * Function to call each time a pseudonym is discovered.
@@ -95,20 +86,14 @@ struct GNUNET_FS_pseudonym_DiscoveryHandle
  * Head of the linked list of functions to call when
  * new pseudonyms are added.
  */
-static struct GNUNET_FS_pseudonym_DiscoveryHandle *disco_head;
+static struct GNUNET_FS_Pseudonym_DiscoveryHandle *disco_head;
 
 /**
  * Tail of the linked list of functions to call when
  * new pseudonyms are added.
  */
-static struct GNUNET_FS_pseudonym_DiscoveryHandle *disco_tail;
+static struct GNUNET_FS_Pseudonym_DiscoveryHandle *disco_tail;
 
-/**
- * Pointer to indiate 'anonymous' pseudonym (global static, all
- * zeros).  We actually use pointer comparisson to detect the
- * "anonymous" pseudonym handle.
- */
-static struct GNUNET_FS_PseudonymHandle anonymous;
 
 /**
  * Internal notification about new tracked URI.
@@ -118,10 +103,10 @@ static struct GNUNET_FS_PseudonymHandle anonymous;
  * @param rating rating of pseudonym
  */
 static void
-internal_notify (const struct GNUNET_FS_PseudonymIdentifier *pseudonym,
+internal_notify (const struct GNUNET_CRYPTO_EccPublicKey *pseudonym,
                  const struct GNUNET_CONTAINER_MetaData *md, int rating)
 {
-  struct GNUNET_FS_pseudonym_DiscoveryHandle *pos;
+  struct GNUNET_FS_Pseudonym_DiscoveryHandle *pos;
 
   for (pos = disco_head; NULL != pos; pos = pos->next)
     pos->callback (pos->callback_cls, pseudonym, NULL, NULL, md, rating);
@@ -139,15 +124,15 @@ internal_notify (const struct GNUNET_FS_PseudonymIdentifier *pseudonym,
  * @param iterator_cls point to a closure
  * @return registration handle
  */
-struct GNUNET_FS_pseudonym_DiscoveryHandle *
+struct GNUNET_FS_Pseudonym_DiscoveryHandle *
 GNUNET_FS_pseudonym_discovery_callback_register (const struct
-                                             GNUNET_CONFIGURATION_Handle *cfg,
-                                              GNUNET_FS_PseudonymIterator iterator, 
-                                             void *iterator_cls)
+                                                GNUNET_CONFIGURATION_Handle *cfg,
+                                                GNUNET_FS_PseudonymIterator iterator, 
+                                                void *iterator_cls)
 {
-  struct GNUNET_FS_pseudonym_DiscoveryHandle *dh;
+  struct GNUNET_FS_Pseudonym_DiscoveryHandle *dh;
 
-  dh = GNUNET_malloc (sizeof (struct GNUNET_FS_pseudonym_DiscoveryHandle));
+  dh = GNUNET_new (struct GNUNET_FS_Pseudonym_DiscoveryHandle);
   dh->callback = iterator;
   dh->callback_cls = iterator_cls;
   GNUNET_CONTAINER_DLL_insert (disco_head, disco_tail, dh);
@@ -162,7 +147,7 @@ GNUNET_FS_pseudonym_discovery_callback_register (const struct
  * @param dh registration to unregister
  */
 void
-GNUNET_FS_pseudonym_discovery_callback_unregister (struct GNUNET_FS_pseudonym_DiscoveryHandle *dh)
+GNUNET_FS_pseudonym_discovery_callback_unregister (struct GNUNET_FS_Pseudonym_DiscoveryHandle *dh)
 {
   GNUNET_CONTAINER_DLL_remove (disco_head, disco_tail, dh);
   GNUNET_free (dh);
@@ -181,7 +166,7 @@ GNUNET_FS_pseudonym_discovery_callback_unregister (struct GNUNET_FS_pseudonym_Di
 static char *
 get_data_filename (const struct GNUNET_CONFIGURATION_Handle *cfg,
                    const char *prefix, 
-                  const struct GNUNET_FS_PseudonymIdentifier *pseudonym)
+                  const struct GNUNET_CRYPTO_EccPublicKey *pseudonym)
 {
   struct GNUNET_CRYPTO_HashAsciiEncoded enc;
   struct GNUNET_HashCode psid;
@@ -189,7 +174,7 @@ get_data_filename (const struct GNUNET_CONFIGURATION_Handle *cfg,
   if (NULL != pseudonym)
   {
     GNUNET_CRYPTO_hash (pseudonym,
-                       sizeof (struct GNUNET_FS_PseudonymIdentifier),
+                       sizeof (struct GNUNET_CRYPTO_EccPublicKey),
                        &psid);
     GNUNET_CRYPTO_hash_to_enc (&psid, &enc);
   }
@@ -244,7 +229,7 @@ get_data_filename_hash (const struct GNUNET_CONFIGURATION_Handle *cfg,
  */
 int
 GNUNET_FS_pseudonym_set_info (const struct GNUNET_CONFIGURATION_Handle *cfg,
-                          const struct GNUNET_FS_PseudonymIdentifier *pseudonym,
+                          const struct GNUNET_CRYPTO_EccPublicKey *pseudonym,
                           const char *name,
                           const struct GNUNET_CONTAINER_MetaData *md, 
                           int32_t rank)
@@ -259,7 +244,7 @@ GNUNET_FS_pseudonym_set_info (const struct GNUNET_CONFIGURATION_Handle *cfg,
     return GNUNET_SYSERR;
   }
   if ((GNUNET_OK != GNUNET_BIO_write (fileW, pseudonym, 
-                                     sizeof (struct GNUNET_FS_PseudonymIdentifier))) ||
+                                     sizeof (struct GNUNET_CRYPTO_EccPublicKey))) ||
       (GNUNET_OK != GNUNET_BIO_write_int32 (fileW, rank)) ||
       (GNUNET_OK != GNUNET_BIO_write_string (fileW, name)) ||
       (GNUNET_OK != GNUNET_BIO_write_meta_data (fileW, md)))
@@ -296,12 +281,12 @@ GNUNET_FS_pseudonym_set_info (const struct GNUNET_CONFIGURATION_Handle *cfg,
  */
 static int
 read_info (const struct GNUNET_CONFIGURATION_Handle *cfg,
-           const struct GNUNET_FS_PseudonymIdentifier *pseudonym,
+           const struct GNUNET_CRYPTO_EccPublicKey *pseudonym,
            struct GNUNET_CONTAINER_MetaData **meta,
           int32_t *rank,
            char **ns_name)
 {
-  struct GNUNET_FS_PseudonymIdentifier pd;
+  struct GNUNET_CRYPTO_EccPublicKey pd;
   char *fn;
   char *emsg;
   struct GNUNET_BIO_ReadHandle *fileR;
@@ -368,12 +353,12 @@ read_info (const struct GNUNET_CONFIGURATION_Handle *cfg,
  */
 char *
 GNUNET_FS_pseudonym_name_uniquify (const struct GNUNET_CONFIGURATION_Handle *cfg,
-                               const struct GNUNET_FS_PseudonymIdentifier *pseudonym,
+                               const struct GNUNET_CRYPTO_EccPublicKey *pseudonym,
                                const char *name,
                                unsigned int *suffix)
 {
   struct GNUNET_HashCode nh;
-  struct GNUNET_FS_PseudonymIdentifier pi;
+  struct GNUNET_CRYPTO_EccPublicKey pi;
   uint64_t len;
   char *fn;
   struct GNUNET_DISK_FileHandle *fh;
@@ -394,11 +379,11 @@ GNUNET_FS_pseudonym_name_uniquify (const struct GNUNET_CONFIGURATION_Handle *cfg
                               GNUNET_DISK_PERM_USER_WRITE);
   i = 0;
   idx = -1;
-  while ((len >= sizeof (struct GNUNET_FS_PseudonymIdentifier)) &&
-         (sizeof (struct GNUNET_FS_PseudonymIdentifier) ==
-          GNUNET_DISK_file_read (fh, &pi, sizeof (struct GNUNET_FS_PseudonymIdentifier))))
+  while ((len >= sizeof (struct GNUNET_CRYPTO_EccPublicKey)) &&
+         (sizeof (struct GNUNET_CRYPTO_EccPublicKey) ==
+          GNUNET_DISK_file_read (fh, &pi, sizeof (struct GNUNET_CRYPTO_EccPublicKey))))
   {
-    if (0 == memcmp (&pi, pseudonym, sizeof (struct GNUNET_FS_PseudonymIdentifier)))
+    if (0 == memcmp (&pi, pseudonym, sizeof (struct GNUNET_CRYPTO_EccPublicKey)))
     {
       idx = i;
       break;
@@ -409,8 +394,9 @@ GNUNET_FS_pseudonym_name_uniquify (const struct GNUNET_CONFIGURATION_Handle *cfg
   if (-1 == idx)
   {
     idx = i;
-    if (sizeof (struct GNUNET_FS_PseudonymIdentifier) !=
-        GNUNET_DISK_file_write (fh, pseudonym, sizeof (struct GNUNET_FS_PseudonymIdentifier)))
+    if (sizeof (struct GNUNET_CRYPTO_EccPublicKey) !=
+        GNUNET_DISK_file_write (fh, pseudonym, 
+                               sizeof (struct GNUNET_CRYPTO_EccPublicKey)))
       LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "write", fn);
   }
   GNUNET_DISK_file_close (fh);
@@ -443,11 +429,11 @@ GNUNET_FS_pseudonym_name_uniquify (const struct GNUNET_CONFIGURATION_Handle *cfg
  */
 int
 GNUNET_FS_pseudonym_get_info (const struct GNUNET_CONFIGURATION_Handle *cfg,
-                          const struct GNUNET_FS_PseudonymIdentifier *pseudonym, 
-                          struct GNUNET_CONTAINER_MetaData **ret_meta,
-                          int32_t *ret_rank, 
-                          char **ret_name, 
-                          int *name_is_a_dup)
+                             const struct GNUNET_CRYPTO_EccPublicKey *pseudonym, 
+                             struct GNUNET_CONTAINER_MetaData **ret_meta,
+                             int32_t *ret_rank, 
+                             char **ret_name, 
+                             int *name_is_a_dup)
 {
   struct GNUNET_CONTAINER_MetaData *meta;
   char *name;
@@ -521,8 +507,8 @@ GNUNET_FS_pseudonym_get_info (const struct GNUNET_CONFIGURATION_Handle *cfg,
  */
 int
 GNUNET_FS_pseudonym_name_to_id (const struct GNUNET_CONFIGURATION_Handle *cfg,
-                            const char *ns_uname, 
-                            struct GNUNET_FS_PseudonymIdentifier *pseudonym)
+                               const char *ns_uname, 
+                               struct GNUNET_CRYPTO_EccPublicKey *pseudonym)
 {
   size_t slen;
   uint64_t len;
@@ -547,7 +533,7 @@ GNUNET_FS_pseudonym_name_to_id (const struct GNUNET_CONFIGURATION_Handle *cfg,
 
   if ((GNUNET_OK != GNUNET_DISK_file_test (fn) ||
        (GNUNET_OK != GNUNET_DISK_file_size (fn, &len, GNUNET_YES, GNUNET_YES))) ||
-      ((idx + 1) * sizeof (struct GNUNET_FS_PseudonymIdentifier) > len))
+      ((idx + 1) * sizeof (struct GNUNET_CRYPTO_EccPublicKey) > len))
   {
     GNUNET_free (fn);
     return GNUNET_SYSERR;
@@ -559,14 +545,15 @@ GNUNET_FS_pseudonym_name_to_id (const struct GNUNET_CONFIGURATION_Handle *cfg,
                               GNUNET_DISK_PERM_USER_WRITE);
   GNUNET_free (fn);
   if (GNUNET_SYSERR ==
-      GNUNET_DISK_file_seek (fh, idx * sizeof (struct GNUNET_FS_PseudonymIdentifier),
+      GNUNET_DISK_file_seek (fh, idx * sizeof (struct GNUNET_CRYPTO_EccPublicKey),
                             GNUNET_DISK_SEEK_SET))
   {
     GNUNET_DISK_file_close (fh);
     return GNUNET_SYSERR;
   }
-  if (sizeof (struct GNUNET_FS_PseudonymIdentifier) !=
-      GNUNET_DISK_file_read (fh, pseudonym, sizeof (struct GNUNET_FS_PseudonymIdentifier)))
+  if (sizeof (struct GNUNET_CRYPTO_EccPublicKey) !=
+      GNUNET_DISK_file_read (fh, pseudonym, 
+                            sizeof (struct GNUNET_CRYPTO_EccPublicKey)))
   {
     GNUNET_DISK_file_close (fh);
     return GNUNET_SYSERR;
@@ -576,7 +563,6 @@ GNUNET_FS_pseudonym_name_to_id (const struct GNUNET_CONFIGURATION_Handle *cfg,
 }
 
 
-
 /**
  * struct used to list the pseudonym
  */
@@ -611,7 +597,7 @@ static int
 list_pseudonym_helper (void *cls, const char *fullname)
 {
   struct ListPseudonymClosure *lpc = cls;
-  struct GNUNET_FS_PseudonymIdentifier pd;
+  struct GNUNET_CRYPTO_EccPublicKey pd;
   char *emsg;
   struct GNUNET_BIO_ReadHandle *fileR;
   int32_t rank;
@@ -671,8 +657,8 @@ list_pseudonym_helper (void *cls, const char *fullname)
  */
 int
 GNUNET_FS_pseudonym_list_all (const struct GNUNET_CONFIGURATION_Handle *cfg,
-                           GNUNET_FS_PseudonymIterator iterator, 
-                          void *iterator_cls)
+                             GNUNET_FS_PseudonymIterator iterator, 
+                             void *iterator_cls)
 {
   struct ListPseudonymClosure cls;
   char *fn;
@@ -700,8 +686,8 @@ GNUNET_FS_pseudonym_list_all (const struct GNUNET_CONFIGURATION_Handle *cfg,
  */
 int
 GNUNET_FS_pseudonym_rank (const struct GNUNET_CONFIGURATION_Handle *cfg,
-                       const struct GNUNET_FS_PseudonymIdentifier *pseudonym, 
-                      int32_t delta)
+                         const struct GNUNET_CRYPTO_EccPublicKey *pseudonym, 
+                         int32_t delta)
 {
   struct GNUNET_CONTAINER_MetaData *meta;
   int ret;
@@ -735,8 +721,8 @@ GNUNET_FS_pseudonym_rank (const struct GNUNET_CONFIGURATION_Handle *cfg,
  */
 int
 GNUNET_FS_pseudonym_add (const struct GNUNET_CONFIGURATION_Handle *cfg,
-                      const struct GNUNET_FS_PseudonymIdentifier *pseudonym,
-                      const struct GNUNET_CONTAINER_MetaData *meta)
+                        const struct GNUNET_CRYPTO_EccPublicKey *pseudonym,
+                        const struct GNUNET_CONTAINER_MetaData *meta)
 {
   char *name;
   int32_t rank;
@@ -767,787 +753,4 @@ GNUNET_FS_pseudonym_add (const struct GNUNET_CONFIGURATION_Handle *cfg,
 }
 
 
-/* ***************************** cryptographic operations ************************* */
-
-/**
- * Handle for a pseudonym (private key).
- */
-struct GNUNET_FS_PseudonymHandle
-{
-  /**
-   * 256-bit 'd' secret value (mod 'n', where n is 256-bit for NIST P-256).
-   */
-  unsigned char d[256 / 8];
-
-  /**
-   * Public key corresponding to the private key.
-   */
-  struct GNUNET_FS_PseudonymIdentifier public_key;
-};
-
-
-/**
- * If target != size, move target bytes to the end of the size-sized
- * buffer and zero out the first target-size bytes.
- *
- * @param buf original buffer
- * @param size number of bytes in the buffer
- * @param target target size of the buffer
- */
-static void
-adjust (unsigned char *buf, size_t size, size_t target)
-{
-  if (size < target)
-  {
-    memmove (&buf[target - size], buf, size);
-    memset (buf, 0, target - size);
-  }
-}
-
-
-/**
- * Extract values from an S-expression.
- *
- * @param array where to store the result(s)
- * @param sexp S-expression to parse
- * @param topname top-level name in the S-expression that is of interest
- * @param elems names of the elements to extract
- * @return 0 on success
- */
-static int
-key_from_sexp (gcry_mpi_t * array, gcry_sexp_t sexp, const char *topname,
-               const char *elems)
-{
-  gcry_sexp_t list;
-  gcry_sexp_t l2;
-  const char *s;
-  unsigned int i;
-  unsigned int idx;
-
-  if (! (list = gcry_sexp_find_token (sexp, topname, 0)))
-    return 1;  
-  l2 = gcry_sexp_cadr (list);
-  gcry_sexp_release (list);
-  list = l2;
-  if (! list)  
-    return 2;
-  idx = 0;
-  for (s = elems; *s; s++, idx++)
-  {
-    if (! (l2 = gcry_sexp_find_token (list, s, 1)))
-    {
-      for (i = 0; i < idx; i++)
-      {
-        gcry_free (array[i]);
-        array[i] = NULL;
-      }
-      gcry_sexp_release (list);
-      return 3;                 /* required parameter not found */
-    }
-    array[idx] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
-    gcry_sexp_release (l2);
-    if (! array[idx])
-    {
-      for (i = 0; i < idx; i++)
-      {
-        gcry_free (array[i]);
-        array[i] = NULL;
-      }
-      gcry_sexp_release (list);
-      return 4;                 /* required parameter is invalid */
-    }
-  }
-  gcry_sexp_release (list);
-  return 0;
-}
-
-
-/**
- * Create a pseudonym.
- *
- * @param filename name of the file to use for storage, NULL for in-memory only
- * @return handle to the private key of the pseudonym
- */
-struct GNUNET_FS_PseudonymHandle *
-GNUNET_FS_pseudonym_create (const char *filename)
-{
-  struct GNUNET_FS_PseudonymHandle *ph;
-  ssize_t ret;
-  gcry_sexp_t r_key;
-  gcry_sexp_t params;
-  gcry_ctx_t ctx;
-  gcry_mpi_point_t q;
-  gcry_mpi_t q_x;
-  gcry_mpi_t q_y;
-  gcry_error_t rc;
-  gcry_mpi_t d;
-  size_t size;
-
-  ph = GNUNET_malloc (sizeof (struct GNUNET_FS_PseudonymHandle));
-  if ( (NULL != filename) &&
-       (GNUNET_YES == GNUNET_DISK_file_test (filename)) )
-  {
-    ret = GNUNET_DISK_fn_read (filename, ph, 
-                              sizeof (struct GNUNET_FS_PseudonymHandle));
-    /* Note: we don't do any validation here, maybe we should? */
-    if (sizeof (struct GNUNET_FS_PseudonymHandle) == ret)
-      return ph;
-  }  
-  if (0 != (rc = gcry_sexp_build (&params, NULL,
-                                  "(genkey(ecdsa(curve \"NIST P-256\")))")))
-  {
-    LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
-    return NULL;
-  }
-  if (0 != (rc = gcry_pk_genkey (&r_key, params)))
-  {
-    LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_pk_genkey", rc);
-    gcry_sexp_release (params);
-    gcry_sexp_release (r_key);
-    return NULL;
-  }
-  gcry_sexp_release (params);
-  /* extract "d" (secret key) from r_key */
-  rc = key_from_sexp (&d, r_key, "private-key", "d");
-  if (0 != rc)
-    rc = key_from_sexp (&d, r_key, "private-key", "d");
-  if (0 != rc)
-    rc = key_from_sexp (&d, r_key, "ecc", "d");
-  if (0 != rc)
-  {
-    gcry_sexp_release (r_key);
-    LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "key_from_sexp", rc);
-    return NULL;
-  }
-  size = sizeof (ph->d);
-  GNUNET_assert (0 ==
-                 gcry_mpi_print (GCRYMPI_FMT_USG, ph->d, size, &size,
-                                 d));
-  gcry_mpi_release (d);
-  adjust (ph->d, size, sizeof (ph->d));
-
-  /* extract 'q' (public key) from r_key */
-  if (0 != (rc = gcry_mpi_ec_new (&ctx, r_key, NULL)))
-  {
-    LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_ec_new", rc);  /* erroff gives more info */
-    gcry_sexp_release (r_key);
-    return NULL;
-  }  
-  gcry_sexp_release (r_key);
-  q = gcry_mpi_ec_get_point ("q", ctx, 0);
-  q_x = gcry_mpi_new (256);
-  q_y = gcry_mpi_new (256);
-  gcry_mpi_ec_get_affine (q_x, q_y, q, ctx);
-  gcry_mpi_point_release (q);
-  gcry_ctx_release (ctx);
-
-  /* store q_x/q_y in public key */
-  size = sizeof (ph->public_key.q_x);  
-  if (0 !=
-      gcry_mpi_print (GCRYMPI_FMT_USG, ph->public_key.q_x, size, &size,
-                     q_x))
-  {
-    LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_print", rc);
-    gcry_mpi_release (q_x);
-    gcry_mpi_release (q_y);
-    return NULL;
-
-  }
-  adjust (ph->public_key.q_x, size, sizeof (ph->public_key.q_x));
-  gcry_mpi_release (q_x);
-
-  size = sizeof (ph->public_key.q_y);  
-  if (0 !=
-      gcry_mpi_print (GCRYMPI_FMT_USG, ph->public_key.q_y, size, &size,
-                     q_y))
-  {
-    LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_print", rc);
-    gcry_mpi_release (q_y);
-    return NULL;
-  }
-  adjust (ph->public_key.q_y, size, sizeof (ph->public_key.q_y));
-  gcry_mpi_release (q_y);
-
-  /* write to disk */
-  if (NULL != filename)
-  {
-    ret = GNUNET_DISK_fn_write (filename, ph, sizeof (struct GNUNET_FS_PseudonymHandle),
-                               GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE);
-    if (sizeof (struct GNUNET_FS_PseudonymHandle) != ret)
-    {
-      GNUNET_free (ph);
-      return NULL;
-    }
-  }
-  return ph;
-}
-
-
-/**
- * Create a pseudonym, from a file that must already exist.
- *
- * @param filename name of the file to use for storage, NULL for in-memory only
- * @return handle to the private key of the pseudonym
- */
-struct GNUNET_FS_PseudonymHandle *
-GNUNET_FS_pseudonym_create_from_existing_file (const char *filename)
-{
-  struct GNUNET_FS_PseudonymHandle *ph;
-  ssize_t ret;
-
-  ph = GNUNET_malloc (sizeof (struct GNUNET_FS_PseudonymHandle));
-  ret = GNUNET_DISK_fn_read (filename, ph, 
-                            sizeof (struct GNUNET_FS_PseudonymHandle));
-  if (sizeof (struct GNUNET_FS_PseudonymHandle) != ret)
-  {
-    GNUNET_free (ph);
-    return NULL;
-  }
-  /* Note: we don't do any validation here; maybe we should? */
-  return ph;
-}
-
-
-/**
- * Get the handle for the 'anonymous' pseudonym shared by all users.
- * That pseudonym uses a fixed 'secret' for the private key; this
- * construction is useful to make anonymous and pseudonymous APIs
- * (and packets) indistinguishable on the network.  See #2564.
- *
- * @return handle to the (non-secret) private key of the 'anonymous' pseudonym
- */
-struct GNUNET_FS_PseudonymHandle *
-GNUNET_FS_pseudonym_get_anonymous_pseudonym_handle ()
-{
-  return &anonymous;
-}
-
-
-/**
- * Destroy a pseudonym handle.  Does NOT remove the private key from
- * the disk.
- *
- * @param ph pseudonym handle to destroy
- */
-void
-GNUNET_FS_pseudonym_destroy (struct GNUNET_FS_PseudonymHandle *ph)
-{
-  if (&anonymous != ph)
-    GNUNET_free (ph);
-}
-
-
-/**
- * Convert the data specified in the given purpose argument to an
- * S-expression suitable for signature operations.
- *
- * @param purpose data to convert
- * @return converted s-expression
- */
-static gcry_sexp_t
-data_to_pkcs1 (const struct GNUNET_FS_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 'd' used for signing (corresponds to 'x' in #2564)
- * @param purpose data to sign
- * @param seed hash of the plaintext of the data that we are signing, 
- *             used for deterministic PRNG for anonymous signing;
- *             corresponds to 'k' in section 2.7 of #2564
- * @param signing_key modifier to apply to the private key for signing ('h');
- *                    see section 2.3 of #2564.
- * @param signature where to store the signature
- * @return GNUNET_SYSERR on failure
- */
-int 
-GNUNET_FS_pseudonym_sign (struct GNUNET_FS_PseudonymHandle *ph,
-                         const struct GNUNET_FS_PseudonymSignaturePurpose *purpose,
-                         const struct GNUNET_HashCode *seed,
-                         const struct GNUNET_HashCode *signing_key,
-                         struct GNUNET_FS_PseudonymSignature *signature)
-{
-  size_t size;
-  size_t erroff;
-  gcry_mpi_t d;
-  gcry_mpi_t k;
-  gcry_mpi_t h;
-  gcry_mpi_t dh;
-  gcry_mpi_t n; /* n from P-256 */
-  gcry_sexp_t spriv;
-  gcry_sexp_t data;
-  gcry_sexp_t result;
-  gcry_mpi_t rs[2];
-  int rc;
-
-  /* get private key 'd' from pseudonym */
-  if (&anonymous == ph)
-  {
-    d = gcry_mpi_new (0);
-    gcry_mpi_set_ui (d, 0);
-  }
-  else
-  {
-    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);
-  
-  /* 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_FS_PseudonymSignature));
-    return GNUNET_SYSERR;
-  }
-  if (NULL != seed)
-    gcry_mpi_release (k);
-  gcry_sexp_release (data);
-  gcry_sexp_release (spriv);
-
-
-  /* extract 'r' and 's' values from sexpression 'result' and store in 'signature' */
-  if (0 != (rc = key_from_sexp (rs, result, "sig-val", "rs")))
-  {
-    GNUNET_break (0);
-    gcry_sexp_release (result);
-    return GNUNET_SYSERR;
-  }
-  gcry_sexp_release (result);
-  size = sizeof (signature->sig_r);
-  if (0 != (rc = gcry_mpi_print (GCRYMPI_FMT_USG, signature->sig_r, size,
-                                 &size, rs[0])))
-  {
-    LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_print", rc);
-    gcry_mpi_release (rs[0]);
-    gcry_mpi_release (rs[1]);
-    return GNUNET_SYSERR;
-  }
-
-  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]);
-  GNUNET_FS_pseudonym_get_identifier (ph, &signature->signer);
-  return GNUNET_OK;
-}
-
-
-/**
- * Get an ECC context (with Q set to the respective public key) from
- * a pseudonym.
- *
- * @param pseudonym with information on 'q'
- * @return curve context
- */
-static gcry_ctx_t 
-get_context_from_pseudonym (struct GNUNET_FS_PseudonymIdentifier *pseudonym)
-{
-  static struct GNUNET_FS_PseudonymIdentifier zerop;
-  gcry_ctx_t ctx;
-  gcry_mpi_t q_x;
-  gcry_mpi_t q_y;
-  gcry_mpi_t zero;
-  gcry_mpi_point_t q;
-  size_t size;
-  int rc;
-
-  /* extract 'q' from pseudonym */
-  if (0 == memcmp (pseudonym, &zerop, sizeof (zerop)))
-  {
-    /* create basic ECC context */
-    if (0 != (rc = gcry_mpi_ec_new (&ctx, NULL, "NIST P-256")))
-    {
-      LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_ec_new", rc);  /* erroff gives more info */
-      return NULL;
-    }  
-    /* initialize 'ctx' with 'q' = 0 */
-    zero = gcry_mpi_new (0);
-    gcry_mpi_set_ui (zero, 0);
-    q = gcry_mpi_point_new (0);
-    gcry_mpi_point_set (q, zero, zero, zero);
-    gcry_mpi_ec_set_point ("q", q, ctx);
-    gcry_mpi_release (zero);
-    gcry_mpi_point_release (q);
-    return ctx;
-  }
-  size = sizeof (pseudonym->q_x);
-  if (0 != (rc = gcry_mpi_scan (&q_x, GCRYMPI_FMT_USG, pseudonym->q_x, size, &size)))
-  {
-    LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
-    return NULL;
-  }
-  size = sizeof (pseudonym->q_y);
-  if (0 != (rc = gcry_mpi_scan (&q_y, GCRYMPI_FMT_USG, pseudonym->q_y, size, &size)))
-  {
-    LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
-    gcry_mpi_release (q_x);
-    return NULL;
-  }
-  q = gcry_mpi_point_new (256);
-  gcry_mpi_point_set (q, q_x, q_y, GCRYMPI_CONST_ONE);
-  gcry_mpi_release (q_x);
-  gcry_mpi_release (q_y);
-
-  /* create basic ECC context */
-  if (0 != (rc = gcry_mpi_ec_new (&ctx, NULL, "NIST P-256")))
-  {
-    LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_ec_new", rc);  /* erroff gives more info */
-    gcry_mpi_point_release (q);
-    return NULL;
-  }  
-  /* initialize 'ctx' with 'q' */
-  gcry_mpi_ec_set_point ("q", q, ctx);
-  gcry_mpi_point_release (q);
-  return ctx;
-}
-
-
-/**
- * Given a pseudonym and a signing key, derive the corresponding public
- * key that would be used to verify the resulting signature.
- *
- * @param pseudonym the public key (dQ in ECDSA)
- * @param signing_key input to derive 'h' (see section 2.4 of #2564)
- * @param verification_key resulting public key to verify the signature
- *        created from the '(d+h)' of 'pseudonym' and the 'signing_key';
- *        the value stored here can then be given to GNUNET_FS_pseudonym_verify.
- * @return GNUNET_OK on success, GNUNET_SYSERR on error
- */
-int
-GNUNET_FS_pseudonym_derive_verification_key (struct GNUNET_FS_PseudonymIdentifier *pseudonym,
-                                            const struct GNUNET_HashCode *signing_key,
-                                            struct GNUNET_FS_PseudonymIdentifier *verification_key)
-{
-  gcry_mpi_t h;  
-  size_t size;
-  int rc;
-  gcry_ctx_t ctx;
-  gcry_mpi_point_t 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_point_release (g);
-  gcry_mpi_release (h);
-
-  /* get Q = dG from 'pseudonym' */
-  q = gcry_mpi_ec_get_point ("q", ctx, 0);
-  /* calculate V = Q + hG = dG + hG = (d + h)G*/
-  v = gcry_mpi_point_new (0);
-  gcry_mpi_ec_add (v, q, hg, ctx);
-  gcry_mpi_point_release (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, ctx);
-
-  gcry_mpi_point_release (v);
-  gcry_ctx_release (ctx);
-
-  size = sizeof (verification_key->q_x);
-  if (0 != (rc = gcry_mpi_print (GCRYMPI_FMT_USG, verification_key->q_x, size,
-                                 &size, v_x)))
-  {
-    LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_print", rc);
-    gcry_mpi_release (v_x);
-    gcry_mpi_release (v_y);
-    return GNUNET_SYSERR;
-  }
-  gcry_mpi_release (v_x);
-  size = sizeof (verification_key->q_y);
-  if (0 != (rc = gcry_mpi_print (GCRYMPI_FMT_USG, verification_key->q_y, size,
-                                 &size, v_y)))
-  {
-    LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_print", rc);
-    gcry_mpi_release (v_y);
-    return GNUNET_SYSERR;
-  }
-  gcry_mpi_release (v_y);
-  return GNUNET_OK;
-}
-
-
-/**
- * Verify a signature made with a pseudonym.
- *
- * @param purpose data that was signed
- * @param signature signature to verify
- * @param verification_key public key to use for checking the signature;
- *                    corresponds to 'g^(x+h)' in section 2.4 of #2564.
- * @return GNUNET_OK on success (signature valid, 'pseudonym' set),
- *         GNUNET_SYSERR if the signature is invalid
- */
-int
-GNUNET_FS_pseudonym_verify (const struct GNUNET_FS_PseudonymSignaturePurpose *purpose,
-                           const struct GNUNET_FS_PseudonymSignature *signature,
-                           const struct GNUNET_FS_PseudonymIdentifier *verification_key)
-{
-  gcry_sexp_t data;
-  gcry_sexp_t sig_sexpr;
-  gcry_sexp_t pk_sexpr;
-  size_t size;
-  gcry_ctx_t ctx;
-  gcry_mpi_t r;
-  gcry_mpi_t s;
-  gcry_mpi_point_t q;
-  gcry_mpi_t q_x;
-  gcry_mpi_t q_y;
-  size_t erroff;
-  int rc;
-
-  /* build s-expression for signature */
-  size = sizeof (signature->sig_r);
-  if (0 != (rc = gcry_mpi_scan (&r, GCRYMPI_FMT_USG,
-                                signature->sig_r, size, &size)))
-  {
-    LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
-    return GNUNET_SYSERR;
-  }
-  size = sizeof (signature->sig_s);
-  if (0 != (rc = gcry_mpi_scan (&s, GCRYMPI_FMT_USG,
-                                signature->sig_s, size, &size)))
-  {
-    LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
-    gcry_mpi_release (r);
-    return GNUNET_SYSERR;
-  }
-  if (0 != (rc = gcry_sexp_build (&sig_sexpr, &erroff, "(sig-val(ecdsa(r %m)(s %m)))",
-                                  r, s)))
-  {
-    LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
-    gcry_mpi_release (r);
-    gcry_mpi_release (s);
-    return GNUNET_SYSERR;
-  }
-  gcry_mpi_release (r);
-  gcry_mpi_release (s);
-
-
-  /* build s-expression for data that was signed */
-  data = data_to_pkcs1 (purpose);
-
-  /* create context of public key and initialize Q */
-  size = sizeof (verification_key->q_x);
-  if (0 != (rc = gcry_mpi_scan (&q_x, GCRYMPI_FMT_USG,
-                                verification_key->q_x, size, &size)))
-  {
-    LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
-    gcry_sexp_release (data);
-    gcry_sexp_release (sig_sexpr);
-    return GNUNET_SYSERR;
-  }
-  size = sizeof (verification_key->q_y);
-  if (0 != (rc = gcry_mpi_scan (&q_y, GCRYMPI_FMT_USG,
-                                verification_key->q_y, size, &size)))
-  {
-    LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
-    gcry_sexp_release (data);
-    gcry_sexp_release (sig_sexpr);
-    gcry_mpi_release (q_x);
-    return GNUNET_SYSERR;
-  }
-  q = gcry_mpi_point_new (256);
-  gcry_mpi_point_set (q, q_x, q_y, GCRYMPI_CONST_ONE); 
-  gcry_mpi_release (q_x);
-  gcry_mpi_release (q_y);
-
-  /* create basic ECC context */
-  if (0 != (rc = gcry_mpi_ec_new (&ctx, NULL, "NIST P-256")))
-  {
-    LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_ec_new", rc);  /* erroff gives more info */
-    gcry_sexp_release (data);
-    gcry_sexp_release (sig_sexpr);
-    gcry_mpi_point_release (q);
-    return GNUNET_SYSERR;
-  }  
-  /* initialize 'ctx' with 'q' */
-  gcry_mpi_ec_set_point ("q", q, ctx);
-  gcry_mpi_point_release (q);
-
-  /* convert 'ctx' to 'sexp' */
-  if (0 != (rc = gcry_pubkey_get_sexp (&pk_sexpr, GCRY_PK_GET_PUBKEY, ctx)))
-  {
-    LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_from_context", rc);
-    gcry_ctx_release (ctx);
-    gcry_sexp_release (data);
-    gcry_sexp_release (sig_sexpr);
-    return GNUNET_SYSERR;
-  }
-  gcry_ctx_release (ctx);
-
-  /* finally, verify the signature */
-  rc = gcry_pk_verify (sig_sexpr, data, pk_sexpr);
-  gcry_sexp_release (sig_sexpr);
-  gcry_sexp_release (data);
-  gcry_sexp_release (pk_sexpr);
-  if (rc)
-  {
-    LOG (GNUNET_ERROR_TYPE_WARNING,
-         _("ECDSA signature verification failed at %s:%d: %s\n"), __FILE__,
-         __LINE__, gcry_strerror (rc));
-    return GNUNET_SYSERR;
-  }
-  return GNUNET_OK;
-}
-
-
-/**
- * Get the identifier (public key) of a pseudonym.
- *
- * @param ph pseudonym handle with the private key
- * @param pseudonym pseudonym identifier (set based on 'ph')
- */
-void
-GNUNET_FS_pseudonym_get_identifier (struct GNUNET_FS_PseudonymHandle *ph,
-                                   struct GNUNET_FS_PseudonymIdentifier *pseudonym)
-{
-  if (&anonymous == ph)
-    memset (pseudonym, 0, sizeof (struct GNUNET_FS_PseudonymIdentifier));
-  else
-    memcpy (pseudonym, &ph->public_key,
-           sizeof (struct GNUNET_FS_PseudonymIdentifier));
-}
-
-
-/**
- * Remove pseudonym from the set of known pseudonyms.
- *
- * @param cfg overall configuration
- * @param id the pseudonym identifier
- * @return GNUNET_OK on success, GNUNET_SYSERR on failure
- */
-int
-GNUNET_FS_pseudonym_remove (const struct GNUNET_CONFIGURATION_Handle *cfg,
-                           const struct GNUNET_FS_PseudonymIdentifier *id)
-{
-  char *fn;
-  int result;
-
-  fn = get_data_filename (cfg, PS_METADATA_DIR, id);
-  if (NULL == fn)
-    return GNUNET_SYSERR;
-  result = UNLINK (fn);
-  GNUNET_free (fn);  
-  return (0 == result) ? GNUNET_OK : GNUNET_SYSERR;
-}
-
-/* end of pseudonym.c */
+/* end of fs_pseudonym.c */