fix
[oweals/gnunet.git] / src / util / crypto_rsa.c
index b61729e0642bfd7326899dbfae92c98e889e5fec..7f0c8169242eca1c491aa449e385aae62c7c2016 100644 (file)
 #include "gnunet_crypto_lib.h"
 #include "gnunet_disk_lib.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)
+
 /**
  * The private information of an RSA key pair.
  * NOTE: this must match the definition in crypto_ksk.c
@@ -60,13 +66,13 @@ struct RsaPrivateKeyBinaryEncoded
    * Total size of the structure, in bytes, in big-endian!
    */
   uint16_t len GNUNET_PACKED;
-  uint16_t sizen GNUNET_PACKED; /*  in big-endian! */
-  uint16_t sizee GNUNET_PACKED; /*  in big-endian! */
-  uint16_t sized GNUNET_PACKED; /*  in big-endian! */
-  uint16_t sizep GNUNET_PACKED; /*  in big-endian! */
-  uint16_t sizeq GNUNET_PACKED; /*  in big-endian! */
-  uint16_t sizedmp1 GNUNET_PACKED;      /*  in big-endian! */
-  uint16_t sizedmq1 GNUNET_PACKED;      /*  in big-endian! */
+  uint16_t sizen GNUNET_PACKED;        /*  in big-endian! */
+  uint16_t sizee GNUNET_PACKED;        /*  in big-endian! */
+  uint16_t sized GNUNET_PACKED;        /*  in big-endian! */
+  uint16_t sizep GNUNET_PACKED;        /*  in big-endian! */
+  uint16_t sizeq GNUNET_PACKED;        /*  in big-endian! */
+  uint16_t sizedmp1 GNUNET_PACKED;     /*  in big-endian! */
+  uint16_t sizedmq1 GNUNET_PACKED;     /*  in big-endian! */
   /* followed by the actual values */
 };
 
@@ -81,7 +87,7 @@ struct RsaPrivateKeyBinaryEncoded
  * a failure of the command 'cmd' with the message given
  * by gcry_strerror(rc).
  */
-#define LOG_GCRY(level, cmd, rc) do { GNUNET_log(level, _("`%s' failed at %s:%d with error: %s\n"), cmd, __FILE__, __LINE__, gcry_strerror(rc)); } while(0);
+#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);
 
 /**
  * If target != size, move target bytes to the
@@ -108,10 +114,10 @@ GNUNET_CRYPTO_rsa_key_create ()
   gcry_sexp_t s_key;
   gcry_sexp_t s_keyparam;
 
-  GNUNET_assert (0 == gcry_sexp_build (&s_keyparam,
-                                       NULL,
-                                       "(genkey(rsa(nbits %d)(rsa-use-e 3:257)))",
-                                       HOSTKEY_LEN));
+  GNUNET_assert (0 ==
+                gcry_sexp_build (&s_keyparam, NULL,
+                                 "(genkey(rsa(nbits %d)(rsa-use-e 3:257)))",
+                                 HOSTKEY_LEN));
   GNUNET_assert (0 == gcry_pk_genkey (&s_key, s_keyparam));
   gcry_sexp_release (s_keyparam);
 #if EXTRA_CHECKS
@@ -133,8 +139,8 @@ GNUNET_CRYPTO_rsa_key_free (struct GNUNET_CRYPTO_RsaPrivateKey *hostkey)
 }
 
 static int
-key_from_sexp (gcry_mpi_t * array,
-               gcry_sexp_t sexp, const char *topname, const char *elems)
+key_from_sexp (gcry_mpi_t * array, gcry_sexp_t sexp, const char *topname,
+              const char *elems)
 {
   gcry_sexp_t list, l2;
   const char *s;
@@ -158,27 +164,27 @@ key_from_sexp (gcry_mpi_t * array,
     {
       l2 = gcry_sexp_find_token (list, s, 1);
       if (!l2)
-        {
-          for (i = 0; i < idx; i++)
-            {
-              gcry_free (array[i]);
-              array[i] = NULL;
-            }
-          gcry_sexp_release (list);
-          return 3;             /* required parameter not found */
-        }
+       {
+         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 */
-        }
+       {
+         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;
@@ -186,45 +192,46 @@ key_from_sexp (gcry_mpi_t * array,
 
 /**
  * Extract the public key of the host.
- * @param hostkey the hostkey to extract into the result.
- * @param result where to write the result.
+ * @param priv the private key
+ * @param pub where to write the public key
  */
 void
 GNUNET_CRYPTO_rsa_key_get_public (const struct GNUNET_CRYPTO_RsaPrivateKey
-                                  *hostkey,
-                                  struct
-                                  GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded
-                                  *result)
+                                 *priv,
+                                 struct
+                                 GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded
+                                 *pub)
 {
   gcry_mpi_t skey[2];
   size_t size;
   int rc;
 
-  rc = key_from_sexp (skey, hostkey->sexp, "public-key", "ne");
+  rc = key_from_sexp (skey, priv->sexp, "public-key", "ne");
   if (rc)
-    rc = key_from_sexp (skey, hostkey->sexp, "private-key", "ne");
+    rc = key_from_sexp (skey, priv->sexp, "private-key", "ne");
   if (rc)
-    rc = key_from_sexp (skey, hostkey->sexp, "rsa", "ne");
+    rc = key_from_sexp (skey, priv->sexp, "rsa", "ne");
   GNUNET_assert (0 == rc);
-  result->len =
+  pub->len =
     htons (sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded) -
-           sizeof (result->padding));
-  result->sizen = htons (GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH);
-  result->padding = 0;
+          sizeof (pub->padding));
+  pub->sizen = htons (GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH);
+  pub->padding = 0;
   size = GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH;
