-fixes
[oweals/gnunet.git] / src / util / crypto_rsa.c
index 6be2f53c0c0a942727718014623a185c04b61790..ee7e5e9f8238acdac54b7836feba200367dacfe2 100644 (file)
 #include "gnunet_common.h"
 #include "gnunet_crypto_lib.h"
 #include "gnunet_disk_lib.h"
+#include "gnunet_strings_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.
@@ -47,30 +54,6 @@ struct GNUNET_CRYPTO_RsaPrivateKey
 };
 
 
-/**
- * GNUnet mandates a certain format for the encoding
- * of private RSA key information that is provided
- * by the RSA implementations.  This format is used
- * to serialize a private RSA key (typically when
- * writing it to disk).
- */
-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! */
-  /* followed by the actual values */
-};
-
-
 #define HOSTKEY_LEN 2048
 
 #define EXTRA_CHECKS ALLOW_EXTRA_CHECKS
@@ -81,7 +64,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
@@ -99,7 +82,9 @@ adjust (unsigned char *buf, size_t size, size_t target)
 }
 
 /**
- * This HostKey implementation uses RSA.
+ * Create a new private key. Caller must free return value.
+ *
+ * @return fresh private key
  */
 struct GNUNET_CRYPTO_RsaPrivateKey *
 GNUNET_CRYPTO_rsa_key_create ()
@@ -108,10 +93,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
@@ -124,6 +109,7 @@ GNUNET_CRYPTO_rsa_key_create ()
 
 /**
  * Free memory occupied by hostkey
+ * @param hostkey pointer to the memory to free
  */
 void
 GNUNET_CRYPTO_rsa_key_free (struct GNUNET_CRYPTO_RsaPrivateKey *hostkey)
@@ -133,8 +119,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;
@@ -192,8 +178,8 @@ key_from_sexp (gcry_mpi_t * array,
 void
 GNUNET_CRYPTO_rsa_key_get_public (const struct GNUNET_CRYPTO_RsaPrivateKey
                                   *priv,
-                                  struct
-                                  GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *pub)
+                                  struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded
+                                  *pub)
 {
   gcry_mpi_t skey[2];
   size_t size;
@@ -211,15 +197,16 @@ GNUNET_CRYPTO_rsa_key_get_public (const struct GNUNET_CRYPTO_RsaPrivateKey
   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,
-                                      &pub->key[0], size, &size, skey[0]));
+  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,
                                  &pub->key
-                                 [GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH],
-                                 size, &size, skey[1]));
+                                 [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);
@@ -228,6 +215,70 @@ GNUNET_CRYPTO_rsa_key_get_public (const struct GNUNET_CRYPTO_RsaPrivateKey
 }
 
 
+/**
+ * Convert a public key to a string.
+ *
+ * @param pub key to convert
+ * @return string representing  'pub'
+ */
+char *
+GNUNET_CRYPTO_rsa_public_key_to_string (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *pub)
+{
+  char *pubkeybuf;
+  size_t keylen = (sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded)) * 8;
+  char *end;
+
+  if (keylen % 5 > 0)
+    keylen += 5 - keylen % 5;
+  keylen /= 5;
+  pubkeybuf = GNUNET_malloc (keylen + 1);
+  end = GNUNET_STRINGS_data_to_string ((unsigned char *) pub, 
+                                      sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), 
+                                      pubkeybuf, 
+                                      keylen);
+  if (NULL == end)
+  {
+    GNUNET_free (pubkeybuf);
+    return NULL;
+  }
+  *end = '\0';
+  return pubkeybuf;
+}
+
+
+/**
+ * Convert a string representing a public key to a public key.
+ *
+ * @param enc encoded public key
+ * @param enclen number of bytes in enc (without 0-terminator)
+ * @param pub where to store the public key
+ * @return GNUNET_OK on success
+ */
+int
+GNUNET_CRYPTO_rsa_public_key_from_string (const char *enc, 
+                                         size_t enclen,
+                                         struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *pub)
+{
+  size_t keylen = (sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded)) * 8;
+
+  if (keylen % 5 > 0)
+    keylen += 5 - keylen % 5;
+  keylen /= 5;
+  if (enclen != keylen)
+    return GNUNET_SYSERR;
+
+  if (GNUNET_OK != GNUNET_STRINGS_string_to_data (enc, enclen,
+                                                (unsigned char*) pub,
+                                                sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded)))
+    return GNUNET_SYSERR;
+  if ( (ntohs (pub->len) != sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded)) ||
+       (ntohs (pub->padding) != 0) ||
+       (ntohs (pub->sizen) != GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH) )
+    return GNUNET_SYSERR;
+  return GNUNET_OK;
+}
+
+
 /**
  * Internal: publicKey => RSA-Key.
  *
@@ -271,8 +322,8 @@ public2PrivateKey (const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded
     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)
@@ -292,10 +343,10 @@ public2PrivateKey (const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded
  * @returns encoding of the private key.
  *    The first 4 bytes give the size of the array, as usual.
  */
