(void) GNUNET_DISK_file_close (fd);
return NULL;
}
+ if (0 == fs)
+ {
+ GNUNET_break (GNUNET_OK == GNUNET_DISK_file_close (fd));
+ return NULL;
+ }
if (fs > UINT16_MAX)
{
LOG (GNUNET_ERROR_TYPE_ERROR,
- _("File `%s' does not contain a valid private key. Deleting it.\n"),
- filename);
+ _("File `%s' does not contain a valid private key (too long, %llu bytes). Deleting it.\n"),
+ filename,
+ (unsigned long long) fs);
GNUNET_break (GNUNET_OK == GNUNET_DISK_file_close (fd));
if (0 != UNLINK (filename))
LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "unlink", filename);
(NULL == (ret = GNUNET_CRYPTO_rsa_decode_key ((char *) enc, len))))
{
LOG (GNUNET_ERROR_TYPE_ERROR,
- _("File `%s' does not contain a valid private key. Deleting it.\n"),
- filename);
+ _("File `%s' does not contain a valid private key (failed decode, %llu bytes). Deleting it.\n"),
+ filename,
+ (unsigned long long) fs);
GNUNET_break (GNUNET_OK == GNUNET_DISK_file_close (fd));
if (0 != UNLINK (filename))
LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "unlink", filename);
}
+/**
+ * Wait for a short time (we're trying to lock a file or want
+ * to give another process a shot at finishing a disk write, etc.).
+ * Sleeps for 100ms (as that should be long enough for virtually all
+ * modern systems to context switch and allow another process to do
+ * some 'real' work).
+ */
+static void
+short_wait ()
+{
+ struct GNUNET_TIME_Relative timeout;
+
+ timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 100);
+ (void) GNUNET_NETWORK_socket_select (NULL, NULL, NULL, timeout);
+}
+
+
/**
* Create a new private key by reading it from a file. If the
* files does not exist, create a new key and write it to the
sizeof (struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded),
GNUNET_YES))
{
- sleep (1);
+ short_wait (1);
if (0 == ++cnt % 10)
{
ec = errno;
_
("This may be ok if someone is currently generating a hostkey.\n"));
}
- sleep (1);
+ short_wait (1);
continue;
}
if (GNUNET_YES != GNUNET_DISK_file_test (filename))
_
("This may be ok if someone is currently generating a hostkey.\n"));
}
- sleep (2); /* wait a bit longer! */
+ short_wait (1); /* wait a bit longer! */
continue;
}
break;
const struct GNUNET_SCHEDULER_TaskContext *tc)
{
struct GNUNET_CRYPTO_RsaKeyGenerationContext *gc = cls;
- enum GNUNET_OS_ProcessStatusType type;
- unsigned long code;
struct GNUNET_CRYPTO_RsaPrivateKey *pk;
gc->read_task = GNUNET_SCHEDULER_NO_TASK;
GNUNET_CRYPTO_rsa_key_create_stop (gc);
return;
}
- if (GNUNET_OK !=
- GNUNET_OS_process_status (gc->gnunet_rsa,
- &type, &code))
- {
- GNUNET_break (0);
- gc->cont (gc->cont_cls, NULL, _("internal error"));
- GNUNET_CRYPTO_rsa_key_create_stop (gc);
- return;
- }
+ GNUNET_assert (GNUNET_OK ==
+ GNUNET_OS_process_wait (gc->gnunet_rsa));
GNUNET_OS_process_destroy (gc->gnunet_rsa);
gc->gnunet_rsa = NULL;
- if ( (GNUNET_OS_PROCESS_EXITED != type) ||
- (0 != code) )
- {
- gc->cont (gc->cont_cls, NULL, _("gnunet-rsa failed"));
- GNUNET_CRYPTO_rsa_key_create_stop (gc);
- return;
- }
if (NULL == (pk = try_read_key (gc->filename)))
{
GNUNET_break (0);
return;
}
gc->cont (gc->cont_cls, pk, NULL);
+ GNUNET_DISK_pipe_close (gc->gnunet_rsa_out);
GNUNET_free (gc->filename);
GNUNET_free (gc);
}
{
struct GNUNET_CRYPTO_RsaKeyGenerationContext *gc;
struct GNUNET_CRYPTO_RsaPrivateKey *pk;
+ const char *weak_random;
if (NULL != (pk = try_read_key (filename)))
{
GNUNET_free (gc);
return NULL;
}
+ weak_random = NULL;
+ if (GNUNET_YES ==
+ GNUNET_CRYPTO_random_is_weak ())
+ weak_random = "-w";
gc->gnunet_rsa = GNUNET_OS_start_process (GNUNET_NO,
GNUNET_OS_INHERIT_STD_ERR,
NULL,
gc->gnunet_rsa_out,
"gnunet-rsa",
- "gnunet-rsa",
+ "gnunet-rsa",
gc->filename,
+ weak_random,
NULL);
if (NULL == gc->gnunet_rsa)
{