-  GNUNET_assert (0 == gcry_mpi_print (GCRYMPI_FMT_USG,
-                                      &result->key[0], size, &size, skey[0]));
-  adjust (&result->key[0], size, GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH);
+  GNUNET_assert (0 ==
+                gcry_mpi_print (GCRYMPI_FMT_USG, &pub->key[0], size, &size,
+                                skey[0]));
+  adjust (&pub->key[0], size, GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH);
   size =
     GNUNET_CRYPTO_RSA_KEY_LENGTH - GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH;
   GNUNET_assert (0 ==
-                 gcry_mpi_print (GCRYMPI_FMT_USG,
-                                 &result->
-                                 key[GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH],
-                                 size, &size, skey[1]));
-  adjust (&result->key[GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH], size,
-          GNUNET_CRYPTO_RSA_KEY_LENGTH -
-          GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH);
+                gcry_mpi_print (GCRYMPI_FMT_USG,
+                                &pub->key
+                                [GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH],
+                                size, &size, skey[1]));
+  adjust (&pub->key[GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH], size,
+         GNUNET_CRYPTO_RSA_KEY_LENGTH -
+         GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH);
   gcry_mpi_release (skey[0]);
   gcry_mpi_release (skey[1]);
 }
@@ -238,7 +245,7 @@ GNUNET_CRYPTO_rsa_key_get_public (const struct GNUNET_CRYPTO_RsaPrivateKey
  */
 static struct GNUNET_CRYPTO_RsaPrivateKey *
 public2PrivateKey (const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded
-                   *publicKey)
+                  *publicKey)
 {
   struct GNUNET_CRYPTO_RsaPrivateKey *ret;
   gcry_sexp_t result;
@@ -267,21 +274,21 @@ public2PrivateKey (const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded
     GNUNET_CRYPTO_RSA_KEY_LENGTH - GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH;
   rc =
     gcry_mpi_scan (&e, GCRYMPI_FMT_USG,
-                   &publicKey->key[GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH],
-                   size, &size);
+                  &publicKey->key[GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH],
+                  size, &size);
   if (rc)
     {
       LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
       gcry_mpi_release (n);
       return NULL;
     }
-  rc = gcry_sexp_build (&result,
-                        &erroff, "(public-key(rsa(n %m)(e %m)))", n, e);
+  rc = gcry_sexp_build (&result, &erroff, "(public-key(rsa(n %m)(e %m)))", n,
+                       e);
   gcry_mpi_release (n);
   gcry_mpi_release (e);
   if (rc)
     {
-      LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);        /* erroff gives more info */
+      LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);       /* erroff gives more info */
       return NULL;
     }
   ret = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_RsaPrivateKey));
@@ -332,17 +339,18 @@ rsa_encode_key (const struct GNUNET_CRYPTO_RsaPrivateKey *hostkey)
   for (i = 0; i < 6; i++)
     {
       if (pkv[i] != NULL)
-        {
-          GNUNET_assert (0 == gcry_mpi_aprint (GCRYMPI_FMT_USG,
-                                               (unsigned char **) &pbu[i],
-                                               &sizes[i], pkv[i]));
-          size += sizes[i];
-        }
+       {
+         GNUNET_assert (0 ==
+                        gcry_mpi_aprint (GCRYMPI_FMT_USG,
+                                         (unsigned char **) &pbu[i],
+                                         &sizes[i], pkv[i]));
+         size += sizes[i];
+       }
       else
-        {
-          pbu[i] = NULL;
-          sizes[i] = 0;
-        }
+       {
+         pbu[i] = NULL;
+         sizes[i] = 0;
+       }
     }
   GNUNET_assert (size < 65536);
   retval = GNUNET_malloc (size);
@@ -370,9 +378,9 @@ rsa_encode_key (const struct GNUNET_CRYPTO_RsaPrivateKey *hostkey)
   for (i = 0; i < 6; i++)
     {
       if (pkv[i] != NULL)
-        gcry_mpi_release (pkv[i]);
+       gcry_mpi_release (pkv[i]);
       if (pbu[i] != NULL)
-        free (pbu[i]);
+       free (pbu[i]);
     }
   return retval;
 }
@@ -380,23 +388,32 @@ rsa_encode_key (const struct GNUNET_CRYPTO_RsaPrivateKey *hostkey)
 /**
  * Decode the private key from the file-format back
  * to the "normal", internal format.
+ *
+ * @param buf the buffer where the private key data is stored
+ * @param len the length of the data in 'buffer'
  */