-static struct RsaPrivateKeyBinaryEncoded *
-rsa_encode_key (const struct GNUNET_CRYPTO_RsaPrivateKey *hostkey)
+struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded *
+GNUNET_CRYPTO_rsa_encode_key (const struct GNUNET_CRYPTO_RsaPrivateKey *hostkey)
 {
-  struct RsaPrivateKeyBinaryEncoded *retval;
+  struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded *retval;
   gcry_mpi_t pkv[6];
   void *pbu[6];
   size_t sizes[6];
@@ -324,14 +375,15 @@ rsa_encode_key (const struct GNUNET_CRYPTO_RsaPrivateKey *hostkey)
   if (rc)
     rc = key_from_sexp (pkv, hostkey->sexp, "rsa", "ned");
   GNUNET_assert (0 == rc);
-  size = sizeof (struct RsaPrivateKeyBinaryEncoded);
+  size = sizeof (struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded);
   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]));
+      GNUNET_assert (0 ==
+                     gcry_mpi_aprint (GCRYMPI_FMT_USG,
+                                      (unsigned char **) &pbu[i], &sizes[i],
+                                      pkv[i]));
       size += sizes[i];
     }
     else
@@ -373,6 +425,7 @@ rsa_encode_key (const struct GNUNET_CRYPTO_RsaPrivateKey *hostkey)
   return retval;
 }
 
+
 /**
  * Decode the private key from the file-format back
  * to the "normal", internal format.
@@ -384,8 +437,8 @@ 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;
+  const struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded *encoding =
+      (const struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded *) buf;
   gcry_sexp_t res;
   gcry_mpi_t n, e, d, p, q, u;
   int rc;
@@ -399,10 +452,9 @@ GNUNET_CRYPTO_rsa_decode_key (const char *buf, uint16_t len)
 
   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)
   {
@@ -410,10 +462,9 @@ GNUNET_CRYPTO_rsa_decode_key (const char *buf, uint16_t len)
     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)
   {
@@ -422,10 +473,9 @@ GNUNET_CRYPTO_rsa_decode_key (const char *buf, uint16_t len)
     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)
   {
@@ -438,10 +488,9 @@ GNUNET_CRYPTO_rsa_decode_key (const char *buf, uint16_t len)
   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)
     {
@@ -457,10 +506,9 @@ GNUNET_CRYPTO_rsa_decode_key (const char *buf, uint16_t len)
   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)
     {
@@ -478,13 +526,12 @@ GNUNET_CRYPTO_rsa_decode_key (const char *buf, uint16_t len)
   pos += ntohs (encoding->sizedmp1);
   pos += ntohs (encoding->sizedmq1);
   size =
-      ntohs (encoding->len) - sizeof (struct RsaPrivateKeyBinaryEncoded) - pos;
+      ntohs (encoding->len) - sizeof (struct GNUNET_CRYPTO_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);
@@ -551,7 +598,7 @@ GNUNET_CRYPTO_rsa_decode_key (const char *buf, uint16_t len)
  * 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 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.
@@ -563,7 +610,7 @@ struct GNUNET_CRYPTO_RsaPrivateKey *
 GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename)
 {
   struct GNUNET_CRYPTO_RsaPrivateKey *ret;
-  struct RsaPrivateKeyBinaryEncoded *enc;
+  struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded *enc;
   uint16_t len;
   struct GNUNET_DISK_FileHandle *fd;
   unsigned int cnt;
@@ -577,9 +624,8 @@ GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename)
   while (GNUNET_YES != GNUNET_DISK_file_test (filename))
   {
     fd = GNUNET_DISK_file_open (filename,
-                                GNUNET_DISK_OPEN_WRITE |
-                                GNUNET_DISK_OPEN_CREATE |
-                                GNUNET_DISK_OPEN_FAILIFEXISTS,
+                                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)
@@ -590,40 +636,37 @@ GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename)
         {
           /* must exist but not be accessible, fail for good! */
           if (0 != ACCESS (filename, R_OK))
-            GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
-                                      "access", filename);
+            LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "access", filename);
           else
             GNUNET_break (0);   /* what is going on!? */
           return NULL;
         }
         continue;
       }
-      GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "open", filename);
+      LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "open", filename);
       return NULL;
     }
     cnt = 0;
 
     while (GNUNET_YES !=
            GNUNET_DISK_file_lock (fd, 0,
-                                  sizeof (struct
-                                          RsaPrivateKeyBinaryEncoded),
+                                  sizeof (struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded),
                                   GNUNET_YES))
     {
       sleep (1);
       if (0 == ++cnt % 10)
       {
         ec = errno;
-        GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                    _
-                    ("Could not aquire lock on file `%s': %s...\n"),
-                    filename, STRERROR (ec));
+        LOG (GNUNET_ERROR_TYPE_ERROR,
+             _("Could not aquire lock on file `%s': %s...\n"), filename,
+             STRERROR (ec));
       }
     }
-    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-                _("Creating a new private key.  This may take a while.\n"));
+    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);
+    enc = GNUNET_CRYPTO_rsa_encode_key (ret);
     GNUNET_assert (enc != NULL);
     GNUNET_assert (ntohs (enc->len) ==
                    GNUNET_DISK_file_write (fd, enc, ntohs (enc->len)));
@@ -632,14 +675,14 @@ GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename)
     GNUNET_DISK_file_sync (fd);
     if (GNUNET_YES !=
         GNUNET_DISK_file_unlock (fd, 0,
-                                 sizeof (struct RsaPrivateKeyBinaryEncoded)))
-      GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename);
+                                 sizeof (struct GNUNET_CRYPTO_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);
-    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-                _("I am host `%s'.  Stored new private key in `%s'.\n"),
-                GNUNET_i2s (&pid), filename);
+    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! */
@@ -647,7 +690,7 @@ GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename)
                               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;
@@ -655,18 +698,18 @@ GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename)
   {
     if (GNUNET_YES !=
         GNUNET_DISK_file_lock (fd, 0,
-                               sizeof (struct RsaPrivateKeyBinaryEncoded),
+                               sizeof (struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded),
                                GNUNET_NO))
     {
       if (0 == ++cnt % 60)
       {
         ec = errno;
-        GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                    _("Could not aquire lock on file `%s': %s...\n"),
-                    filename, STRERROR (ec));
-        GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                    _
-                    ("This may be ok if someone is currently generating a hostkey.\n"));
+        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;
@@ -674,35 +717,35 @@ GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename)
     if (GNUNET_YES != GNUNET_DISK_file_test (filename))
     {
       /* eh, what!? File we opened is now gone!? */
-      GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "stat", filename);
+      LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "stat", filename);
       if (GNUNET_YES !=
           GNUNET_DISK_file_unlock (fd, 0,
-                                   sizeof (struct RsaPrivateKeyBinaryEncoded)))
-        GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename);
+                                   sizeof (struct GNUNET_CRYPTO_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))
+    if (fs < sizeof (struct GNUNET_CRYPTO_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)))
-        GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename);
+                                   sizeof (struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded)))
+        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) fs,
-                    (unsigned int) sizeof (struct RsaPrivateKeyBinaryEncoded));
-        GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                    _
-                    ("This may be ok if someone is currently generating a hostkey.\n"));
+        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 GNUNET_CRYPTO_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;
@@ -716,33 +759,61 @@ GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename)
   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.  Deleting it.\n"),
-                filename);
+    LOG (GNUNET_ERROR_TYPE_ERROR,
+         _("File `%s' does not contain a valid private key.  Deleting it.\n"),
+         filename);
     if (0 != UNLINK (filename))
     {
-      GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "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)))
-    GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename);
+                               sizeof (struct GNUNET_CRYPTO_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);
-    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-                _("I am host `%s'.  Read private key from `%s'.\n"),
-                GNUNET_i2s (&pid), filename);
+    LOG (GNUNET_ERROR_TYPE_INFO,
+         _("I am host `%s'.  Read private key from `%s'.\n"), GNUNET_i2s (&pid),
+         filename);
   }
   return ret;
 }
 
 