-static struct GNUNET_CRYPTO_RsaPrivateKey *
-rsa_decode_key (const struct RsaPrivateKeyBinaryEncoded *encoding)
+struct GNUNET_CRYPTO_RsaPrivateKey *
+GNUNET_CRYPTO_rsa_decode_key (const char *buf, uint16_t len)
 {
   struct GNUNET_CRYPTO_RsaPrivateKey *ret;
+  const struct RsaPrivateKeyBinaryEncoded *encoding =
+    (const struct RsaPrivateKeyBinaryEncoded *) buf;
   gcry_sexp_t res;
   gcry_mpi_t n, e, d, p, q, u;
   int rc;
   size_t size;
   int pos;
+  uint16_t enc_len;
+
+  enc_len = ntohs (encoding->len);
+  if (len != enc_len)
+    return NULL;
 
   pos = 0;
   size = ntohs (encoding->sizen);
-  rc = gcry_mpi_scan (&n,
-                      GCRYMPI_FMT_USG,
-                      &((const unsigned char *) (&encoding[1]))[pos],
-                      size, &size);
+  rc = gcry_mpi_scan (&n, GCRYMPI_FMT_USG,
+                     &((const unsigned char *) (&encoding[1]))[pos], size,
+                     &size);
   pos += ntohs (encoding->sizen);
   if (rc)
     {
@@ -404,10 +421,9 @@ rsa_decode_key (const struct RsaPrivateKeyBinaryEncoded *encoding)
       return NULL;
     }
   size = ntohs (encoding->sizee);
-  rc = gcry_mpi_scan (&e,
-                      GCRYMPI_FMT_USG,
-                      &((const unsigned char *) (&encoding[1]))[pos],
-                      size, &size);
+  rc = gcry_mpi_scan (&e, GCRYMPI_FMT_USG,
+                     &((const unsigned char *) (&encoding[1]))[pos], size,
+                     &size);
   pos += ntohs (encoding->sizee);
   if (rc)
     {
@@ -416,10 +432,9 @@ rsa_decode_key (const struct RsaPrivateKeyBinaryEncoded *encoding)
       return NULL;
     }
   size = ntohs (encoding->sized);
-  rc = gcry_mpi_scan (&d,
-                      GCRYMPI_FMT_USG,
-                      &((const unsigned char *) (&encoding[1]))[pos],
-                      size, &size);
+  rc = gcry_mpi_scan (&d, GCRYMPI_FMT_USG,
+                     &((const unsigned char *) (&encoding[1]))[pos], size,
+                     &size);
   pos += ntohs (encoding->sized);
   if (rc)
     {
@@ -432,40 +447,38 @@ rsa_decode_key (const struct RsaPrivateKeyBinaryEncoded *encoding)
   size = ntohs (encoding->sizep);
   if (size > 0)
     {
-      rc = gcry_mpi_scan (&q,
-                          GCRYMPI_FMT_USG,
-                          &((const unsigned char *) (&encoding[1]))[pos],
-                          size, &size);
+      rc = gcry_mpi_scan (&q, GCRYMPI_FMT_USG,
+                         &((const unsigned char *) (&encoding[1]))[pos],
+                         size, &size);
       pos += ntohs (encoding->sizep);
       if (rc)
-        {
-          LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
-          gcry_mpi_release (n);
-          gcry_mpi_release (e);
-          gcry_mpi_release (d);
-          return NULL;
-        }
+       {
+         LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
+         gcry_mpi_release (n);
+         gcry_mpi_release (e);
+         gcry_mpi_release (d);
+         return NULL;
+       }
     }
   else
     q = NULL;
   size = ntohs (encoding->sizeq);
   if (size > 0)
     {
-      rc = gcry_mpi_scan (&p,
-                          GCRYMPI_FMT_USG,
-                          &((const unsigned char *) (&encoding[1]))[pos],
-                          size, &size);
+      rc = gcry_mpi_scan (&p, GCRYMPI_FMT_USG,
+                         &((const unsigned char *) (&encoding[1]))[pos],
+                         size, &size);
       pos += ntohs (encoding->sizeq);
       if (rc)
-        {
-          LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
-          gcry_mpi_release (n);
-          gcry_mpi_release (e);
-          gcry_mpi_release (d);
-          if (q != NULL)
-            gcry_mpi_release (q);
-          return NULL;
-        }
+       {
+         LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
+         gcry_mpi_release (n);
+         gcry_mpi_release (e);
+         gcry_mpi_release (d);
+         if (q != NULL)
+           gcry_mpi_release (q);
+         return NULL;
+       }
     }
   else
     p = NULL;
@@ -475,46 +488,45 @@ rsa_decode_key (const struct RsaPrivateKeyBinaryEncoded *encoding)
     ntohs (encoding->len) - sizeof (struct RsaPrivateKeyBinaryEncoded) - pos;
   if (size > 0)
     {
-      rc = gcry_mpi_scan (&u,
-                          GCRYMPI_FMT_USG,
-                          &((const unsigned char *) (&encoding[1]))[pos],
-                          size, &size);
+      rc = gcry_mpi_scan (&u, GCRYMPI_FMT_USG,
+                         &((const unsigned char *) (&encoding[1]))[pos],
+                         size, &size);
       if (rc)
-        {
-          LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
-          gcry_mpi_release (n);
-          gcry_mpi_release (e);
-          gcry_mpi_release (d);
-          if (p != NULL)
-            gcry_mpi_release (p);
-          if (q != NULL)
-            gcry_mpi_release (q);
-          return NULL;
-        }
+       {
+         LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
+         gcry_mpi_release (n);
+         gcry_mpi_release (e);
+         gcry_mpi_release (d);
+         if (p != NULL)
+           gcry_mpi_release (p);
+         if (q != NULL)
+           gcry_mpi_release (q);
+         return NULL;
+       }
     }
   else
     u = NULL;
 
   if ((p != NULL) && (q != NULL) && (u != NULL))
     {
-      rc = gcry_sexp_build (&res, &size,        /* erroff */
-                            "(private-key(rsa(n %m)(e %m)(d %m)(p %m)(q %m)(u %m)))",
-                            n, e, d, p, q, u);
+      rc = gcry_sexp_build (&res, &size,       /* erroff */
+                           "(private-key(rsa(n %m)(e %m)(d %m)(p %m)(q %m)(u %m)))",
+                           n, e, d, p, q, u);
     }
   else
     {
       if ((p != NULL) && (q != NULL))
-        {
-          rc = gcry_sexp_build (&res, &size,    /* erroff */
-                                "(private-key(rsa(n %m)(e %m)(d %m)(p %m)(q %m)))",
-                                n, e, d, p, q);
-        }
+       {
+         rc = gcry_sexp_build (&res, &size,    /* erroff */
+                               "(private-key(rsa(n %m)(e %m)(d %m)(p %m)(q %m)))",
+                               n, e, d, p, q);
+       }
       else
-        {
-          rc = gcry_sexp_build (&res, &size,    /* erroff */
-                                "(private-key(rsa(n %m)(e %m)(d %m)))",
-                                n, e, d);
-        }
+       {
+         rc = gcry_sexp_build (&res, &size,    /* erroff */
+                               "(private-key(rsa(n %m)(e %m)(d %m)))", n, e,
+                               d);
+       }
     }
   gcry_mpi_release (n);
   gcry_mpi_release (e);
@@ -546,10 +558,8 @@ rsa_decode_key (const struct RsaPrivateKeyBinaryEncoded *encoding)
  * files does not exist, create a new key and write it to the
  * file.  Caller must free return value.  Note that this function
  * can not guarantee that another process might not be trying
- * the same operation on the same file at the same time.  The
- * caller must somehow know that the file either already exists
- * with a valid key OR be sure that no other process is calling
- * this function at the same time.  If the contents of the file
+ * the same operation on the same file at the same time.
+ * If the contents of the file
  * are invalid the old file is deleted and a fresh key is
  * created.
  *
@@ -559,173 +569,192 @@ rsa_decode_key (const struct RsaPrivateKeyBinaryEncoded *encoding)
 struct GNUNET_CRYPTO_RsaPrivateKey *
 GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename)
 {
-  struct flock fl;
   struct GNUNET_CRYPTO_RsaPrivateKey *ret;
   struct RsaPrivateKeyBinaryEncoded *enc;
-  struct stat sbuf;
   uint16_t len;
-  int fd;
+  struct GNUNET_DISK_FileHandle *fd;
   unsigned int cnt;
   int ec;
+  uint64_t fs;
+  struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pub;
+  struct GNUNET_PeerIdentity pid;
 
   if (GNUNET_SYSERR == GNUNET_DISK_directory_create_for_file (filename))
     return NULL;
-  while (0 != STAT (filename, &sbuf))
+  while (GNUNET_YES != GNUNET_DISK_file_test (filename))
     {
-      fd = open (filename, O_WRONLY | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
-      if (-1 == fd)
-        {
-          if (errno == EEXIST)
-            continue;
-          GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
-                                    "open", filename);
-          return NULL;
-        }
-      memset (&fl, 0, sizeof (struct flock));
-      fl.l_type = F_WRLCK;
-      fl.l_whence = SEEK_SET;
-      fl.l_len = sizeof (struct RsaPrivateKeyBinaryEncoded);
+      fd = GNUNET_DISK_file_open (filename,
+                                 GNUNET_DISK_OPEN_WRITE |
+                                 GNUNET_DISK_OPEN_CREATE |
+                                 GNUNET_DISK_OPEN_FAILIFEXISTS,
+                                 GNUNET_DISK_PERM_USER_READ |
+                                 GNUNET_DISK_PERM_USER_WRITE);
+      if (NULL == fd)
+       {
+         if (errno == EEXIST)
+           {
+             if (GNUNET_YES != GNUNET_DISK_file_test (filename))
+               {
+                 /* must exist but not be accessible, fail for good! */
+                 if (0 != ACCESS (filename, R_OK))
+                   LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "access",
+                                      filename);
+                 else
+                   GNUNET_break (0);   /* what is going on!? */
+                 return NULL;
+               }
+             continue;
+           }
+         LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "open", filename);
+         return NULL;
+       }
       cnt = 0;
-      while (0 != fcntl (fd, F_SETLK, &fl))
-        {
-          sleep (1);
-          if (0 == ++cnt % 10)
-            {
-              ec = errno;
-              fl.l_type = F_GETLK;
-              fcntl (fd, F_GETLK, &fl);
-              GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                          _
-                          ("Could not aquire lock on file `%s' due to process %u: %s...\n"),
-                          filename, fl.l_pid, STRERROR (errno));
-            }
-          memset (&fl, 0, sizeof (struct flock));
-          fl.l_type = F_WRLCK;
-          fl.l_whence = SEEK_SET;
-          fl.l_len = sizeof (struct RsaPrivateKeyBinaryEncoded);
-        }
-      GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-                  _("Creating a new private key.  This may take a while.\n"));
+
+      while (GNUNET_YES !=
+            GNUNET_DISK_file_lock (fd, 0,
+                                   sizeof (struct
+                                           RsaPrivateKeyBinaryEncoded),
+                                   GNUNET_YES))
+       {
+         sleep (1);
+         if (0 == ++cnt % 10)
+           {
+             ec = errno;
+             LOG (GNUNET_ERROR_TYPE_ERROR,
+                  _("Could not aquire lock on file `%s': %s...\n"), filename,
+                  STRERROR (ec));
+           }
+       }
+      LOG (GNUNET_ERROR_TYPE_INFO,
+          _("Creating a new private key.  This may take a while.\n"));
       ret = GNUNET_CRYPTO_rsa_key_create ();
       GNUNET_assert (ret != NULL);
       enc = rsa_encode_key (ret);
       GNUNET_assert (enc != NULL);