+/**
+ * Setup a hostkey file for a peer given the name of the
+ * configuration file (!).  This function is used so that
+ * at a later point code can be certain that reading a
+ * hostkey is fast (for example in time-dependent testcases).
+ *
+ * @param cfg_name name of the configuration file to use
+ */
+void
+GNUNET_CRYPTO_setup_hostkey (const char *cfg_name)
+{
+  struct GNUNET_CONFIGURATION_Handle *cfg;
+  struct GNUNET_CRYPTO_RsaPrivateKey *pk;
+  char *fn;
+
+  cfg = GNUNET_CONFIGURATION_create ();
+  (void) GNUNET_CONFIGURATION_load (cfg, cfg_name);
+  if (GNUNET_OK == 
+      GNUNET_CONFIGURATION_get_value_filename (cfg, "GNUNETD", "HOSTKEY", &fn))
+  {
+    pk = GNUNET_CRYPTO_rsa_key_create_from_file (fn);
+    if (NULL != pk)
+      GNUNET_CRYPTO_rsa_key_free (pk);
+    GNUNET_free (fn);
+  }
+  GNUNET_CONFIGURATION_destroy (cfg);
+}
+
+
 /**
  * Encrypt a block with the public key of another host that uses the
  * same cipher.
@@ -754,10 +825,9 @@ 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,
-                           size_t size,
-                           const struct
-                           GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *publicKey,
+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;
@@ -786,15 +856,16 @@ 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));
   return GNUNET_OK;
 }
 
+
 /**
  * Decrypt a given block with the hostkey.
  *
@@ -807,8 +878,8 @@ GNUNET_CRYPTO_rsa_encrypt (const void *block,
  */
 ssize_t
 GNUNET_CRYPTO_rsa_decrypt (const struct GNUNET_CRYPTO_RsaPrivateKey * key,
-                           const struct GNUNET_CRYPTO_RsaEncryptedData *
-                           block, void *result, size_t max)
+                           const struct GNUNET_CRYPTO_RsaEncryptedData * block,
+                           void *result, size_t max)
 {
   gcry_sexp_t resultsexp;
   gcry_sexp_t data;
@@ -822,12 +893,12 @@ GNUNET_CRYPTO_rsa_decrypt (const struct GNUNET_CRYPTO_RsaPrivateKey * key,
   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, key->sexp));
   gcry_sexp_release (data);
@@ -858,8 +929,8 @@ GNUNET_CRYPTO_rsa_decrypt (const struct GNUNET_CRYPTO_RsaPrivateKey * key,
  */
 int
 GNUNET_CRYPTO_rsa_sign (const struct GNUNET_CRYPTO_RsaPrivateKey *key,
-                        const struct GNUNET_CRYPTO_RsaSignaturePurpose
-                        *purpose, struct GNUNET_CRYPTO_RsaSignature *sig)
+                        const struct GNUNET_CRYPTO_RsaSignaturePurpose *purpose,
+                        struct GNUNET_CRYPTO_RsaSignature *sig)
 {
   gcry_sexp_t result;
   gcry_sexp_t data;
@@ -886,9 +957,9 @@ GNUNET_CRYPTO_rsa_sign (const struct GNUNET_CRYPTO_RsaPrivateKey *key,
   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;
@@ -927,9 +998,9 @@ GNUNET_CRYPTO_rsa_verify (uint32_t purpose,
     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_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));
@@ -937,9 +1008,10 @@ GNUNET_CRYPTO_rsa_verify (uint32_t purpose,
   bufSize = strlen (FORMATSTRING) + 1;
   buff = GNUNET_malloc (bufSize);
   memcpy (buff, FORMATSTRING, bufSize);
-  memcpy (&buff[strlen (FORMATSTRING) -
-                strlen
-                ("0123456789012345678901234567890123456789012345678901234567890123))")],
+  memcpy (&buff
+          [strlen (FORMATSTRING) -
+           strlen
+           ("0123456789012345678901234567890123456789012345678901234567890123))")],
           &hc, sizeof (GNUNET_HashCode));
   GNUNET_assert (0 == gcry_sexp_new (&data, buff, bufSize, 0));
   GNUNET_free (buff);
@@ -956,9 +1028,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;