-      GNUNET_assert (ntohs (enc->len) == WRITE (fd, enc, ntohs (enc->len)));
+      GNUNET_assert (ntohs (enc->len) ==
+                    GNUNET_DISK_file_write (fd, enc, ntohs (enc->len)));
       GNUNET_free (enc);
-      fdatasync (fd);
-      memset (&fl, 0, sizeof (struct flock));
-      fl.l_type = F_UNLCK;
-      fl.l_whence = SEEK_SET;
-      fl.l_len = sizeof (struct RsaPrivateKeyBinaryEncoded);
-      cnt = 0;
-      if (0 != fcntl (fd, F_SETLK, &fl))
-        GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
-                                  "fcntl", filename);
-      GNUNET_assert (0 == CLOSE (fd));
-      GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-                  _("Stored new private key in `%s'.\n"), filename);
+
+      GNUNET_DISK_file_sync (fd);
+      if (GNUNET_YES !=
+         GNUNET_DISK_file_unlock (fd, 0,
+                                  sizeof (struct
+                                          RsaPrivateKeyBinaryEncoded)))
+       LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename);
+      GNUNET_assert (GNUNET_YES == GNUNET_DISK_file_close (fd));
+      GNUNET_CRYPTO_rsa_key_get_public (ret, &pub);
+      GNUNET_CRYPTO_hash (&pub, sizeof (pub), &pid.hashPubKey);
+      LOG (GNUNET_ERROR_TYPE_INFO,
+          _("I am host `%s'.  Stored new private key in `%s'.\n"),
+          GNUNET_i2s (&pid), filename);
       return ret;
     }
   /* hostkey file exists already, read it! */
-  fd = open (filename, O_RDONLY);
-  if (-1 == fd)
+  fd = GNUNET_DISK_file_open (filename, GNUNET_DISK_OPEN_READ,
+                             GNUNET_DISK_PERM_NONE);
+  if (NULL == fd)
     {
-      GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "open", filename);
+      LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "open", filename);
       return NULL;
     }
   cnt = 0;
   while (1)
     {
-      memset (&fl, 0, sizeof (struct flock));
-      fl.l_type = F_RDLCK;
-      fl.l_whence = SEEK_SET;
-      fl.l_len = sizeof (struct RsaPrivateKeyBinaryEncoded);
-      if (0 != fcntl (fd, F_SETLK, &fl))
-        {
-          if (0 == ++cnt % 10)
-            {
-              ec = errno;
-              fl.l_type = F_GETLK;
-              fcntl (fd, F_GETLK, &fl);
-              GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                          _
-                          ("Could not aquire lock on file `%s' due to process %u: %s...\n"),
-                          filename, fl.l_pid, STRERROR (errno));
-              GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                          _
-                          ("This may be ok if someone is currently generating a hostkey.\n"));
-            }
-          sleep (1);
-          continue;
-        }
-      if (0 != STAT (filename, &sbuf))
-        {
-          /* eh, what!? File we opened is now gone!? */
-          GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
-                                    "stat", filename);
-          memset (&fl, 0, sizeof (struct flock));
-          fl.l_type = F_UNLCK;
-          fl.l_whence = SEEK_SET;
-          fl.l_len = sizeof (struct RsaPrivateKeyBinaryEncoded);
-          if (0 != fcntl (fd, F_SETLK, &fl))
-            GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
-                                      "fcntl", filename);
-          GNUNET_assert (0 == CLOSE (fd));
-          return NULL;
-        }
-      if (sbuf.st_size < sizeof (struct RsaPrivateKeyBinaryEncoded))
-        {
-          /* maybe we got the read lock before the hostkey generating
-             process had a chance to get the write lock; give it up! */
-          memset (&fl, 0, sizeof (struct flock));
-          fl.l_type = F_UNLCK;
-          fl.l_whence = SEEK_SET;
-          fl.l_len = sizeof (struct RsaPrivateKeyBinaryEncoded);
-          if (0 != fcntl (fd, F_SETLK, &fl))
-            GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
-                                      "fcntl", filename);
-          if (0 == ++cnt % 10)
-            {
-              GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                          _
-                          ("When trying to read hostkey file `%s' I found %u bytes but I need at least %u.\n"),
-                          filename, (unsigned int) sbuf.st_size,
-                          (unsigned int) sizeof (struct
-                                                 RsaPrivateKeyBinaryEncoded));
-              GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                          _
-                          ("This may be ok if someone is currently generating a hostkey.\n"));
-            }
-          sleep (2);            /* wait a bit longer! */
-          continue;
-        }
+      if (GNUNET_YES !=
+         GNUNET_DISK_file_lock (fd, 0,
+                                sizeof (struct RsaPrivateKeyBinaryEncoded),
+                                GNUNET_NO))
+       {
+         if (0 == ++cnt % 60)
+           {
+             ec = errno;
+             LOG (GNUNET_ERROR_TYPE_ERROR,
+                  _("Could not aquire lock on file `%s': %s...\n"), filename,
+                  STRERROR (ec));
+             LOG (GNUNET_ERROR_TYPE_ERROR,
+                  _
+                  ("This may be ok if someone is currently generating a hostkey.\n"));
+           }
+         sleep (1);
+         continue;
+       }
+      if (GNUNET_YES != GNUNET_DISK_file_test (filename))
+       {
+         /* eh, what!? File we opened is now gone!? */
+         LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "stat", filename);
+         if (GNUNET_YES !=
+             GNUNET_DISK_file_unlock (fd, 0,
+                                      sizeof (struct
+                                              RsaPrivateKeyBinaryEncoded)))
+           LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename);
+         GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_close (fd));
+
+         return NULL;
+       }
+      if (GNUNET_YES != GNUNET_DISK_file_size (filename, &fs, GNUNET_YES))
+       fs = 0;
+      if (fs < sizeof (struct RsaPrivateKeyBinaryEncoded))
+       {
+         /* maybe we got the read lock before the hostkey generating
+          * process had a chance to get the write lock; give it up! */
+         if (GNUNET_YES !=
+             GNUNET_DISK_file_unlock (fd, 0,
+                                      sizeof (struct
+                                              RsaPrivateKeyBinaryEncoded)))
+           LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename);
+         if (0 == ++cnt % 10)
+           {
+             LOG (GNUNET_ERROR_TYPE_ERROR,
+                  _
+                  ("When trying to read hostkey file `%s' I found %u bytes but I need at least %u.\n"),
+                  filename, (unsigned int) fs,
+                  (unsigned int) sizeof (struct RsaPrivateKeyBinaryEncoded));
+             LOG (GNUNET_ERROR_TYPE_ERROR,
+                  _
+                  ("This may be ok if someone is currently generating a hostkey.\n"));
+           }
+         sleep (2);            /* wait a bit longer! */
+         continue;
+       }
       break;
     }
-  enc = GNUNET_malloc (sbuf.st_size);
-  GNUNET_assert (sbuf.st_size == READ (fd, enc, sbuf.st_size));
+  enc = GNUNET_malloc (fs);
+  GNUNET_assert (fs == GNUNET_DISK_file_read (fd, enc, fs));
   len = ntohs (enc->len);
-  if ((len != sbuf.st_size) || (NULL == (ret = rsa_decode_key (enc))))
+  ret = NULL;
+  if ((len != fs) ||
+      (NULL == (ret = GNUNET_CRYPTO_rsa_decode_key ((char *) enc, len))))
     {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  _
-                  ("File `%s' does not contain a valid private key.  You should delete it.\n"),
-                  filename);
-      GNUNET_free (enc);
+      LOG (GNUNET_ERROR_TYPE_ERROR,
+          _
+          ("File `%s' does not contain a valid private key.  Deleting it.\n"),
+          filename);
+      if (0 != UNLINK (filename))
+       {
+         LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "unlink", filename);
+       }
+    }
+  GNUNET_free (enc);
+  if (GNUNET_YES !=
+      GNUNET_DISK_file_unlock (fd, 0,
+                              sizeof (struct RsaPrivateKeyBinaryEncoded)))
+    LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename);
+  GNUNET_assert (GNUNET_YES == GNUNET_DISK_file_close (fd));
+  if (ret != NULL)
+    {
+      GNUNET_CRYPTO_rsa_key_get_public (ret, &pub);
+      GNUNET_CRYPTO_hash (&pub, sizeof (pub), &pid.hashPubKey);
+      LOG (GNUNET_ERROR_TYPE_INFO,
+          _("I am host `%s'.  Read private key from `%s'.\n"),
+          GNUNET_i2s (&pid), filename);
     }
-  memset (&fl, 0, sizeof (struct flock));
-  fl.l_type = F_UNLCK;
-  fl.l_whence = SEEK_SET;
-  fl.l_len = sizeof (struct RsaPrivateKeyBinaryEncoded);
-  if (0 != fcntl (fd, F_SETLK, &fl))
-    GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename);
-  GNUNET_assert (0 == CLOSE (fd));
   return ret;
 }
 
 
 /**
  * Encrypt a block with the public key of another host that uses the
- * same cyper.
+ * same cipher.
  *
  * @param block the block to encrypt
  * @param size the size of block
@@ -734,11 +763,10 @@ GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename)
  * @returns GNUNET_SYSERR on error, GNUNET_OK if ok
  */
 int
-GNUNET_CRYPTO_rsa_encrypt (const void *block,
-                           uint16_t size,
-                           const struct
-                           GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *publicKey,
-                           struct GNUNET_CRYPTO_RsaEncryptedData *target)
+GNUNET_CRYPTO_rsa_encrypt (const void *block, size_t size,
+                          const struct
+                          GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *publicKey,
+                          struct GNUNET_CRYPTO_RsaEncryptedData *target)
 {
   gcry_sexp_t result;
   gcry_sexp_t data;
@@ -750,12 +778,14 @@ GNUNET_CRYPTO_rsa_encrypt (const void *block,
 
   GNUNET_assert (size <= sizeof (GNUNET_HashCode));
   pubkey = public2PrivateKey (publicKey);
+  if (pubkey == NULL)
+    return GNUNET_SYSERR;
   isize = size;
   GNUNET_assert (0 ==
-                 gcry_mpi_scan (&val, GCRYMPI_FMT_USG, block, isize, &isize));
+                gcry_mpi_scan (&val, GCRYMPI_FMT_USG, block, isize, &isize));
   GNUNET_assert (0 ==
-                 gcry_sexp_build (&data, &erroff,
-                                  "(data (flags pkcs1)(value %m))", val));
+                gcry_sexp_build (&data, &erroff,
+                                 "(data (flags pkcs1)(value %m))", val));
   gcry_mpi_release (val);
   GNUNET_assert (0 == gcry_pk_encrypt (&result, data, pubkey->sexp));
   gcry_sexp_release (data);
@@ -764,29 +794,29 @@ GNUNET_CRYPTO_rsa_encrypt (const void *block,
   GNUNET_assert (0 == key_from_sexp (&rval, result, "rsa", "a"));
   gcry_sexp_release (result);
   isize = sizeof (struct GNUNET_CRYPTO_RsaEncryptedData);
-  GNUNET_assert (0 == gcry_mpi_print (GCRYMPI_FMT_USG,
-                                      (unsigned char *) target, isize, &isize,
-                                      rval));
+  GNUNET_assert (0 ==
+                gcry_mpi_print (GCRYMPI_FMT_USG, (unsigned char *) target,
+                                isize, &isize, rval));
   gcry_mpi_release (rval);
   adjust (&target->encoding[0], isize,
-          sizeof (struct GNUNET_CRYPTO_RsaEncryptedData));
+         sizeof (struct GNUNET_CRYPTO_RsaEncryptedData));
   return GNUNET_OK;
 }
 
 /**
  * Decrypt a given block with the hostkey.
  *
- * @param hostkey the hostkey with which to decrypt this block
+ * @param key the key with which to decrypt this block
  * @param block the data to decrypt, encoded as returned by encrypt
  * @param result pointer to a location where the result can be stored
  * @param max the maximum number of bits to store for the result, if
  *        the decrypted block is bigger, an error is returned
- * @returns the size of the decrypted block, -1 on error
+ * @return the size of the decrypted block, -1 on error
  */
-int
-GNUNET_CRYPTO_rsa_decrypt (const struct GNUNET_CRYPTO_RsaPrivateKey *hostkey,
-                           const struct GNUNET_CRYPTO_RsaEncryptedData *block,
-                           void *result, uint16_t max)
+ssize_t
+GNUNET_CRYPTO_rsa_decrypt (const struct GNUNET_CRYPTO_RsaPrivateKey * key,
+                          const struct GNUNET_CRYPTO_RsaEncryptedData *
+                          block, void *result, size_t max)
 {
   gcry_sexp_t resultsexp;
   gcry_sexp_t data;
@@ -797,26 +827,26 @@ GNUNET_CRYPTO_rsa_decrypt (const struct GNUNET_CRYPTO_RsaPrivateKey *hostkey,
   unsigned char *tmp;
 
 #if EXTRA_CHECKS
-  GNUNET_assert (0 == gcry_pk_testkey (hostkey->sexp));
+  GNUNET_assert (0 == gcry_pk_testkey (key->sexp));
 #endif
   size = sizeof (struct GNUNET_CRYPTO_RsaEncryptedData);
-  GNUNET_assert (0 == gcry_mpi_scan (&val,
-                                     GCRYMPI_FMT_USG, &block->encoding[0],
-                                     size, &size));
   GNUNET_assert (0 ==
-                 gcry_sexp_build (&data, &erroff,
-                                  "(enc-val(flags)(rsa(a %m)))", val));
+                gcry_mpi_scan (&val, GCRYMPI_FMT_USG, &block->encoding[0],
+                               size, &size));
+  GNUNET_assert (0 ==
+                gcry_sexp_build (&data, &erroff,
+                                 "(enc-val(flags)(rsa(a %m)))", val));
   gcry_mpi_release (val);
-  GNUNET_assert (0 == gcry_pk_decrypt (&resultsexp, data, hostkey->sexp));
+  GNUNET_assert (0 == gcry_pk_decrypt (&resultsexp, data, key->sexp));
   gcry_sexp_release (data);
   /* resultsexp has format "(value %m)" */
   GNUNET_assert (NULL !=
-                 (val = gcry_sexp_nth_mpi (resultsexp, 1, GCRYMPI_FMT_USG)));
+                (val = gcry_sexp_nth_mpi (resultsexp, 1, GCRYMPI_FMT_USG)));
   gcry_sexp_release (resultsexp);
   tmp = GNUNET_malloc (max + HOSTKEY_LEN / 8);
   size = max + HOSTKEY_LEN / 8;
   GNUNET_assert (0 ==
-                 gcry_mpi_print (GCRYMPI_FMT_USG, tmp, size, &size, val));
+                gcry_mpi_print (GCRYMPI_FMT_USG, tmp, size, &size, val));
   gcry_mpi_release (val);
   endp = tmp;
   endp += (size - max);
@@ -830,15 +860,15 @@ GNUNET_CRYPTO_rsa_decrypt (const struct GNUNET_CRYPTO_RsaPrivateKey *hostkey,
 /**
  * Sign a given block.
  *
- * @param hostkey private key to use for the signing
+ * @param key private key to use for the signing
  * @param purpose what to sign (size, purpose)
- * @param result where to write the signature
+ * @param sig where to write the signature
  * @return GNUNET_SYSERR on error, GNUNET_OK on success
  */
 int
-GNUNET_CRYPTO_rsa_sign (const struct GNUNET_CRYPTO_RsaPrivateKey *hostkey,
-                        const struct GNUNET_CRYPTO_RsaSignaturePurpose
-                        *purpose, struct GNUNET_CRYPTO_RsaSignature *sig)
+GNUNET_CRYPTO_rsa_sign (const struct GNUNET_CRYPTO_RsaPrivateKey *key,
+                       const struct GNUNET_CRYPTO_RsaSignaturePurpose
+                       *purpose, struct GNUNET_CRYPTO_RsaSignature *sig)
 {
   gcry_sexp_t result;
   gcry_sexp_t data;
@@ -854,20 +884,20 @@ GNUNET_CRYPTO_rsa_sign (const struct GNUNET_CRYPTO_RsaPrivateKey *hostkey,
   buff = GNUNET_malloc (bufSize);
   memcpy (buff, FORMATSTRING, bufSize);
   memcpy (&buff
-          [bufSize -
-           strlen
-           ("0123456789012345678901234567890123456789012345678901234567890123))")
-           - 1], &hc, sizeof (GNUNET_HashCode));
+         [bufSize -
+          strlen
+          ("0123456789012345678901234567890123456789012345678901234567890123))")
+          - 1], &hc, sizeof (GNUNET_HashCode));
   GNUNET_assert (0 == gcry_sexp_new (&data, buff, bufSize, 0));
   GNUNET_free (buff);
-  GNUNET_assert (0 == gcry_pk_sign (&result, data, hostkey->sexp));
+  GNUNET_assert (0 == gcry_pk_sign (&result, data, key->sexp));
   gcry_sexp_release (data);
   GNUNET_assert (0 == key_from_sexp (&rval, result, "rsa", "s"));
   gcry_sexp_release (result);
   ssize = sizeof (struct GNUNET_CRYPTO_RsaSignature);
-  GNUNET_assert (0 == gcry_mpi_print (GCRYMPI_FMT_USG,
-                                      (unsigned char *) sig, ssize, &ssize,
-                                      rval));
+  GNUNET_assert (0 ==
+                gcry_mpi_print (GCRYMPI_FMT_USG, (unsigned char *) sig,
+                                ssize, &ssize, rval));
   gcry_mpi_release (rval);
   adjust (sig->sig, ssize, sizeof (struct GNUNET_CRYPTO_RsaSignature));
   return GNUNET_OK;
@@ -885,11 +915,11 @@ GNUNET_CRYPTO_rsa_sign (const struct GNUNET_CRYPTO_RsaPrivateKey *hostkey,
  */
 int
 GNUNET_CRYPTO_rsa_verify (uint32_t purpose,
-                          const struct GNUNET_CRYPTO_RsaSignaturePurpose
-                          *validate,
-                          const struct GNUNET_CRYPTO_RsaSignature *sig,
-                          const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded
-                          *publicKey)
+                         const struct GNUNET_CRYPTO_RsaSignaturePurpose
+                         *validate,
+                         const struct GNUNET_CRYPTO_RsaSignature *sig,
+                         const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded
+                         *publicKey)
 {
   gcry_sexp_t data;
   gcry_sexp_t sigdata;
@@ -903,24 +933,24 @@ GNUNET_CRYPTO_rsa_verify (uint32_t purpose,
   int rc;
 
   if (purpose != ntohl (validate->purpose))
-    return GNUNET_SYSERR;       /* purpose mismatch */
+    return GNUNET_SYSERR;      /* purpose mismatch */
   GNUNET_CRYPTO_hash (validate, ntohl (validate->size), &hc);
   size = sizeof (struct GNUNET_CRYPTO_RsaSignature);
-  GNUNET_assert (0 == gcry_mpi_scan (&val,
-                                     GCRYMPI_FMT_USG,
-                                     (const unsigned char *) sig, size,
-                                     &size));
   GNUNET_assert (0 ==
-                 gcry_sexp_build (&sigdata, &erroff, "(sig-val(rsa(s %m)))",
-                                  val));
+                gcry_mpi_scan (&val, GCRYMPI_FMT_USG,
+                               (const unsigned char *) sig, size, &size));
+  GNUNET_assert (0 ==
+                gcry_sexp_build (&sigdata, &erroff, "(sig-val(rsa(s %m)))",
+                                 val));
   gcry_mpi_release (val);
   bufSize = strlen (FORMATSTRING) + 1;
   buff = GNUNET_malloc (bufSize);
   memcpy (buff, FORMATSTRING, bufSize);
-  memcpy (&buff[strlen (FORMATSTRING) -
-                strlen
-                ("0123456789012345678901234567890123456789012345678901234567890123))")],
-          &hc, sizeof (GNUNET_HashCode));
+  memcpy (&buff
+         [strlen (FORMATSTRING) -
+          strlen
+          ("0123456789012345678901234567890123456789012345678901234567890123))")],
+         &hc, sizeof (GNUNET_HashCode));
   GNUNET_assert (0 == gcry_sexp_new (&data, buff, bufSize, 0));
   GNUNET_free (buff);
   hostkey = public2PrivateKey (publicKey);
@@ -936,9 +966,9 @@ GNUNET_CRYPTO_rsa_verify (uint32_t purpose,
   gcry_sexp_release (sigdata);
   if (rc)
     {
-      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                  _("RSA signature verification failed at %s:%d: %s\n"),
-                  __FILE__, __LINE__, gcry_strerror (rc));
+      LOG (GNUNET_ERROR_TYPE_WARNING,
+          _("RSA signature verification failed at %s:%d: %s\n"), __FILE__,
+          __LINE__, gcry_strerror (rc));
       return GNUNET_SYSERR;
     }
   return GNUNET_OK;